{
  "generatedAt": "2026-09-21T13:53:31.646Z",
  "libVersion": "1.20.0",
  "components": {
    "Accordion": {
      "name": "Accordion",
      "group": "components",
      "folderName": "Accordion",
      "role": "primary",
      "description": "Список сворачиваемых секций с заголовками — для скрытия объёмного контента до клика",
      "props": [],
      "propsTypeName": "ComponentProps<typeof Accordion>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Accordion/Accordion.d.ts",
      "type": "wrapper",
      "atomicBase": "Accordion",
      "category": "Локальные компоненты",
      "keywords": [
        "сворачиваемые блоки",
        "expand collapse",
        "раскрывающийся список"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "defaultActiveEventKey",
          "type": "number[]",
          "required": false,
          "inheritedFrom": "Accordion",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Accordion",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "((index?: number, value?: boolean) => void) | undefined",
          "required": false,
          "inheritedFrom": "Accordion",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "singleActive",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Accordion",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"h2\" | \"h3\" | \"h4\" | \"h5\" | \"s\" | \"l\" | \"m\" | \"xs\"",
          "required": false,
          "inheritedFrom": "Accordion",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretching",
          "type": "\"filled\" | \"fixed\"",
          "required": false,
          "inheritedFrom": "Accordion",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\"",
          "required": false,
          "inheritedFrom": "Accordion",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Accordion } from '@daisforge/ui';",
      "minimalUsage": "<Accordion />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в LeftPanel.stories.tsx",
          "type": "usage",
          "code": "<Accordion size=\"s\" view=\"clear\" stretching=\"filled\">\n                          <AccordionItem\n                            type=\"arrow\"\n                            title=\"Короткий текст тут\"\n                          >\n                            <List view=\"default\" size=\"s\" variant=\"tight\">\n                              <ListItem>\n                                Aaa +{' '}\n                                {index % 2 === 0\n                                  ? 'aaaaa aaaaaaaaa aaaaaaa aaaaaaaaa'.repeat(\n                                      // eslint-disable-next-line prettier/prettier\n                                      10,\n                                    )\n                                  : ''}\n                              </ListItem>\n                            </List>\n                          </AccordionItem>\n                        </Accordion>",
          "sourceFile": "packages/storybook/src/stories/LeftPanel/LeftPanel.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Примеры Accordion",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Accordion, AccordionItem } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Accordion>\n                <AccordionItem title=\"Как оплатить заправку бонусами СберСпасибо?\">После указания деталей заправки нажмите кнопку «К оплате». Откроется окно оплаты, где вы сможете списать бонусы и оплатить ими до 99% стоимости топлива</AccordionItem>\n                <AccordionItem title=\"Как оплатить заправку бонусами СберСпасибо?\">После указания деталей заправки нажмите кнопку «К оплате». Откроется окно оплаты, где вы сможете списать бонусы и оплатить ими до 99% стоимости топлива</AccordionItem>\n                <AccordionItem title=\"Как оплатить заправку бонусами СберСпасибо?\">После указания деталей заправки нажмите кнопку «К оплате». Откроется окно оплаты, где вы сможете списать бонусы и оплатить ими до 99% стоимости топлива</AccordionItem>\n            </Accordion>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Использование AccordionItem атрибута Type",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Accordion, AccordionItem } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Accordion size=\"s\">\n                <AccordionItem type=\"arrow\" title=\"Как оплатить заправку бонусами СберСпасибо?\">После указания деталей заправки нажмите кнопку «К оплате». Откроется окно оплаты, где вы сможете списать бонусы и оплатить ими до 99% стоимости топлива</AccordionItem>\n                <AccordionItem type=\"arrow\" title=\"Как оплатить заправку бонусами СберСпасибо?\">После указания деталей заправки нажмите кнопку «К оплате». Откроется окно оплаты, где вы сможете списать бонусы и оплатить ими до 99% стоимости топлива</AccordionItem>\n                <AccordionItem type=\"arrow\" title=\"Как оплатить заправку бонусами СберСпасибо?\">После указания деталей заправки нажмите кнопку «К оплате». Откроется окно оплаты, где вы сможете списать бонусы и оплатить ими до 99% стоимости топлива</AccordionItem>\n            </Accordion>\n        </div>\n    );\n}"
        }
      ]
    },
    "AccordionItem": {
      "name": "AccordionItem",
      "group": "components",
      "folderName": "Accordion",
      "role": "primary",
      "description": "Одна секция аккордеона с заголовком и телом — используется внутри Accordion",
      "props": [
        {
          "name": "alignWithTitle",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "bodyProps",
          "type": "React.HTMLAttributes<HTMLDivElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "defaultIconContent",
          "type": "AccordionItemDefaultIconContent | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "defaultIconPlacement",
          "type": "AccordionItemDefaultIconPlacement | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "eventKey",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "index",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChange",
          "type": "((index: number, value: boolean) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onClick",
          "type": "(React.MouseEventHandler<HTMLElement> & ((index: number, value: boolean) => void)) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "opened",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "title",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "titleProps",
          "type": "React.HTMLAttributes<HTMLElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"clear\" | \"arrow\" | \"sign\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "value",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof AccordionItem>",
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Accordion/ui/AccordionItem/AccordionItem.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "секция аккордеона",
        "collapsible panel",
        "раскрывающийся блок"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { AccordionItem } from '@daisforge/ui';",
      "minimalUsage": "<AccordionItem />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в LeftPanel.stories.tsx",
          "type": "usage",
          "code": "<AccordionItem\n                            type=\"arrow\"\n                            title=\"Короткий текст тут\"\n                          >\n                            <List view=\"default\" size=\"s\" variant=\"tight\">\n                              <ListItem>\n                                Aaa +{' '}\n                                {index % 2 === 0\n                                  ? 'aaaaa aaaaaaaaa aaaaaaa aaaaaaaaa'.repeat(\n                                      // eslint-disable-next-line prettier/prettier\n                                      10,\n                                    )\n                                  : ''}\n                              </ListItem>\n                            </List>\n                          </AccordionItem>",
          "sourceFile": "packages/storybook/src/stories/LeftPanel/LeftPanel.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Примеры Accordion",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Accordion, AccordionItem } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Accordion>\n                <AccordionItem title=\"Как оплатить заправку бонусами СберСпасибо?\">После указания деталей заправки нажмите кнопку «К оплате». Откроется окно оплаты, где вы сможете списать бонусы и оплатить ими до 99% стоимости топлива</AccordionItem>\n                <AccordionItem title=\"Как оплатить заправку бонусами СберСпасибо?\">После указания деталей заправки нажмите кнопку «К оплате». Откроется окно оплаты, где вы сможете списать бонусы и оплатить ими до 99% стоимости топлива</AccordionItem>\n                <AccordionItem title=\"Как оплатить заправку бонусами СберСпасибо?\">После указания деталей заправки нажмите кнопку «К оплате». Откроется окно оплаты, где вы сможете списать бонусы и оплатить ими до 99% стоимости топлива</AccordionItem>\n            </Accordion>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Использование AccordionItem атрибута Type",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Accordion, AccordionItem } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Accordion size=\"s\">\n                <AccordionItem type=\"arrow\" title=\"Как оплатить заправку бонусами СберСпасибо?\">После указания деталей заправки нажмите кнопку «К оплате». Откроется окно оплаты, где вы сможете списать бонусы и оплатить ими до 99% стоимости топлива</AccordionItem>\n                <AccordionItem type=\"arrow\" title=\"Как оплатить заправку бонусами СберСпасибо?\">После указания деталей заправки нажмите кнопку «К оплате». Откроется окно оплаты, где вы сможете списать бонусы и оплатить ими до 99% стоимости топлива</AccordionItem>\n                <AccordionItem type=\"arrow\" title=\"Как оплатить заправку бонусами СберСпасибо?\">После указания деталей заправки нажмите кнопку «К оплате». Откроется окно оплаты, где вы сможете списать бонусы и оплатить ими до 99% стоимости топлива</AccordionItem>\n            </Accordion>\n        </div>\n    );\n}"
        }
      ]
    },
    "AiAgentPopover": {
      "name": "AiAgentPopover",
      "group": "components",
      "folderName": "AiAgentPopover",
      "role": "primary",
      "description": "Плавающий перетаскиваемый и изменяемый по размеру popover для AI-ассистента поверх экрана",
      "props": [
        {
          "name": "calculateOffset",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включить / Выключить перерасчёт offset для кастомных значений placement. top-right, top-left, bottom-right, bottom-left, чтобы стрелка popover была в центре target элемента, а контент пропорционально смещен в зависимости от placement.",
          "default": "true"
        },
        {
          "name": "calculatePlacement",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включить / Выключить перерасчёт placement в режиме draggable.",
          "default": "true"
        },
        {
          "name": "defaultPosition",
          "type": "AiAgentPopoverCustomPlacement | AiAgentPopoverPosition | undefined",
          "required": false,
          "description": "Начальная позиция при первом рендере (используется только если НЕ передан positionState и НЕ используется useStorage)",
          "default": "'bottom-right'"
        },
        {
          "name": "dragBoundary",
          "type": "AiAgentPopoverDragBoundary | undefined",
          "required": false,
          "description": "Ограничение области в рамках которой можно перемещать элемент"
        },
        {
          "name": "draggable",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включить / Выключить перетаскивание",
          "default": "false"
        },
        {
          "name": "ignoreToggleOnDrag",
          "type": "boolean | undefined",
          "required": false,
          "description": "В момент драга сохранять текущий стейт видимости popover. При перетаскивании закрытого popover в момент завершения перетаскивания popover не откроется, если этот пропс активен. Аналогично с открытым состоянием.",
          "default": "true"
        },
        {
          "name": "onPositionChange",
          "type": "((pos: { x: number; y: number; }) => void) | undefined",
          "required": false,
          "description": "Callback смены позиции в draggable режиме в момент перетаскивания"
        },
        {
          "name": "placement",
          "type": "AiAgentPopoverPlacement",
          "required": false,
          "description": "Позиция отображения popover.",
          "default": "'auto'"
        },
        {
          "name": "positionState",
          "type": "AiAgentPopoverPositionState | undefined",
          "required": false,
          "description": "Внешний стейт позиции [position, setPosition].\nЕсли не передан, будет использован внутренний стейт. Не используется для интеграции с localStorage. Данное поле отвечает за полное внешнее управление позицией"
        },
        {
          "name": "resizable",
          "type": "boolean | ((placement: AiAgentPopoverPlacement) => Partial<{ disabled?: boolean | undefined; directions?: ResizeDirections | undefined; defaultSize?: { width?: number | undefined; height?: number | undefined; } | undefined; minWidth?: number | undefined; minHeight?: number | undefined; maxWidth?: number | undefined; maxHeight?: number | undefined; icons?: { topRight?: React.ReactNode; bottomRight?…",
          "required": false,
          "description": "Включить / настроить resizable-режим.\n- `true`: включить с дефолтной конфигурацией (иконка ресайза автоматически позиционируется в зависимости от placement).\n- `(placement: AiAgentPopoverPlacement) => config`: функция для кастомной конфигурации. Принимает текущий placement,\n  возвращает частичную конфигурацию, которая мержится с дефолтной.",
          "default": "undefined"
        },
        {
          "name": "targetDataAttributes",
          "type": "DataAttributes | undefined",
          "required": false,
          "description": "Data-атрибуты для target-кнопки (MagicButton). Например: data-onboarding-id, data-testid"
        },
        {
          "name": "useStorage",
          "type": "string | boolean | undefined",
          "required": false,
          "description": "Сохранять ли позицию в localStorage.\n- `true`: автосохранение с ключом `ai-agent-popover-position`.\n- `string`: кастомный ключ (например, `my-popover-position`).\n- `false`: отключено.",
          "default": "false"
        },
        {
          "name": "animated",
          "type": "boolean | undefined",
          "required": false,
          "description": "Анимированное появление Popover"
        },
        {
          "name": "closeOnEsc",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрывать окно при нажатии ESC.",
          "default": "true"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрывать окно при нажатии вне области окна. (Если trigger === 'click')"
        },
        {
          "name": "frame",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "В каком контейнере позиционируется(по умолчанию document), можно также указать id элемента или ref для него."
        },
        {
          "name": "hasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": "Есть ли стрелка над элементом."
        },
        {
          "name": "isFocusTrapped",
          "type": "boolean | undefined",
          "required": false,
          "description": "Блокировать ли фокус на всплывающем окне.",
          "default": "true"
        },
        {
          "name": "offset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 14]"
        },
        {
          "name": "onResizeEnd",
          "type": "((resizableContainer?: React.RefObject<Resizable> | undefined) => void) | undefined",
          "required": false,
          "description": "Обработчик остановки ресайза."
        },
        {
          "name": "onResizeStart",
          "type": "((resizableContainer?: React.RefObject<Resizable> | undefined) => void) | undefined",
          "required": false,
          "description": "Обработчик начала ресайза."
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean, event: Event | React.SyntheticEvent<Element, Event>) => void) | undefined",
          "required": false,
          "description": "Событие сворачивания/разворачивания всплывающего окна."
        },
        {
          "name": "opened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Всплывающее окно раскрыто или нет."
        },
        {
          "name": "preventOverflow",
          "type": "boolean | undefined",
          "required": false,
          "description": "Предотвратить автоматическое изменение положения."
        },
        {
          "name": "stretchHeight",
          "type": "boolean | undefined",
          "required": false,
          "description": "Растянуть Popover до границы доступной области по вертикали."
        },
        {
          "name": "target",
          "type": "string | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | ((instance: HTMLElement | null) => void) | React.RefObject<HTMLElement> | null | undefined",
          "required": false,
          "description": "Элемент или ref на элемент, рядом с которым произойдет вызов всплывающего окна."
        },
        {
          "name": "trigger",
          "type": "PopoverTrigger | undefined",
          "required": false,
          "description": "Способ открытия всплывающего окна - наведение или клик мышью.",
          "default": "'click'"
        },
        {
          "name": "usePortal",
          "type": "boolean | undefined",
          "required": false,
          "description": "Находится ли в портале.",
          "default": "false"
        },
        {
          "name": "zIndex",
          "type": "string | undefined",
          "required": false,
          "description": "Значение z-index для Popover."
        },
        {
          "name": "contentContainerClassNames",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isOpen",
          "type": "boolean | undefined",
          "required": false,
          "description": "",
          "deprecated": true
        }
      ],
      "propsTypeName": "AiAgentPopoverProps",
      "sourceFile": "packages/ui-kit/src/components/AiAgentPopover/AiAgentPopover.tsx",
      "type": "wrapper",
      "category": "Локальные компоненты",
      "hint": "Не путать с PopoverDF — тот универсальный. AiAgentPopover только для команды AI-агента.",
      "keywords": [
        "ai-ассистент",
        "draggable popover",
        "плавающее окно"
      ],
      "scope": "internal",
      "docs": "# AiAgentPopover\n\nОбёртка над [SDDS Popover](https://plasma.sberdevices.ru/sdds-finai/components/popover/) — компонент для отображения контекстного попапа рядом с элементом.\nИспользуется, например, для показа AI-ассистента или справочной информации.\n\n## Ключевые особенности\n\n- Гибкое позиционирование с автоматической коррекцией (`calculatePlacement`, `calculateOffset`)\n- Режим перетаскивания (`draggable`) с порогом срабатывания и границами\n- Кастомные anchor-точки для точного размещения (`defaultPosition`)\n- Автосохранение позиции в localStorage (`useStorage`)\n- Resizable-режим с автоматическим позиционированием иконки ресайза\n- Контролируемый стейт видимости через `opened` / `onToggle`\n\n## Особенности\n\n**Режим перетаскивания (draggable)**\n\n```tsx\n<AiAgentPopover draggable dragBoundary={{ top: 20, bottom: 20 }}>\n  Контент попапа\n</AiAgentPopover>\n```\n\nОсобенности работы:\n\n- Порог срабатывания (5px) - предотвращает случайные срабатывания при клике\n- Границы перемещения - ограничиваются областью окна с учетом dragBoundary\n- Игнор кликов - при активации ignoreToggleOnDrag не открывает popover после перетаскивания\n\n**Автоматические расчеты** `calculatePlacement` и `calculateOffset`\n\n```tsx\n<AiAgentPopover\n  calculatePlacement={false}\n  calculateOffset={false}\n  placement=\"bottom-right\"\n>\n  Контент попапа с выключенными расчётами В данном примере, несмотря на\n  использования кастомного значения placement, корректировка offset работать не\n  будет, так как ее отключили. calculatePlacement также не будет работать,\n  потому сама опция выключена, к тому же нет draggable режима.\n</AiAgentPopover>\n```\n\nОсобенности работы:\n\n- calculatePlacement и calculateOffset включены по умолчанию\n- calculatePlacement используется в режиме draggable. Процесс вычисления нужного значения placement происходит в момент перетаскивания target. Фича делит экран на 6 секторов. Для каждого сектора свой placement. 1 - bottom-left, 2 - bottom, 3 - bottom-right, 4 - top-right, 5 - top, 6 - top-left. Если в момент вычисления placement контент popover выходит за границы экрана, то будет применено значение auto, корректировки offset в таком случае не будет и popover будет вести себя стандартно, как ведет себя атомарный компонент.\n- calculateOffset необходим для вычисления правильного (с точки зрения дизайн-макетов) значения offset для каждого кастомного значения placement (bottom-left, bottom-right, top-left, top-right).\n\n**Кастомные позиции**\n\n```tsx\n// Вариант 1: Координаты\n<AiAgentPopover defaultPosition={{ x: 200, y: 200 }} />\n\n// Вариант 2: Кастомное размещение\n<AiAgentPopover defaultPosition=\"bottom-left\" />\n\n// Вариант 3: Нужные кастомные значения, но чтобы popover открывался вниз со смещением влево\n<AiAgentPopover defaultPosition={{ x: 200, y: 200 }} placement=\"bottom-left\" />\n```\n\nЛогика расчёта:\n\ndefaultPosition может быть как объектом с координатами, так и строковым значением (как кастомные placement). Если вы выбираете defaultPosition как строковую позицию (top-left, top-right, bottom-left, bottom-right), то target элемент popover встанет в нужную заранее подготовленную позицию. Такое поведение актуально, если НЕ активирован useStorage (иначе позиция берется из localStorage) и НЕ заданы значения dragBoundary, которые не позволяют ему там находиться и НЕ используется positionState (внешний [стейт, сеттер] позиции)\n\n**Resizable-режим**\n\n```tsx\n// Вариант 1: Дефолтная конфигурация — иконка ресайза позиционируется автоматически\n<AiAgentPopover draggable resizable>\n  Контент попапа\n</AiAgentPopover>\n\n// Вариант 2: Callback — получаем текущий placement, переопределяем нужные поля\n<AiAgentPopover\n  draggable\n  resizable={(placement) => ({\n    defaultSize: { width: 300, height: 200 },\n    minWidth: 250,\n    maxWidth: 600,\n  })}\n>\n  Контент попапа\n</AiAgentPopover>\n```\n\nОсобенности работы:\n\n- Проп `resizable` принимает `boolean` или callback-функцию `(placement) => Partial<AiAgentPopoverResizableConfig>`\n- При `resizable={true}` иконка ресайза (`IconResizeCorneredFill`) автоматически позиционируется в угол, диагонально противоположный target-элементу, в зависимости от текущего placement:\n  - `bottom-right` / `bottom` → иконка в правом нижнем углу\n  - `bottom-left` → иконка в левом нижнем углу\n  - `top-right` / `top` → иконка в правом верхнем углу\n  - `top-left` → иконка в левом верхнем углу\n- Иконка автоматически отзеркаливается (`scaleX`/`scaleY`) для корректного визуального отображения в каждом углу\n- При передаче callback-функции результат мержится с дефолтной конфигурацией — можно переопределить только нужные поля (`defaultSize`, `minWidth`, `icons`, `hiddenIcons` и т.д.)\n- Свойства `onResizeStart` и `onResizeEnd` передаются отдельными пропсами, как и раньше\n\n**Рекомендации по использованию**\n\nОптимальные параметры для AI-ассистента:\n\n```tsx\n<AiAgentPopover\n  draggable\n  useStorage=\"your-custom-key-for-local-storage\"\n  defaultPosition=\"bottom-right\"\n  dragBoundary={{ bottom: 10, right: 10, top: 10, left: 10 }}\n>\n <div style={{ minWidth: '224px' }}>\n  <H3>AI Assistant</H3>\n  <BodyS style={{ margin: '8px 0', color: textSecondary }}>\n    Пример содержимого AI-ассистента\n  </BodyS>\n  <div style={{ display: 'flex', gap: '8px', width: '100%' }}>\n    <Button\n      size=\"s\"\n      view=\"secondary\"\n      onClick={onClose}\n      style={{ flexGrow: 1 }}\n    >\n      Отмена\n    </Button>\n    <Button size=\"s\" view=\"accent\" style={{ flexGrow: 1 }}>\n      Применить\n    </Button>\n  </div>\n  </div>\n<AiAgentPopover />\n```\n\n**Отключение автоматики:**\n\n```tsx\n<AiAgentPopover\n  calculatePlacement={false}\n  calculateOffset={false}\n  placement=\"right\"\n  offset={[10, 20]}\n>\n <div style={{ minWidth: '224px' }}>\n  <H3>AI Assistant</H3>\n  <BodyS style={{ margin: '8px 0', color: textSecondary }}>\n    Пример содержимого AI-ассистента\n  </BodyS>\n  <div style={{ display: 'flex', gap: '8px', width: '100%' }}>\n    <Button\n      size=\"s\"\n      view=\"secondary\"\n      onClick={onClose}\n      style={{ flexGrow: 1 }}\n    >\n      Отмена\n    </Button>\n    <Button size=\"s\" view=\"accent\" style={{ flexGrow: 1 }}>\n      Применить\n    </Button>\n  </div>\n  </div>\n<AiAgentPopover />\n```\n\n**Контролирование стейта видимости снаружи:**\n\n```tsx\nfunction Example() {\n  const [isOpen, setIsOpen] = useState(false);\n  return (\n    <div style={{ display: 'flex', justifyContent: 'center', padding: '50px' }}>\n      <AiAgentPopover\n        draggable\n        opened={isOpen}\n        onToggle={setIsOpen}\n        defaultPosition=\"bottom-right\"\n        useStorage=\"custom-key-for-local-storage\"\n      >\n        <PopoverContent onClose={() => setIsOpen(false)} />\n      </AiAgentPopover>\n    </div>\n  );\n}\n```\n\n> Подробнее о типах и пропсах — [AiAgentPopover API](?path=/docs/локальные-компоненты-aiagentpopover-api--docs)",
      "apiDocs": "# AiAgentPopover API\n\n## AiAgentPopoverProps\n\n> Базовые пропсы наследуются от `PopoverProps`: [SDDS Popover](https://plasma.sberdevices.ru/sdds-finai/components/popover/)\n\n```typescript\ntype AiAgentPopoverProps = Omit<\n  PopoverProps,\n  'view' | 'placement' | 'resizable'\n> & {\n  contentContainerClassNames?: string;\n  /**\n   * Включить / Выключить перерасчёт offset для кастомных значений placement. top-right, top-left, bottom-right, bottom-left, чтобы стрелка popover была в центре target элемента, а контент пропорционально смещен в зависимости от placement.\n   * @default true\n   */\n  calculateOffset?: boolean;\n  /**\n   * Включить / Выключить перерасчёт placement в режиме draggable.\n   * @default true\n   */\n  calculatePlacement?: boolean;\n  /**\n   * Позиция отображения popover.\n   * @default auto\n   */\n  placement?: AiAgentPopoverPlacement;\n  /**\n   * Включить / Выключить перетаскивание\n   * @default false\n   */\n  draggable?: boolean;\n  /**\n   * Внешний стейт позиции [position, setPosition].\n   * Если не передан, будет использован внутренний стейт. Не используется для интеграции с localStorage. Данное поле отвечает за полное внешнее управление позицией\n   */\n  positionState?: AiAgentPopoverPositionState;\n  /**\n   * Начальная позиция при первом рендере (используется только если НЕ передан positionState и НЕ используется useStorage)\n   * @default \"bottom-right\"\n   */\n  defaultPosition?: AiAgentPopoverPosition | AiAgentPopoverCustomPlacement;\n  /**\n   * Ограничение области в рамках которой можно перемещать элемент\n   */\n  dragBoundary?: AiAgentPopoverDragBoundary;\n  /**\n   * В момент драга сохранять текущий стейт видимости popover. При перетаскивании закрытого popover в момент завершения перетаскивания popover не откроется, если этот пропс активен. Аналогично с открытым состоянием.\n   * @default true\n   */\n  ignoreToggleOnDrag?: boolean;\n  /**\n   * Callback смены позиции в draggable режиме в момент перетаскивания\n   */\n  onPositionChange?: (pos: { x: number; y: number }) => void;\n  /**\n   * Сохранять ли позицию в localStorage.\n   * - `true`: автосохранение с ключом `ai-agent-popover-position`.\n   * - `string`: кастомный ключ (например, `my-popover-position`).\n   * - `false`: отключено.\n   * @default false\n   */\n  useStorage?: boolean | string;\n  /**\n   * Включить / настроить resizable-режим.\n   * - `true`: включить с дефолтной конфигурацией (иконка ресайза автоматически позиционируется в зависимости от placement).\n   * - `(placement: AiAgentPopoverPlacement) => config`: функция для кастомной конфигурации. Принимает текущий placement,\n   *   возвращает частичную конфигурацию, которая мержится с дефолтной.\n   * @default undefined\n   */\n  resizable?:\n    | boolean\n    | ((\n        placement: AiAgentPopoverPlacement,\n      ) => Partial<AiAgentPopoverResizableConfig>);\n\n  /**\n   * Data-атрибуты для target-кнопки (MagicButton). Например: data-onboarding-id, data-testid\n   */\n  targetDataAttributes?: DataAttributes;\n};\n```\n\n## AiAgentPopoverCustomPlacement\n\n```typescript\ntype AiAgentPopoverCustomPlacement =\n  | 'top-right'\n  | 'top-left'\n  | 'bottom-right'\n  | 'bottom-left';\n```\n\n## AiAgentPopoverPlacement\n\n```typescript\ntype AiAgentPopoverPlacement =\n  | PopoverProps['placement']\n  | AiAgentPopoverCustomPlacement;\n```",
      "curatedStories": [
        {
          "exportName": "Resizable",
          "displayName": "Resizable",
          "type": "full-code",
          "code": "import { AiAgentPopover } from '@daisforge/ui';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/AiAgentPopover/AiAgentPopover.stories.tsx',\n  'PopoverContent',\n)}\n\nrender() {\n    return (\n      <div\n        style={{\n          height: '100vh',\n        }}\n      >\n        <AiAgentPopover\n          draggable\n          defaultPosition=\"bottom-right\"\n          dragBoundary={{\n            bottom: 10,\n            top: 10,\n            left: 10,\n            right: 10,\n          }}\n          resizable={() => ({ minWidth: 250 })}\n          onResizeStart={() => {\n            // eslint-disable-next-line no-console\n            console.debug('resize start');\n          }}\n          onResizeEnd={() => {\n            // eslint-disable-next-line no-console\n            console.debug('resize end');\n          }}\n          useStorage\n          targetDataAttributes={{\n            'data-testid': 'aiAgentPopover',\n          }}\n        >\n          <PopoverContent onClose={() => alert('close')} />\n        </AiAgentPopover>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Uncontrolled",
          "displayName": "Example",
          "type": "full-code",
          "code": "import { AiAgentPopover } from '@daisforge/ui';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/AiAgentPopover/AiAgentPopover.stories.tsx',\n  'PopoverContent',\n)}\n\nrender() {\n    return (\n      <div\n        style={{\n          height: '100vh',\n        }}\n      >\n        <AiAgentPopover\n          draggable\n          defaultPosition=\"bottom-right\"\n          dragBoundary={{\n            bottom: 10,\n            top: 10,\n            left: 10,\n            right: 10,\n          }}\n          onPositionChange={(pos) => {\n            // eslint-disable-next-line no-console\n            console.debug('pos', pos);\n          }}\n          useStorage\n          targetDataAttributes={{\n            'data-testid': 'aiAgentPopover',\n          }}\n        >\n          <PopoverContent onClose={() => alert('close')} />\n        </AiAgentPopover>\n      </div>\n    );\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { AiAgentPopover } from '@daisforge/ui';",
      "minimalUsage": "<AiAgentPopover />",
      "examples": [
        {
          "exportName": "Resizable",
          "displayName": "Resizable",
          "type": "full-code",
          "code": "import { AiAgentPopover } from '@daisforge/ui';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/AiAgentPopover/AiAgentPopover.stories.tsx',\n  'PopoverContent',\n)}\n\nrender() {\n    return (\n      <div\n        style={{\n          height: '100vh',\n        }}\n      >\n        <AiAgentPopover\n          draggable\n          defaultPosition=\"bottom-right\"\n          dragBoundary={{\n            bottom: 10,\n            top: 10,\n            left: 10,\n            right: 10,\n          }}\n          resizable={() => ({ minWidth: 250 })}\n          onResizeStart={() => {\n            // eslint-disable-next-line no-console\n            console.debug('resize start');\n          }}\n          onResizeEnd={() => {\n            // eslint-disable-next-line no-console\n            console.debug('resize end');\n          }}\n          useStorage\n          targetDataAttributes={{\n            'data-testid': 'aiAgentPopover',\n          }}\n        >\n          <PopoverContent onClose={() => alert('close')} />\n        </AiAgentPopover>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Uncontrolled",
          "displayName": "Example",
          "type": "full-code",
          "code": "import { AiAgentPopover } from '@daisforge/ui';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/AiAgentPopover/AiAgentPopover.stories.tsx',\n  'PopoverContent',\n)}\n\nrender() {\n    return (\n      <div\n        style={{\n          height: '100vh',\n        }}\n      >\n        <AiAgentPopover\n          draggable\n          defaultPosition=\"bottom-right\"\n          dragBoundary={{\n            bottom: 10,\n            top: 10,\n            left: 10,\n            right: 10,\n          }}\n          onPositionChange={(pos) => {\n            // eslint-disable-next-line no-console\n            console.debug('pos', pos);\n          }}\n          useStorage\n          targetDataAttributes={{\n            'data-testid': 'aiAgentPopover',\n          }}\n        >\n          <PopoverContent onClose={() => alert('close')} />\n        </AiAgentPopover>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в AiAgentPopover.stories.tsx",
          "type": "usage",
          "code": "<AiAgentPopover\n          draggable\n          defaultPosition=\"bottom-right\"\n          dragBoundary={{\n            bottom: 10,\n            top: 10,\n            left: 10,\n            right: 10,\n          }}\n          resizable={() => ({ minWidth: 250 })}\n          onResizeStart={() => {\n            // eslint-disable-next-line no-console\n            console.debug('resize start');\n          }}\n          onResizeEnd={() => {\n            // eslint-disable-next-line no-console\n            console.debug('resize end');\n          }}\n          useStorage\n          targetDataAttributes={{\n            'data-testid': 'aiAgentPopover',\n          }}\n        >\n          <PopoverContent onClose={() => alert('close')} />\n        </AiAgentPopover>",
          "sourceFile": "packages/storybook/src/stories/AiAgentPopover/AiAgentPopover.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в AiAgentPopover.stories.tsx",
          "type": "usage",
          "code": "<AiAgentPopover\n          draggable\n          defaultPosition=\"bottom-right\"\n          dragBoundary={{\n            bottom: 10,\n            top: 10,\n            left: 10,\n            right: 10,\n          }}\n          onPositionChange={(pos) => {\n            // eslint-disable-next-line no-console\n            console.debug('pos', pos);\n          }}\n          useStorage\n          targetDataAttributes={{\n            'data-testid': 'aiAgentPopover',\n          }}\n        >\n          <PopoverContent onClose={() => alert('close')} />\n        </AiAgentPopover>",
          "sourceFile": "packages/storybook/src/stories/AiAgentPopover/AiAgentPopover.stories.tsx"
        }
      ]
    },
    "AnalyticalWidget": {
      "name": "AnalyticalWidget",
      "group": "components",
      "folderName": "AnalyticalWidget",
      "role": "primary",
      "description": "Карточка-виджет фиксированного размера со слотами шапки, фильтров, табов и контента",
      "props": [
        {
          "name": "contentSlot",
          "type": "React.ReactNode",
          "required": true,
          "description": "ReactNode с контентом"
        },
        {
          "name": "size",
          "type": "AnalyticalWidgetSize",
          "required": true,
          "description": "Размер виджета",
          "default": "'l'"
        },
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные стили styled-components для основного контейнера виджета"
        },
        {
          "name": "classes",
          "type": "AnalyticalWidgetClasses | undefined",
          "required": false,
          "description": "Кастомные классы для слотов и самого компонента"
        },
        {
          "name": "headerSlot",
          "type": "React.ReactNode",
          "required": false,
          "description": "ReactNode для шапки"
        },
        {
          "name": "middleSlot",
          "type": "React.ReactNode",
          "required": false,
          "description": "ReactNode (в основном для табов. Отображается только в режиме l)"
        },
        {
          "name": "scrollable",
          "type": "boolean | undefined",
          "required": false,
          "description": "Добавление или удаление скролла у contentSlot",
          "default": "true"
        },
        {
          "name": "topSlot",
          "type": "React.ReactNode",
          "required": false,
          "description": "ReactNode (в основном для фильтров)"
        }
      ],
      "propsTypeName": "AnalyticalWidgetProps",
      "compoundParts": [
        {
          "name": "Header",
          "typeName": "AnalyticalWidgetHeaderProps",
          "props": [
            {
              "name": "badge",
              "type": "string | undefined",
              "required": false,
              "description": "Метка справа от заголовка"
            },
            {
              "name": "badgeStyles",
              "type": "React.CSSProperties | undefined",
              "required": false,
              "description": "Стили для метки (badge). Позволяет переопределить, например, text-transform"
            },
            {
              "name": "infoTooltipProps",
              "type": "Omit<TooltipProps, \"text\" | \"target\"> | undefined",
              "required": false,
              "description": "Пропсы для Tooltip иконки i, справа от тега."
            },
            {
              "name": "infoTooltipText",
              "type": "string | undefined",
              "required": false,
              "description": "Текст Tooltip при наведении на иконку i, справа от тега. Если не передать этот параметр, то иконка отображаться не будет"
            },
            {
              "name": "rightSlot",
              "type": "React.ReactNode",
              "required": false,
              "description": "Слот для контента в правой части шапки"
            },
            {
              "name": "subtitle",
              "type": "React.ReactNode",
              "required": false,
              "description": "Подзаголовок. Строка обрезается троеточием (truncated text) с Tooltip при наведении\nна обрезанный текст. Можно передать произвольный ReactNode (например, Skeleton на\nвремя загрузки) — он рендерится как есть, без тултипа."
            },
            {
              "name": "subtitleTooltipProps",
              "type": "Omit<TooltipProps, \"text\" | \"target\"> | undefined",
              "required": false,
              "description": "Пропсы для Tooltip подзаголовка"
            },
            {
              "name": "title",
              "type": "React.ReactNode",
              "required": false,
              "description": "Заголовок. Строка обрезается троеточием (truncated text) с Tooltip при наведении\nна обрезанный текст. Можно передать произвольный ReactNode (например, Skeleton на\nвремя загрузки данных с бэкенда) — он рендерится как есть, без тултипа."
            },
            {
              "name": "titleLinkProps",
              "type": "Omit<PropsType<{ view: { default: PolymorphicClassName; secondary: PolymorphicClassName; tertiary: PolymorphicClassName; paragraph: PolymorphicClassName; accent: PolymorphicClassName; positive: PolymorphicClassName; warning: PolymorphicClassName; negative: PolymorphicClassName; clear: PolymorphicClassName; }; disabled: { true: PolymorphicClassName; }; focused: { true: PolymorphicClassName; }; }> &…",
              "required": false,
              "description": "Если необходимо title сделать ссылкой.\nПропсы для компонента Link, который оборачивает заголовок.",
              "default": "underline=\"none\""
            },
            {
              "name": "titleTooltipProps",
              "type": "Omit<TooltipProps, \"text\" | \"target\"> | undefined",
              "required": false,
              "description": "Пропсы для Tooltip заголовка"
            },
            {
              "name": "hrefProps",
              "type": "{ onClick?: React.MouseEventHandler<HTMLAnchorElement> | undefined; onKeyDown?: React.KeyboardEventHandler<HTMLAnchorElement> | undefined; } | undefined",
              "required": false,
              "description": "",
              "deprecated": true
            }
          ]
        },
        {
          "name": "FilterIconButton",
          "typeName": "IconButtonFilterProps",
          "props": [
            {
              "name": "as",
              "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
              "required": false,
              "description": "Сменить рендер на другой тип компонента."
            },
            {
              "name": "dropdownProps",
              "type": "(Omit<DropdownProps<ItemOption>, \"view\" | \"size\"> & Pick<PropsType<{ size: { m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; view: { default: PolymorphicClassName; }; }> & { items: ItemOption[]; trigger?: DropdownTrigger | undefined; placement?: DropdownPlacement | undefined; children?: React.ReactNode; variant?: \"normal\" | \"tight\" | undefined; zIndex?: Property.ZInd…",
              "required": false,
              "description": ""
            },
            {
              "name": "iconSize",
              "type": "\"xs\" | \"s\" | \"m\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "redSquare",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "additionalContent",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "appearance",
              "type": "\"default\" | \"outline\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "blur",
              "type": "\"small\" | \"medium\" | \"large\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentLeft",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "contentPlacing",
              "type": "\"default\" | \"relaxed\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentRight",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "focused",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "isLoading",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "loader",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "outlined",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "pin",
              "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftLeft",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftRight",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "size",
              "type": "\"xs\" | \"s\" | \"xxs\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "square",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretch",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretching",
              "type": "\"auto\" | \"filled\" | \"fixed\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "text",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "type",
              "type": "\"button\" | \"submit\" | \"reset\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "value",
              "type": "string | number | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "view",
              "type": "\"clear\" | \"default\" | \"secondary\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"black\" | \"white\" | \"gradient\" | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "DotsIconButton",
          "typeName": "AnalyticalWidgetIconButtonDotsProps",
          "props": [
            {
              "name": "absolute",
              "type": "boolean | undefined",
              "required": false,
              "description": "Позиционировать кнопку абсолютом в правом верхнем углу ближайшего\nrelative-контейнера. Для потребителей (напр. GridDND рабочих столов),\nу которых нет доступа к контенту виджета.",
              "default": "false"
            },
            {
              "name": "absoluteOffset",
              "type": "number | undefined",
              "required": false,
              "description": "Отступ (top/right) при `absolute`.",
              "default": "12"
            },
            {
              "name": "as",
              "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
              "required": false,
              "description": "Сменить рендер на другой тип компонента."
            },
            {
              "name": "dropdownProps",
              "type": "(Omit<DropdownProps<ItemOption>, \"view\" | \"size\"> & Pick<PropsType<{ size: { m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; view: { default: PolymorphicClassName; }; }> & { items: ItemOption[]; trigger?: DropdownTrigger | undefined; placement?: DropdownPlacement | undefined; children?: React.ReactNode; variant?: \"normal\" | \"tight\" | undefined; zIndex?: Property.ZInd…",
              "required": false,
              "description": ""
            },
            {
              "name": "iconOrientation",
              "type": "\"horizontal\" | \"vertical\" | undefined",
              "required": false,
              "description": "",
              "default": "'vertical'"
            },
            {
              "name": "iconSize",
              "type": "\"xs\" | \"s\" | \"m\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "isLoading",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "loader",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "position",
              "type": "any",
              "required": false,
              "description": ""
            },
            {
              "name": "size",
              "type": "\"xs\" | \"s\" | \"m\" | \"l\" | undefined",
              "required": false,
              "description": "",
              "default": "'m'"
            },
            {
              "name": "type",
              "type": "\"button\" | \"submit\" | \"reset\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "view",
              "type": "\"default\" | \"secondary\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"gradient\" | \"info\" | undefined",
              "required": false,
              "description": "",
              "default": "'default'"
            }
          ]
        },
        {
          "name": "Chips",
          "typeName": "AnalyticalWidgetChipsGroupProps",
          "props": [
            {
              "name": "chips",
              "type": "AnalyticalWidgetFixedChipProps[]",
              "required": true,
              "description": "Пропсы для чипов"
            },
            {
              "name": "opened",
              "type": "boolean",
              "required": true,
              "description": "",
              "default": "false"
            },
            {
              "name": "commonSize",
              "type": "\"xs\" | \"s\" | \"m\" | undefined",
              "required": false,
              "description": "",
              "default": "'xs'"
            },
            {
              "name": "commonView",
              "type": "\"clear\" | \"default\" | \"accent\" | undefined",
              "required": false,
              "description": "",
              "default": "'default'"
            }
          ]
        }
      ],
      "sourceFile": "packages/ui-kit/src/components/AnalyticalWidget/AnalyticalWidget.tsx",
      "type": "composition",
      "category": "Композиции",
      "hint": "Это layout, не фильтрация. Compound-компоненты (Header, Chips, FilterIconButton) — это примеры наполнения, а не обязательная часть. Widget — универсальный аналог.",
      "keywords": [
        "дашборд-виджет",
        "аналитическая карточка",
        "панель с фильтрами"
      ],
      "scope": "internal",
      "docs": "# AnalyticalWidget\n\nАналитический виджет с адаптивным поведением и слотами для контента.\n\n## Ключевые особенности\n\n- Три размера (`L`, `M`, `S`) с разными параметрами высоты, ширины, border-radius и padding\n- Слоты: `headerSlot`, `topSlot`, `middleSlot` (только для `L`), `contentSlot`\n- `middleSlot` видим только при размере `L`\n- Прокрутка контентной области (`scrollable`)\n- Кастомизация через `classes`, `$css` и CSS-переменные\n\n## Compound-компоненты\n\n```ts\nAnalyticalWidget.Header = AnalyticalWidgetHeader;\nAnalyticalWidget.FilterIconButton = IconButtonFilter;\nAnalyticalWidget.DotsIconButton = IconButtonDots;\nAnalyticalWidget.Chips = AnalyticalWidgetChipsGroup;\n```\n\n- `AnalyticalWidget.Header` — шапка виджета с заголовком и слотами для действий\n- `AnalyticalWidget.FilterIconButton` — кнопка-иконка для фильтров (с поддержкой Dropdown). Поддерживает красный индикатор применения фильтров\n- `AnalyticalWidget.DotsIconButton` — кнопка-иконка для дополнительных действий (с поддержкой Dropdown)\n- `AnalyticalWidget.Chips` — чипы для отображения применённых фильтров\n\n## CSS-переменные\n\n- `--analytical-widget-bg` — фон всего виджета\n- `--analytical-widget-padding` — внутренние отступы контейнера\n- `--analytical-widget-br` — радиус скругления углов\n- `--analytical-widget-min-height` — минимальная высота контентной области\n\n## Особенности\n\n- Все параметры можно переопределить через CSS-переменные, нативные/кастомные классы компонента или проп `$css` для основного контейнера. Объект `analyticalWidgetClassNames` доступен для импорта\n- Кнопка троеточия вставляется через микрофронт другой командой — место под неё зарезервировано. В stories показан пример через `position: absolute`\n- Высота, ширина, border-radius, padding зависят от размера и имеют фиксированные значения\n\n<AnalyticalWidgetInfoAboutAdaptive />\n\nОписание типов и compound-пропсов — в разделе [API](/docs/композиции-analyticalwidget-api--docs).",
      "apiDocs": "# AnalyticalWidget API\n\n## AnalyticalWidgetProps\n\n```typescript\ntype AnalyticalWidgetProps = {\n  /**\n   * Размер виджета\n   */\n  size: AnalyticalWidgetSize;\n  /**\n   * Добавление или удаление скролла у contentSlot\n   */\n  scrollable?: boolean;\n  /**\n   * ReactNode для шапки\n   */\n  headerSlot?: ReactNode;\n  /**\n   * ReactNode (в основном для фильтров)\n   */\n  topSlot?: ReactNode;\n  /**\n   * ReactNode (в основном для табов. Отображается только в режиме l)\n   */\n  middleSlot?: ReactNode;\n  /**\n   * ReactNode с контентом\n   */\n  contentSlot: ReactNode;\n  /**\n   * Кастомные классы для слотов и самого компонента\n   */\n  classes?: AnalyticalWidgetClasses;\n  /**\n   * Кастомные стили styled-components для основного контейнера виджета\n   */\n  $css?: string | CSSObject | FlattenSimpleInterpolation;\n};\n```\n\n## AnalyticalWidgetSize\n\n```typescript\ntype AnalyticalWidgetSize = 'l' | 'm' | 's';\n```\n\n## AnalyticalWidgetClasses\n\n```typescript\ntype AnalyticalWidgetClasses = {\n  /**\n   * Кастомный класс для root элемента\n   */\n  root?: string;\n  /**\n   * Кастомный класс для topSlot элемента\n   */\n  topSlot?: string;\n  /**\n   * Кастомный класс для middleSlot элемента\n   */\n  middleSlot?: string;\n  /**\n   * Кастомный класс для contentSlot элемента\n   */\n  contentSlot?: string;\n};\n```\n\n## Compound types\n\n### AnalyticalWidget.Header\n\n```typescript\ninterface AnalyticalWidgetHeaderProps {\n  /**\n   * Заголовок. Строка обрезается троеточием (truncated text) с Tooltip при наведении\n   * на обрезанный текст. Можно передать произвольный ReactNode (например, Skeleton на\n   * время загрузки данных с бэкенда) — он рендерится как есть, без тултипа.\n   */\n  title?: ReactNode;\n  /**\n   * Пропсы для Tooltip заголовка\n   */\n  titleTooltipProps?: Omit<TooltipProps, 'text' | 'target'>;\n  /**\n   * Метка справа от заголовка\n   */\n  badge?: string;\n  /**\n   * Стили для метки (badge). Позволяет переопределить, например, text-transform\n   */\n  badgeStyles?: CSSProperties;\n  /**\n   * Подзаголовок. Строка обрезается троеточием (truncated text) с Tooltip при наведении\n   * на обрезанный текст. Можно передать произвольный ReactNode (например, Skeleton на\n   * время загрузки) — он рендерится как есть, без тултипа.\n   */\n  subtitle?: ReactNode;\n  /**\n   * Пропсы для Tooltip подзаголовка\n   */\n  subtitleTooltipProps?: Omit<TooltipProps, 'text' | 'target'>;\n  /**\n   * Текст Tooltip при наведении на иконку i, справа от тега. Если не передать этот параметр, то иконка отображаться не будет\n   */\n  infoTooltipText?: string;\n  /**\n   * Пропсы для Tooltip иконки i, справа от тега.\n   */\n  infoTooltipProps?: Omit<TooltipProps, 'text' | 'target'>;\n  /**\n   * @deprecated Стрелка больше не рисуется. Используйте `titleLinkProps`.\n   */\n  href?: string;\n  /**\n   * @deprecated Стрелка больше не рисуется. Используйте `titleLinkProps`.\n   */\n  hrefProps?: {\n    onClick?: MouseEventHandler<HTMLAnchorElement>;\n    onKeyDown?: KeyboardEventHandler<HTMLAnchorElement>;\n  };\n  /**\n   * Если необходимо title сделать ссылкой.\n   * Пропсы для компонента Link, который оборачивает заголовок.\n   * @default underline=\"none\"\n   */\n  titleLinkProps?: Omit<LinkCompProps, 'ref'>;\n  /**\n   * Слот для контента в правой части шапки\n   */\n  rightSlot?: ReactNode;\n  /**\n   * Имя класса для шапки\n   */\n  className?: string;\n}\n```\n\n### AnalyticalWidget.Chips\n\n```typescript\ntype AnalyticalWidgetFixedChipProps = ChipCompProps & {\n  key?: string | number;\n};\n```\n\n### AnalyticalWidget.FilterIconButton\n\n```typescript\ntype IconButtonFilterProps = IconButtonProps & {\n  redSquare?: boolean;\n  dropdownProps?: ComponentProps<typeof Dropdown>;\n  iconSize?: ComponentProps<typeof Icon>['size'];\n};\n```\n\n### AnalyticalWidget.DotsIconButton\n\n```typescript\ntype IconButtonDotsProps = IconButtonProps & {\n  dropdownProps?: ComponentProps<typeof Dropdown>;\n  iconSize?: ComponentProps<typeof Icon>['size'];\n  iconOrientation?: 'horizontal' | 'vertical';\n};\n```",
      "curatedStories": [
        {
          "exportName": "AnalyticalWidgetL",
          "displayName": "AnalyticalWidgetL",
          "type": "full-code",
          "code": "import {\n  Box,\n  Combobox,\n  Flow,\n  SegmentGroup,\n  SegmentProvider,\n  TooltipList,\n  useFiltersList,\n  IconDone,\n  SegmentItem,\n  AnalyticalWidget,\n  textInfo\n} from '@daisforge/ui';\nimport type { ItemOrGroup } from '@daisforge/ui';\n\nimport React, { useMemo, useReducer, useState } from 'react';\n\ntype Filters = {\n  searchedV: string;\n  blocks: string[];\n  tribes: string[];\n  allocation: string;\n  year: number | null;\n  filterButton: string;\n  dotsButton: string;\n};\n\nconst DEFAULT_FILTERS: Filters = {\n  searchedV: '',\n  blocks: [],\n  tribes: [],\n  allocation: '',\n  year: null,\n  filterButton: '',\n  dotsButton: '',\n};\n\nconst LABELS: { [key in keyof Filters]: string } = {\n  searchedV: 'Поиск',\n  blocks: 'Блок',\n  tribes: 'Трайб',\n  allocation: 'Аллокация',\n  year: 'Год',\n  filterButton: 'Фильтры',\n  dotsButton: 'Меню',\n};\n\nconst useFetch = (key: 'blocks' | 'tribes' | 'allocation', num = 10) =>\n  useMemo(\n    () =>\n      Array(num)\n        .fill(0)\n        .map((_, i) => ({\n          label: \\\n\n() => {\n    const [filters, updateFilters] = useReducer(\n      filtersReducer,\n      DEFAULT_FILTERS,\n    );\n    const filtersBlocksOption = useFetch('blocks', 10);\n    const filtersTribesOption = useFetch('tribes', 15);\n    const filtersAllocationOption = useFetch('allocation', 10);\n    const someItems = Array(3).fill(0);\n\n    const { filterList, filterListOpened } = useFiltersList({\n      filters,\n      options: {\n        blocks: filtersBlocksOption,\n        tribes: filtersTribesOption,\n        allocation: filtersAllocationOption,\n        filterButton: filterButtonOptions,\n        dotsButton: dotsButtonOptions,\n      } as Record<keyof Filters, { label: string; value: string }[]>,\n      updateFilters: (key, newV) => updateFilters({ [key]: newV }),\n      filtersInfo: {\n        searchedV: { label: 'Поиск', clearedValue: '' },\n        blocks: { label: 'Блок', clearedValue: [] },\n        tribes: { label: 'Трайб', clearedValue: [] },\n        allocation: { label: 'Аллокация', clearedValue: '' },\n        year: { label: 'Год', clearedValue: null },\n        filterButton: { label: 'Фильтр', clearedValue: '' },\n        dotsButton: { label: 'Меню', clearedValue: '' },\n      },\n    });\n\n    const chipsList = filterList\n      .map((item) => {\n        if ('groupLabel' in item) {\n          return item.items.map((innerItem) => ({\n            text: String(innerItem.label),\n            view: 'default' as const,\n            hasClear: false as const,\n            onClick: innerItem.onClick,\n          }));\n        }\n        return {\n          text: String(item.label),\n          view: 'default' as const,\n          hasClear: false as const,\n          onClick: item.onClick,\n        };\n      })\n      .flat();\n\n    return (\n      <GridContainerL>\n        <SegmentProvider defaultSelected={['item_0']}>\n          <div\n            style={{\n              position: 'relative',\n              width: 'min-content',\n            }}\n          >\n            <AnalyticalWidget\n              size=\"l\"\n              headerSlot={\n                <AnalyticalWidget.Header\n                  title=\"Analytic widget L\"\n                  badge=\"TA\"\n                  subtitle=\"Monthly report\"\n                  rightSlot={\n                    <Flow\n                      alignment=\"center\"\n                      mainAxisGap=\"8px\"\n                      style={{\n                        flexWrap: 'nowrap',\n                      }}\n                    >\n                      <SegmentGroup hasBackground size=\"xs\">\n                        {someItems.map((_, i) => (\n                          <SegmentItem\n                            // eslint-disable-next-line react/no-array-index-key\n                            key={`item:${i}`}\n                            value={`item_${i}`}\n                            label={`Label${i + 1}`}\n                            size=\"xs\"\n                            view=\"primary\"\n                          />\n                        ))}\n                      </SegmentGroup>\n                    </Flow>\n                  }\n                  infoTooltipText=\"Info\"\n                  href=\"/\"\n                />\n              }\n              topSlot={\n                <Flow orientation=\"vertical\" mainAxisGap={8}>\n                  <AnalyticalWidget.Chips\n                    opened={filterListOpened}\n                    isWrapped\n                    gap=\"wide\"\n                    isCommonChipStyles={false}\n                    chips={chipsList}\n                  />\n                </Flow>\n              }\n              contentSlot={\n                <div\n                  style={{\n                    minHeight: 'fit-content',\n                  }}\n                >\n                  {longText()}\n                </div>\n              }\n              classes={{\n                topSlot: 'myCustomClassForTopSlot',\n                middleSlot: 'myCustomClassForMiddleSlot',\n                contentSlot: 'myCustomClassForContentSlot',\n                root: 'myCustomClassForRoot',\n              }}\n            />\n            <AnalyticalWidget.DotsIconButton\n              absolute\n              dropdownProps={{\n                items: generateButtonItems(\n                  'dotsButton',\n                  dotsButtonOptions,\n                  filterList,\n                ),\n                onItemSelect(item) {\n                  updateFilters({\n                    dotsButton:\n                      filters.dotsButton === item.value?.toString()\n                        ? ''\n                        : item.value?.toString() ?? '',\n                  });\n                },\n              }}\n            />\n          </div>\n        </SegmentProvider>\n      </GridContainerL>\n    );\n  }"
        },
        {
          "exportName": "AnalyticalWidgetM",
          "displayName": "AnalyticalWidgetM",
          "type": "full-code",
          "code": "import {\n  Box,\n  Combobox,\n  Flow,\n  SegmentGroup,\n  SegmentProvider,\n  TooltipList,\n  useFiltersList,\n  IconDone,\n  SegmentItem,\n  AnalyticalWidget,\n  textInfo\n} from '@daisforge/ui';\nimport type { ItemOrGroup } from '@daisforge/ui';\n\nimport React, { useMemo, useReducer, useState } from 'react';\n\ntype Filters = {\n  searchedV: string;\n  blocks: string[];\n  tribes: string[];\n  allocation: string;\n  year: number | null;\n  filterButton: string;\n  dotsButton: string;\n};\n\nconst DEFAULT_FILTERS: Filters = {\n  searchedV: '',\n  blocks: [],\n  tribes: [],\n  allocation: '',\n  year: null,\n  filterButton: '',\n  dotsButton: '',\n};\n\nconst LABELS: { [key in keyof Filters]: string } = {\n  searchedV: 'Поиск',\n  blocks: 'Блок',\n  tribes: 'Трайб',\n  allocation: 'Аллокация',\n  year: 'Год',\n  filterButton: 'Фильтры',\n  dotsButton: 'Меню',\n};\n\nconst useFetch = (key: 'blocks' | 'tribes' | 'allocation', num = 10) =>\n  useMemo(\n    () =>\n      Array(num)\n        .fill(0)\n        .map((_, i) => ({\n          label: \\\n\n() => {\n    const [filters, updateFilters] = useReducer(\n      filtersReducer,\n      DEFAULT_FILTERS,\n    );\n    const filtersBlocksOption = useFetch('blocks', 10);\n    const filtersTribesOption = useFetch('tribes', 15);\n    const filtersAllocationOption = useFetch('allocation', 10);\n    const someItems = Array(3).fill(0);\n\n    const { filterList, filterListOpened } = useFiltersList({\n      filters,\n      options: {\n        blocks: filtersBlocksOption,\n        tribes: filtersTribesOption,\n        allocation: filtersAllocationOption,\n        filterButton: filterButtonOptions,\n        dotsButton: dotsButtonOptions,\n      } as Record<keyof Filters, { label: string; value: string }[]>,\n      updateFilters: (key, newV) => updateFilters({ [key]: newV }),\n      filtersInfo: {\n        searchedV: { label: 'Поиск', clearedValue: '' },\n        blocks: { label: 'Блок', clearedValue: [] },\n        tribes: { label: 'Трайб', clearedValue: [] },\n        allocation: { label: 'Аллокация', clearedValue: '' },\n        year: { label: 'Год', clearedValue: null },\n        filterButton: { label: 'Фильтр', clearedValue: '' },\n        dotsButton: { label: 'Меню', clearedValue: '' },\n      },\n    });\n\n    const chipsList = filterList\n      .map((item, index) => {\n        if ('groupLabel' in item) {\n          return item.items.map((innerItem, innerIdex) => ({\n            text: String(innerItem.label),\n            view: 'default' as const,\n            hasClear: false as const,\n            onClick: innerItem.onClick,\n            key: `chip-key${index}-${innerIdex}-${innerItem.label}`,\n          }));\n        }\n        return {\n          text: String(item.label),\n          view: 'default' as const,\n          hasClear: false as const,\n          onClick: item.onClick,\n          key: `chip-key-${index}-${item.label}`,\n        };\n      })\n      .flat();\n\n    return (\n      <GridContainerM>\n        <SegmentProvider defaultSelected={['item_0']}>\n          <div\n            style={{\n              position: 'relative',\n              width: 'min-content',\n            }}\n          >\n            <AnalyticalWidget\n              size=\"m\"\n              headerSlot={\n                <AnalyticalWidget.Header\n                  title=\"Analytic widget M\"\n                  badge=\"TA\"\n                  subtitle=\"Monthly report\"\n                  rightSlot={\n                    <Flow\n                      alignment=\"center\"\n                      mainAxisGap=\"8px\"\n                      style={{\n                        flexWrap: 'nowrap',\n                      }}\n                    >\n                      <SegmentGroup hasBackground size=\"xs\">\n                        {someItems.map((_, i) => (\n                          <SegmentItem\n                            // eslint-disable-next-line react/no-array-index-key\n                            key={`item:${i}`}\n                            value={`item_${i}`}\n                            label={`Label${i + 1}`}\n                            size=\"xs\"\n                            view=\"primary\"\n                          />\n                        ))}\n                      </SegmentGroup>\n                    </Flow>\n                  }\n                  infoTooltipText=\"Info\"\n                  href=\"/\"\n                />\n              }\n              topSlot={\n                <Flow orientation=\"vertical\" mainAxisGap={8}>\n                  <AnalyticalWidget.Chips\n                    opened={filterListOpened}\n                    isWrapped\n                    gap=\"wide\"\n                    isCommonChipStyles={false}\n                    chips={chipsList}\n                  />\n                </Flow>\n              }\n              contentSlot={\n                <div\n                  style={{\n                    minHeight: 'fit-content',\n                  }}\n                >\n                  {longText()}\n                </div>\n              }\n              classes={{\n                topSlot: 'myCustomClassForTopSlot',\n                middleSlot: 'myCustomClassForMiddleSlot',\n                contentSlot: 'myCustomClassForContentSlot',\n                root: 'myCustomClassForRoot',\n              }}\n            />\n            <AnalyticalWidget.DotsIconButton\n              absolute\n              dropdownProps={{\n                items: generateButtonItems(\n                  'dotsButton',\n                  dotsButtonOptions,\n                  filterList,\n                ),\n                onItemSelect(item) {\n                  updateFilters({\n                    dotsButton:\n                      filters.dotsButton === item.value?.toString()\n                        ? ''\n                        : item.value?.toString() ?? '',\n                  });\n                },\n              }}\n            />\n          </div>\n        </SegmentProvider>\n      </GridContainerM>\n    );\n  }"
        },
        {
          "exportName": "AnalyticalWidgetS",
          "displayName": "AnalyticalWidgetS",
          "type": "full-code",
          "code": "import {\n  Box,\n  Combobox,\n  Flow,\n  SegmentGroup,\n  SegmentProvider,\n  TooltipList,\n  useFiltersList,\n  IconDone,\n  SegmentItem,\n  AnalyticalWidget,\n  textInfo\n} from '@daisforge/ui';\nimport type { ItemOrGroup } from '@daisforge/ui';\n\nimport React, { useMemo, useReducer, useState } from 'react';\n\ntype Filters = {\n  searchedV: string;\n  blocks: string[];\n  tribes: string[];\n  allocation: string;\n  year: number | null;\n  filterButton: string;\n  dotsButton: string;\n};\n\nconst DEFAULT_FILTERS: Filters = {\n  searchedV: '',\n  blocks: [],\n  tribes: [],\n  allocation: '',\n  year: null,\n  filterButton: '',\n  dotsButton: '',\n};\n\nconst LABELS: { [key in keyof Filters]: string } = {\n  searchedV: 'Поиск',\n  blocks: 'Блок',\n  tribes: 'Трайб',\n  allocation: 'Аллокация',\n  year: 'Год',\n  filterButton: 'Фильтры',\n  dotsButton: 'Меню',\n};\n\nconst useFetch = (key: 'blocks' | 'tribes' | 'allocation', num = 10) =>\n  useMemo(\n    () =>\n      Array(num)\n        .fill(0)\n        .map((_, i) => ({\n          label: \\\n\n() => {\n    const [filters, updateFilters] = useReducer(\n      filtersReducer,\n      DEFAULT_FILTERS,\n    );\n    const filtersBlocksOption = useFetch('blocks', 10);\n    const filtersTribesOption = useFetch('tribes', 15);\n    const filtersAllocationOption = useFetch('allocation', 10);\n\n    const { filterList, filterListOpened } = useFiltersList({\n      filters,\n      options: {\n        blocks: filtersBlocksOption,\n        tribes: filtersTribesOption,\n        allocation: filtersAllocationOption,\n        filterButton: filterButtonOptions,\n        dotsButton: dotsButtonOptions,\n      } as Record<keyof Filters, { label: string; value: string }[]>,\n      updateFilters: (key, newV) => updateFilters({ [key]: newV }),\n      filtersInfo: {\n        searchedV: { label: 'Поиск', clearedValue: '' },\n        blocks: { label: 'Блок', clearedValue: [] },\n        tribes: { label: 'Трайб', clearedValue: [] },\n        allocation: { label: 'Аллокация', clearedValue: '' },\n        year: { label: 'Год', clearedValue: null },\n        filterButton: { label: 'Фильтр', clearedValue: '' },\n        dotsButton: { label: 'Меню', clearedValue: '' },\n      },\n    });\n\n    const chipsList = filterList\n      .map((item) => {\n        if ('groupLabel' in item) {\n          return item.items.map((innerItem) => ({\n            text: String(innerItem.label),\n            view: 'default' as const,\n            hasClear: false as const,\n            onClick: innerItem.onClick,\n          }));\n        }\n        return {\n          text: String(item.label),\n          view: 'default' as const,\n          hasClear: false as const,\n          onClick: item.onClick,\n        };\n      })\n      .flat();\n\n    return (\n      <GridContainerS>\n        <SegmentProvider defaultSelected={['item_0']}>\n          <div\n            style={{\n              position: 'relative',\n              width: 'min-content',\n            }}\n          >\n            <AnalyticalWidget\n              size=\"s\"\n              headerSlot={\n                <AnalyticalWidget.Header\n                  title=\"Заголовок\"\n                  badge=\"TA\"\n                  subtitle=\"Подзаголовок здесь\"\n                  infoTooltipText=\"Info\"\n                  href=\"/\"\n                />\n              }\n              topSlot={\n                <Flow orientation=\"vertical\" mainAxisGap={8}>\n                  <AnalyticalWidget.Chips\n                    opened={filterListOpened}\n                    isWrapped\n                    gap=\"wide\"\n                    isCommonChipStyles={false}\n                    chips={chipsList}\n                  />\n                </Flow>\n              }\n              contentSlot={\n                <div\n                  style={{\n                    minHeight: 'fit-content',\n                  }}\n                >\n                  {longText()}\n                </div>\n              }\n              classes={{\n                topSlot: 'myCustomClassForTopSlot',\n                middleSlot: 'myCustomClassForMiddleSlot',\n                contentSlot: 'myCustomClassForContentSlot',\n                root: 'myCustomClassForRoot',\n              }}\n            />\n            <AnalyticalWidget.DotsIconButton\n              absolute\n              dropdownProps={{\n                items: generateButtonItems(\n                  'dotsButton',\n                  dotsButtonOptions,\n                  filterList,\n                ),\n                onItemSelect(item) {\n                  updateFilters({\n                    dotsButton:\n                      filters.dotsButton === item.value?.toString()\n                        ? ''\n                        : item.value?.toString() ?? '',\n                  });\n                },\n              }}\n            />\n          </div>\n        </SegmentProvider>\n      </GridContainerS>\n    );\n  }"
        },
        {
          "exportName": "AnalyticalWidgetCustomTopSlot",
          "displayName": "Custom topSlot + rightSlot",
          "type": "full-code",
          "code": "() => {\n    const [filters, updateFilters] = useReducer(\n      filtersReducer,\n      DEFAULT_FILTERS,\n    );\n    const filtersBlocksOption = useFetch('blocks', 10);\n    const filtersTribesOption = useFetch('tribes', 15);\n    const filtersAllocationOption = useFetch('allocation', 10);\n    const [period, setPeriod] = useState('month');\n\n    const { filterList } = useFiltersList({\n      filters,\n      options: {\n        blocks: filtersBlocksOption,\n        tribes: filtersTribesOption,\n        allocation: filtersAllocationOption,\n        filterButton: filterButtonOptions,\n        dotsButton: dotsButtonOptions,\n      } as Record<keyof Filters, { label: string; value: string }[]>,\n      updateFilters: (key, newV) => updateFilters({ [key]: newV }),\n      filtersInfo: {\n        searchedV: { label: 'Поиск', clearedValue: '' },\n        blocks: { label: 'Блок', clearedValue: [] },\n        tribes: { label: 'Трайб', clearedValue: [] },\n        allocation: { label: 'Аллокация', clearedValue: '' },\n        year: { label: 'Год', clearedValue: null },\n        filterButton: { label: 'Фильтр', clearedValue: '' },\n        dotsButton: { label: 'Меню', clearedValue: '' },\n      },\n    });\n\n    const customChips = filterList.flatMap((item) =>\n      'groupLabel' in item\n        ? item.items.map((inner) => ({\n            label: String(inner.label),\n            onClick: inner.onClick,\n          }))\n        : [{ label: String(item.label), onClick: item.onClick }],\n    );\n    const hasChips = customChips.length > 0;\n    const lastRef = useRef(customChips);\n    if (hasChips) {\n      lastRef.current = customChips;\n    }\n    const renderedChips = hasChips ? customChips : lastRef.current;\n\n    return (\n      <div style={{ padding: 20, background: 'grey' }}>\n        <div style={{ position: 'relative', width: 600, height: 512 }}>\n          <AnalyticalWidget\n            size=\"l\"\n            headerSlot={\n              <AnalyticalWidget.Header\n                title=\"Custom topSlot\"\n                badge=\"TA\"\n                subtitle=\"Свои чипы + Select в rightSlot\"\n                infoTooltipText=\"Info\"\n                rightSlot={\n                  <Select\n                    size=\"xs\"\n                    value={period}\n                    onChange={(v) => setPeriod(v as string)}\n                    items={[\n                      { label: 'Месяц', value: 'month' },\n                      { label: 'Квартал', value: 'quarter' },\n                      { label: 'Год', value: 'year' },\n                    ]}\n                  />\n                }\n              />\n            }\n            topSlot={\n              <div className={analyticalWidgetClassNames.selfSpacedTopSlot}>\n                <Collapse isOpen={hasChips} unMountOnClose>\n                  <div\n                    style={{\n                      display: 'flex',\n                      flexWrap: 'wrap',\n                      gap: 4,\n                      paddingTop: 8,\n                    }}\n                  >\n                    {renderedChips.map((chip, index) => (\n                      <button\n                        type=\"button\"\n                        // eslint-disable-next-line react/no-array-index-key\n                        key={`${chip.label}-${index}`}\n                        onClick={chip.onClick}\n                        style={{\n                          padding: '2px 8px',\n                          borderRadius: 12,\n                          background: 'rgba(0, 0, 0, 0.06)',\n                          border: 'none',\n                          fontSize: 12,\n                          lineHeight: '16px',\n                          whiteSpace: 'nowrap',\n                          cursor: 'pointer',\n                        }}\n                      >\n                        {chip.label}\n                      </button>\n                    ))}\n                  </div>\n                </Collapse>\n              </div>\n            }\n            contentSlot={\n              <div style={{ minHeight: 'fit-content' }}>{longText()}</div>\n            }\n          />\n          <AnalyticalWidget.DotsIconButton\n            absolute\n            dropdownProps={{\n              items: generateButtonItems(\n                'dotsButton',\n                dotsButtonOptions,\n                filterList,\n              ),\n              onItemSelect(item) {\n                updateFilters({\n                  dotsButton:\n                    filters.dotsButton === item.value?.toString()\n                      ? ''\n                      : item.value?.toString() ?? '',\n                });\n              },\n            }}\n          />\n        </div>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "AnalyticalWidgetHeaderSkeleton",
          "displayName": "Header: skeleton title/subtitle",
          "type": "full-code",
          "code": "() => {\n    const [loading, setLoading] = useState(true);\n\n    return (\n      <div style={{ padding: 20, background: 'grey' }}>\n        <div style={{ marginBottom: 12 }}>\n          <Button size=\"s\" onClick={() => setLoading((v) => !v)}>\n            {loading ? 'Загрузить данные' : 'Показать скелетон'}\n          </Button>\n        </div>\n        <div style={{ position: 'relative', width: 600, height: 512 }}>\n          <AnalyticalWidget\n            size=\"l\"\n            headerSlot={\n              <AnalyticalWidget.Header\n                title={\n                  loading ? (\n                    <LineSkeleton size=\"bodyM\" style={{ width: 180 }} />\n                  ) : (\n                    'Аналитический виджет'\n                  )\n                }\n                badge={loading ? undefined : 'TA'}\n                subtitle={\n                  loading ? (\n                    <LineSkeleton size=\"bodyXS\" style={{ width: 120 }} />\n                  ) : (\n                    'Данные за месяц'\n                  )\n                }\n                infoTooltipText=\"Info\"\n              />\n            }\n            contentSlot={\n              <div style={{ minHeight: 'fit-content' }}>{longText()}</div>\n            }\n          />\n        </div>\n      </div>\n    );\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { AnalyticalWidget } from '@daisforge/ui';",
      "minimalUsage": "<AnalyticalWidget contentSlot={'Контент'} size={{}}>\n  {/* части: AnalyticalWidget.Header, AnalyticalWidget.FilterIconButton, AnalyticalWidget.DotsIconButton, AnalyticalWidget.Chips */}\n</AnalyticalWidget>",
      "examples": [
        {
          "exportName": "AnalyticalWidgetL",
          "displayName": "AnalyticalWidgetL",
          "type": "full-code",
          "code": "import {\n  Box,\n  Combobox,\n  Flow,\n  SegmentGroup,\n  SegmentProvider,\n  TooltipList,\n  useFiltersList,\n  IconDone,\n  SegmentItem,\n  AnalyticalWidget,\n  textInfo\n} from '@daisforge/ui';\nimport type { ItemOrGroup } from '@daisforge/ui';\n\nimport React, { useMemo, useReducer, useState } from 'react';\n\ntype Filters = {\n  searchedV: string;\n  blocks: string[];\n  tribes: string[];\n  allocation: string;\n  year: number | null;\n  filterButton: string;\n  dotsButton: string;\n};\n\nconst DEFAULT_FILTERS: Filters = {\n  searchedV: '',\n  blocks: [],\n  tribes: [],\n  allocation: '',\n  year: null,\n  filterButton: '',\n  dotsButton: '',\n};\n\nconst LABELS: { [key in keyof Filters]: string } = {\n  searchedV: 'Поиск',\n  blocks: 'Блок',\n  tribes: 'Трайб',\n  allocation: 'Аллокация',\n  year: 'Год',\n  filterButton: 'Фильтры',\n  dotsButton: 'Меню',\n};\n\nconst useFetch = (key: 'blocks' | 'tribes' | 'allocation', num = 10) =>\n  useMemo(\n    () =>\n      Array(num)\n        .fill(0)\n        .map((_, i) => ({\n          label: \\\n\n() => {\n    const [filters, updateFilters] = useReducer(\n      filtersReducer,\n      DEFAULT_FILTERS,\n    );\n    const filtersBlocksOption = useFetch('blocks', 10);\n    const filtersTribesOption = useFetch('tribes', 15);\n    const filtersAllocationOption = useFetch('allocation', 10);\n    const someItems = Array(3).fill(0);\n\n    const { filterList, filterListOpened } = useFiltersList({\n      filters,\n      options: {\n        blocks: filtersBlocksOption,\n        tribes: filtersTribesOption,\n        allocation: filtersAllocationOption,\n        filterButton: filterButtonOptions,\n        dotsButton: dotsButtonOptions,\n      } as Record<keyof Filters, { label: string; value: string }[]>,\n      updateFilters: (key, newV) => updateFilters({ [key]: newV }),\n      filtersInfo: {\n        searchedV: { label: 'Поиск', clearedValue: '' },\n        blocks: { label: 'Блок', clearedValue: [] },\n        tribes: { label: 'Трайб', clearedValue: [] },\n        allocation: { label: 'Аллокация', clearedValue: '' },\n        year: { label: 'Год', clearedValue: null },\n        filterButton: { label: 'Фильтр', clearedValue: '' },\n        dotsButton: { label: 'Меню', clearedValue: '' },\n      },\n    });\n\n    const chipsList = filterList\n      .map((item) => {\n        if ('groupLabel' in item) {\n          return item.items.map((innerItem) => ({\n            text: String(innerItem.label),\n            view: 'default' as const,\n            hasClear: false as const,\n            onClick: innerItem.onClick,\n          }));\n        }\n        return {\n          text: String(item.label),\n          view: 'default' as const,\n          hasClear: false as const,\n          onClick: item.onClick,\n        };\n      })\n      .flat();\n\n    return (\n      <GridContainerL>\n        <SegmentProvider defaultSelected={['item_0']}>\n          <div\n            style={{\n              position: 'relative',\n              width: 'min-content',\n            }}\n          >\n            <AnalyticalWidget\n              size=\"l\"\n              headerSlot={\n                <AnalyticalWidget.Header\n                  title=\"Analytic widget L\"\n                  badge=\"TA\"\n                  subtitle=\"Monthly report\"\n                  rightSlot={\n                    <Flow\n                      alignment=\"center\"\n                      mainAxisGap=\"8px\"\n                      style={{\n                        flexWrap: 'nowrap',\n                      }}\n                    >\n                      <SegmentGroup hasBackground size=\"xs\">\n                        {someItems.map((_, i) => (\n                          <SegmentItem\n                            // eslint-disable-next-line react/no-array-index-key\n                            key={`item:${i}`}\n                            value={`item_${i}`}\n                            label={`Label${i + 1}`}\n                            size=\"xs\"\n                            view=\"primary\"\n                          />\n                        ))}\n                      </SegmentGroup>\n                    </Flow>\n                  }\n                  infoTooltipText=\"Info\"\n                  href=\"/\"\n                />\n              }\n              topSlot={\n                <Flow orientation=\"vertical\" mainAxisGap={8}>\n                  <AnalyticalWidget.Chips\n                    opened={filterListOpened}\n                    isWrapped\n                    gap=\"wide\"\n                    isCommonChipStyles={false}\n                    chips={chipsList}\n                  />\n                </Flow>\n              }\n              contentSlot={\n                <div\n                  style={{\n                    minHeight: 'fit-content',\n                  }}\n                >\n                  {longText()}\n                </div>\n              }\n              classes={{\n                topSlot: 'myCustomClassForTopSlot',\n                middleSlot: 'myCustomClassForMiddleSlot',\n                contentSlot: 'myCustomClassForContentSlot',\n                root: 'myCustomClassForRoot',\n              }}\n            />\n            <AnalyticalWidget.DotsIconButton\n              absolute\n              dropdownProps={{\n                items: generateButtonItems(\n                  'dotsButton',\n                  dotsButtonOptions,\n                  filterList,\n                ),\n                onItemSelect(item) {\n                  updateFilters({\n                    dotsButton:\n                      filters.dotsButton === item.value?.toString()\n                        ? ''\n                        : item.value?.toString() ?? '',\n                  });\n                },\n              }}\n            />\n          </div>\n        </SegmentProvider>\n      </GridContainerL>\n    );\n  }"
        },
        {
          "exportName": "AnalyticalWidgetM",
          "displayName": "AnalyticalWidgetM",
          "type": "full-code",
          "code": "import {\n  Box,\n  Combobox,\n  Flow,\n  SegmentGroup,\n  SegmentProvider,\n  TooltipList,\n  useFiltersList,\n  IconDone,\n  SegmentItem,\n  AnalyticalWidget,\n  textInfo\n} from '@daisforge/ui';\nimport type { ItemOrGroup } from '@daisforge/ui';\n\nimport React, { useMemo, useReducer, useState } from 'react';\n\ntype Filters = {\n  searchedV: string;\n  blocks: string[];\n  tribes: string[];\n  allocation: string;\n  year: number | null;\n  filterButton: string;\n  dotsButton: string;\n};\n\nconst DEFAULT_FILTERS: Filters = {\n  searchedV: '',\n  blocks: [],\n  tribes: [],\n  allocation: '',\n  year: null,\n  filterButton: '',\n  dotsButton: '',\n};\n\nconst LABELS: { [key in keyof Filters]: string } = {\n  searchedV: 'Поиск',\n  blocks: 'Блок',\n  tribes: 'Трайб',\n  allocation: 'Аллокация',\n  year: 'Год',\n  filterButton: 'Фильтры',\n  dotsButton: 'Меню',\n};\n\nconst useFetch = (key: 'blocks' | 'tribes' | 'allocation', num = 10) =>\n  useMemo(\n    () =>\n      Array(num)\n        .fill(0)\n        .map((_, i) => ({\n          label: \\\n\n() => {\n    const [filters, updateFilters] = useReducer(\n      filtersReducer,\n      DEFAULT_FILTERS,\n    );\n    const filtersBlocksOption = useFetch('blocks', 10);\n    const filtersTribesOption = useFetch('tribes', 15);\n    const filtersAllocationOption = useFetch('allocation', 10);\n    const someItems = Array(3).fill(0);\n\n    const { filterList, filterListOpened } = useFiltersList({\n      filters,\n      options: {\n        blocks: filtersBlocksOption,\n        tribes: filtersTribesOption,\n        allocation: filtersAllocationOption,\n        filterButton: filterButtonOptions,\n        dotsButton: dotsButtonOptions,\n      } as Record<keyof Filters, { label: string; value: string }[]>,\n      updateFilters: (key, newV) => updateFilters({ [key]: newV }),\n      filtersInfo: {\n        searchedV: { label: 'Поиск', clearedValue: '' },\n        blocks: { label: 'Блок', clearedValue: [] },\n        tribes: { label: 'Трайб', clearedValue: [] },\n        allocation: { label: 'Аллокация', clearedValue: '' },\n        year: { label: 'Год', clearedValue: null },\n        filterButton: { label: 'Фильтр', clearedValue: '' },\n        dotsButton: { label: 'Меню', clearedValue: '' },\n      },\n    });\n\n    const chipsList = filterList\n      .map((item, index) => {\n        if ('groupLabel' in item) {\n          return item.items.map((innerItem, innerIdex) => ({\n            text: String(innerItem.label),\n            view: 'default' as const,\n            hasClear: false as const,\n            onClick: innerItem.onClick,\n            key: `chip-key${index}-${innerIdex}-${innerItem.label}`,\n          }));\n        }\n        return {\n          text: String(item.label),\n          view: 'default' as const,\n          hasClear: false as const,\n          onClick: item.onClick,\n          key: `chip-key-${index}-${item.label}`,\n        };\n      })\n      .flat();\n\n    return (\n      <GridContainerM>\n        <SegmentProvider defaultSelected={['item_0']}>\n          <div\n            style={{\n              position: 'relative',\n              width: 'min-content',\n            }}\n          >\n            <AnalyticalWidget\n              size=\"m\"\n              headerSlot={\n                <AnalyticalWidget.Header\n                  title=\"Analytic widget M\"\n                  badge=\"TA\"\n                  subtitle=\"Monthly report\"\n                  rightSlot={\n                    <Flow\n                      alignment=\"center\"\n                      mainAxisGap=\"8px\"\n                      style={{\n                        flexWrap: 'nowrap',\n                      }}\n                    >\n                      <SegmentGroup hasBackground size=\"xs\">\n                        {someItems.map((_, i) => (\n                          <SegmentItem\n                            // eslint-disable-next-line react/no-array-index-key\n                            key={`item:${i}`}\n                            value={`item_${i}`}\n                            label={`Label${i + 1}`}\n                            size=\"xs\"\n                            view=\"primary\"\n                          />\n                        ))}\n                      </SegmentGroup>\n                    </Flow>\n                  }\n                  infoTooltipText=\"Info\"\n                  href=\"/\"\n                />\n              }\n              topSlot={\n                <Flow orientation=\"vertical\" mainAxisGap={8}>\n                  <AnalyticalWidget.Chips\n                    opened={filterListOpened}\n                    isWrapped\n                    gap=\"wide\"\n                    isCommonChipStyles={false}\n                    chips={chipsList}\n                  />\n                </Flow>\n              }\n              contentSlot={\n                <div\n                  style={{\n                    minHeight: 'fit-content',\n                  }}\n                >\n                  {longText()}\n                </div>\n              }\n              classes={{\n                topSlot: 'myCustomClassForTopSlot',\n                middleSlot: 'myCustomClassForMiddleSlot',\n                contentSlot: 'myCustomClassForContentSlot',\n                root: 'myCustomClassForRoot',\n              }}\n            />\n            <AnalyticalWidget.DotsIconButton\n              absolute\n              dropdownProps={{\n                items: generateButtonItems(\n                  'dotsButton',\n                  dotsButtonOptions,\n                  filterList,\n                ),\n                onItemSelect(item) {\n                  updateFilters({\n                    dotsButton:\n                      filters.dotsButton === item.value?.toString()\n                        ? ''\n                        : item.value?.toString() ?? '',\n                  });\n                },\n              }}\n            />\n          </div>\n        </SegmentProvider>\n      </GridContainerM>\n    );\n  }"
        },
        {
          "exportName": "AnalyticalWidgetS",
          "displayName": "AnalyticalWidgetS",
          "type": "full-code",
          "code": "import {\n  Box,\n  Combobox,\n  Flow,\n  SegmentGroup,\n  SegmentProvider,\n  TooltipList,\n  useFiltersList,\n  IconDone,\n  SegmentItem,\n  AnalyticalWidget,\n  textInfo\n} from '@daisforge/ui';\nimport type { ItemOrGroup } from '@daisforge/ui';\n\nimport React, { useMemo, useReducer, useState } from 'react';\n\ntype Filters = {\n  searchedV: string;\n  blocks: string[];\n  tribes: string[];\n  allocation: string;\n  year: number | null;\n  filterButton: string;\n  dotsButton: string;\n};\n\nconst DEFAULT_FILTERS: Filters = {\n  searchedV: '',\n  blocks: [],\n  tribes: [],\n  allocation: '',\n  year: null,\n  filterButton: '',\n  dotsButton: '',\n};\n\nconst LABELS: { [key in keyof Filters]: string } = {\n  searchedV: 'Поиск',\n  blocks: 'Блок',\n  tribes: 'Трайб',\n  allocation: 'Аллокация',\n  year: 'Год',\n  filterButton: 'Фильтры',\n  dotsButton: 'Меню',\n};\n\nconst useFetch = (key: 'blocks' | 'tribes' | 'allocation', num = 10) =>\n  useMemo(\n    () =>\n      Array(num)\n        .fill(0)\n        .map((_, i) => ({\n          label: \\\n\n() => {\n    const [filters, updateFilters] = useReducer(\n      filtersReducer,\n      DEFAULT_FILTERS,\n    );\n    const filtersBlocksOption = useFetch('blocks', 10);\n    const filtersTribesOption = useFetch('tribes', 15);\n    const filtersAllocationOption = useFetch('allocation', 10);\n\n    const { filterList, filterListOpened } = useFiltersList({\n      filters,\n      options: {\n        blocks: filtersBlocksOption,\n        tribes: filtersTribesOption,\n        allocation: filtersAllocationOption,\n        filterButton: filterButtonOptions,\n        dotsButton: dotsButtonOptions,\n      } as Record<keyof Filters, { label: string; value: string }[]>,\n      updateFilters: (key, newV) => updateFilters({ [key]: newV }),\n      filtersInfo: {\n        searchedV: { label: 'Поиск', clearedValue: '' },\n        blocks: { label: 'Блок', clearedValue: [] },\n        tribes: { label: 'Трайб', clearedValue: [] },\n        allocation: { label: 'Аллокация', clearedValue: '' },\n        year: { label: 'Год', clearedValue: null },\n        filterButton: { label: 'Фильтр', clearedValue: '' },\n        dotsButton: { label: 'Меню', clearedValue: '' },\n      },\n    });\n\n    const chipsList = filterList\n      .map((item) => {\n        if ('groupLabel' in item) {\n          return item.items.map((innerItem) => ({\n            text: String(innerItem.label),\n            view: 'default' as const,\n            hasClear: false as const,\n            onClick: innerItem.onClick,\n          }));\n        }\n        return {\n          text: String(item.label),\n          view: 'default' as const,\n          hasClear: false as const,\n          onClick: item.onClick,\n        };\n      })\n      .flat();\n\n    return (\n      <GridContainerS>\n        <SegmentProvider defaultSelected={['item_0']}>\n          <div\n            style={{\n              position: 'relative',\n              width: 'min-content',\n            }}\n          >\n            <AnalyticalWidget\n              size=\"s\"\n              headerSlot={\n                <AnalyticalWidget.Header\n                  title=\"Заголовок\"\n                  badge=\"TA\"\n                  subtitle=\"Подзаголовок здесь\"\n                  infoTooltipText=\"Info\"\n                  href=\"/\"\n                />\n              }\n              topSlot={\n                <Flow orientation=\"vertical\" mainAxisGap={8}>\n                  <AnalyticalWidget.Chips\n                    opened={filterListOpened}\n                    isWrapped\n                    gap=\"wide\"\n                    isCommonChipStyles={false}\n                    chips={chipsList}\n                  />\n                </Flow>\n              }\n              contentSlot={\n                <div\n                  style={{\n                    minHeight: 'fit-content',\n                  }}\n                >\n                  {longText()}\n                </div>\n              }\n              classes={{\n                topSlot: 'myCustomClassForTopSlot',\n                middleSlot: 'myCustomClassForMiddleSlot',\n                contentSlot: 'myCustomClassForContentSlot',\n                root: 'myCustomClassForRoot',\n              }}\n            />\n            <AnalyticalWidget.DotsIconButton\n              absolute\n              dropdownProps={{\n                items: generateButtonItems(\n                  'dotsButton',\n                  dotsButtonOptions,\n                  filterList,\n                ),\n                onItemSelect(item) {\n                  updateFilters({\n                    dotsButton:\n                      filters.dotsButton === item.value?.toString()\n                        ? ''\n                        : item.value?.toString() ?? '',\n                  });\n                },\n              }}\n            />\n          </div>\n        </SegmentProvider>\n      </GridContainerS>\n    );\n  }"
        },
        {
          "exportName": "AnalyticalWidgetCustomTopSlot",
          "displayName": "Custom topSlot + rightSlot",
          "type": "full-code",
          "code": "() => {\n    const [filters, updateFilters] = useReducer(\n      filtersReducer,\n      DEFAULT_FILTERS,\n    );\n    const filtersBlocksOption = useFetch('blocks', 10);\n    const filtersTribesOption = useFetch('tribes', 15);\n    const filtersAllocationOption = useFetch('allocation', 10);\n    const [period, setPeriod] = useState('month');\n\n    const { filterList } = useFiltersList({\n      filters,\n      options: {\n        blocks: filtersBlocksOption,\n        tribes: filtersTribesOption,\n        allocation: filtersAllocationOption,\n        filterButton: filterButtonOptions,\n        dotsButton: dotsButtonOptions,\n      } as Record<keyof Filters, { label: string; value: string }[]>,\n      updateFilters: (key, newV) => updateFilters({ [key]: newV }),\n      filtersInfo: {\n        searchedV: { label: 'Поиск', clearedValue: '' },\n        blocks: { label: 'Блок', clearedValue: [] },\n        tribes: { label: 'Трайб', clearedValue: [] },\n        allocation: { label: 'Аллокация', clearedValue: '' },\n        year: { label: 'Год', clearedValue: null },\n        filterButton: { label: 'Фильтр', clearedValue: '' },\n        dotsButton: { label: 'Меню', clearedValue: '' },\n      },\n    });\n\n    const customChips = filterList.flatMap((item) =>\n      'groupLabel' in item\n        ? item.items.map((inner) => ({\n            label: String(inner.label),\n            onClick: inner.onClick,\n          }))\n        : [{ label: String(item.label), onClick: item.onClick }],\n    );\n    const hasChips = customChips.length > 0;\n    const lastRef = useRef(customChips);\n    if (hasChips) {\n      lastRef.current = customChips;\n    }\n    const renderedChips = hasChips ? customChips : lastRef.current;\n\n    return (\n      <div style={{ padding: 20, background: 'grey' }}>\n        <div style={{ position: 'relative', width: 600, height: 512 }}>\n          <AnalyticalWidget\n            size=\"l\"\n            headerSlot={\n              <AnalyticalWidget.Header\n                title=\"Custom topSlot\"\n                badge=\"TA\"\n                subtitle=\"Свои чипы + Select в rightSlot\"\n                infoTooltipText=\"Info\"\n                rightSlot={\n                  <Select\n                    size=\"xs\"\n                    value={period}\n                    onChange={(v) => setPeriod(v as string)}\n                    items={[\n                      { label: 'Месяц', value: 'month' },\n                      { label: 'Квартал', value: 'quarter' },\n                      { label: 'Год', value: 'year' },\n                    ]}\n                  />\n                }\n              />\n            }\n            topSlot={\n              <div className={analyticalWidgetClassNames.selfSpacedTopSlot}>\n                <Collapse isOpen={hasChips} unMountOnClose>\n                  <div\n                    style={{\n                      display: 'flex',\n                      flexWrap: 'wrap',\n                      gap: 4,\n                      paddingTop: 8,\n                    }}\n                  >\n                    {renderedChips.map((chip, index) => (\n                      <button\n                        type=\"button\"\n                        // eslint-disable-next-line react/no-array-index-key\n                        key={`${chip.label}-${index}`}\n                        onClick={chip.onClick}\n                        style={{\n                          padding: '2px 8px',\n                          borderRadius: 12,\n                          background: 'rgba(0, 0, 0, 0.06)',\n                          border: 'none',\n                          fontSize: 12,\n                          lineHeight: '16px',\n                          whiteSpace: 'nowrap',\n                          cursor: 'pointer',\n                        }}\n                      >\n                        {chip.label}\n                      </button>\n                    ))}\n                  </div>\n                </Collapse>\n              </div>\n            }\n            contentSlot={\n              <div style={{ minHeight: 'fit-content' }}>{longText()}</div>\n            }\n          />\n          <AnalyticalWidget.DotsIconButton\n            absolute\n            dropdownProps={{\n              items: generateButtonItems(\n                'dotsButton',\n                dotsButtonOptions,\n                filterList,\n              ),\n              onItemSelect(item) {\n                updateFilters({\n                  dotsButton:\n                    filters.dotsButton === item.value?.toString()\n                      ? ''\n                      : item.value?.toString() ?? '',\n                });\n              },\n            }}\n          />\n        </div>\n      </div>\n    );\n  }"
        }
      ]
    },
    "ApprovalCenter": {
      "name": "ApprovalCenter",
      "group": "components",
      "folderName": "ApprovalCenter",
      "role": "primary",
      "description": "Панель согласования с превью, историей действий и жизненным циклом стадий по вкладкам",
      "props": [
        {
          "name": "tabs",
          "type": "ApprovalCenterTabs",
          "required": true,
          "description": "Параметры вкладок"
        },
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные CSS-стили для контейнера"
        },
        {
          "name": "history",
          "type": "HistoryItem[] | undefined",
          "required": false,
          "description": "Параметры вкладки истории"
        },
        {
          "name": "lifeCycle",
          "type": "LifeCycleItem[] | undefined",
          "required": false,
          "description": "Параметры вкладки жизненного цикла"
        },
        {
          "name": "preview",
          "type": "ApprovalCenterPreview | undefined",
          "required": false,
          "description": "Параметры превью"
        }
      ],
      "propsTypeName": "ApprovalCenterProps",
      "sourceFile": "packages/ui-kit/src/components/ApprovalCenter/ApprovalCenter.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "согласование заявки",
        "workflow approval",
        "история действий"
      ],
      "docs": "# ApprovalCenter\n\nКомпонент согласований. Используется в случаях, когда необходимо необходимо отобразить последовательные согласования между группами лиц. Показывает текущее состояние, а также общую историю.\n\n## Ключевые особенности\n\n- Поддержка превью `preview` - экран, необходимый для кейсов, когда данные ещё не были получены\n- Возможность переключения и скрытия вкладок `tabs` - управление состоянием вкладок (`Tabs`)\n- Управление жизненным циклом `lifeCycle` - параметры отображения вкладки жизненного цикла\n- Управление историей `history` - параметры отображения вкладки истории\n- Кастомизация через `$css` - передача собственных CSS стилей в корневой элемент компонента",
      "apiDocs": "# ApprovalCenter API\n\n## ApprovalCenterProps\n\n```typescript\ntype ApprovalCenterProps = {\n  /**\n   * Дополнительный класс для корневого элемента\n   */\n  className?: string;\n  /**\n   * Кастомные CSS-стили для контейнера\n   */\n  $css?: string | CSSObject | FlattenSimpleInterpolation;\n  /**\n   * Параметры превью\n   */\n  preview?: ApprovalCenterPreview;\n  /**\n   * Параметры вкладок\n   */\n  tabs: ApprovalCenterTabs;\n  /**\n   * Параметры вкладки жизненного цикла\n   */\n  lifeCycle?: LifeCycleItem[];\n  /**\n   * Параметры вкладки истории\n   */\n  history?: HistoryItem[];\n};\n```\n\n## ApprovalCenterPreview\n\n```typescript\ntype ApprovalCenterPreview = {\n  /**\n   * Параметры кнопки превью\n   */\n  button?: PreviewButton;\n  /**\n   * Переключить превью в режим загрузки\n   */\n  loading?: boolean;\n};\n```\n\n## PreviewButton\n\n```typescript\ntype PreviewButton = {\n  /**\n   * Колбэк, вызываемый по клику\n   */\n  onClick: () => void;\n  /**\n   * Текстовая надпись\n   */\n  text: string;\n};\n```\n\n## ApprovalCenterTabs\n\n```typescript\ntype ApprovalCenterTabs = {\n  /**\n   * Текущая открытая вкладка\n   */\n  active: 'LIFE_CYCLE';\n  /**\n   * Список доступных вкладок\n   */\n  available:\n    | ['LIFE_CYCLE', 'HISTORY']\n    | ['HISTORY', 'LIFE_CYCLE']\n    | ['HISTORY']\n    | ['LIFE_CYCLE'];\n};\n```\n\n## LifeCycleItem\n\n```typescript\ntype LifeCycleItem = {\n  /**\n   * Статус\n   */\n  status: LifeCycleStatus;\n  /**\n   * Заголовок\n   */\n  title: string;\n  /**\n   * Заголовок выполненного действия\n   */\n  actionTitle?: string;\n  /**\n   * Дата выполненного действия\n   */\n  actionDate?: string;\n  /**\n   * Этапы (аккордеон)\n   */\n  stages?: StageItem[];\n  /**\n   * Вспомогательные кнопки\n   */\n  buttons?: LifeCycleButton[];\n};\n```\n\n## LifeCycleStatus\n\n```typescript\ntype LifeCycleStatus = 'DEFAULT' | 'WAIT' | 'SUCCESSFUL' | 'FAILURE';\n```\n\n## StageItem\n\n```typescript\ntype StageItem = {\n  /**\n   * Статус\n   */\n  status: StageStatus;\n  /**\n   * Заголовок\n   */\n  title: string;\n  /**\n   * Открыт ли элемент аккордеона\n   */\n  open?: boolean;\n  /**\n   * Комментарий\n   */\n  comment?: string;\n  /**\n   * Тултип на иконке статуса\n   */\n  tooltip?: { text: string };\n  /**\n   * Пометка (обычно звёздочка)\n   */\n  mark?: { tooltip: { text: string }; icon: ReactNode };\n  /**\n   * Заголовок действия\n   */\n  actionTitle?: string;\n  /**\n   * Заголовок даты\n   */\n  actionDate?: string;\n  /**\n   * ФИО людей, отвечающих за согласование\n   */\n  assignee?: [string, ...string[]];\n  /**\n   * Вспомогательные кнопки\n   */\n  buttons?: LifeCycleButton[];\n};\n```\n\n## StageStatus\n\n```typescript\ntype StageStatus = 'DEFAULT' | 'WAIT' | 'SUCCESSFUL' | 'FAILURE';\n```\n\n## LifeCycleButton\n\n```typescript\ntype LifeCycleButton = {\n  /**\n   * Слот для контента слева\n   */\n  contentLeft: ReactNode;\n  /**\n   * Колбэк, вызываемый по клику\n   */\n  onClick: () => void;\n  /**\n   * Текстовая надпись\n   */\n  text: string;\n};\n```\n\n## HistoryItem\n\n```typescript\ntype HistoryItem = {\n  /**\n   * Статус\n   */\n  status: HistoryItemStatus;\n  /**\n   * Заголовок действия\n   */\n  actionTitle: string;\n  /**\n   * Дата действия\n   */\n  actionDate: string;\n};\n```\n\n## HistoryItemStatus\n\n```typescript\ntype HistoryItemStatus = 'DEFAULT' | 'WAIT' | 'SUCCESSFUL' | 'FAILURE';\n```",
      "curatedStories": [
        {
          "exportName": "Preview",
          "displayName": "Preview",
          "type": "args-only",
          "code": "{\n    tabs: {\n      active: 'LIFE_CYCLE',\n      available: ['LIFE_CYCLE', 'HISTORY'],\n    },\n    preview: {\n      button: {\n        onClick: () => {},\n        text: 'Показать жизненный цикл',\n      },\n      loading: false,\n    },\n  }"
        },
        {
          "exportName": "LoadingPreview",
          "displayName": "Loading preview",
          "type": "args-only",
          "code": "{\n    tabs: {\n      active: 'LIFE_CYCLE',\n      available: ['LIFE_CYCLE', 'HISTORY'],\n    },\n    preview: {\n      button: {\n        onClick: () => {},\n        text: 'Показать жизненный цикл',\n      },\n      loading: true,\n    },\n  }"
        },
        {
          "exportName": "WithTabs",
          "displayName": "With tabs",
          "type": "args-only",
          "code": "{\n    tabs: {\n      active: 'LIFE_CYCLE',\n      available: ['LIFE_CYCLE', 'HISTORY'],\n    },\n    lifeCycle,\n    history,\n  }"
        },
        {
          "exportName": "WithoutTabs",
          "displayName": "Without tabs",
          "type": "args-only",
          "code": "{\n    tabs: {\n      active: 'LIFE_CYCLE',\n      available: ['LIFE_CYCLE'],\n    },\n    lifeCycle,\n    history,\n  }"
        },
        {
          "exportName": "WithScroll",
          "displayName": "With scroll",
          "type": "args-only",
          "code": "{\n    tabs: {\n      active: 'LIFE_CYCLE',\n      available: ['LIFE_CYCLE', 'HISTORY'],\n    },\n    lifeCycle,\n    history,\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ApprovalCenter } from '@daisforge/ui';",
      "minimalUsage": "<ApprovalCenter tabs={{}} />",
      "examples": [
        {
          "exportName": "Preview",
          "displayName": "Preview",
          "type": "args-only",
          "code": "{\n    tabs: {\n      active: 'LIFE_CYCLE',\n      available: ['LIFE_CYCLE', 'HISTORY'],\n    },\n    preview: {\n      button: {\n        onClick: () => {},\n        text: 'Показать жизненный цикл',\n      },\n      loading: false,\n    },\n  }"
        },
        {
          "exportName": "LoadingPreview",
          "displayName": "Loading preview",
          "type": "args-only",
          "code": "{\n    tabs: {\n      active: 'LIFE_CYCLE',\n      available: ['LIFE_CYCLE', 'HISTORY'],\n    },\n    preview: {\n      button: {\n        onClick: () => {},\n        text: 'Показать жизненный цикл',\n      },\n      loading: true,\n    },\n  }"
        },
        {
          "exportName": "WithTabs",
          "displayName": "With tabs",
          "type": "args-only",
          "code": "{\n    tabs: {\n      active: 'LIFE_CYCLE',\n      available: ['LIFE_CYCLE', 'HISTORY'],\n    },\n    lifeCycle,\n    history,\n  }"
        },
        {
          "exportName": "WithoutTabs",
          "displayName": "Without tabs",
          "type": "args-only",
          "code": "{\n    tabs: {\n      active: 'LIFE_CYCLE',\n      available: ['LIFE_CYCLE'],\n    },\n    lifeCycle,\n    history,\n  }"
        }
      ]
    },
    "Attach": {
      "name": "Attach",
      "group": "components",
      "folderName": "Attach",
      "role": "primary",
      "description": "Поле для прикрепления локального файла к форме",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "acceptedFileFormats",
          "type": "string[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "additionalContent",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "buttonType",
          "type": "\"button\" | \"iconButton\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentPlacing",
          "type": "\"default\" | \"relaxed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "customIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "dropdownOptions",
          "type": "DropdownOptions | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "files",
          "type": "File[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "flow",
          "type": "\"horizontal\" | \"vertical\" | \"auto\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hasAttachment",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "helperText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "helperTextView",
          "type": "\"default\" | \"negative\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hideButtonOnAttach",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isLoading",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "loader",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "onClear",
          "type": "((fileInfo: FileInfo) => void) | ((fileInfo: FileInfo) => void) | ((fileInfo: FileInfo) => void) | ((fileInfo: FileInfo) => void) | ((fileInfo: FileInfo) => void) | ((fileInfo: FileInfo) => void) | ((fileInfo: FileInfo) => void) | ((fileInfo: FileInfo) => void) | ((fileInfo: FileInfo) => void) | ((fileInfo: FileInfo) => void) | ((fileInfo: FileInfo) => void) | ((fileInfo: FileInfo) => void) | ((fi…",
          "required": false,
          "description": ""
        },
        {
          "name": "outlined",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftLeft",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftRight",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "square",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretch",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretching",
          "type": "\"auto\" | \"filled\" | \"fixed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "text",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"secondary\" | \"clear\" | \"success\" | \"warning\" | \"critical\" | \"dark\" | \"black\" | \"white\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChange",
          "type": "(React.ChangeEventHandler<HTMLInputElement> & React.FormEventHandler<HTMLElement>) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"button\" | \"reset\" | \"submit\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "value",
          "type": "((string | number | readonly string[]) & (string | number)) | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof Attach>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Attach/Attach.d.ts",
      "type": "wrapper",
      "atomicBase": "Attach",
      "category": "Локальные компоненты",
      "keywords": [
        "загрузка файла",
        "file upload",
        "прикрепить документ"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Attach } from '@daisforge/ui';",
      "minimalUsage": "<Attach />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Attach } from '@daisforge/ui';\nexport function App() {\n    return (\n        <Attach text=\"Загрузить файл\" />\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Фильтр форматов файлов",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Attach } from '@daisforge/ui';\nexport function App() {\n    return (\n        <Attach acceptedFileFormats={['.pdf', '.doc']} text=\"Загрузить документ\" />\n    );\n}"
        }
      ]
    },
    "Autocomplete": {
      "name": "Autocomplete",
      "group": "components",
      "folderName": "Autocomplete",
      "role": "primary",
      "description": "Поле ввода с подсказками из выпадающего списка и кнопкой очистки значения",
      "props": [
        {
          "name": "onClear",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Callback при нажатии на кнопку очистки поля ввода."
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChange",
          "type": "React.ChangeEventHandler<HTMLInputElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "React.HTMLInputTypeAttribute | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "AutocompleteProps",
      "sourceFile": "packages/ui-kit/src/components/Autocomplete/Autocomplete.tsx",
      "type": "wrapper",
      "atomicBase": "Autocomplete",
      "formVariant": "FormAutocomplete",
      "category": "Локальные компоненты",
      "keywords": [
        "поле с подсказками",
        "search input",
        "выбор из списка при вводе",
        "автокомплит"
      ],
      "docs": "# Autocomplete\n\nКомпонент Autocomplete - обертка над `Autocomplete` из `@salutejs/sdds-finai` с добавлением логики отображения иконки замка при `disabled` или `readOnly`.\n\n## Ключевые особенности\n\n- Поле ввода с автодополнением на основе SDDS Autocomplete\n- Автоматическое отображение иконки замка при `disabled` или `readOnly`\n- Поддержка `onClear` с крестиком очистки\n- Доступные размеры: `s`, `xs`\n\n> Подробнее о типах и пропсах — [Autocomplete API](?path=/docs/локальные-компоненты-autocomplete-api--docs)",
      "apiDocs": "# Autocomplete API\n\nОбёртка над `Autocomplete` из `@salutejs/sdds-finai`. Добавляет `onClear`.\n\n## Кастомные пропсы (добавлены в обёртке)\n\n```typescript\ntype AutocompleteProps = AutocompleteBaseProps & {\n  /**\n   * Callback при нажатии на кнопку очистки поля ввода.\n   */\n  onClear?: () => void;\n};\n```\n\n## Пропсы из @salutejs/sdds-finai\n\nКомпонент принимает все пропсы атомарного `Autocomplete` из `@salutejs/sdds-finai` (включая пропсы `TextField`).\n\nПолное описание — в документации: [Autocomplete](https://plasma.sberdevices.ru/sdds-finai/components/autocomplete/)",
      "curatedStories": [
        {
          "exportName": "Default",
          "displayName": "Default",
          "type": "full-code",
          "code": "import { Autocomplete } from '@daisforge/ui';\n\n(args: AutocompleteProps) => {\n    const [value, setValue] = useState('');\n\n    return (\n      <div style={{ width: '400px', minHeight: '300px' }}>\n        <Autocomplete\n          {...args}\n          value={value}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue(e.target.value)\n          }\n          onSuggestionSelect={(item) => setValue(item.label)}\n          suggestions={mockData}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Sizes",
          "displayName": "Размеры",
          "type": "full-code",
          "code": "import { Autocomplete } from '@daisforge/ui';\n\n(args: AutocompleteProps) => {\n    const sizes = ['s', 'xs'] as const;\n    const [values, setValues] = useState<Record<string, string>>({\n      l: '',\n      m: '',\n      s: '',\n      xs: '',\n    });\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '400px',\n          minHeight: '300px',\n        }}\n      >\n        {sizes.map((size) => (\n          <Autocomplete\n            {...args}\n            key={size}\n            size={size}\n            label={`Size: ${size}`}\n            placeholder=\"Начните вводить\"\n            value={values[size]}\n            onChange={(e: ChangeEvent<HTMLInputElement>) =>\n              setValues((prev) => ({ ...prev, [size]: e.target.value }))\n            }\n            onSuggestionSelect={(item) =>\n              setValues((prev) => ({ ...prev, [size]: item.label }))\n            }\n            suggestions={mockData}\n          />\n        ))}\n      </div>\n    );\n  }"
        },
        {
          "exportName": "WithClear",
          "displayName": "Различные варианты",
          "type": "full-code",
          "code": "import { Autocomplete } from '@daisforge/ui';\n\n(args: AutocompleteProps) => {\n    const [value1, setValue1] = useState('Алексей');\n    const [value2, setValue2] = useState('Екатерина');\n    const [value3, setValue3] = useState('');\n    const [value4, setValue4] = useState('Дмитрий');\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '400px',\n          minHeight: '300px',\n        }}\n      >\n        {/* Сценарий 3: onClear + value → только крестик */}\n        <Autocomplete\n          {...args}\n          label=\"onClear + value → крестик\"\n          value={value1}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue1(e.target.value)\n          }\n          onSuggestionSelect={(item) => setValue1(item.label)}\n          onClear={() => setValue1('')}\n          suggestions={mockData}\n        />\n\n        {/* Сценарий 2: onClear + value + contentRight → [крестик | иконка] рядом */}\n        <Autocomplete\n          {...args}\n          label=\"onClear + value + contentRight → рядом\"\n          value={value2}\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue2(e.target.value)\n          }\n          onSuggestionSelect={(item) => setValue2(item.label)}\n          onClear={() => setValue2('')}\n          suggestions={mockData}\n        />\n\n        {/* Сценарий 4: onClear без value → крестик скрыт, contentRight как есть */}\n        <Autocomplete\n          {...args}\n          label=\"Пустое значение — крестик скрыт\"\n          value={value3}\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue3(e.target.value)\n          }\n          onSuggestionSelect={(item) => setValue3(item.label)}\n          onClear={() => setValue3('')}\n          suggestions={mockData}\n        />\n\n        {/* Сценарий 1: readOnly → замок (заменяет всё) */}\n        <Autocomplete\n          {...args}\n          label=\"ReadOnly — замок вместо крестика и contentRight\"\n          value=\"Только для чтения\"\n          readOnly\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onClear={() => {}}\n          suggestions={mockData}\n        />\n\n        {/* Сценарий 1: disabled → замок (заменяет всё) */}\n        <Autocomplete\n          {...args}\n          label=\"Disabled — замок вместо крестика и contentRight\"\n          value=\"Заблокировано\"\n          disabled\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onClear={() => {}}\n          suggestions={mockData}\n        />\n\n        {/* Сценарий 4: только contentRight, без onClear */}\n        <Autocomplete\n          {...args}\n          label=\"Только contentRight, без onClear\"\n          value={value4}\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue4(e.target.value)\n          }\n          onSuggestionSelect={(item) => setValue4(item.label)}\n          suggestions={mockData}\n        />\n      </div>\n    );\n  }"
        }
      ],
      "chooseWhen": "Вне react-hook-form — самостоятельное поле с value/onChange, без встроенной интеграции с формой.",
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "afterList",
          "type": "ReactNode",
          "required": false,
          "description": "Ячейка для контента в конце выпадающего списка.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "beforeList",
          "type": "ReactNode",
          "required": false,
          "description": "Ячейка для контента в начале выпадающего списка.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "clear",
          "type": "boolean",
          "required": false,
          "description": "view применяется с clear-токенами",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента слева.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента справа.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultValue",
          "type": "string",
          "required": false,
          "description": "Значение поля ввода по-умолчанию.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "filter",
          "type": "((data: T) => boolean)",
          "required": false,
          "description": "Коллбэк фильтра подсказок.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "flip",
          "type": "boolean",
          "required": false,
          "description": "Отображение выпадающего списка сверху, если снизу недостаточно места.",
          "default": "false",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasDivider",
          "type": "boolean",
          "required": false,
          "description": "отобразить ли divider",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintContentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean",
          "required": false,
          "description": "Видимость стрелки (хвоста).",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOffset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "description": "Направление раскрытия тултипа.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPortal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "Портал для окна подсказки. Принимает id контейнера или ref.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetIcon",
          "type": "ReactNode",
          "required": false,
          "description": "Иконка, рядом с которым произойдет вызов всплывающего окна.\nЕсли свойство не задано, применится иконка по умолчанию.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение иконки подсказки, когда отсутствует label\nили же он имеет labelPlacement='inner'.",
          "default": "`outer`",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintText",
          "type": "string",
          "required": false,
          "description": "Текст тултипа",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\"",
          "required": false,
          "description": "Способ открытия тултипа - наведение или клик мышью",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintWidth",
          "type": "string",
          "required": false,
          "description": "Ширина окна (в rem).",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "leftHelper",
          "type": "ReactNode",
          "required": false,
          "description": "Вспомогательный текст снизу слева для поля ввода.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "listMaxHeight",
          "type": "string",
          "required": false,
          "description": "Максимальная высота выпадающего списка подсказок.",
          "default": "25rem",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "listWidth",
          "type": "string",
          "required": false,
          "description": "Ширина выпадающего списка подсказок.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onScroll",
          "type": "((e: UIEvent<HTMLElement, UIEvent>) => void)",
          "required": false,
          "description": "Коллбэк, срабатывающий при скролле.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onSearch",
          "type": "(((value: string, event?: KeyboardEvent<HTMLInputElement>) => void) & ((value: string, event?: KeyboardEvent<HTMLInputElement>) => void)) | undefined",
          "required": false,
          "description": "Callback по нажатию Enter",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onSuggestionSelect",
          "type": "((data: T) => void)",
          "required": false,
          "description": "Коллбэк, который срабатывает при выборе подсказки.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optional",
          "type": "boolean",
          "required": false,
          "description": "Флаг необязательности поля",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optionalText",
          "type": "string",
          "required": false,
          "description": "Подпись для указания необязательности поля",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "portal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "Портал для выпадающего списка. Принимает id контейнера или ref.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderItem",
          "type": "((item: T) => ReactNode)",
          "required": false,
          "description": "Callback для кастомной настройки элемента в выпадающем списке.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderList",
          "type": "((data?: T[]) => ReactNode)",
          "required": false,
          "description": "Коллбэк для рендера кастомного списка подсказок.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderListEnd",
          "type": "(() => ReactNode)",
          "required": false,
          "description": "Коллбэк для рендера элемента в конце выпадающего списка.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "requiredPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "rightHelper",
          "type": "ReactNode",
          "required": false,
          "description": "Вспомогательный текст снизу справа для поля ввода.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "rootClassName",
          "type": "string",
          "required": false,
          "description": "ClassName для внешней обертки компонента.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "rootStyle",
          "type": "CSSProperties",
          "required": false,
          "description": "Style для внешней обертки компонента.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "suggestions",
          "type": "T[]",
          "required": false,
          "description": "Массив подсказок.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textAfter",
          "type": "string",
          "required": false,
          "description": "Слот для вспомогательного текста справа.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textBefore",
          "type": "string",
          "required": false,
          "description": "Слот для вспомогательного текста слева.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "threshold",
          "type": "number",
          "required": false,
          "description": "Минимальное число введенных символов, при котором открывается дропдаун.",
          "default": "2",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "titleCaption",
          "type": "ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу справа.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string",
          "required": false,
          "description": "Значение поля ввода.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "virtual",
          "type": "boolean",
          "required": false,
          "description": "Виртуализация в выпадающем списке.",
          "default": "false",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "ZIndex",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего списка.",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"viewMode\"",
          "required": false,
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintView",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "required",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "default": "'s'",
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\"",
          "required": false,
          "inheritedFrom": "Autocomplete",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Autocomplete } from '@daisforge/ui';",
      "minimalUsage": "<Autocomplete />",
      "examples": [
        {
          "exportName": "Default",
          "displayName": "Default",
          "type": "full-code",
          "code": "import { Autocomplete } from '@daisforge/ui';\n\n(args: AutocompleteProps) => {\n    const [value, setValue] = useState('');\n\n    return (\n      <div style={{ width: '400px', minHeight: '300px' }}>\n        <Autocomplete\n          {...args}\n          value={value}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue(e.target.value)\n          }\n          onSuggestionSelect={(item) => setValue(item.label)}\n          suggestions={mockData}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Sizes",
          "displayName": "Размеры",
          "type": "full-code",
          "code": "import { Autocomplete } from '@daisforge/ui';\n\n(args: AutocompleteProps) => {\n    const sizes = ['s', 'xs'] as const;\n    const [values, setValues] = useState<Record<string, string>>({\n      l: '',\n      m: '',\n      s: '',\n      xs: '',\n    });\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '400px',\n          minHeight: '300px',\n        }}\n      >\n        {sizes.map((size) => (\n          <Autocomplete\n            {...args}\n            key={size}\n            size={size}\n            label={`Size: ${size}`}\n            placeholder=\"Начните вводить\"\n            value={values[size]}\n            onChange={(e: ChangeEvent<HTMLInputElement>) =>\n              setValues((prev) => ({ ...prev, [size]: e.target.value }))\n            }\n            onSuggestionSelect={(item) =>\n              setValues((prev) => ({ ...prev, [size]: item.label }))\n            }\n            suggestions={mockData}\n          />\n        ))}\n      </div>\n    );\n  }"
        },
        {
          "exportName": "WithClear",
          "displayName": "Различные варианты",
          "type": "full-code",
          "code": "import { Autocomplete } from '@daisforge/ui';\n\n(args: AutocompleteProps) => {\n    const [value1, setValue1] = useState('Алексей');\n    const [value2, setValue2] = useState('Екатерина');\n    const [value3, setValue3] = useState('');\n    const [value4, setValue4] = useState('Дмитрий');\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '400px',\n          minHeight: '300px',\n        }}\n      >\n        {/* Сценарий 3: onClear + value → только крестик */}\n        <Autocomplete\n          {...args}\n          label=\"onClear + value → крестик\"\n          value={value1}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue1(e.target.value)\n          }\n          onSuggestionSelect={(item) => setValue1(item.label)}\n          onClear={() => setValue1('')}\n          suggestions={mockData}\n        />\n\n        {/* Сценарий 2: onClear + value + contentRight → [крестик | иконка] рядом */}\n        <Autocomplete\n          {...args}\n          label=\"onClear + value + contentRight → рядом\"\n          value={value2}\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue2(e.target.value)\n          }\n          onSuggestionSelect={(item) => setValue2(item.label)}\n          onClear={() => setValue2('')}\n          suggestions={mockData}\n        />\n\n        {/* Сценарий 4: onClear без value → крестик скрыт, contentRight как есть */}\n        <Autocomplete\n          {...args}\n          label=\"Пустое значение — крестик скрыт\"\n          value={value3}\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue3(e.target.value)\n          }\n          onSuggestionSelect={(item) => setValue3(item.label)}\n          onClear={() => setValue3('')}\n          suggestions={mockData}\n        />\n\n        {/* Сценарий 1: readOnly → замок (заменяет всё) */}\n        <Autocomplete\n          {...args}\n          label=\"ReadOnly — замок вместо крестика и contentRight\"\n          value=\"Только для чтения\"\n          readOnly\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onClear={() => {}}\n          suggestions={mockData}\n        />\n\n        {/* Сценарий 1: disabled → замок (заменяет всё) */}\n        <Autocomplete\n          {...args}\n          label=\"Disabled — замок вместо крестика и contentRight\"\n          value=\"Заблокировано\"\n          disabled\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onClear={() => {}}\n          suggestions={mockData}\n        />\n\n        {/* Сценарий 4: только contentRight, без onClear */}\n        <Autocomplete\n          {...args}\n          label=\"Только contentRight, без onClear\"\n          value={value4}\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue4(e.target.value)\n          }\n          onSuggestionSelect={(item) => setValue4(item.label)}\n          suggestions={mockData}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в Autocomplete.stories.tsx",
          "type": "usage",
          "code": "<Autocomplete\n            {...args}\n            key={size}\n            size={size}\n            label={`Size: ${size}`}\n            placeholder=\"Начните вводить\"\n            value={values[size]}\n            onChange={(e: ChangeEvent<HTMLInputElement>) =>\n              setValues((prev) => ({ ...prev, [size]: e.target.value }))\n            }\n            onSuggestionSelect={(item) =>\n              setValues((prev) => ({ ...prev, [size]: item.label }))\n            }\n            suggestions={mockData}\n          />",
          "sourceFile": "packages/storybook/src/stories/Autocomplete/Autocomplete.stories.tsx"
        }
      ]
    },
    "AutocompleteSearch": {
      "name": "AutocompleteSearch",
      "group": "components",
      "folderName": "AutocompleteSearch",
      "role": "primary",
      "description": "Поле поиска на основе Autocomplete с иконкой лупы, счётчиком найденного и пустым состоянием",
      "props": [
        {
          "name": "beforeListTotal",
          "type": "number | boolean | undefined",
          "required": false,
          "description": "Показать/Скрыть count значение в начале выпадающего листа. Или указать собственное число"
        },
        {
          "name": "beforeListTotalEntity",
          "type": "string | undefined",
          "required": false,
          "description": "Добавление названия сущности в начале выпадающего списка"
        },
        {
          "name": "onClear",
          "type": "((() => void) & (() => void)) | undefined",
          "required": false,
          "description": "Действие при выполнении нажатия на кнопку очистки поля ввода\nCallback при нажатии на кнопку очистки поля ввода."
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | undefined",
          "required": false,
          "description": "Размер Поля ввода",
          "default": "'s'"
        },
        {
          "name": "afterList",
          "type": "React.ReactNode",
          "required": false,
          "description": "Ячейка для контента в конце выпадающего списка."
        },
        {
          "name": "beforeList",
          "type": "React.ReactNode",
          "required": false,
          "description": "Ячейка для контента в начале выпадающего списка."
        },
        {
          "name": "contentLeft",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": "Слот для контента слева."
        },
        {
          "name": "contentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": "Слот для контента справа."
        },
        {
          "name": "defaultValue",
          "type": "string | undefined",
          "required": false,
          "description": "Значение поля ввода по-умолчанию."
        },
        {
          "name": "filter",
          "type": "((data: SuggestionItemType) => boolean) | undefined",
          "required": false,
          "description": "Коллбэк фильтра подсказок."
        },
        {
          "name": "flip",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отображение выпадающего списка сверху, если снизу недостаточно места.",
          "default": "false"
        },
        {
          "name": "hasDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": "отобразить ли divider"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false"
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`."
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": "Видимость стрелки (хвоста)."
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": "Направление раскрытия тултипа."
        },
        {
          "name": "hintPortal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "Портал для окна подсказки. Принимает id контейнера или ref."
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": "Иконка, рядом с которым произойдет вызов всплывающего окна.\nЕсли свойство не задано, применится иконка по умолчанию."
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": "Расположение иконки подсказки, когда отсутствует label\nили же он имеет labelPlacement='inner'.",
          "default": "`outer`"
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": "Текст тултипа"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": "Способ открытия тултипа - наведение или клик мышью"
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": "Ширина окна (в rem)."
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean | undefined",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)"
        },
        {
          "name": "leftHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": "Вспомогательный текст снизу слева для поля ввода."
        },
        {
          "name": "listMaxHeight",
          "type": "string | undefined",
          "required": false,
          "description": "Максимальная высота выпадающего списка подсказок.",
          "default": "25rem"
        },
        {
          "name": "listWidth",
          "type": "string | undefined",
          "required": false,
          "description": "Ширина выпадающего списка подсказок."
        },
        {
          "name": "onScroll",
          "type": "((e: React.UIEvent<HTMLElement, UIEvent>) => void) | undefined",
          "required": false,
          "description": "Коллбэк, срабатывающий при скролле."
        },
        {
          "name": "onSearch",
          "type": "(((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | undefined",
          "required": false,
          "description": "Callback по нажатию Enter"
        },
        {
          "name": "onSuggestionSelect",
          "type": "((data: SuggestionItemType) => void) | undefined",
          "required": false,
          "description": "Коллбэк, который срабатывает при выборе подсказки."
        },
        {
          "name": "optional",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг необязательности поля"
        },
        {
          "name": "optionalText",
          "type": "string | undefined",
          "required": false,
          "description": "Подпись для указания необязательности поля"
        },
        {
          "name": "portal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "Портал для выпадающего списка. Принимает id контейнера или ref."
        },
        {
          "name": "renderItem",
          "type": "((item: SuggestionItemType) => React.ReactNode) | undefined",
          "required": false,
          "description": "Callback для кастомной настройки элемента в выпадающем списке."
        },
        {
          "name": "renderList",
          "type": "((data?: SuggestionItemType[] | undefined) => React.ReactNode) | undefined",
          "required": false,
          "description": "Коллбэк для рендера кастомного списка подсказок."
        },
        {
          "name": "renderListEnd",
          "type": "(() => React.ReactNode) | undefined",
          "required": false,
          "description": "Коллбэк для рендера элемента в конце выпадающего списка."
        },
        {
          "name": "requiredPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right"
        },
        {
          "name": "rightHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": "Вспомогательный текст снизу справа для поля ввода."
        },
        {
          "name": "rootClassName",
          "type": "string | undefined",
          "required": false,
          "description": "ClassName для внешней обертки компонента."
        },
        {
          "name": "rootStyle",
          "type": "React.CSSProperties | undefined",
          "required": false,
          "description": "Style для внешней обертки компонента."
        },
        {
          "name": "suggestions",
          "type": "SuggestionItemType[] | undefined",
          "required": false,
          "description": "Массив подсказок."
        },
        {
          "name": "textAfter",
          "type": "string | undefined",
          "required": false,
          "description": "Слот для вспомогательного текста справа."
        },
        {
          "name": "textBefore",
          "type": "string | undefined",
          "required": false,
          "description": "Слот для вспомогательного текста слева."
        },
        {
          "name": "threshold",
          "type": "number | undefined",
          "required": false,
          "description": "Минимальное число введенных символов, при котором открывается дропдаун.",
          "default": "2"
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу справа."
        },
        {
          "name": "value",
          "type": "string | undefined",
          "required": false,
          "description": "Значение поля ввода."
        },
        {
          "name": "virtual",
          "type": "boolean | undefined",
          "required": false,
          "description": "Виртуализация в выпадающем списке.",
          "default": "false"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего списка."
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"viewMode\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintView",
          "type": "\"default\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "labelPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChange",
          "type": "React.ChangeEventHandler<HTMLInputElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "React.HTMLInputTypeAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"warning\" | \"negative\" | \"positive\" | \"edited\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "handlerClear",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Действие при выполнении нажатия на кнопку очистки поля ввода",
          "deprecated": true
        },
        {
          "name": "clear",
          "type": "boolean | undefined",
          "required": false,
          "description": "view применяется с clear-токенами",
          "deprecated": true
        }
      ],
      "propsTypeName": "AutocompleteSearchProps",
      "sourceFile": "packages/ui-kit/src/components/AutocompleteSearch/AutocompleteSearch.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "строка поиска",
        "search field",
        "поиск с автодополнением"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { AutocompleteSearch } from '@daisforge/ui';",
      "minimalUsage": "<AutocompleteSearch />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в AutoCompleteSearch.stories.tsx",
          "type": "usage",
          "code": "<AutocompleteSearch\n            {...args}\n            key={size}\n            size={size}\n            placeholder={`Size: ${size}`}\n            value={values[size]}\n            onChange={(e: ChangeEvent<HTMLInputElement>) =>\n              setValues((prev) => ({ ...prev, [size]: e.target.value }))\n            }\n            onSuggestionSelect={(item) =>\n              setValues((prev) => ({ ...prev, [size]: item.label }))\n            }\n            onClear={() => setValues((prev) => ({ ...prev, [size]: '' }))}\n            suggestions={mockData}\n          />",
          "sourceFile": "packages/storybook/src/stories/AutoCompleteSearch/AutoCompleteSearch.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в AutoCompleteSearch.stories.tsx",
          "type": "usage",
          "code": "<AutocompleteSearch\n          {...args}\n          value={value}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue(e.target.value)\n          }\n          onSuggestionSelect={(item) => setValue(item.label)}\n          onClear={() => setValue('')}\n          suggestions={mockData}\n          beforeListTotal\n          beforeListTotalEntity=\"[сущность]\"\n        />",
          "sourceFile": "packages/storybook/src/stories/AutoCompleteSearch/AutoCompleteSearch.stories.tsx"
        }
      ]
    },
    "Avatar": {
      "name": "Avatar",
      "group": "components",
      "folderName": "Avatar",
      "role": "primary",
      "description": "Изображение или инициалы пользователя с индикатором статуса и формой отображения",
      "props": [],
      "propsTypeName": "AvatarProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Avatar/Avatar.d.ts",
      "type": "wrapper",
      "atomicBase": "Avatar",
      "category": "Локальные компоненты",
      "keywords": [
        "аватар пользователя",
        "user photo",
        "иконка профиля"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "badgeView",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"light\"",
          "required": false,
          "description": "Вид Badge",
          "default": "default",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента справа, например `Icon`",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "count",
          "type": "number",
          "required": false,
          "description": "Отображаемое число. Не может быть меньше 1.",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "counterView",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"light\"",
          "required": false,
          "description": "Вид Counter",
          "default": "default",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customBackgroundColor",
          "type": "string",
          "required": false,
          "description": "Пользовательский цвет фона",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customBorderRadius",
          "type": "string | number",
          "required": false,
          "description": "Кастомный border-radius для fit варианта",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customColor",
          "type": "string",
          "required": false,
          "description": "Пользовательский цвет текста и иконок",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customText",
          "type": "string",
          "required": false,
          "description": "Кастомный текст вместо фотографии",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "extraPlacement",
          "type": "\"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\"",
          "required": false,
          "description": "Расположение дополнительного элемента",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focused",
          "type": "boolean",
          "required": false,
          "description": "Фокус",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasExtra",
          "type": "boolean",
          "required": false,
          "description": "Включить отображение дополнительного элемента",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isScalable",
          "type": "boolean",
          "required": false,
          "description": "Масштабируемый при наведении",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maxCount",
          "type": "number",
          "required": false,
          "description": "Максимальное отображаемое число. Не может быть меньше 1.",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pilled",
          "type": "boolean",
          "required": false,
          "description": "Компонент c округлым border-radius",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"xxl\" | \"s\" | \"l\" | \"m\" | \"fit\"",
          "required": false,
          "description": "Размер аватара",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "status",
          "type": "\"active\" | \"inactive\"",
          "required": false,
          "description": "Статус профиля",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "statusLabels",
          "type": "StatusLabels",
          "required": false,
          "description": "Словарь для озвучивания значений свойства status [a11y]",
          "default": "{ active: 'Активен', inactive: 'Неактивен' }",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "string",
          "required": false,
          "description": "Текстовая надпись",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "type",
          "type": "\"badge\" | \"counter\"",
          "required": false,
          "description": "Тип дополнительного элемента",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "url",
          "type": "string",
          "required": false,
          "description": "Ссылка на фотографию",
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "clear",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "name",
          "type": "string",
          "required": false,
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shape",
          "type": "\"circled\"",
          "required": false,
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "transparent",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "Avatar",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Avatar } from '@daisforge/ui';",
      "minimalUsage": "<Avatar />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в Widget.stories.tsx",
          "type": "usage",
          "code": "<Avatar size=\"l\" name=\"Задача №2\" />",
          "sourceFile": "packages/storybook/src/stories/Widget/Widget.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvas.highlightActiveTypeSplitView.stories.tsx",
          "type": "usage",
          "code": "<Avatar size={avatarSize} name={title} />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.HighlightActiveType/TableCanvas.highlightActiveTypeSplitView.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Инициалы вместо фотографии",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Avatar } from '@daisforge/ui';\nexport function App() {\n    return (\n        <>\n            <Avatar name=\"Иван Фадеев\" />\n        </>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Увеличение при наведении",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Avatar } from '@daisforge/ui';\nexport function App() {\n    return (\n        <>\n            <Avatar isScalable name=\"Иван Фадеев\" />\n        </>\n    );\n}"
        }
      ]
    },
    "AvatarGroup": {
      "name": "AvatarGroup",
      "group": "components",
      "folderName": "AvatarGroup",
      "role": "primary",
      "description": "Группа перекрывающихся аватаров для отображения нескольких участников компактно",
      "props": [],
      "propsTypeName": "AvatarGroupProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/AvatarGroup/AvatarGroup.d.ts",
      "type": "wrapper",
      "atomicBase": "AvatarGroup",
      "category": "Локальные компоненты",
      "keywords": [
        "список участников",
        "stacked avatars",
        "команда пользователей"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { AvatarGroup } from '@daisforge/ui';",
      "minimalUsage": "<AvatarGroup />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Example 1",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Avatar, AvatarGroup } from '@daisforge/ui';\nexport function App() {\n    return (\n        <AvatarGroup>\n                {\n                    Array(5).fill(true).map(() => (\n                        <Avatar size=\"xxl\" url=\"https://avatars.githubusercontent.com/u/1813468?v=4\" />\n                    ))\n                }\n            </AvatarGroup>\n    );\n}"
        }
      ]
    },
    "Badge": {
      "name": "Badge",
      "group": "components",
      "folderName": "Badge",
      "role": "primary",
      "description": "Небольшая цветная метка со счётчиком или статусом рядом с элементом интерфейса",
      "props": [],
      "propsTypeName": "BadgeProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Badge/Badge.d.ts",
      "type": "wrapper",
      "atomicBase": "Badge",
      "category": "Локальные компоненты",
      "keywords": [
        "метка статуса",
        "counter label",
        "индикатор количества"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "appearance",
          "type": "\"clear\" | \"transparent\" | \"default\"",
          "required": false,
          "description": "Стиль для UI конфигурации\nВлияет на выбор предустановленного набора токенов",
          "default": "default",
          "inheritedFrom": "Badge",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`",
          "inheritedFrom": "Badge",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента справа, например `Icon`",
          "inheritedFrom": "Badge",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customBackgroundColor",
          "type": "string",
          "required": false,
          "description": "Пользовательский цвет фона",
          "inheritedFrom": "Badge",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customColor",
          "type": "string",
          "required": false,
          "description": "Пользовательский цвет текста и иконок",
          "inheritedFrom": "Badge",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maxWidth",
          "type": "Width<string | number>",
          "required": false,
          "description": "Обрезает контент по максимальной ширине и добавляет ...",
          "default": "'auto'",
          "inheritedFrom": "Badge",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pilled",
          "type": "boolean",
          "required": false,
          "description": "Компонент c округлым border-radius",
          "default": "false",
          "inheritedFrom": "Badge",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\" | \"xs\"",
          "required": false,
          "description": "Размер Badge",
          "default": "m",
          "inheritedFrom": "Badge",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "string",
          "required": false,
          "description": "Текстовая надпись",
          "inheritedFrom": "Badge",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"light\"",
          "required": false,
          "description": "Вид Badge",
          "default": "default",
          "inheritedFrom": "Badge",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "clear",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Badge",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "transparent",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Badge",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "truncate",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Badge",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Badge } from '@daisforge/ui';",
      "minimalUsage": "<Badge />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в Widget.stories.tsx",
          "type": "usage",
          "code": "<Badge size=\"s\" transparent view=\"accent\" text=\"В работе\" />",
          "sourceFile": "packages/storybook/src/stories/Widget/Widget.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в BlockTitle.stories.tsx",
          "type": "usage",
          "code": "<Badge\n              size={titleBadgeSize}\n              view=\"default\"\n              text=\"Label\"\n              style={{ marginLeft: '12px' }}\n            />",
          "sourceFile": "packages/storybook/src/stories/BlockTitle/BlockTitle.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Размер badge",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Badge } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Badge text=\"Бейдж\" size=\"l\" />\n            <Badge text=\"Бейдж\" size=\"m\" />\n            <Badge text=\"Бейдж\" size=\"s\" />\n            <Badge text=\"Бейдж\" size=\"xs\" />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Скругленность badge",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Badge } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Badge text=\"Бейдж\" size=\"l\" pilled />\n            <Badge text=\"Бейдж\" size=\"m\" pilled />\n            <Badge text=\"Бейдж\" size=\"s\" pilled />\n            <Badge text=\"Бейдж\" size=\"xs\" pilled />\n        </div>\n    );\n}"
        }
      ]
    },
    "BlockGradientScroll": {
      "name": "BlockGradientScroll",
      "group": "components",
      "folderName": "BlockGradientScroll",
      "role": "primary",
      "description": "Прокручиваемый блок с градиентной тенью у краёв, сигнализирующей о скрытом контенте",
      "props": [
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные стили styled-components."
        },
        {
          "name": "variant",
          "type": "BlockGradientScrollVariant | undefined",
          "required": false,
          "description": "Варианты отображения градиента, white | gray. По умолчанию white",
          "default": "'white'"
        }
      ],
      "propsTypeName": "BlockGradientScrollProps",
      "sourceFile": "packages/ui-kit/src/components/BlockGradientScroll/BlockGradientScroll.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "скролл с тенью",
        "fade scroll",
        "индикатор прокрутки"
      ],
      "docs": "# BlockGradientScroll\n\nГрадиент-индикатор скролла — визуальная подсказка пользователю, что контент можно скроллить.\n\n## Ключевые особенности\n\n- Автоматически появляется при наличии скролла\n- Плавно исчезает при достижении конца\n- Доступен как компонент и как миксин для styled-components\n\n## Особенности\n\n- Основано на CSS `animation-timeline` — [поддержка браузеров](https://caniuse.com/?search=animation-timeline)\n- Тема определяется один раз в момент создания компонента/стилей (`getActiveTheme()`), при переключении темы градиент не обновится автоматически\n- Компонент автоматически получает padding через `getComputedStyle` — prop не нужен\n- Миксин принимает padding и сам применяет его к контейнеру — дублирование не требуется\n- Variant `white` (default) — белый/тёмный фон; `gray` — серый фон\n- `$css` позволяет передать дополнительные стили через styled-components\n\n## Экспорты\n\n### Компонент\n\n- `BlockGradientScroll` — React-компонент (`@daisforge/ui`)\n- `BlockGradientScrollProps` — Тип пропсов (`@daisforge/ui`)\n\n### Миксин\n\n- `BlockGradientScrollMixin` — Основной миксин (`@daisforge/ui/mixins`)\n- `BlockGradientScrollPadding` — Тип для padding (`@daisforge/ui/mixins`)\n- `BlockGradientScrollVariant` — Тип для variant (`@daisforge/ui/mixins`)\n- `BlockGradientScrollOptions` — Тип опций миксина (`@daisforge/ui/mixins`)\n\n### Внутренние (для кастомизации)\n\n- `blockGradientScrollContainerStyles` — Базовые стили контейнера\n- `blockGradientScrollAfterStyles` — Стили псевдоэлемента ::after\n- `blockGradientScrollKeyframes` — Keyframes анимации\n\n---\n\n## Использование\n\n### Компонент\n\nКомпонент **автоматически** получает padding'и из ваших стилей — просто укажите их в `style`, `className` или `$css`:\n\n<Source\n  language=\"tsx\"\n  code={`\n// Компонент сам определит padding из style\n<BlockGradientScroll\n  variant=\"white\"\n  style={{\n    maxHeight: 300,\n    overflowY: 'auto',\n    padding: 24,\n    background: '#ffffff',\n  }}\n>\n  {children}\n</BlockGradientScroll>\n`}\n/>\n\n### Миксин\n\nМиксин **сам применяет padding** к контейнеру — не нужно дублировать:\n\n<Source language=\"tsx\" code={`\n// Миксин сам применит padding: 24px ко всем сторонам\nconst Box = styled.div\\`\n  max-height: 300px;\n  overflow-y: auto;\n  background: #ffffff;\n\n\\${BlockGradientScrollMixin({ padding: 24, variant: 'white' })}\n\\`;\n`} />\n\n---\n\n## Примеры\n\n### 1. Базовый компонент\n\n<Source language=\"tsx\" code={`\n\n// Padding автоматически подхватывается из style\n\n<BlockGradientScroll\n  variant=\"white\"\n  style={{\n    maxHeight: 300,\n    overflowY: 'auto',\n    padding: 24,\n    background: '#ffffff',\n  }}\n>\n  <Item />\n  <Item />\n  <Item />\n</BlockGradientScroll>\n`} />\n\n<Canvas of={BlockGradientScrollStories.Default} />\n\n### 2. Миксин (styled-components)\n\n<Source language=\"tsx\" code={`\n\n// Миксин сам применяет padding — дублирование не нужно\nconst ScrollableBox = styled.div\\`\nmax-height: 300px;\noverflow-y: auto;\nbackground: #ffffff;\n\n\\${BlockGradientScrollMixin({ padding: 24, variant: 'white' })}\n\\`;\n\n<ScrollableBox>\n  <Item />\n  <Item />\n</ScrollableBox>\n`} />\n\n<Canvas of={BlockGradientScrollStories.MixinUsage} />\n\n### 3. Мало контента — градиент скрыт\n\nЕсли контент помещается без скролла, градиент автоматически скрыт (`opacity: 0`).\n\n<Canvas of={BlockGradientScrollStories.NoScroll} />\n\n### 4. Несколько контейнеров\n\nКаждый контейнер работает независимо благодаря `scroll-timeline`.\n\n<Canvas of={BlockGradientScrollStories.MultipleContainers} />\n\n### 5. Способы стилизации\n\nКомпонент поддерживает три способа кастомизации: `style`, `className`, `$css`.\n\n<Canvas of={BlockGradientScrollStories.StylingMethods} />\n\n> Подробнее о типах и пропсах — [BlockGradientScroll API](?path=/docs/локальные-компоненты-blockgradientscroll-api--docs)",
      "apiDocs": "# BlockGradientScroll API\n\n## BlockGradientScrollProps (компонент)\n\n```typescript\ntype BlockGradientScrollProps = Omit<\n  ComponentProps<'div'>,\n  'children' | 'ref'\n> & {\n  /**\n   * Контент внутри scroll-контейнера\n   */\n  children?: ReactNode;\n  /**\n   * Кастомные стили styled-components.\n   *\n   * @remarks\n   * Приоритет стилей (от низкого к высокому):\n   * 1. Базовые стили компонента\n   * 2. `$css` (styled-components стили)\n   * 3. `className` (CSS классы)\n   * 4. `style` (inline стили) — наивысший приоритет\n   *\n   * Padding из `style` автоматически подхватывается для градиента.\n   */\n  $css?: string | CSSObject | FlattenSimpleInterpolation;\n  /**\n   * Варианты отображения градиента, white | gray. По умолчанию white\n   */\n  variant?: BlockGradientScrollVariant;\n};\n```\n\n## BlockGradientScrollPadding (миксин)\n\n```typescript\ntype BlockGradientScrollPadding =\n  | number\n  | {\n      /** Верхний отступ */\n      top?: number;\n      /** Shorthand для left и right (применяется если left/right не указаны) */\n      inline?: number;\n      /** Левый отступ (приоритет над inline) */\n      left?: number;\n      /** Правый отступ (приоритет над inline) */\n      right?: number;\n      /** Нижний отступ */\n      bottom?: number;\n    };\n```\n\n## BlockGradientScrollVariant\n\n```typescript\ntype BlockGradientScrollVariant = 'white' | 'gray';\n```",
      "curatedStories": [
        {
          "exportName": "Default",
          "displayName": "1. Базовый компонент",
          "type": "args-only",
          "code": "{\n    variant: 'white',\n    style: {\n      maxHeight: 300,\n      overflowY: 'auto',\n      padding: 24,\n      background: surfaceSolidCard,\n      borderRadius: 8,\n      border: `1px solid ${outlineAccent}`,\n    },\n    children: generateItems(8),\n  }"
        },
        {
          "exportName": "MixinUsage",
          "displayName": "2. Миксин (styled-components)",
          "type": "full-code",
          "code": "() => (\n    <DemoContainer>\n      <div style={{ display: 'flex', gap: 20 }}>\n        <div style={{ flex: 1 }}>\n          <p style={{ marginBottom: 8, fontWeight: 500 }}>variant: white</p>\n          <BoxWithMixin>{generateItems(6)}</BoxWithMixin>\n        </div>\n        <div style={{ flex: 1 }}>\n          <p style={{ marginBottom: 8, fontWeight: 500 }}>variant: gray</p>\n          <BoxWithMixinGray>{generateItems(6)}</BoxWithMixinGray>\n        </div>\n      </div>\n    </DemoContainer>\n  )"
        },
        {
          "exportName": "NoScroll",
          "displayName": "3. Мало контента (без скролла)",
          "type": "args-only",
          "code": "{\n    variant: 'white',\n    style: {\n      maxHeight: 300,\n      overflowY: 'auto',\n      padding: 24,\n      borderRadius: 8,\n      border: `1px solid ${outlineAccent}`,\n    },\n    children: generateItems(2),\n  }"
        },
        {
          "exportName": "MultipleContainers",
          "displayName": "4. Несколько контейнеров",
          "type": "full-code",
          "code": "() => (\n    <DemoContainer>\n      <div style={{ display: 'flex', gap: 20 }}>\n        <BlockGradientScroll\n          variant=\"white\"\n          style={{\n            flex: 1,\n            maxHeight: 300,\n            overflowY: 'auto',\n            padding: 24,\n            borderRadius: 8,\n            border: `1px solid ${outlineAccent}`,\n          }}\n        >\n          {generateItems(6)}\n        </BlockGradientScroll>\n\n        <BlockGradientScroll\n          variant=\"gray\"\n          style={{\n            flex: 1,\n            maxHeight: 300,\n            overflowY: 'auto',\n            padding: 24,\n            background: surfaceSolidPrimary,\n            borderRadius: 8,\n            border: `1px solid ${outlineAccent}`,\n          }}\n        >\n          {generateItems(6)}\n        </BlockGradientScroll>\n\n        <BlockGradientScroll\n          variant=\"white\"\n          style={{\n            flex: 1,\n            maxHeight: 300,\n            overflowY: 'auto',\n            padding: '0 16px 32px',\n            borderRadius: 8,\n            border: `1px solid ${outlineAccent}`,\n          }}\n        >\n          {generateItems(6)}\n        </BlockGradientScroll>\n      </div>\n    </DemoContainer>\n  )"
        },
        {
          "exportName": "DynamicContent",
          "displayName": "5. Динамический контент",
          "type": "full-code",
          "code": "function DynamicContentRender() {\n    const [items, setItems] = useState([1, 2, 3]);\n\n    const addItem = () => {\n      setItems((prev) => [...prev, Math.max(...prev, 0) + 1]);\n    };\n\n    const removeItem = () => {\n      setItems((prev) => (prev.length > 0 ? prev.slice(0, -1) : prev));\n    };\n\n    const reset = () => {\n      setItems([1, 2, 3]);\n    };\n\n    return (\n      <DemoContainer>\n        <div style={{ marginBottom: 16, display: 'flex', gap: 8 }}>\n          <Button\n            onClick={addItem}\n            style={{\n              background: textPositive,\n              color: textPrimary,\n              border: 'none',\n              borderRadius: 4,\n              cursor: 'pointer',\n            }}\n          >\n            + Добавить\n          </Button>\n          <Button\n            onClick={removeItem}\n            style={{\n              background: textNegative,\n              color: textPrimary,\n              border: 'none',\n              borderRadius: 4,\n              cursor: 'pointer',\n            }}\n          >\n            − Удалить\n          </Button>\n          <Button\n            onClick={reset}\n            style={{\n              background: textInfo,\n              color: textPrimary,\n              border: 'none',\n              borderRadius: 4,\n              cursor: 'pointer',\n            }}\n          >\n            Сбросить\n          </Button>\n          <span\n            style={{\n              alignSelf: 'center',\n              marginLeft: 8,\n              color: textWarningMinor,\n            }}\n          >\n            Элементов: {items.length}\n          </span>\n        </div>\n\n        <BlockGradientScroll\n          variant=\"white\"\n          style={{\n            maxHeight: 300,\n            overflowY: 'auto',\n            padding: 24,\n            borderRadius: 8,\n            border: `1px solid ${outlineAccent}`,\n          }}\n        >\n          {items.map((id) => (\n            <DemoItem key={id}>\n              <h3>Элемент {id}</h3>\n            </DemoItem>\n          ))}\n          {items.length === 0 && (\n            <div\n              style={{\n                color: textWarningMinor,\n                textAlign: 'center',\n                padding: 40,\n              }}\n            >\n              Пусто. Добавь элементы.\n            </div>\n          )}\n        </BlockGradientScroll>\n      </DemoContainer>\n    );\n  }"
        },
        {
          "exportName": "StylingMethods",
          "displayName": "6. Способы стилизации (style, className, $css)",
          "type": "full-code",
          "code": "() => (\n    <DemoContainer>\n      <style>\n        {`\n          .custom-gradient-box {\n            max-height: 200px;\n            overflow-y: auto;\n            padding: 20px;\n            background: #fff8e1;\n            border-radius: 8px;\n            border: 2px dashed #ffa000;\n          }\n        `}\n      </style>\n\n      <div style={{ display: 'flex', gap: 20, flexDirection: 'column' }}>\n        {/* style prop */}\n        <div>\n          <p style={{ marginBottom: 8, fontWeight: 500 }}>\n            1. Через style prop\n          </p>\n          <pre\n            style={{\n              color: '#000',\n              background: '#f5f5f5',\n              padding: 12,\n              borderRadius: 4,\n              fontSize: 12,\n              marginBottom: 8,\n              overflow: 'auto',\n            }}\n          >\n            {`<BlockGradientScroll\n  variant=\"white\"\n  style={{\n    maxHeight: 200,\n    overflowY: 'auto',\n    padding: 20,\n    background: '#e8f5e9',\n    border: '2px solid #4caf50',\n  }}\n>\n  {children}\n</BlockGradientScroll>`}\n          </pre>\n          <BlockGradientScroll\n            variant=\"white\"\n            style={{\n              maxHeight: 200,\n              overflowY: 'auto',\n              padding: 20,\n              background: '#e8f5e9',\n              borderRadius: 8,\n              border: '2px solid #4caf50',\n            }}\n          >\n            {generateItems(5)}\n          </BlockGradientScroll>\n        </div>\n\n        {/* className prop */}\n        <div>\n          <p style={{ marginBottom: 8, fontWeight: 500 }}>2. Через className</p>\n          <pre\n            style={{\n              color: '#000',\n              background: '#f5f5f5',\n              padding: 12,\n              borderRadius: 4,\n              fontSize: 12,\n              marginBottom: 8,\n              overflow: 'auto',\n            }}\n          >\n            {`.custom-gradient-box {\n  max-height: 200px;\n  overflow-y: auto;\n  padding: 20px;\n  background: #fff8e1;\n  border: 2px dashed #ffa000;\n}\n\n<BlockGradientScroll\n  variant=\"white\"\n  className=\"custom-gradient-box\"\n>\n  {children}\n</BlockGradientScroll>`}\n          </pre>\n          <BlockGradientScroll variant=\"white\" className=\"custom-gradient-box\">\n            {generateItems(5)}\n          </BlockGradientScroll>\n        </div>\n\n        {/* $css prop */}\n        <div>\n          <p style={{ marginBottom: 8, fontWeight: 500 }}>\n            3. Через $css (styled-components)\n          </p>\n          <pre\n            style={{\n              color: '#000',\n              background: '#f5f5f5',\n              padding: 12,\n              borderRadius: 4,\n              fontSize: 12,\n              marginBottom: 8,\n              overflow: 'auto',\n            }}\n          >\n            {`<BlockGradientScroll\n  variant=\"white\"\n  $css={\\`\n    max-height: 200px;\n    overflow-y: auto;\n    padding: 20px;\n    background: linear-gradient(...);\n    border: 2px solid #2196f3;\n  \\`}\n>\n  {children}\n</BlockGradientScroll>`}\n          </pre>\n          <BlockGradientScroll\n            variant=\"white\"\n            $css={`\n              max-height: 200px;\n              overflow-y: auto;\n              padding: 20px;\n              background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);\n              border-radius: 8px;\n              border: 2px solid #2196f3;\n            `}\n          >\n            {generateItems(5)}\n          </BlockGradientScroll>\n        </div>\n      </div>\n    </DemoContainer>\n  )"
        },
        {
          "exportName": "AdaptiveLessThan1280",
          "displayName": "1280 Адаптив",
          "type": "full-code",
          "code": "() => (\n    <DemoContainer>\n      <div\n        style={{\n          display: 'flex',\n          gap: 20,\n          flexDirection: 'column',\n        }}\n      >\n        <div>\n          <p style={{ marginBottom: 8, fontWeight: 500 }}>\n            Компонент `BlockGradientScroll`\n          </p>\n          <BlockGradientScroll\n            variant=\"white\"\n            style={{\n              maxHeight: 300,\n              overflowY: 'auto',\n              padding: 24,\n              borderRadius: 8,\n              border: `1px solid ${outlineAccent}`,\n            }}\n          >\n            {generateItems(8)}\n          </BlockGradientScroll>\n        </div>\n\n        <div>\n          <p style={{ marginBottom: 8, fontWeight: 500 }}>\n            Миксин `BlockGradientScrollMixin`\n          </p>\n          <BoxWithMixin>{generateItems(8)}</BoxWithMixin>\n        </div>\n      </div>\n    </DemoContainer>\n  )"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { BlockGradientScroll } from '@daisforge/ui';",
      "minimalUsage": "<BlockGradientScroll />",
      "examples": [
        {
          "exportName": "MixinUsage",
          "displayName": "2. Миксин (styled-components)",
          "type": "full-code",
          "code": "() => (\n    <DemoContainer>\n      <div style={{ display: 'flex', gap: 20 }}>\n        <div style={{ flex: 1 }}>\n          <p style={{ marginBottom: 8, fontWeight: 500 }}>variant: white</p>\n          <BoxWithMixin>{generateItems(6)}</BoxWithMixin>\n        </div>\n        <div style={{ flex: 1 }}>\n          <p style={{ marginBottom: 8, fontWeight: 500 }}>variant: gray</p>\n          <BoxWithMixinGray>{generateItems(6)}</BoxWithMixinGray>\n        </div>\n      </div>\n    </DemoContainer>\n  )"
        },
        {
          "exportName": "MultipleContainers",
          "displayName": "4. Несколько контейнеров",
          "type": "full-code",
          "code": "() => (\n    <DemoContainer>\n      <div style={{ display: 'flex', gap: 20 }}>\n        <BlockGradientScroll\n          variant=\"white\"\n          style={{\n            flex: 1,\n            maxHeight: 300,\n            overflowY: 'auto',\n            padding: 24,\n            borderRadius: 8,\n            border: `1px solid ${outlineAccent}`,\n          }}\n        >\n          {generateItems(6)}\n        </BlockGradientScroll>\n\n        <BlockGradientScroll\n          variant=\"gray\"\n          style={{\n            flex: 1,\n            maxHeight: 300,\n            overflowY: 'auto',\n            padding: 24,\n            background: surfaceSolidPrimary,\n            borderRadius: 8,\n            border: `1px solid ${outlineAccent}`,\n          }}\n        >\n          {generateItems(6)}\n        </BlockGradientScroll>\n\n        <BlockGradientScroll\n          variant=\"white\"\n          style={{\n            flex: 1,\n            maxHeight: 300,\n            overflowY: 'auto',\n            padding: '0 16px 32px',\n            borderRadius: 8,\n            border: `1px solid ${outlineAccent}`,\n          }}\n        >\n          {generateItems(6)}\n        </BlockGradientScroll>\n      </div>\n    </DemoContainer>\n  )"
        },
        {
          "exportName": "DynamicContent",
          "displayName": "5. Динамический контент",
          "type": "full-code",
          "code": "function DynamicContentRender() {\n    const [items, setItems] = useState([1, 2, 3]);\n\n    const addItem = () => {\n      setItems((prev) => [...prev, Math.max(...prev, 0) + 1]);\n    };\n\n    const removeItem = () => {\n      setItems((prev) => (prev.length > 0 ? prev.slice(0, -1) : prev));\n    };\n\n    const reset = () => {\n      setItems([1, 2, 3]);\n    };\n\n    return (\n      <DemoContainer>\n        <div style={{ marginBottom: 16, display: 'flex', gap: 8 }}>\n          <Button\n            onClick={addItem}\n            style={{\n              background: textPositive,\n              color: textPrimary,\n              border: 'none',\n              borderRadius: 4,\n              cursor: 'pointer',\n            }}\n          >\n            + Добавить\n          </Button>\n          <Button\n            onClick={removeItem}\n            style={{\n              background: textNegative,\n              color: textPrimary,\n              border: 'none',\n              borderRadius: 4,\n              cursor: 'pointer',\n            }}\n          >\n            − Удалить\n          </Button>\n          <Button\n            onClick={reset}\n            style={{\n              background: textInfo,\n              color: textPrimary,\n              border: 'none',\n              borderRadius: 4,\n              cursor: 'pointer',\n            }}\n          >\n            Сбросить\n          </Button>\n          <span\n            style={{\n              alignSelf: 'center',\n              marginLeft: 8,\n              color: textWarningMinor,\n            }}\n          >\n            Элементов: {items.length}\n          </span>\n        </div>\n\n        <BlockGradientScroll\n          variant=\"white\"\n          style={{\n            maxHeight: 300,\n            overflowY: 'auto',\n            padding: 24,\n            borderRadius: 8,\n            border: `1px solid ${outlineAccent}`,\n          }}\n        >\n          {items.map((id) => (\n            <DemoItem key={id}>\n              <h3>Элемент {id}</h3>\n            </DemoItem>\n          ))}\n          {items.length === 0 && (\n            <div\n              style={{\n                color: textWarningMinor,\n                textAlign: 'center',\n                padding: 40,\n              }}\n            >\n              Пусто. Добавь элементы.\n            </div>\n          )}\n        </BlockGradientScroll>\n      </DemoContainer>\n    );\n  }"
        },
        {
          "exportName": "StylingMethods",
          "displayName": "6. Способы стилизации (style, className, $css)",
          "type": "full-code",
          "code": "() => (\n    <DemoContainer>\n      <style>\n        {`\n          .custom-gradient-box {\n            max-height: 200px;\n            overflow-y: auto;\n            padding: 20px;\n            background: #fff8e1;\n            border-radius: 8px;\n            border: 2px dashed #ffa000;\n          }\n        `}\n      </style>\n\n      <div style={{ display: 'flex', gap: 20, flexDirection: 'column' }}>\n        {/* style prop */}\n        <div>\n          <p style={{ marginBottom: 8, fontWeight: 500 }}>\n            1. Через style prop\n          </p>\n          <pre\n            style={{\n              color: '#000',\n              background: '#f5f5f5',\n              padding: 12,\n              borderRadius: 4,\n              fontSize: 12,\n              marginBottom: 8,\n              overflow: 'auto',\n            }}\n          >\n            {`<BlockGradientScroll\n  variant=\"white\"\n  style={{\n    maxHeight: 200,\n    overflowY: 'auto',\n    padding: 20,\n    background: '#e8f5e9',\n    border: '2px solid #4caf50',\n  }}\n>\n  {children}\n</BlockGradientScroll>`}\n          </pre>\n          <BlockGradientScroll\n            variant=\"white\"\n            style={{\n              maxHeight: 200,\n              overflowY: 'auto',\n              padding: 20,\n              background: '#e8f5e9',\n              borderRadius: 8,\n              border: '2px solid #4caf50',\n            }}\n          >\n            {generateItems(5)}\n          </BlockGradientScroll>\n        </div>\n\n        {/* className prop */}\n        <div>\n          <p style={{ marginBottom: 8, fontWeight: 500 }}>2. Через className</p>\n          <pre\n            style={{\n              color: '#000',\n              background: '#f5f5f5',\n              padding: 12,\n              borderRadius: 4,\n              fontSize: 12,\n              marginBottom: 8,\n              overflow: 'auto',\n            }}\n          >\n            {`.custom-gradient-box {\n  max-height: 200px;\n  overflow-y: auto;\n  padding: 20px;\n  background: #fff8e1;\n  border: 2px dashed #ffa000;\n}\n\n<BlockGradientScroll\n  variant=\"white\"\n  className=\"custom-gradient-box\"\n>\n  {children}\n</BlockGradientScroll>`}\n          </pre>\n          <BlockGradientScroll variant=\"white\" className=\"custom-gradient-box\">\n            {generateItems(5)}\n          </BlockGradientScroll>\n        </div>\n\n        {/* $css prop */}\n        <div>\n          <p style={{ marginBottom: 8, fontWeight: 500 }}>\n            3. Через $css (styled-components)\n          </p>\n          <pre\n            style={{\n              color: '#000',\n              background: '#f5f5f5',\n              padding: 12,\n              borderRadius: 4,\n              fontSize: 12,\n              marginBottom: 8,\n              overflow: 'auto',\n            }}\n          >\n            {`<BlockGradientScroll\n  variant=\"white\"\n  $css={\\`\n    max-height: 200px;\n    overflow-y: auto;\n    padding: 20px;\n    background: linear-gradient(...);\n    border: 2px solid #2196f3;\n  \\`}\n>\n  {children}\n</BlockGradientScroll>`}\n          </pre>\n          <BlockGradientScroll\n            variant=\"white\"\n            $css={`\n              max-height: 200px;\n              overflow-y: auto;\n              padding: 20px;\n              background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);\n              border-radius: 8px;\n              border: 2px solid #2196f3;\n            `}\n          >\n            {generateItems(5)}\n          </BlockGradientScroll>\n        </div>\n      </div>\n    </DemoContainer>\n  )"
        }
      ]
    },
    "BlockTitle": {
      "name": "BlockTitle",
      "group": "components",
      "folderName": "BlockTitle",
      "role": "primary",
      "description": "Заголовок раздела страницы с подзаголовком, кнопкой назад и слотами для действий",
      "props": [
        {
          "name": "containerProps",
          "type": "({ [x: string]: any; [x: number]: any; [x: symbol]: any; } & { theme?: DefaultTheme | undefined; } & { as?: string | React.ComponentType<any> | undefined; forwardedAs?: string | React.ComponentType<any> | undefined; }) | undefined",
          "required": false,
          "description": "Передача props в контейнер"
        },
        {
          "name": "description",
          "type": "string | undefined",
          "required": false,
          "description": "Текст Заголовка"
        },
        {
          "name": "onBackButtonClick",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Callback при клике на кнопку со стрелкой назад слева от заголовка"
        },
        {
          "name": "rightSlot",
          "type": "BlockTitleAdaptiveSlot",
          "required": false,
          "description": "Слот для правой части"
        },
        {
          "name": "titleLeftSlot",
          "type": "BlockTitleAdaptiveSlot",
          "required": false,
          "description": "Иконка слева от заголовка (обычно используется иконка)"
        },
        {
          "name": "titleRightSlot",
          "type": "BlockTitleAdaptiveSlot",
          "required": false,
          "description": "Иконка справа от заголовка (обычно используется иконка)"
        },
        {
          "name": "titleSize",
          "type": "\"BodyL\" | \"BodyM\" | \"BodyS\" | \"BodyXS\" | \"BodyXXS\" | \"DsplL\" | \"DsplM\" | \"DsplS\" | \"H1\" | \"H2\" | \"H3\" | \"H4\" | \"H5\" | \"TextL\" | \"TextM\" | \"TextS\" | \"TextXS\" | undefined",
          "required": false,
          "description": "Размер заголовка",
          "default": "'H2'"
        },
        {
          "name": "titleTooltipProps",
          "type": "Omit<TooltipProps, \"text\" | \"target\" | \"trigger\" | \"opened\"> | undefined",
          "required": false,
          "description": "Пропсы тултипа, которым оборачивается обрезанный `title`."
        },
        {
          "name": "topSlot",
          "type": "BlockTitleAdaptiveSlot",
          "required": false,
          "description": "Слот для верхней части"
        },
        {
          "name": "disableMediaAdaptive",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отключает принудительный адаптив компонента на viewport <= 1280px.",
          "deprecated": true,
          "default": "false"
        }
      ],
      "propsTypeName": "BlockTitleProps",
      "sourceFile": "packages/ui-kit/src/components/BlockTitle/BlockTitle.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "заголовок раздела",
        "page heading",
        "шапка блока"
      ],
      "docs": "# BlockTitle\n\nКомпонент заголовка блока с поддержкой слотов для дополнительных элементов и кнопки «назад».\n\n## Ключевые особенности\n\n- Настраиваемый размер заголовка через вариант типографики (`titleSize`)\n- Описание под заголовком (`description`)\n- Слоты: `titleLeftSlot`, `titleRightSlot`, `topSlot`, `rightSlot`\n- Настройка тултипа обрезанного заголовка (ширина, позиция) через `titleTooltipProps`\n- Кнопка «назад» через `onBackButtonClick`\n- Кастомизация контейнера через `containerProps` (Box с `$css`)\n\n## Особенности\n\n- Компонент можно стилизовать: обернув в `styled`, используя `$css` в `containerProps`, или используя объект `blockTitleClassNames` для обращения к подэлементам\n- Слоты `titleLeftSlot`, `titleRightSlot`, `topSlot`, `rightSlot` принимают `ReactNode` или callback с размерами для адаптива\n- По умолчанию адаптив на viewport `<= 1280px` включен; временно отключить его можно через deprecated-проп `disableMediaAdaptive`\n\n## Тултип заголовка\n\n`title` оборачивается в `TypographyWithAutoTooltip`: если текст не помещается в две строки, при наведении показывается тултип с полным заголовком. По умолчанию ширина тултипа не ограничена, поэтому длинный заголовок вытягивается в одну строку. Ограничить ширину и задать позицию можно через `titleTooltipProps`:\n\n```tsx\n<BlockTitle\n  title=\"Очень длинный заголовок страницы\"\n  titleTooltipProps={{ maxWidth: '300px', placement: 'bottom-start' }}\n/>\n```\n\n`titleTooltipProps` принимает пропсы `Tooltip` (кроме `text`, `target`, `trigger`, `opened`, которыми управляет сам компонент): `maxWidth`, `minWidth`, `placement`, `view`, `offset`, `mouseEnterDelay` и другие.\n\n## Использование адаптивных слотов\n\nЕсли слот не должен менять размеры, передавайте обычный `ReactNode`:\n\n```tsx\n<BlockTitle title=\"Title\" titleRightSlot={<IconPlasma size=\"s\" />} />\n```\n\nЕсли в слоте есть иконка, Badge или кнопки, передавайте callback и используйте размеры из аргумента:\n\n```tsx\n<BlockTitle\n  title=\"Страница\"\n  titleSize=\"H4\"\n  titleRightSlot={({ titleBadgeSize }) => (\n    <Badge size={titleBadgeSize} view=\"default\" text=\"Label\" />\n  )}\n  rightSlot={({ buttonSize, actionIconSize }) => (\n    <div style={{ display: 'flex', gap: s.x4 }}>\n      <IconButton size={buttonSize} view=\"secondary\">\n        <IconDotsVerticalCenteredOutline\n          size={actionIconSize}\n          color=\"inherit\"\n        />\n      </IconButton>\n      <Button size={buttonSize} view=\"secondary\">\n        Label\n      </Button>\n      <Button size={buttonSize} view=\"accent\">\n        Label\n      </Button>\n    </div>\n  )}\n/>\n```\n\nРазмеры, которые приходят в callback (в зависимости от viewport):\n\n```\n| Поле                                         | <= 1280px | > 1280px |\n| -------------------------------------------- | --------- | -------- |\n| buttonSize                                   | xs        | s        |\n| actionIconSize                               | xs        | s        |\n| titleIconSize (для H4/H5)                    | xs        | s        |\n| titleBadgeSize (для H4/H5)                   | s         | m        |\n| titleIconSize (для остальных)                | s         | s        |\n| titleBadgeSize (для остальных)               | m         | m        |\n```\n\n> Подробнее о типах и пропсах — [BlockTitle API](?path=/docs/композиции-blocktitle-api--docs)",
      "apiDocs": "# BlockTitle API\n\n## BlockTitleProps\n\n```typescript\ntype BlockTitleProps = {\n  /**\n   * Текст заголовка\n   */\n  title?: string;\n  /**\n   * Размер заголовка\n   */\n  titleSize?: ComponentProps<typeof Typography>['variant'];\n  /**\n   * Пропсы тултипа, которым оборачивается обрезанный `title`.\n   *\n   * @remarks\n   * Тултип показывается автоматически, когда `title` не помещается в две строки.\n   * По умолчанию ширина тултипа не ограничена, из-за чего длинный заголовок\n   * растягивается в одну строку — ограничьте её через `maxWidth`.\n   *\n   * @example\n   * ```tsx\n   * <BlockTitle\n   *   title=\"Очень длинный заголовок\"\n   *   titleTooltipProps={{ maxWidth: '300px', placement: 'auto-start' }}\n   * />\n   * ```\n   */\n  titleTooltipProps?: TypographyWithAutoTooltipProps<'H2'>['tooltipProps'];\n  /**\n   * Иконка слева от заголовка (обычно используется иконка)\n   */\n  titleLeftSlot?: BlockTitleAdaptiveSlot;\n  /**\n   * Иконка справа от заголовка (обычно используется иконка)\n   */\n  titleRightSlot?: BlockTitleAdaptiveSlot;\n  /**\n   * Текст Заголовка\n   */\n  description?: string;\n  /**\n   * Слот для верхней части\n   */\n  topSlot?: BlockTitleAdaptiveSlot;\n  /**\n   * Слот для правой части\n   */\n  rightSlot?: BlockTitleAdaptiveSlot;\n  /**\n   * Отключает принудительный адаптив компонента на viewport <= 1280px.\n   *\n   * @deprecated Используйте только в крайних случаях, когда команда временно не готова адаптировать вёрстку под 1280px.\n   *\n   * @remarks\n   * При `true` компонент использует desktop-размеры для слотов и кнопки назад даже на viewport <= 1280px.\n   * Это временный escape hatch, не основной сценарий использования.\n   *\n   * @default false\n   */\n  disableMediaAdaptive?: boolean;\n  /**\n   * Передача props в контейнер\n   */\n  containerProps?: ComponentProps<typeof Box>;\n  /**\n   * Callback при клике на кнопку со стрелкой назад слева от заголовка\n   */\n  onBackButtonClick?: () => void;\n};\n```\n\n## BlockTitleSlotSizesProps\n\n```typescript\ntype BlockTitleSlotSizesProps = {\n  /**\n   * Размер иконки рядом с заголовком\n   */\n  titleIconSize: 's' | 'xs';\n  /**\n   * Размер Badge рядом с заголовком\n   */\n  titleBadgeSize: 'm' | 's';\n  /**\n   * Размер кнопок в правом слоте\n   */\n  buttonSize: 's' | 'xs';\n  /**\n   * Размер иконок внутри кнопок в правом слоте\n   */\n  actionIconSize: 's' | 'xs';\n};\n```\n\n## BlockTitleAdaptiveSlot\n\n```typescript\ntype BlockTitleAdaptiveSlot =\n  | ReactNode\n  | ((props: BlockTitleSlotSizesProps) => ReactNode);\n```",
      "curatedStories": [
        {
          "exportName": "BlockTitleSlots",
          "displayName": "BlockTitle Slots",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        Box,\n        Button,\n        IconButton,\n        BlockTitle,\n        type BlockTitleSlotSizesProps\n    } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n\n() => (\n    <div\n      style={{\n        height: '100vh',\n        padding: '20px',\n        display: 'flex',\n        backgroundColor: lightBackgroundPrimary,\n      }}\n    >\n      {/* Компонент левой панели */}\n      <LeftPanelBlock />\n      <div\n        style={{\n          flex: 1,\n          padding: s.x8,\n          boxShadow: shadowDownSoftS,\n          backgroundColor: surfaceSolidCard,\n          borderRadius: s.x8,\n        }}\n      >\n        <BlockTitle\n          title=\"Title\"\n          description=\"description\"\n          titleSize=\"H5\"\n          /* Правая и левая иконки */\n          titleLeftSlot={({ titleIconSize }: BlockTitleSlotSizesProps) => (\n            <IconPlasma size={titleIconSize} />\n          )}\n          titleRightSlot={({ titleIconSize }: BlockTitleSlotSizesProps) => (\n            <IconPlasma size={titleIconSize} />\n          )}\n          /* Кастомный блок сверху */\n          topSlot={\n            <Box\n              style={{\n                padding: s.x8,\n                borderRadius: br.s,\n                border: `1px solid ${surfaceInfo}`,\n                color: surfaceInfo,\n                backgroundColor: surfaceAccentMinor,\n              }}\n            >\n              <BodyS>BlockTitle topSlot</BodyS>\n            </Box>\n          }\n          /* Правая часть */\n          rightSlot={\n            <Box\n              style={{\n                padding: s.x8,\n                borderRadius: br.s,\n                border: `1px solid ${surfaceInfo}`,\n                color: surfaceInfo,\n                backgroundColor: surfaceAccentMinor,\n                width: '200px',\n              }}\n            >\n              <BodyS>BlockTitle rightSlot</BodyS>\n            </Box>\n          }\n        />\n      </div>\n    </div>\n  )"
        },
        {
          "exportName": "BlockTitleExample",
          "displayName": "BlockTitle Example",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        Box,\n        Button,\n        IconButton,\n        BlockTitle,\n        type BlockTitleSlotSizesProps\n    } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n\n() => (\n    <div\n      style={{\n        height: '100vh',\n        padding: '20px',\n        display: 'flex',\n        backgroundColor: lightBackgroundPrimary,\n      }}\n    >\n      {/* Компонент левой панели */}\n      <LeftPanelBlock />\n      <div\n        style={{\n          flex: 1,\n          padding: s.x8,\n          boxShadow: shadowDownSoftS,\n          backgroundColor: surfaceSolidCard,\n          borderRadius: s.x8,\n        }}\n      >\n        <BlockTitle\n          title=\"Страница\"\n          titleSize=\"H4\"\n          /* Кастомный блок сверху */\n          topSlot={({ titleBadgeSize }: BlockTitleSlotSizesProps) => (\n            <div style={{ display: 'flex', gap: s.x2 }}>\n              <Badge\n                size={titleBadgeSize}\n                view=\"light\"\n                text=\"Обновил: 12345678\"\n              />\n              <Badge\n                size={titleBadgeSize}\n                view=\"light\"\n                text=\"Дата изменения: 03.06.2025, 09:00\"\n              />\n              <Chip size=\"xs\" view=\"accent\" text=\"Описание\" />\n            </div>\n          )}\n          /* Правая часть */\n          rightSlot={renderRightActionsSlot}\n        />\n      </div>\n    </div>\n  )"
        },
        {
          "exportName": "BlockTitleWithBadge",
          "displayName": "BlockTitle с Badge",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        Box,\n        Button,\n        IconButton,\n        BlockTitle,\n        type BlockTitleSlotSizesProps\n    } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n\n() => (\n    <div\n      style={{\n        height: '100vh',\n        padding: '20px',\n        display: 'flex',\n        backgroundColor: lightBackgroundPrimary,\n      }}\n    >\n      <LeftPanelBlock />\n      <div\n        style={{\n          flex: 1,\n          padding: s.x8,\n          boxShadow: shadowDownSoftS,\n          backgroundColor: surfaceSolidCard,\n          borderRadius: s.x8,\n        }}\n      >\n        <BlockTitle\n          title=\"Title\"\n          description=\"Description\"\n          titleRightSlot={({ titleBadgeSize }: BlockTitleSlotSizesProps) => (\n            <Badge\n              size={titleBadgeSize}\n              view=\"default\"\n              text=\"Label\"\n              style={{ marginLeft: '12px' }}\n            />\n          )}\n          rightSlot={renderRightActionsSlot}\n        />\n      </div>\n    </div>\n  )"
        },
        {
          "exportName": "BlockTitleWithBackButton",
          "displayName": "BlockTitle с кнопкой назад",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        Box,\n        Button,\n        IconButton,\n        BlockTitle,\n        type BlockTitleSlotSizesProps\n    } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n\n() => (\n    <div\n      style={{\n        height: '100vh',\n        padding: '20px',\n        display: 'flex',\n        backgroundColor: lightBackgroundPrimary,\n      }}\n    >\n      <LeftPanelBlock />\n      <div\n        style={{\n          flex: 1,\n          padding: s.x8,\n          boxShadow: shadowDownSoftS,\n          backgroundColor: surfaceSolidCard,\n          borderRadius: s.x8,\n        }}\n      >\n        <BlockTitle\n          title=\"Title\"\n          titleSize=\"H3\"\n          description=\"Description\"\n          // eslint-disable-next-line no-alert\n          onBackButtonClick={() => alert('onBackClick')}\n          titleRightSlot={({ titleBadgeSize }: BlockTitleSlotSizesProps) => (\n            <Badge\n              size={titleBadgeSize}\n              view=\"default\"\n              text=\"Label\"\n              style={{ marginLeft: '12px' }}\n            />\n          )}\n          rightSlot={renderRightActionsSlot}\n        />\n      </div>\n    </div>\n  )"
        },
        {
          "exportName": "BlockTitleWithBackButtonAndIcon",
          "displayName": "BlockTitle с кнопкой назад и иконкой",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        Box,\n        Button,\n        IconButton,\n        BlockTitle,\n        type BlockTitleSlotSizesProps\n    } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n\n() => (\n    <div\n      style={{\n        height: '100vh',\n        padding: '20px',\n        display: 'flex',\n        backgroundColor: lightBackgroundPrimary,\n      }}\n    >\n      <LeftPanelBlock />\n      <div\n        style={{\n          flex: 1,\n          padding: s.x8,\n          boxShadow: shadowDownSoftS,\n          backgroundColor: surfaceSolidCard,\n          borderRadius: s.x8,\n        }}\n      >\n        <BlockTitle\n          title=\"Title\"\n          description=\"Description\"\n          // eslint-disable-next-line no-alert\n          onBackButtonClick={() => alert('onBackClick')}\n          titleRightSlot={({ titleIconSize }: BlockTitleSlotSizesProps) => (\n            <IconPlasma size={titleIconSize} />\n          )}\n          rightSlot={renderRightActionsSlot}\n        />\n      </div>\n    </div>\n  )"
        },
        {
          "exportName": "BlockTitleWithTooltipProps",
          "displayName": "BlockTitle с настройкой тултипа заголовка",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        Box,\n        Button,\n        IconButton,\n        BlockTitle,\n        type BlockTitleSlotSizesProps\n    } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n\n() => (\n    <div\n      style={{\n        height: '100vh',\n        padding: '20px',\n        display: 'flex',\n        backgroundColor: lightBackgroundPrimary,\n      }}\n    >\n      <LeftPanelBlock />\n      <div\n        style={{\n          flex: 1,\n          padding: s.x8,\n          boxShadow: shadowDownSoftS,\n          backgroundColor: surfaceSolidCard,\n          borderRadius: s.x8,\n        }}\n      >\n        <BlockTitle\n          title={longTitle}\n          description=\"Наведите на заголовок — тултип ограничен по ширине и раскрывается вниз\"\n          /* Ограничиваем ширину тултипа и задаём его позицию */\n          titleTooltipProps={{ maxWidth: '300px', placement: 'bottom-start' }}\n          rightSlot={renderRightActionsSlot}\n        />\n      </div>\n    </div>\n  )"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { BlockTitle } from '@daisforge/ui';",
      "minimalUsage": "<BlockTitle />",
      "examples": [
        {
          "exportName": "BlockTitleSlots",
          "displayName": "BlockTitle Slots",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        Box,\n        Button,\n        IconButton,\n        BlockTitle,\n        type BlockTitleSlotSizesProps\n    } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n\n() => (\n    <div\n      style={{\n        height: '100vh',\n        padding: '20px',\n        display: 'flex',\n        backgroundColor: lightBackgroundPrimary,\n      }}\n    >\n      {/* Компонент левой панели */}\n      <LeftPanelBlock />\n      <div\n        style={{\n          flex: 1,\n          padding: s.x8,\n          boxShadow: shadowDownSoftS,\n          backgroundColor: surfaceSolidCard,\n          borderRadius: s.x8,\n        }}\n      >\n        <BlockTitle\n          title=\"Title\"\n          description=\"description\"\n          titleSize=\"H5\"\n          /* Правая и левая иконки */\n          titleLeftSlot={({ titleIconSize }: BlockTitleSlotSizesProps) => (\n            <IconPlasma size={titleIconSize} />\n          )}\n          titleRightSlot={({ titleIconSize }: BlockTitleSlotSizesProps) => (\n            <IconPlasma size={titleIconSize} />\n          )}\n          /* Кастомный блок сверху */\n          topSlot={\n            <Box\n              style={{\n                padding: s.x8,\n                borderRadius: br.s,\n                border: `1px solid ${surfaceInfo}`,\n                color: surfaceInfo,\n                backgroundColor: surfaceAccentMinor,\n              }}\n            >\n              <BodyS>BlockTitle topSlot</BodyS>\n            </Box>\n          }\n          /* Правая часть */\n          rightSlot={\n            <Box\n              style={{\n                padding: s.x8,\n                borderRadius: br.s,\n                border: `1px solid ${surfaceInfo}`,\n                color: surfaceInfo,\n                backgroundColor: surfaceAccentMinor,\n                width: '200px',\n              }}\n            >\n              <BodyS>BlockTitle rightSlot</BodyS>\n            </Box>\n          }\n        />\n      </div>\n    </div>\n  )"
        },
        {
          "exportName": "BlockTitleExample",
          "displayName": "BlockTitle Example",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        Box,\n        Button,\n        IconButton,\n        BlockTitle,\n        type BlockTitleSlotSizesProps\n    } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n\n() => (\n    <div\n      style={{\n        height: '100vh',\n        padding: '20px',\n        display: 'flex',\n        backgroundColor: lightBackgroundPrimary,\n      }}\n    >\n      {/* Компонент левой панели */}\n      <LeftPanelBlock />\n      <div\n        style={{\n          flex: 1,\n          padding: s.x8,\n          boxShadow: shadowDownSoftS,\n          backgroundColor: surfaceSolidCard,\n          borderRadius: s.x8,\n        }}\n      >\n        <BlockTitle\n          title=\"Страница\"\n          titleSize=\"H4\"\n          /* Кастомный блок сверху */\n          topSlot={({ titleBadgeSize }: BlockTitleSlotSizesProps) => (\n            <div style={{ display: 'flex', gap: s.x2 }}>\n              <Badge\n                size={titleBadgeSize}\n                view=\"light\"\n                text=\"Обновил: 12345678\"\n              />\n              <Badge\n                size={titleBadgeSize}\n                view=\"light\"\n                text=\"Дата изменения: 03.06.2025, 09:00\"\n              />\n              <Chip size=\"xs\" view=\"accent\" text=\"Описание\" />\n            </div>\n          )}\n          /* Правая часть */\n          rightSlot={renderRightActionsSlot}\n        />\n      </div>\n    </div>\n  )"
        },
        {
          "exportName": "BlockTitleWithBadge",
          "displayName": "BlockTitle с Badge",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        Box,\n        Button,\n        IconButton,\n        BlockTitle,\n        type BlockTitleSlotSizesProps\n    } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n\n() => (\n    <div\n      style={{\n        height: '100vh',\n        padding: '20px',\n        display: 'flex',\n        backgroundColor: lightBackgroundPrimary,\n      }}\n    >\n      <LeftPanelBlock />\n      <div\n        style={{\n          flex: 1,\n          padding: s.x8,\n          boxShadow: shadowDownSoftS,\n          backgroundColor: surfaceSolidCard,\n          borderRadius: s.x8,\n        }}\n      >\n        <BlockTitle\n          title=\"Title\"\n          description=\"Description\"\n          titleRightSlot={({ titleBadgeSize }: BlockTitleSlotSizesProps) => (\n            <Badge\n              size={titleBadgeSize}\n              view=\"default\"\n              text=\"Label\"\n              style={{ marginLeft: '12px' }}\n            />\n          )}\n          rightSlot={renderRightActionsSlot}\n        />\n      </div>\n    </div>\n  )"
        },
        {
          "exportName": "BlockTitleWithBackButton",
          "displayName": "BlockTitle с кнопкой назад",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        Box,\n        Button,\n        IconButton,\n        BlockTitle,\n        type BlockTitleSlotSizesProps\n    } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n\n() => (\n    <div\n      style={{\n        height: '100vh',\n        padding: '20px',\n        display: 'flex',\n        backgroundColor: lightBackgroundPrimary,\n      }}\n    >\n      <LeftPanelBlock />\n      <div\n        style={{\n          flex: 1,\n          padding: s.x8,\n          boxShadow: shadowDownSoftS,\n          backgroundColor: surfaceSolidCard,\n          borderRadius: s.x8,\n        }}\n      >\n        <BlockTitle\n          title=\"Title\"\n          titleSize=\"H3\"\n          description=\"Description\"\n          // eslint-disable-next-line no-alert\n          onBackButtonClick={() => alert('onBackClick')}\n          titleRightSlot={({ titleBadgeSize }: BlockTitleSlotSizesProps) => (\n            <Badge\n              size={titleBadgeSize}\n              view=\"default\"\n              text=\"Label\"\n              style={{ marginLeft: '12px' }}\n            />\n          )}\n          rightSlot={renderRightActionsSlot}\n        />\n      </div>\n    </div>\n  )"
        }
      ]
    },
    "Box": {
      "name": "Box",
      "group": "components",
      "folderName": "Box",
      "role": "primary",
      "description": "Базовый div-контейнер с пропсами отступов, размеров и рамки вместо инлайн-стилей",
      "props": [
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные стили styled-components для Box-контейнера"
        },
        {
          "name": "as",
          "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"article\" | \"button\" | \"dialog\" | \"figure\" | \"form\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"search\" | \"switch\" | \"table\" | \"text\" | \"time\" | \"div\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"big\" | \"blockquote\" | \"body\" | \"br\" | \"canvas\" | \"caption\" | \"center\" | \"cite\" …",
          "required": false,
          "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
        },
        {
          "name": "background",
          "type": "Property.Background<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "backgroundColor",
          "type": "Property.BackgroundColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "border",
          "type": "Property.Border<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderColor",
          "type": "Property.BorderColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderRadius",
          "type": "Property.BorderRadius<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
        },
        {
          "name": "borderStyle",
          "type": "Property.BorderStyle | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderWidth",
          "type": "Property.BorderWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "bottom",
          "type": "Property.Bottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "boxSizing",
          "type": "Property.BoxSizing | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
        },
        {
          "name": "cursor",
          "type": "Property.Cursor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
        },
        {
          "name": "display",
          "type": "Property.Display | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "flexDirection",
          "type": "Property.FlexDirection | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
        },
        {
          "name": "flexGrow",
          "type": "Property.FlexGrow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
        },
        {
          "name": "flexShrink",
          "type": "Property.FlexShrink | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
        },
        {
          "name": "flexWrap",
          "type": "Property.FlexWrap | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "gap",
          "type": "Property.Gap<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
        },
        {
          "name": "height",
          "type": "Property.Height<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "justifyContent",
          "type": "Property.JustifyContent | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "justifyItems",
          "type": "Property.JustifyItems | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
        },
        {
          "name": "justifySelf",
          "type": "Property.JustifySelf | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
        },
        {
          "name": "left",
          "type": "Property.Left<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "margin",
          "type": "Property.Margin<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginBottom",
          "type": "Property.MarginBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginLeft",
          "type": "Property.MarginLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginRight",
          "type": "Property.MarginRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginTop",
          "type": "Property.MarginTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "maxHeight",
          "type": "Property.MaxHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "maxWidth",
          "type": "Property.MaxWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "minHeight",
          "type": "Property.MinHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "minWidth",
          "type": "Property.MinWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "opacity",
          "type": "Property.Opacity | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
        },
        {
          "name": "overflow",
          "type": "Property.Overflow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "padding",
          "type": "Property.Padding<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingBottom",
          "type": "Property.PaddingBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingLeft",
          "type": "Property.PaddingLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingRight",
          "type": "Property.PaddingRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingTop",
          "type": "Property.PaddingTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "position",
          "type": "Property.Position | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "right",
          "type": "Property.Right<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "top",
          "type": "Property.Top<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "width",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        }
      ],
      "propsTypeName": "BoxProps",
      "sourceFile": "packages/ui-kit/src/components/Box/Box.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "контейнер-обёртка",
        "layout box",
        "утилитарный div"
      ],
      "docs": "# Box\n\nАналог компонента Box из [MUI](https://mui.com/material-ui/react-box/).\nПрименяется для создания кастомных контейнеров.\n\n## Ключевые особенности\n\n- Принимает любые CSS-свойства напрямую как пропсы (display, padding, margin и т.д.)\n- Поддержка `$css` для кастомных стилей через styled-components\n- Полиморфный компонент — проп `as` позволяет менять HTML-элемент (`div`, `li`, `section` и т.д.)\n- Проп `hidden` для скрытия элемента\n\n> Подробнее о типах и пропсах — [Box API](?path=/docs/локальные-компоненты-box-api--docs)",
      "apiDocs": "# Box API\n\nБазовый контейнер-обёртка. Собственный компонент (не из `@salutejs/sdds-finai`). Принимает CSS-свойства как пропсы.\n\n## BoxProps\n\n```typescript\ntype BoxProps = ComponentProps<typeof Box> & BoxBaseProps;\n```\n\n## Основные пропсы\n\n- `$css` (`string | CSSObject`) — кастомные стили styled-components\n- `hidden` (`boolean`) — скрыть элемент (`display: none`)\n- `as` (`ElementType`) — HTML-тег или компонент для корневого узла (`div`, `li`, `section` и т.д.)\n\n## CSS-пропсы (передаются напрямую)\n\nРазмеры: `width`, `maxWidth`, `minWidth`, `height`, `maxHeight`, `minHeight`\n\nОтступы: `margin`, `marginLeft/Right/Top/Bottom`, `padding`, `paddingLeft/Right/Top/Bottom`\n\nFlexbox: `display`, `flexDirection`, `justifyContent`, `justifyItems`, `justifySelf`, `flexGrow`, `flexWrap`, `flexShrink`, `gap`\n\nПозиционирование: `position`, `top`, `left`, `right`, `bottom`, `zIndex`\n\nВизуальные: `background`, `backgroundColor`, `opacity`, `border`, `borderWidth`, `borderColor`, `borderStyle`, `borderRadius`\n\nПрочие: `boxSizing`, `overflow`, `cursor`",
      "curatedStories": [
        {
          "exportName": "Default",
          "displayName": "Box",
          "type": "full-code",
          "code": "// textAccent - токен акцентного цвета\nimport { Box, textAccent, textNegative } from '@daisforge/ui';\n\n() => (\n    <Box\n      $css={{\n        height: '200px',\n        width: '500px',\n        display: 'flex',\n        justifyContent: 'center',\n        alignItems: 'center',\n        gap: 16,\n        background: textAccent,\n        borderRadius: 16,\n        color: 'white',\n      }}\n    >\n      Box №1\n      <Box height={100} background={textNegative}>\n        Box №2\n      </Box>\n    </Box>\n  )"
        },
        {
          "exportName": "CSSObject",
          "displayName": "Стилизация через CSS Object",
          "type": "full-code",
          "code": "import { Box, textAccent } from '@daisforge/ui';\n\n() => (\n    <Box\n      $css={{\n        height: '200px',\n        width: '500px',\n        background: textAccent,\n        borderRadius: 16,\n        color: 'white',\n      }}\n    />\n  )"
        },
        {
          "exportName": "CSSString",
          "displayName": "Стилизация через CSS String",
          "type": "full-code",
          "code": "import { Box, textPositive } from '@daisforge/ui';\n\n() => (\n    <Box\n      $css={`\n            height: 100px;\n            width: 300px;\n            background: ${textPositive};\n            border-radius: 8px;\n        `}\n    />\n  )"
        },
        {
          "exportName": "CSSProps",
          "displayName": "Стилизация через props",
          "type": "full-code",
          "code": "import { Box } from '@daisforge/ui';\n\n() => (\n    <Box\n      height={200}\n      width={200}\n      background=\"yellow\"\n      border=\"8px solid green\"\n    />\n  )"
        },
        {
          "exportName": "BoxAnyComponent",
          "displayName": "React компонент корневого узла",
          "type": "full-code",
          "code": "import { Box, Button } from '@daisforge/ui';\n\n() => (\n    <Box as={Link} onClick={() => alert('Я кнопка')}>\n      Теперь это кнопка (нажми на меня)\n    </Box>\n  )"
        },
        {
          "exportName": "BoxHtmlComponent",
          "displayName": "HTML корневого узла",
          "type": "full-code",
          "code": "import { Box } from '@daisforge/ui';\n\n() => <Box as=\"input\" placeholder=\"Теперь это Input\" />"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Box } from '@daisforge/ui';",
      "minimalUsage": "<Box />",
      "examples": [
        {
          "exportName": "Default",
          "displayName": "Box",
          "type": "full-code",
          "code": "// textAccent - токен акцентного цвета\nimport { Box, textAccent, textNegative } from '@daisforge/ui';\n\n() => (\n    <Box\n      $css={{\n        height: '200px',\n        width: '500px',\n        display: 'flex',\n        justifyContent: 'center',\n        alignItems: 'center',\n        gap: 16,\n        background: textAccent,\n        borderRadius: 16,\n        color: 'white',\n      }}\n    >\n      Box №1\n      <Box height={100} background={textNegative}>\n        Box №2\n      </Box>\n    </Box>\n  )"
        },
        {
          "exportName": "CSSObject",
          "displayName": "Стилизация через CSS Object",
          "type": "full-code",
          "code": "import { Box, textAccent } from '@daisforge/ui';\n\n() => (\n    <Box\n      $css={{\n        height: '200px',\n        width: '500px',\n        background: textAccent,\n        borderRadius: 16,\n        color: 'white',\n      }}\n    />\n  )"
        },
        {
          "exportName": "CSSString",
          "displayName": "Стилизация через CSS String",
          "type": "full-code",
          "code": "import { Box, textPositive } from '@daisforge/ui';\n\n() => (\n    <Box\n      $css={`\n            height: 100px;\n            width: 300px;\n            background: ${textPositive};\n            border-radius: 8px;\n        `}\n    />\n  )"
        },
        {
          "exportName": "CSSProps",
          "displayName": "Стилизация через props",
          "type": "full-code",
          "code": "import { Box } from '@daisforge/ui';\n\n() => (\n    <Box\n      height={200}\n      width={200}\n      background=\"yellow\"\n      border=\"8px solid green\"\n    />\n  )"
        }
      ]
    },
    "Breadcrumbs": {
      "name": "Breadcrumbs",
      "group": "components",
      "folderName": "Breadcrumbs",
      "role": "primary",
      "description": "Цепочка навигационных ссылок, показывающая путь пользователя по разделам",
      "props": [],
      "propsTypeName": "BreadcrumbsProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Breadcrumbs/Breadcrumbs.d.ts",
      "type": "wrapper",
      "atomicBase": "Breadcrumbs",
      "category": "Локальные компоненты",
      "keywords": [
        "хлебные крошки",
        "navigation trail",
        "путь по разделам"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "items",
          "type": "BreadcrumbsItem[]",
          "required": true,
          "description": "Элементы Breadcrumbs",
          "inheritedFrom": "Breadcrumbs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "separator",
          "type": "ReactNode",
          "required": false,
          "description": "Элемент разделителя",
          "inheritedFrom": "Breadcrumbs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "showItems",
          "type": "number",
          "required": false,
          "description": "Количество показываемых элементов - все остальные сокращаются",
          "inheritedFrom": "Breadcrumbs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\" | \"xs\"",
          "required": false,
          "description": "Размер компонента",
          "inheritedFrom": "Breadcrumbs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "Breadcrumbs",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Breadcrumbs } from '@daisforge/ui';",
      "minimalUsage": "<Breadcrumbs items={[]} />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Example 3",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Breadcrumbs } from '@daisforge/ui';\nexport function App() {\n    const items = [\n        { title: 'Home', href: '/' },\n        { title: 'About as', href: '/' },\n        { renderItem: () => <span>Custom Item</span> },\n        { title: 'Contacts' },\n    ];\n    return (\n        <div style={{\"flexDirection\": 'column'}}>\n            <div>\n                <Breadcrumbs items={items} showItems={2} />\n            </div>\n            <div>\n                 <Breadcrumbs items={items} showItems={3} />\n            </div>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Example 2",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Breadcrumbs } from '@daisforge/ui';\nexport function App() {\n    const items = [\n        { title: 'Home', href: '/' },\n        { title: 'Without link' },\n        { title: 'Disabled', disabled: true },\n        { title: 'Disabled with link', href: '/', disabled: true },\n        {\n            title: 'On Click',\n            onClick: () => {\n                alert('On Click');\n            },\n        },\n        { renderItem: () => <span style={{ cursor: 'pointer' }}>Custom </span> },\n        { title: 'Main' },\n    ];\n    return (\n        <div>\n            <Breadcrumbs items={items} />\n        </div>\n    );\n}"
        }
      ]
    },
    "Button": {
      "name": "Button",
      "group": "components",
      "folderName": "Button",
      "role": "primary",
      "description": "Стандартная кнопка действия с вариантами размера, цвета, иконкой и состоянием загрузки",
      "props": [
        {
          "name": "as",
          "type": "((React.ComponentType<any> | keyof JSX.IntrinsicElements) & \"button\") | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "type",
          "type": "\"button\" | \"submit\" | \"reset\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ButtonProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Button/Button.d.ts",
      "type": "wrapper",
      "atomicBase": "Button",
      "category": "Локальные компоненты",
      "keywords": [
        "кнопка действия",
        "primary action",
        "call to action"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "additionalContent",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\"",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\"",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentPlacing",
          "type": "ContentPlacing",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focused",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isLoading",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "loader",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "outlined",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\"",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftLeft",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftRight",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\"",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "square",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretching",
          "type": "\"auto\" | \"filled\" | \"fixed\"",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "string",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"secondary\" | \"black\" | \"white\"",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Button } from '@daisforge/ui';",
      "minimalUsage": "<Button />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в AiChatDAIS.tsx",
          "type": "usage",
          "code": "<Button\n                disabled={messages.length === 0}\n                view=\"secondary\"\n                size=\"xxs\"\n                className=\"clear-history-btn\"\n                onClick={() => setClearModalOpened(true)}\n                title=\"Очистить историю поиска\"\n                type=\"button\"\n                contentRight={<IconTrashOutline color=\"inherit\" size=\"xs\" />}\n              >\n                Очистить историю поиска\n              </Button>",
          "sourceFile": "packages/storybook/src/stories/AiChatDAIS/AiChatDAIS.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в Stories.stories.tsx",
          "type": "usage",
          "code": "<Button\n                size=\"s\"\n                view=\"accent\"\n                stretching=\"filled\"\n                as=\"a\"\n                href=\"#\"\n                text=\"Открыть\"\n              />",
          "sourceFile": "packages/storybook/src/stories/Stories/Stories.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Гиперссылка Гиперссылка Компонент поддерживает вывод в виде тега  <a> , для этого необходимо указать свойство  as",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Button } from '@daisforge/ui';\nexport function App() {\n    return (\n        <Button as=\"a\" text=\"Гиперссылка\" />\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Размер кнопки",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Button } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Button text=\"Button\" size=\"s\" />\n            <Button text=\"Button\" size=\"xs\" />\n            <Button text=\"Button\" size=\"xxs\" />\n        </div>\n    );\n}"
        }
      ]
    },
    "ButtonBase": {
      "name": "ButtonBase",
      "group": "components",
      "folderName": "ButtonBase",
      "role": "primary",
      "description": "Базовый примитив кнопки без готовых стилей — основа для кастомных кликабельных элементов",
      "props": [
        {
          "name": "as",
          "type": "string | React.ComponentType<any> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof ButtonBase>",
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/ButtonBase/index.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "базовый примитив",
        "unstyled button",
        "кастомная кнопка"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ButtonBase } from '@daisforge/ui';",
      "minimalUsage": "<ButtonBase />",
      "examples": []
    },
    "ButtonGroup": {
      "name": "ButtonGroup",
      "group": "components",
      "folderName": "ButtonGroup",
      "role": "primary",
      "description": "Группа связанных кнопок с общим отступом, формой и ориентацией расположения",
      "props": [],
      "propsTypeName": "ButtonGroupProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/ButtonGroup/ButtonGroup.d.ts",
      "type": "wrapper",
      "atomicBase": "ButtonGroup",
      "category": "Локальные компоненты",
      "keywords": [
        "группа кнопок",
        "toolbar buttons",
        "набор действий"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "gap",
          "type": "\"none\" | \"dense\" | \"wide\"",
          "required": false,
          "description": "Отступы между кнопками внутри группы",
          "default": "dense",
          "inheritedFrom": "ButtonGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isCommonButtonStyles",
          "type": "boolean",
          "required": false,
          "description": "Группа кнопок будет переопределять view и size для всех кнопок",
          "default": "true",
          "inheritedFrom": "ButtonGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\"",
          "required": false,
          "description": "Направление группы",
          "default": "horizontal",
          "inheritedFrom": "ButtonGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shape",
          "type": "\"default\" | \"segmented\"",
          "required": false,
          "description": "Скругления для кнопок внутри группы",
          "default": "default",
          "inheritedFrom": "ButtonGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\"",
          "required": false,
          "description": "Размер группы кнопок",
          "inheritedFrom": "ButtonGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretching",
          "type": "\"auto\" | \"filled\"",
          "required": false,
          "description": "Ширина группы кнопок",
          "default": "auto",
          "inheritedFrom": "ButtonGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"secondary\" | \"black\" | \"white\"",
          "required": false,
          "description": "Вид группы кнопок",
          "inheritedFrom": "ButtonGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ButtonGroup } from '@daisforge/ui';",
      "minimalUsage": "<ButtonGroup />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Компонент  ButtonGroup  - это обертка для Button. Принимает в себя группу кнопок.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { ButtonGroup, Button } from '@daisforge/ui';\nexport function App() {\n    return (\n        <ButtonGroup>\n            {Array(5)\n                .fill(true)\n                .map((_, i) => (\n                    <Button text={`Button ${i}`} />\n                ))}\n        </ButtonGroup>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Размер и вид группы кнопок",
          "type": "vendor",
          "code": "import React from 'react';\nimport { ButtonGroup, Button } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <ButtonGroup size=\"s\" view=\"secondary\">\n                {Array(5)\n                    .fill(true)\n                    .map((_, i) => (\n                        <Button text={`Button ${i}`} />\n                    ))}\n            </ButtonGroup>\n            <ButtonGroup isCommonButtonStyles={false}>\n                <Button size=\"s\" text=\"Primary\" view=\"primary\" />\n                <Button size=\"xs\" text=\"Positive\" view=\"positive\" />\n            </ButtonGroup>\n        </div>\n    );\n}"
        }
      ]
    },
    "Calendar": {
      "name": "Calendar",
      "group": "components",
      "folderName": "Calendar",
      "role": "primary",
      "description": "Календарь для выбора одной даты или диапазона дат с отметкой событий",
      "props": [
        {
          "name": "onChangeVisibleDate",
          "type": "((date: Date) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
        }
      ],
      "propsTypeName": "CalendarProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Calendar/Calendar.d.ts",
      "type": "wrapper",
      "atomicBase": "Calendar",
      "category": "Локальные компоненты",
      "keywords": [
        "выбор даты",
        "date picker",
        "диапазон дат"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "onChangeValue",
          "type": "((value: Date, dateInfo?: DateInfo | undefined) => void) | ((values: [DateType, DateType], dateInfo?: DateInfo | undefined) => void)",
          "required": true,
          "description": "Обработчик изменения значения.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "(Date & CalendarValueType) | [DateType, DateType]",
          "required": true,
          "description": "Выбранное значение.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "date",
          "type": "DateObject",
          "required": false,
          "description": "Состояние календаря, отвечающее за отображение.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabledList",
          "type": "DisabledDay[]",
          "required": false,
          "description": "Список отключенных дней.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabledMonthList",
          "type": "DisabledDay[]",
          "required": false,
          "description": "Список отключенных месяцев.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabledQuarterList",
          "type": "DisabledDay[]",
          "required": false,
          "description": "Список отключенных кварталов.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabledYearList",
          "type": "DisabledDay[]",
          "required": false,
          "description": "Список отключенных годов.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventList",
          "type": "EventDay[]",
          "required": false,
          "description": "Список событий.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventMonthList",
          "type": "EventDay[]",
          "required": false,
          "description": "Список событий по месяцам.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventQuarterList",
          "type": "EventDay[]",
          "required": false,
          "description": "Список событий по кварталам.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventTooltipOptions",
          "type": "EventTooltipOptions",
          "required": false,
          "description": "Свойства всплывающей подсказки для событий.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventYearList",
          "type": "EventDay[]",
          "required": false,
          "description": "Список событий по годам.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focusedDate",
          "type": "DateType",
          "required": false,
          "description": "Дата, определяющая отображаемый период календаря.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "includeEdgeDates",
          "type": "boolean",
          "required": false,
          "description": "Должны ли значения минимального и максимального дня включаться в диапазон.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isDouble",
          "type": "boolean",
          "required": false,
          "description": "Режим отображения: двойной или одинарный.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isRange",
          "type": "boolean",
          "required": false,
          "description": "Режим выбора: диапазон или одинарный.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "locale",
          "type": "Locales",
          "required": false,
          "description": "Выбранный язык календаря. Влияет на название дней, месяцев",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "max",
          "type": "Date",
          "required": false,
          "description": "Максимальное значение даты.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "min",
          "type": "Date",
          "required": false,
          "description": "Минимальное значение даты.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderFromDate",
          "type": "Date",
          "required": false,
          "description": "Дата с которой начинается календарная сетка при отсутсвии значения.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "string",
          "required": false,
          "description": "Размер календаря.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretched",
          "type": "boolean",
          "required": false,
          "description": "Растянуть календарь на всю доступную ширину и высоту",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "type",
          "type": "\"Days\" | \"Months\" | \"Years\" | \"Quarters\"",
          "required": false,
          "description": "Конечный тип отображения календаря: дни, месяца, года, кварталы.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "string",
          "required": false,
          "description": "Вид календаря.",
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeSingleValue",
          "type": "((value: Date, dateInfo?: DateInfo) => void)",
          "required": false,
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeStartOfRange",
          "type": "((value: Date, dateInfo?: DateInfo) => void)",
          "required": false,
          "inheritedFrom": "Calendar",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Calendar } from '@daisforge/ui';",
      "minimalUsage": "<Calendar onChangeValue={() => {}} value={{}} />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в TableCanvas.filtering.stories.tsx",
          "type": "usage",
          "code": "<Calendar\n                  value={filters?.['date']}\n                  onChangeValue={(v) => {\n                    if (setFilters)\n                      setFilters((prev) => ({\n                        ...prev,\n                        date: v,\n                      }));\n                  }}\n                />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Filtering/TableCanvas.filtering.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Всплывающая подсказка для событий календаря",
          "type": "vendor",
          "code": "type EventDay {\n        date: Date;\n        color?: string;\n        eventInfo?: ReactNode;\n    }"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Выбор языка.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { CalendarBase } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: \"grid\", gridTemplateColumns: \"1fr 1fr\", gap: \"2rem\" }}>\n            <CalendarBase\n                type=\"Days\"\n                locale=\"en\"\n            />\n            <CalendarBase\n                type=\"Months\"\n                locale=\"en\"\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "CalendarBase": {
      "name": "CalendarBase",
      "group": "components",
      "folderName": "Calendar",
      "role": "primary",
      "description": "Базовый календарь для выбора одной даты без встроенного поля ввода",
      "props": [
        {
          "name": "onChangeValue",
          "type": "(value: Date, dateInfo?: DateInfo | undefined) => void",
          "required": true,
          "description": "Обработчик изменения значения."
        },
        {
          "name": "value",
          "type": "CalendarValueType",
          "required": true,
          "description": "Выбранное значение."
        },
        {
          "name": "date",
          "type": "DateObject | undefined",
          "required": false,
          "description": "Состояние календаря, отвечающее за отображение."
        },
        {
          "name": "disabledList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных дней."
        },
        {
          "name": "disabledMonthList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных месяцев."
        },
        {
          "name": "disabledQuarterList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных кварталов."
        },
        {
          "name": "disabledYearList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных годов."
        },
        {
          "name": "eventList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий."
        },
        {
          "name": "eventMonthList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по месяцам."
        },
        {
          "name": "eventQuarterList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по кварталам."
        },
        {
          "name": "eventTooltipOptions",
          "type": "EventTooltipOptions | undefined",
          "required": false,
          "description": "Свойства всплывающей подсказки для событий."
        },
        {
          "name": "eventYearList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по годам."
        },
        {
          "name": "focusedDate",
          "type": "DateType",
          "required": false,
          "description": "Дата, определяющая отображаемый период календаря."
        },
        {
          "name": "includeEdgeDates",
          "type": "boolean | undefined",
          "required": false,
          "description": "Должны ли значения минимального и максимального дня включаться в диапазон."
        },
        {
          "name": "locale",
          "type": "Locales | undefined",
          "required": false,
          "description": "Выбранный язык календаря. Влияет на название дней, месяцев"
        },
        {
          "name": "max",
          "type": "Date | undefined",
          "required": false,
          "description": "Максимальное значение даты."
        },
        {
          "name": "min",
          "type": "Date | undefined",
          "required": false,
          "description": "Минимальное значение даты."
        },
        {
          "name": "onChangeVisibleDate",
          "type": "((date: Date) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
        },
        {
          "name": "renderFromDate",
          "type": "Date | undefined",
          "required": false,
          "description": "Дата с которой начинается календарная сетка при отсутсвии значения."
        },
        {
          "name": "size",
          "type": "string | undefined",
          "required": false,
          "description": "Размер календаря."
        },
        {
          "name": "stretched",
          "type": "boolean | undefined",
          "required": false,
          "description": "Растянуть календарь на всю доступную ширину и высоту"
        },
        {
          "name": "type",
          "type": "\"Days\" | \"Months\" | \"Years\" | \"Quarters\" | undefined",
          "required": false,
          "description": "Конечный тип отображения календаря: дни, месяца, года, кварталы."
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": "Вид календаря."
        }
      ],
      "propsTypeName": "CalendarBaseProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Calendar/Calendar.d.ts",
      "type": "wrapper",
      "atomicBase": "CalendarBase",
      "category": "Локальные компоненты",
      "keywords": [
        "выбор одной даты",
        "date grid",
        "сетка календаря"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { CalendarBase } from '@daisforge/ui';",
      "minimalUsage": "<CalendarBase onChangeValue={() => {}} value={{}} />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Выбор языка.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { CalendarBase } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: \"grid\", gridTemplateColumns: \"1fr 1fr\", gap: \"2rem\" }}>\n            <CalendarBase\n                type=\"Days\"\n                locale=\"en\"\n            />\n            <CalendarBase\n                type=\"Months\"\n                locale=\"en\"\n            />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Calendar Calendar Props (свойства) для компонента Calendar",
          "type": "vendor",
          "code": "import React from 'react';\nimport { CalendarBase } from '@daisforge/ui';\nexport function App() {\n    const min = new Date(2022, 4, 0);\n    const max = new Date(2022, 7, 15);\n    const [value, setValue] = React.useState(new Date(2022, 5, 6));\n    const handleOnChange = React.useCallback((newValue) => {\n        setValue(newValue);\n    }, []);\n    return (\n        <div>\n            <CalendarBase\n                value={value}\n                min={min}\n                max={max}\n                onChangeValue={handleOnChange}\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "CalendarBaseRange": {
      "name": "CalendarBaseRange",
      "group": "components",
      "folderName": "Calendar",
      "role": "primary",
      "description": "Базовый календарь для выбора диапазона дат без встроенного поля ввода",
      "props": [
        {
          "name": "onChangeValue",
          "type": "(values: [DateType, DateType], dateInfo?: DateInfo | undefined) => void",
          "required": true,
          "description": "Обработчик изменения значения."
        },
        {
          "name": "value",
          "type": "[DateType, DateType]",
          "required": true,
          "description": "Выбранное значение."
        },
        {
          "name": "date",
          "type": "DateObject | undefined",
          "required": false,
          "description": "Состояние календаря, отвечающее за отображение."
        },
        {
          "name": "disabledList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных дней."
        },
        {
          "name": "disabledMonthList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных месяцев."
        },
        {
          "name": "disabledQuarterList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных кварталов."
        },
        {
          "name": "disabledYearList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных годов."
        },
        {
          "name": "eventList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий."
        },
        {
          "name": "eventMonthList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по месяцам."
        },
        {
          "name": "eventQuarterList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по кварталам."
        },
        {
          "name": "eventTooltipOptions",
          "type": "EventTooltipOptions | undefined",
          "required": false,
          "description": "Свойства всплывающей подсказки для событий."
        },
        {
          "name": "eventYearList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по годам."
        },
        {
          "name": "focusedDate",
          "type": "DateType",
          "required": false,
          "description": "Дата, определяющая отображаемый период календаря."
        },
        {
          "name": "includeEdgeDates",
          "type": "boolean | undefined",
          "required": false,
          "description": "Должны ли значения минимального и максимального дня включаться в диапазон."
        },
        {
          "name": "locale",
          "type": "Locales | undefined",
          "required": false,
          "description": "Выбранный язык календаря. Влияет на название дней, месяцев"
        },
        {
          "name": "max",
          "type": "Date | undefined",
          "required": false,
          "description": "Максимальное значение даты."
        },
        {
          "name": "min",
          "type": "Date | undefined",
          "required": false,
          "description": "Минимальное значение даты."
        },
        {
          "name": "onChangeSingleValue",
          "type": "((value: Date, dateInfo?: DateInfo | undefined) => void) | undefined",
          "required": false,
          "description": "Обработчик для первого клика, когда оба значения диапазона не заданы.\nПозволяет обрабатывать выбор одиночной даты независимо от диапазонной логики."
        },
        {
          "name": "onChangeStartOfRange",
          "type": "((value: Date, dateInfo?: DateInfo | undefined) => void) | undefined",
          "required": false,
          "description": "Обработчик для выбора стартового значения в диапазоне."
        },
        {
          "name": "onChangeVisibleDate",
          "type": "((date: Date) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
        },
        {
          "name": "renderFromDate",
          "type": "Date | undefined",
          "required": false,
          "description": "Дата с которой начинается календарная сетка при отсутсвии значения."
        },
        {
          "name": "size",
          "type": "string | undefined",
          "required": false,
          "description": "Размер календаря."
        },
        {
          "name": "stretched",
          "type": "boolean | undefined",
          "required": false,
          "description": "Растянуть календарь на всю доступную ширину и высоту"
        },
        {
          "name": "type",
          "type": "\"Days\" | \"Months\" | \"Years\" | \"Quarters\" | undefined",
          "required": false,
          "description": "Конечный тип отображения календаря: дни, месяца, года, кварталы."
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": "Вид календаря."
        }
      ],
      "propsTypeName": "ComponentProps<typeof CalendarBaseRange>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Calendar/Calendar.d.ts",
      "type": "wrapper",
      "atomicBase": "CalendarBaseRange",
      "category": "Локальные компоненты",
      "keywords": [
        "выбор периода",
        "date range picker",
        "диапазон дат"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { CalendarBaseRange } from '@daisforge/ui';",
      "minimalUsage": "<CalendarBaseRange onChangeValue={() => {}} value={{}} />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Calendar Calendar Props (свойства) для компонента Calendar",
          "type": "vendor",
          "code": "import React from 'react';\nimport { CalendarBaseRange } from '@daisforge/ui';\nexport function App() {\n    const min = new Date(2022, 4, 0);\n    const max = new Date(2022, 7, 15);\n    const [value, setValue] = React.useState([new Date(2022, 5, 6), new Date(2022, 5, 16)]);\n    const handleOnChange = React.useCallback((newValue) => {\n        setValue(newValue);\n    }, []);\n    return (\n        <div>\n            <CalendarBaseRange\n                value={value}\n                min={min}\n                max={max}\n                onChangeValue={handleOnChange}\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "CalendarDouble": {
      "name": "CalendarDouble",
      "group": "components",
      "folderName": "Calendar",
      "role": "primary",
      "description": "Календарь с двумя месяцами одновременно для выбора одной даты",
      "props": [
        {
          "name": "onChangeValue",
          "type": "(value: Date, dateInfo?: DateInfo | undefined) => void",
          "required": true,
          "description": "Обработчик изменения значения."
        },
        {
          "name": "value",
          "type": "CalendarValueType",
          "required": true,
          "description": "Выбранное значение."
        },
        {
          "name": "date",
          "type": "DateObject | undefined",
          "required": false,
          "description": "Состояние календаря, отвечающее за отображение."
        },
        {
          "name": "disabledList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных дней."
        },
        {
          "name": "disabledMonthList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных месяцев."
        },
        {
          "name": "disabledQuarterList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных кварталов."
        },
        {
          "name": "disabledYearList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных годов."
        },
        {
          "name": "eventList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий."
        },
        {
          "name": "eventMonthList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по месяцам."
        },
        {
          "name": "eventQuarterList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по кварталам."
        },
        {
          "name": "eventTooltipOptions",
          "type": "EventTooltipOptions | undefined",
          "required": false,
          "description": "Свойства всплывающей подсказки для событий."
        },
        {
          "name": "eventYearList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по годам."
        },
        {
          "name": "focusedDate",
          "type": "DateType",
          "required": false,
          "description": "Дата, определяющая отображаемый период календаря."
        },
        {
          "name": "includeEdgeDates",
          "type": "boolean | undefined",
          "required": false,
          "description": "Должны ли значения минимального и максимального дня включаться в диапазон."
        },
        {
          "name": "locale",
          "type": "Locales | undefined",
          "required": false,
          "description": "Выбранный язык календаря. Влияет на название дней, месяцев"
        },
        {
          "name": "max",
          "type": "Date | undefined",
          "required": false,
          "description": "Максимальное значение даты."
        },
        {
          "name": "min",
          "type": "Date | undefined",
          "required": false,
          "description": "Минимальное значение даты."
        },
        {
          "name": "onChangeVisibleDate",
          "type": "((date: Date) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
        },
        {
          "name": "renderFromDate",
          "type": "Date | undefined",
          "required": false,
          "description": "Дата с которой начинается календарная сетка при отсутсвии значения."
        },
        {
          "name": "size",
          "type": "string | undefined",
          "required": false,
          "description": "Размер календаря."
        },
        {
          "name": "stretched",
          "type": "boolean | undefined",
          "required": false,
          "description": "Растянуть календарь на всю доступную ширину и высоту"
        },
        {
          "name": "type",
          "type": "\"Days\" | \"Months\" | \"Years\" | \"Quarters\" | undefined",
          "required": false,
          "description": "Конечный тип отображения календаря: дни, месяца, года, кварталы."
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": "Вид календаря."
        }
      ],
      "propsTypeName": "CalendarDoubleProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Calendar/Calendar.d.ts",
      "type": "wrapper",
      "atomicBase": "CalendarDouble",
      "category": "Локальные компоненты",
      "keywords": [
        "два месяца",
        "double month calendar",
        "выбор даты"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { CalendarDouble } from '@daisforge/ui';",
      "minimalUsage": "<CalendarDouble onChangeValue={() => {}} value={{}} />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Calendar Calendar Props (свойства) для компонента Calendar",
          "type": "vendor",
          "code": "import React from 'react';\nimport { CalendarDouble } from '@daisforge/ui';\nexport function App() {\n    const min = new Date(2022, 4, 0);\n    const max = new Date(2022, 7, 15);\n    const [value, setValue] = React.useState(new Date(2022, 5, 6));\n    const handleOnChange = React.useCallback((newValue) => {\n        setValue(newValue);\n    }, []);\n    return (\n        <div>\n            <CalendarDouble\n                value={value}\n                min={min}\n                max={max}\n                onChangeValue={handleOnChange}\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "CalendarDoubleRange": {
      "name": "CalendarDoubleRange",
      "group": "components",
      "folderName": "Calendar",
      "role": "primary",
      "description": "Календарь с двумя месяцами одновременно для выбора диапазона дат",
      "props": [
        {
          "name": "onChangeValue",
          "type": "(values: [DateType, DateType], dateInfo?: DateInfo | undefined) => void",
          "required": true,
          "description": "Обработчик изменения значения."
        },
        {
          "name": "value",
          "type": "[DateType, DateType]",
          "required": true,
          "description": "Выбранное значение."
        },
        {
          "name": "date",
          "type": "DateObject | undefined",
          "required": false,
          "description": "Состояние календаря, отвечающее за отображение."
        },
        {
          "name": "disabledList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных дней."
        },
        {
          "name": "disabledMonthList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных месяцев."
        },
        {
          "name": "disabledQuarterList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных кварталов."
        },
        {
          "name": "disabledYearList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных годов."
        },
        {
          "name": "eventList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий."
        },
        {
          "name": "eventMonthList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по месяцам."
        },
        {
          "name": "eventQuarterList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по кварталам."
        },
        {
          "name": "eventTooltipOptions",
          "type": "EventTooltipOptions | undefined",
          "required": false,
          "description": "Свойства всплывающей подсказки для событий."
        },
        {
          "name": "eventYearList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по годам."
        },
        {
          "name": "focusedDate",
          "type": "DateType",
          "required": false,
          "description": "Дата, определяющая отображаемый период календаря."
        },
        {
          "name": "includeEdgeDates",
          "type": "boolean | undefined",
          "required": false,
          "description": "Должны ли значения минимального и максимального дня включаться в диапазон."
        },
        {
          "name": "locale",
          "type": "Locales | undefined",
          "required": false,
          "description": "Выбранный язык календаря. Влияет на название дней, месяцев"
        },
        {
          "name": "max",
          "type": "Date | undefined",
          "required": false,
          "description": "Максимальное значение даты."
        },
        {
          "name": "min",
          "type": "Date | undefined",
          "required": false,
          "description": "Минимальное значение даты."
        },
        {
          "name": "onChangeSingleValue",
          "type": "((value: Date, dateInfo?: DateInfo | undefined) => void) | undefined",
          "required": false,
          "description": "Обработчик для первого клика, когда оба значения диапазона не заданы.\nПозволяет обрабатывать выбор одиночной даты независимо от диапазонной логики."
        },
        {
          "name": "onChangeStartOfRange",
          "type": "((value: Date, dateInfo?: DateInfo | undefined) => void) | undefined",
          "required": false,
          "description": "Обработчик для выбора стартового значения в диапазоне."
        },
        {
          "name": "onChangeVisibleDate",
          "type": "((date: Date) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
        },
        {
          "name": "renderFromDate",
          "type": "Date | undefined",
          "required": false,
          "description": "Дата с которой начинается календарная сетка при отсутсвии значения."
        },
        {
          "name": "size",
          "type": "string | undefined",
          "required": false,
          "description": "Размер календаря."
        },
        {
          "name": "stretched",
          "type": "boolean | undefined",
          "required": false,
          "description": "Растянуть календарь на всю доступную ширину и высоту"
        },
        {
          "name": "type",
          "type": "\"Days\" | \"Months\" | \"Years\" | \"Quarters\" | undefined",
          "required": false,
          "description": "Конечный тип отображения календаря: дни, месяца, года, кварталы."
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": "Вид календаря."
        }
      ],
      "propsTypeName": "ComponentProps<typeof CalendarDoubleRange>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Calendar/Calendar.d.ts",
      "type": "wrapper",
      "atomicBase": "CalendarDoubleRange",
      "category": "Локальные компоненты",
      "keywords": [
        "два месяца",
        "выбор периода",
        "date range picker"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { CalendarDoubleRange } from '@daisforge/ui';",
      "minimalUsage": "<CalendarDoubleRange onChangeValue={() => {}} value={{}} />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Calendar Calendar Props (свойства) для компонента Calendar",
          "type": "vendor",
          "code": "import React from 'react';\nimport { CalendarDoubleRange } from '@daisforge/ui';\nexport function App() {\n    const min = new Date(2022, 4, 0);\n    const max = new Date(2022, 7, 15);\n    const [value, setValue] = React.useState([new Date(2022, 5, 6), new Date(2022, 6, 16)]);\n    const handleOnChange = React.useCallback((newValue) => {\n        setValue(newValue);\n    }, []);\n    return (\n        <div>\n            <CalendarDoubleRange\n                value={value}\n                min={min}\n                max={max}\n                onChangeValue={handleOnChange}\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "Card": {
      "name": "Card",
      "group": "components",
      "folderName": "Card",
      "role": "primary",
      "description": "Визуальный контейнер-карточка, объединяющий изображение, текст и действия в один блок",
      "props": [],
      "propsTypeName": "CardProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Card/Card.d.ts",
      "type": "wrapper",
      "atomicBase": "Card",
      "category": "Локальные компоненты",
      "keywords": [
        "карточка контента",
        "content card",
        "блок с превью"
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "CardContent"
      ],
      "inheritedProps": [
        {
          "name": "backgroundType",
          "type": "\"none\" | \"solid\"",
          "required": false,
          "description": "Добавляет цветной отступ с фоном",
          "inheritedFrom": "Card",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\"",
          "required": false,
          "description": "Расположение outer контента",
          "inheritedFrom": "Card",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\"",
          "required": false,
          "description": "Размер контрола.",
          "inheritedFrom": "Card",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "description": "Вид контрола.",
          "inheritedFrom": "Card",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "selected",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Card",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Card } from '@daisforge/ui';",
      "minimalUsage": "<Card />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Пример выбранной карточки с backgroundType=\"solid\"",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Card, CardContent, H3, TextS } from '@daisforge/ui';\nexport function App() {\n    const SvgBackground = (props) => (\n        <svg\n            xmlns=\"http://www.w3.org/2000/svg\"\n            preserveAspectRatio=\"xMinYMin slice\"\n            viewBox=\"1 0.5 8 8\"\n            {...props}\n            style={{ ...props.style, background: 'var(--text-tertiary)' }}\n        >\n            <path stroke=\"#fff\" strokeDasharray={1} d=\"M1 1h7M2 2h7M1 3h7M2 4h7M1 5h7M2 6h7M1 7h7M2 8h7\" />\n        </svg>\n    );\n    return (\n        <Card orientation=\"horizontal\" style={{ width: '400px' }} backgroundType=\"solid\" selected>\n            <div style={{ padding: '30px' }}>\n                <H3>Title</H3>\n                <TextS style={{ paddingTop: '8px' }}>Description</TextS>\n            </div>\n            <CardContent orientation=\"vertical\" aspectRatio=\"4/3\">\n                <SvgBackground width=\"100%\" height=\"100%\" style={{ width: '100%', height: '100%' }} />\n            </CardContent>\n        </Card>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Пример с вложенным контентом",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Card, CardContent, CardInnerContent, H3, TextS } from '@daisforge/ui';\nexport function App() {\n    const SvgBackground = (props) => (\n        <svg\n            xmlns=\"http://www.w3.org/2000/svg\"\n            preserveAspectRatio=\"xMinYMin slice\"\n            viewBox=\"1 0.5 8 8\"\n            {...props}\n            style={{ ...props.style, background: 'var(--text-tertiary)' }}\n        >\n            <path stroke=\"#fff\" strokeDasharray={1} d=\"M1 1h7M2 2h7M1 3h7M2 4h7M1 5h7M2 6h7M1 7h7M2 8h7\" />\n        </svg>\n    );\n    return (\n        <Card orientation=\"horizontal\" style={{ width: '250px' }}>\n            <CardContent orientation='vertical' aspectRatio='1/1'>\n                <CardInnerContent>\n                    <div style={{ padding: '30px' }}>\n                        <H3>Заголовок</H3>\n                        <TextS style={{ paddingTop: '8px' }}>Как оплатить заправку бонусами СберСпасибо?</TextS>\n                    </div>\n                </CardInnerContent>\n                <SvgBackground width=\"100%\" height=\"100%\" style={{ width: '100%', height: '100%' }} />\n            </CardContent>\n        </Card>\n    );\n}"
        }
      ]
    },
    "CardContent": {
      "name": "CardContent",
      "group": "components",
      "folderName": "Card",
      "role": "part",
      "description": "Область содержимого карточки Card — слот compound-структуры.",
      "props": [
        {
          "name": "as",
          "type": "string | React.ComponentType<any> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof CardContent>",
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Card/Card.styles.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "содержимое карточки",
        "card slot",
        "внутренний блок"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Card",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { CardContent } from '@daisforge/ui';",
      "minimalUsage": "<CardContent />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Пример выбранной карточки с backgroundType=\"solid\"",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Card, CardContent, H3, TextS } from '@daisforge/ui';\nexport function App() {\n    const SvgBackground = (props) => (\n        <svg\n            xmlns=\"http://www.w3.org/2000/svg\"\n            preserveAspectRatio=\"xMinYMin slice\"\n            viewBox=\"1 0.5 8 8\"\n            {...props}\n            style={{ ...props.style, background: 'var(--text-tertiary)' }}\n        >\n            <path stroke=\"#fff\" strokeDasharray={1} d=\"M1 1h7M2 2h7M1 3h7M2 4h7M1 5h7M2 6h7M1 7h7M2 8h7\" />\n        </svg>\n    );\n    return (\n        <Card orientation=\"horizontal\" style={{ width: '400px' }} backgroundType=\"solid\" selected>\n            <div style={{ padding: '30px' }}>\n                <H3>Title</H3>\n                <TextS style={{ paddingTop: '8px' }}>Description</TextS>\n            </div>\n            <CardContent orientation=\"vertical\" aspectRatio=\"4/3\">\n                <SvgBackground width=\"100%\" height=\"100%\" style={{ width: '100%', height: '100%' }} />\n            </CardContent>\n        </Card>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Пример с вложенным контентом",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Card, CardContent, CardInnerContent, H3, TextS } from '@daisforge/ui';\nexport function App() {\n    const SvgBackground = (props) => (\n        <svg\n            xmlns=\"http://www.w3.org/2000/svg\"\n            preserveAspectRatio=\"xMinYMin slice\"\n            viewBox=\"1 0.5 8 8\"\n            {...props}\n            style={{ ...props.style, background: 'var(--text-tertiary)' }}\n        >\n            <path stroke=\"#fff\" strokeDasharray={1} d=\"M1 1h7M2 2h7M1 3h7M2 4h7M1 5h7M2 6h7M1 7h7M2 8h7\" />\n        </svg>\n    );\n    return (\n        <Card orientation=\"horizontal\" style={{ width: '250px' }}>\n            <CardContent orientation='vertical' aspectRatio='1/1'>\n                <CardInnerContent>\n                    <div style={{ padding: '30px' }}>\n                        <H3>Заголовок</H3>\n                        <TextS style={{ paddingTop: '8px' }}>Как оплатить заправку бонусами СберСпасибо?</TextS>\n                    </div>\n                </CardInnerContent>\n                <SvgBackground width=\"100%\" height=\"100%\" style={{ width: '100%', height: '100%' }} />\n            </CardContent>\n        </Card>\n    );\n}"
        }
      ]
    },
    "CardInnerContent": {
      "name": "CardInnerContent",
      "group": "components",
      "folderName": "Card",
      "role": "primary",
      "description": "Внутренний контентный контейнер карточки Card для компоновки содержимого",
      "props": [
        {
          "name": "as",
          "type": "string | React.ComponentType<any> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof CardInnerContent>",
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Card/Card.styles.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "содержимое карточки",
        "card body",
        "внутренний блок"
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "CardContent"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { CardInnerContent } from '@daisforge/ui';",
      "minimalUsage": "<CardInnerContent />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Пример с вложенным контентом",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Card, CardContent, CardInnerContent, H3, TextS } from '@daisforge/ui';\nexport function App() {\n    const SvgBackground = (props) => (\n        <svg\n            xmlns=\"http://www.w3.org/2000/svg\"\n            preserveAspectRatio=\"xMinYMin slice\"\n            viewBox=\"1 0.5 8 8\"\n            {...props}\n            style={{ ...props.style, background: 'var(--text-tertiary)' }}\n        >\n            <path stroke=\"#fff\" strokeDasharray={1} d=\"M1 1h7M2 2h7M1 3h7M2 4h7M1 5h7M2 6h7M1 7h7M2 8h7\" />\n        </svg>\n    );\n    return (\n        <Card orientation=\"horizontal\" style={{ width: '250px' }}>\n            <CardContent orientation='vertical' aspectRatio='1/1'>\n                <CardInnerContent>\n                    <div style={{ padding: '30px' }}>\n                        <H3>Заголовок</H3>\n                        <TextS style={{ paddingTop: '8px' }}>Как оплатить заправку бонусами СберСпасибо?</TextS>\n                    </div>\n                </CardInnerContent>\n                <SvgBackground width=\"100%\" height=\"100%\" style={{ width: '100%', height: '100%' }} />\n            </CardContent>\n        </Card>\n    );\n}"
        }
      ]
    },
    "Carousel": {
      "name": "Carousel",
      "group": "components",
      "folderName": "Carousel",
      "role": "primary",
      "description": "Слайдер для показа набора карточек с пагинацией, автопрокруткой и свайпом",
      "props": [
        {
          "name": "autoPlayInterval",
          "type": "number | undefined",
          "required": false,
          "description": "Интервал автоматического пролистывания в мс.",
          "default": "5000"
        },
        {
          "name": "controlArrowsDisabled",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включение/выключение стрелок управления слайдами.",
          "default": "false"
        },
        {
          "name": "defaultIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Номер слайда по-умолчанию.\nТолько при uncontrolled-режиме.",
          "default": "0"
        },
        {
          "name": "gap",
          "type": "Property.Gap<string | number> | undefined",
          "required": false,
          "description": "Отступ между слайдами.",
          "default": "20px"
        },
        {
          "name": "index",
          "type": "number | undefined",
          "required": false,
          "description": "Номер слайда.\nControlled-режим."
        },
        {
          "name": "onChangeIndex",
          "type": "((index: number) => void) | undefined",
          "required": false,
          "description": "Callback для изменения слайда;"
        },
        {
          "name": "paginationOptions",
          "type": "{ disabled?: boolean | undefined; visibleDots?: number | undefined; centered?: boolean | undefined; } | undefined",
          "required": false,
          "description": "Опции управления пагинацией."
        },
        {
          "name": "scrollAlign",
          "type": "ScrollAlign | undefined",
          "required": false,
          "description": "Центрирование активного элемента при скролле.",
          "default": "start"
        },
        {
          "name": "size",
          "type": "\"s\" | undefined",
          "required": false,
          "description": "Размер контрола."
        },
        {
          "name": "swipeEnabled",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включение свайпа/drag для touch- и pointer-устройств.",
          "default": "false"
        },
        {
          "name": "view",
          "type": "\"default\" | undefined",
          "required": false,
          "description": "Вид контрола.",
          "default": "default"
        },
        {
          "name": "virtual",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включение виртуализации слайдов.",
          "default": "false"
        }
      ],
      "propsTypeName": "CarouselCompProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Carousel/Carousel.d.ts",
      "type": "wrapper",
      "atomicBase": "Carousel",
      "category": "Локальные компоненты",
      "keywords": [
        "слайдер",
        "галерея баннеров",
        "autoplay",
        "свайп"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Carousel } from '@daisforge/ui';",
      "minimalUsage": "<Carousel />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в Stories.stories.tsx",
          "type": "usage",
          "code": "<Carousel\n        index={carouselIndex}\n        onChangeIndex={setCarouselIndex}\n        scrollAlign=\"start\"\n        gap=\"16px\"\n        style={{ maxWidth: 360 }}\n      >\n        {CAROUSEL_PALETTE.map(([from, to], i) => {\n          const n = i + 1;\n          return (\n            <CarouselItem key={n}>\n              <Stories.Preview\n                title={`Превью ${n}`}\n                image={asset(String(n), from, to)}\n                viewed={viewed[i]}\n                slides={[\n                  { src: asset(`Слайд ${n}.1`, from, to) },\n                  { src: asset(`Слайд ${n}.2`, to, from) },\n                ]}\n              />\n            </CarouselItem>\n          );\n        })}\n      </Carousel>",
          "sourceFile": "packages/storybook/src/stories/Stories/Stories.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Примеры Примеры",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Carousel } from '@daisforge/ui';\nimport styled from 'styled-components';\nexport function App() {\n    const StyledCard = styled.div`\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        border: 1px solid #d6d6d6;\n        border-radius: 12px;\n        width: 320px;\n        height: 180px;\n        background-color: #f4f5f7;\n        color: #1b1f23;\n        font-size: 20px;\n        font-weight: 600;\n    `;\n    const items = Array(10).fill(0).map((_, i) => `Слайд ${i + 1}`);\n    return (\n        <div style={{ display: 'block', width: '500px' }}>\n            <Carousel gap=\"16px\">\n                {items.map((item) => (\n                    <StyledCard key={item}>{item}</StyledCard>\n                ))}\n            </Carousel>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Example 1",
          "type": "vendor",
          "code": "export interface CarouselNewProps extends HTMLAttributes<HTMLDivElement> {\n    /**\n     * Номер слайда.\n     * Controlled-режим.\n     */\n    index?: number;\n    /**\n     * Callback для изменения слайда;\n     */\n    onChangeIndex?: (index: number) => void;\n    /**\n     * Номер слайда по-умолчанию.\n     * Только при uncontrolled-режиме.\n     * @default 0\n     */\n    defaultIndex?: number;\n    /**\n     * Центрирование активного элемента при скролле.\n     * @default start\n     */\n    scrollAlign?: ScrollAlign;\n    /**\n     * Опции управления пагинацией.\n     */\n    paginationOptions?: {\n        /**\n         * Включение/выключение пагинации.\n         * @default false\n         */\n        disabled?: boolean;\n        /**\n         * Количество видимых точек пагинации.\n         * @default 10\n         */\n        visibleDots?: number;\n        /**\n         * Центрирование активной точки.\n         * @default false\n         */\n        centered?: boolean;\n    };\n    /**\n     * Включение/выключение стрелок управления слайдами.\n     * @default false\n     */\n    controlArrowsDisabled?: boolean;\n    /**\n     * Отступ между слайдами.\n     * @default 20px\n     */\n    gap?: CSSProperties['gap'];\n    /**\n     * Зацикливание карусели.\n     * При включении после последнего слайда идет первый, и наоборот.\n     * @default false\n     */\n    loop?: boolean;\n    /**\n     * Автоматическое пролистывание карусели.\n     * @default false\n     */\n    autoPlay?: boolean;\n    /**\n     * Интервал автоматического пролистывания в мс.\n     * @default 5000\n     */\n    autoPlayInterval?: number;\n    /**\n     * Включение свайпа/drag для touch- и pointer-устройств.\n     * @default false\n     */\n    swipeEnabled?: boolean;\n    /**\n     * Включение виртуализации слайдов.\n     * @default false\n     */\n    virtual?: boolean;\n    /**\n     * Размер контрола.\n     */\n    size?: string;\n    /**\n     * Вид контрола.\n     * @default default\n     */\n    view?: string;\n}"
        }
      ]
    },
    "CarouselItem": {
      "name": "CarouselItem",
      "group": "components",
      "folderName": "Carousel",
      "role": "primary",
      "description": "Отдельный слайд внутри Carousel со scroll-snap выравниванием",
      "props": [
        {
          "name": "as",
          "type": "React.ComponentType<any> | keyof JSX.IntrinsicElements | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "scrollSnapAlign",
          "type": "SnapAlign | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "scrollSnapStop",
          "type": "SnapStop | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "CarouselItemCompProps",
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Carousel/CarouselOld/CarouselItem.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "слайд",
        "элемент слайдера",
        "scroll snap"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { CarouselItem } from '@daisforge/ui';",
      "minimalUsage": "<CarouselItem />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в Stories.stories.tsx",
          "type": "usage",
          "code": "<CarouselItem key={n}>\n              <Stories.Preview\n                title={`Превью ${n}`}\n                image={asset(String(n), from, to)}\n                viewed={viewed[i]}\n                slides={[\n                  { src: asset(`Слайд ${n}.1`, from, to) },\n                  { src: asset(`Слайд ${n}.2`, to, from) },\n                ]}\n              />\n            </CarouselItem>",
          "sourceFile": "packages/storybook/src/stories/Stories/Stories.stories.tsx"
        }
      ]
    },
    "CellTextbox": {
      "name": "CellTextbox",
      "group": "components",
      "folderName": "Cell",
      "role": "primary",
      "description": "Текстовый блок ячейки Cell: сочетание заголовка и подзаголовка",
      "props": [
        {
          "name": "subtitle",
          "type": "string | undefined",
          "required": false,
          "description": "Слот для Subtitle"
        }
      ],
      "propsTypeName": "ComponentProps<typeof CellTextbox>",
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Cell/ui/CellTextbox/CellTextbox.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "текст в ячейке",
        "title subtitle",
        "содержимое строки списка"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { CellTextbox } from '@daisforge/ui';",
      "minimalUsage": "<CellTextbox />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "С использованием своих стилей или встроенных компонентов",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Avatar, Cell , CellTextboxLabel , CellTextboxTitle , CellTextboxSubtitle, CellTextbox } from '@daisforge/ui';\nimport { IconChevronRight } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <>\n            <Cell\n                contentLeft={ <Avatar size=\"m\" url=\"https://avatars.githubusercontent.com/u/1813468?v=4\" /> }\n                size=\"m\"\n                contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}\n            >\n                <CellTextbox>\n                    <CellTextboxLabel>Label</CellTextboxLabel>\n                    <CellTextboxTitle>Title</CellTextboxTitle>\n                    <CellTextboxSubtitle>Subtitle</CellTextboxSubtitle>\n                    <div style={{'font-size': '12px', opacity: 0.4}}>Caption</div>\n                </CellTextbox>\n            </Cell>\n        </>\n    );\n}"
        }
      ]
    },
    "CellTextboxLabel": {
      "name": "CellTextboxLabel",
      "group": "components",
      "folderName": "Cell",
      "role": "primary",
      "description": "Надпись-лейбл внутри текстового блока ячейки Cell",
      "props": [],
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Cell/ui/CellTextboxLabel/CellTextboxLabel.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "лейбл ячейки",
        "label",
        "подпись поля списка"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { CellTextboxLabel } from '@daisforge/ui';",
      "minimalUsage": "<CellTextboxLabel />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "С использованием своих стилей или встроенных компонентов",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Avatar, Cell , CellTextboxLabel , CellTextboxTitle , CellTextboxSubtitle, CellTextbox } from '@daisforge/ui';\nimport { IconChevronRight } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <>\n            <Cell\n                contentLeft={ <Avatar size=\"m\" url=\"https://avatars.githubusercontent.com/u/1813468?v=4\" /> }\n                size=\"m\"\n                contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}\n            >\n                <CellTextbox>\n                    <CellTextboxLabel>Label</CellTextboxLabel>\n                    <CellTextboxTitle>Title</CellTextboxTitle>\n                    <CellTextboxSubtitle>Subtitle</CellTextboxSubtitle>\n                    <div style={{'font-size': '12px', opacity: 0.4}}>Caption</div>\n                </CellTextbox>\n            </Cell>\n        </>\n    );\n}"
        }
      ]
    },
    "CellTextboxSubtitle": {
      "name": "CellTextboxSubtitle",
      "group": "components",
      "folderName": "Cell",
      "role": "primary",
      "description": "Подзаголовок внутри текстового блока ячейки Cell",
      "props": [],
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Cell/ui/CellTextboxSubtitle/CellTextboxSubtitle.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "подзаголовок строки",
        "subtitle",
        "вторичный текст ячейки"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { CellTextboxSubtitle } from '@daisforge/ui';",
      "minimalUsage": "<CellTextboxSubtitle />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "С использованием своих стилей или встроенных компонентов",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Avatar, Cell , CellTextboxLabel , CellTextboxTitle , CellTextboxSubtitle, CellTextbox } from '@daisforge/ui';\nimport { IconChevronRight } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <>\n            <Cell\n                contentLeft={ <Avatar size=\"m\" url=\"https://avatars.githubusercontent.com/u/1813468?v=4\" /> }\n                size=\"m\"\n                contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}\n            >\n                <CellTextbox>\n                    <CellTextboxLabel>Label</CellTextboxLabel>\n                    <CellTextboxTitle>Title</CellTextboxTitle>\n                    <CellTextboxSubtitle>Subtitle</CellTextboxSubtitle>\n                    <div style={{'font-size': '12px', opacity: 0.4}}>Caption</div>\n                </CellTextbox>\n            </Cell>\n        </>\n    );\n}"
        }
      ]
    },
    "CellTextboxTitle": {
      "name": "CellTextboxTitle",
      "group": "components",
      "folderName": "Cell",
      "role": "primary",
      "description": "Заголовок внутри текстового блока ячейки Cell",
      "props": [],
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Cell/ui/CellTextboxTitle/CellTextboxTitle.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "заголовок строки",
        "title",
        "основной текст ячейки"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { CellTextboxTitle } from '@daisforge/ui';",
      "minimalUsage": "<CellTextboxTitle />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "С использованием своих стилей или встроенных компонентов",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Avatar, Cell , CellTextboxLabel , CellTextboxTitle , CellTextboxSubtitle, CellTextbox } from '@daisforge/ui';\nimport { IconChevronRight } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <>\n            <Cell\n                contentLeft={ <Avatar size=\"m\" url=\"https://avatars.githubusercontent.com/u/1813468?v=4\" /> }\n                size=\"m\"\n                contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}\n            >\n                <CellTextbox>\n                    <CellTextboxLabel>Label</CellTextboxLabel>\n                    <CellTextboxTitle>Title</CellTextboxTitle>\n                    <CellTextboxSubtitle>Subtitle</CellTextboxSubtitle>\n                    <div style={{'font-size': '12px', opacity: 0.4}}>Caption</div>\n                </CellTextbox>\n            </Cell>\n        </>\n    );\n}"
        }
      ]
    },
    "Cell": {
      "name": "Cell",
      "group": "components",
      "folderName": "Cell",
      "role": "primary",
      "description": "Строка списка со слотами слева/справа, заголовком и подписью",
      "props": [],
      "propsTypeName": "CellProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Cell/Cell.d.ts",
      "type": "wrapper",
      "atomicBase": "Cell",
      "category": "Локальные компоненты",
      "keywords": [
        "строка списка",
        "list item",
        "пункт меню"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "alignContentLeft",
          "type": "AlignProp",
          "required": false,
          "description": "Вертикальное выравнивание контента слева.",
          "inheritedFrom": "Cell",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "alignContentRight",
          "type": "AlignProp",
          "required": false,
          "description": "Вертикальное выравнивание контента справа.",
          "inheritedFrom": "Cell",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "content",
          "type": "ReactNode",
          "required": false,
          "description": "Свойство устарело, вместо этого нужно использовать contentLeft",
          "inheritedFrom": "Cell",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`",
          "inheritedFrom": "Cell",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента спарва, например `Icon`",
          "inheritedFrom": "Cell",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "description",
          "type": "string",
          "required": false,
          "description": "Свойство устарело, вместо этого нужно использовать title",
          "inheritedFrom": "Cell",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\" | \"xs\"",
          "required": false,
          "description": "Размер",
          "inheritedFrom": "Cell",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretching",
          "type": "\"auto\" | \"filled\" | \"fixed\"",
          "required": false,
          "description": "Ширина cell",
          "inheritedFrom": "Cell",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "subtitle",
          "type": "string",
          "required": false,
          "description": "Слот для Subtitle",
          "inheritedFrom": "Cell",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "description": "Вид",
          "inheritedFrom": "Cell",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "Cell",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Cell } from '@daisforge/ui';",
      "minimalUsage": "<Cell />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Базовое использование",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Avatar, Cell } from '@daisforge/ui';\nimport { IconChevronRight } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <>\n            <Cell\n                contentLeft={ <Avatar size=\"m\" url=\"https://avatars.githubusercontent.com/u/1813468?v=4\" /> }\n                size=\"m\"\n                contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}\n                title=\"Title\"\n                subtitle=\"Subtitle\"\n                label=\"Label\"\n            />\n        </>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "С использованием своих стилей или встроенных компонентов",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Avatar, Cell , CellTextboxLabel , CellTextboxTitle , CellTextboxSubtitle, CellTextbox } from '@daisforge/ui';\nimport { IconChevronRight } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <>\n            <Cell\n                contentLeft={ <Avatar size=\"m\" url=\"https://avatars.githubusercontent.com/u/1813468?v=4\" /> }\n                size=\"m\"\n                contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}\n            >\n                <CellTextbox>\n                    <CellTextboxLabel>Label</CellTextboxLabel>\n                    <CellTextboxTitle>Title</CellTextboxTitle>\n                    <CellTextboxSubtitle>Subtitle</CellTextboxSubtitle>\n                    <div style={{'font-size': '12px', opacity: 0.4}}>Caption</div>\n                </CellTextbox>\n            </Cell>\n        </>\n    );\n}"
        }
      ]
    },
    "Checkbox": {
      "name": "Checkbox",
      "group": "components",
      "folderName": "Checkbox",
      "role": "primary",
      "description": "Флажок для переключения параметра между включено и выключено",
      "props": [
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": "Компонента находиться в фокусе"
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "CheckboxProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Checkbox/Checkbox.d.ts",
      "type": "wrapper",
      "atomicBase": "Checkbox",
      "formVariant": "FormCheckbox",
      "category": "Локальные компоненты",
      "keywords": [
        "флажок",
        "чекбокс",
        "toggle параметра"
      ],
      "chooseWhen": "Вне react-hook-form — одиночный флажок с value/onChange напрямую.",
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "appearance",
          "type": "string",
          "required": false,
          "description": "Стиль для UI конфигурации\nВлияет на выбор предустановленного набора токенов",
          "default": "default",
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "checkIcon",
          "type": "ReactNode",
          "required": false,
          "description": "Кастомная иконка галочки.",
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "description",
          "type": "ReactNode",
          "required": false,
          "description": "Описание элемента",
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "indeterminate",
          "type": "boolean",
          "required": false,
          "description": "Неопределенное состояние компонента - когда часть потомков не выбрана.",
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "indeterminateIcon",
          "type": "ReactNode",
          "required": false,
          "description": "Кастомная иконка indeterminate-состояния.",
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу",
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "ChangeEventHandler<HTMLInputElement>",
          "required": false,
          "description": "Обработчик изменения элемента формы",
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "singleLine",
          "type": "boolean",
          "required": false,
          "description": "Title и description в одну строку или с переносом строк",
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\"",
          "required": false,
          "description": "Размер компонента",
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"tertiary\" | \"paragraph\"",
          "required": false,
          "description": "Вид компонента",
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "checked",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultChecked",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maxLength",
          "type": "number",
          "required": false,
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "minLength",
          "type": "number",
          "required": false,
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "name",
          "type": "string",
          "required": false,
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onBlur",
          "type": "FocusEventHandler<HTMLInputElement>",
          "required": false,
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onFocus",
          "type": "FocusEventHandler<HTMLInputElement>",
          "required": false,
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placeholder",
          "type": "string",
          "required": false,
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "required",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "type",
          "type": "string",
          "required": false,
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | number | readonly string[]",
          "required": false,
          "inheritedFrom": "Checkbox",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Checkbox } from '@daisforge/ui';",
      "minimalUsage": "<Checkbox />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в Table.customRenderWithContext.stories.tsx",
          "type": "usage",
          "code": "<Checkbox\n      tabIndex={tabIndex}\n      checked={checked}\n      label={`${checked ? 'Выключить' : 'Включить'} чекбокс`}\n      onChange={(e) => setChecked(e.target.checked)}\n    />",
          "sourceFile": "packages/storybook/src/stories/Table/Table.customRender/Table.customRenderWithContext.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvas.bigData.stories.tsx",
          "type": "usage",
          "code": "<Checkbox\n            label=\"объединение (subRows merged)\"\n            checked={withMerge}\n            onChange={(e) => setWithMerge(e.target.checked)}\n          />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.CellsMerging/TableCanvas.bigData.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Компонент  Checkbox  может содержать лейбл и описание.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Checkbox } from '@daisforge/ui';\nexport function App() {\n    return (\n        <Checkbox label=\"Чекбокс\" description=\"Описание\" defaultChecked />\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Example 1",
          "type": "vendor",
          "code": "import React from 'react';\nimport { ViewContainer, Button, Checkbox, TextField } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <ViewContainer\n                style={{\n                    padding: '1rem',\n                    borderRadius: '1rem',\n                    display: 'flex',\n                    flexDirection: 'column',\n                    gap: '1rem',\n                }}\n            >\n                <h3 style={{ margin: 0 }}>Inside default ViewContainer</h3>\n                <Button text=\"default Button\" />\n                <Checkbox checked label=\"Label\" />\n                <TextField value=\"Example Value\" label=\"Label\" labelPlacement=\"inner\" />\n            </ViewContainer>\n            <br />\n            <ViewContainer\n                view=\"onDark\"\n                style={{\n                    background: '#1a1a1a',\n                    color: 'white',\n                    padding: '1rem',\n                    borderRadius: '1rem',\n                    display: 'flex',\n                    flexDirection: 'column',\n                    gap: '1rem',\n                }}\n            >\n                <h3 style={{ margin: 0 }}>Inside onDark ViewContainer</h3>\n                <Button text=\"default Button\" />\n                <Checkbox checked label=\"Label\" />\n                <TextField value=\"Example Value\" label=\"Label\" labelPlacement=\"inner\" />\n            </ViewContainer>\n            <br />\n            <ViewContainer\n                view=\"onLight\"\n                style={{\n                    background: '#ededed',\n                    color: 'black',\n                    padding: '1rem',\n                    borderRadius: '1rem',\n                    display: 'flex',\n                    flexDirection: 'column',\n                    gap: '1rem',\n                }}\n            >\n                <h3 style={{ margin: 0 }}>Inside onLight ViewContainer</h3>\n                <Button text=\"default Button\" />\n                <Checkbox checked label=\"Label\" />\n                <TextField value=\"Example Value\" label=\"Label\" labelPlacement=\"inner\" />\n            </ViewContainer>\n        </div>\n    );\n}"
        }
      ]
    },
    "Chip": {
      "name": "Chip",
      "group": "components",
      "folderName": "Chip",
      "role": "primary",
      "description": "Компактный тег для фильтров, категорий или выбираемых значений",
      "props": [
        {
          "name": "type",
          "type": "\"button\" | \"submit\" | \"reset\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ChipProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Chip/Chip.d.ts",
      "type": "wrapper",
      "atomicBase": "Chip",
      "category": "Локальные компоненты",
      "keywords": [
        "тег",
        "метка выбора",
        "фильтр-плашка"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "contentClearButton",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента Clear",
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`",
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента справа, например `Icon`",
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasClear",
          "type": "boolean",
          "required": false,
          "description": "Есть ли иконка закрытия",
          "default": "'true'",
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onClear",
          "type": "(() => void)",
          "required": false,
          "description": "Коллбек при взаимодействии с элементом",
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onClickClose",
          "type": "((event: MouseEvent<HTMLDivElement, MouseEvent>) => void)",
          "required": false,
          "description": "Коллбек при нажатии на крестик",
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pilled",
          "type": "boolean",
          "required": false,
          "description": "Компонент c округлым border-radius",
          "default": "'false'",
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\"",
          "required": false,
          "description": "Свойство задает скругление border-radius",
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"m\" | \"xs\" | \"xxs\"",
          "required": false,
          "description": "Размер Chip",
          "default": "'m'",
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "string",
          "required": false,
          "description": "Текстовая надпись",
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\"",
          "required": false,
          "description": "Вид Chip",
          "default": "'primary'",
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"transparent\" | \"default\"",
          "required": false,
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Chip",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Chip } from '@daisforge/ui';",
      "minimalUsage": "<Chip />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в MessageBubble.tsx",
          "type": "usage",
          "code": "<Chip\n              className=\"source-tag\"\n              key={source.componentName}\n              text={`${source.componentName} · ${source.chunkType}`}\n              size=\"xxs\"\n              title={source.meta.url}\n              view=\"accent\"\n              appearance=\"transparent\"\n              onClick={() => {\n                window.open(source.meta.url, '_blank', 'noopener,noreferrer');\n              }}\n              hasClear={false}\n              contentRight={<IconLink size=\"xs\" color=\"inherit\" />}\n            />",
          "sourceFile": "packages/storybook/src/stories/AiChatDAIS/components/MessageBubble.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в AiChatDAIS.tsx",
          "type": "usage",
          "code": "<Chip\n                          view=\"accent\"\n                          appearance=\"transparent\"\n                          pilled\n                          key={chip.text}\n                          size=\"xs\"\n                          text={chip.text}\n                          hasClear={false}\n                          onClick={() => handleQuickChipClick(chip.text)}\n                        />",
          "sourceFile": "packages/storybook/src/stories/AiChatDAIS/AiChatDAIS.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Скругления Скругления Скругления  Chip  задаются свойствами  pilled  и  pin . Если задано  pin , оно имеет приоритет над  pilled .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Chip } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', gap: '1rem' }}>\n            <Chip text=\"pilled=false\" />\n            <Chip text=\"pilled=true\" pilled />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Состояния Состояния Компонент поддерживает состояния  disabled  и  readOnly",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Chip } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', gap: '1rem' }}>\n            <Chip text=\"Активный\" />\n            <Chip text=\"Неактивный\" disabled />\n            <Chip text=\"Только чтение\" readOnly />\n        </div>\n    );\n}"
        }
      ]
    },
    "ChipGroup": {
      "name": "ChipGroup",
      "group": "components",
      "folderName": "ChipGroup",
      "role": "primary",
      "description": "Контейнер для группы тегов с общим отступом и переносом строк",
      "props": [],
      "propsTypeName": "ComponentProps<typeof ChipGroup>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/ChipGroup/ChipGroup.d.ts",
      "type": "wrapper",
      "atomicBase": "ChipGroup",
      "category": "Локальные компоненты",
      "keywords": [
        "группа тегов",
        "список фильтров",
        "обёртка меток"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "gap",
          "type": "\"dense\" | \"wide\"",
          "required": false,
          "description": "Отступы между элементами внутри группы",
          "default": "dense",
          "inheritedFrom": "ChipGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isCommonChipStyles",
          "type": "boolean",
          "required": false,
          "description": "Группа будет переопределять view и size для всех элементов внутри",
          "default": "'true'",
          "inheritedFrom": "ChipGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isWrapped",
          "type": "boolean",
          "required": false,
          "description": "Переносить ли элементы на новый ряд, при нехватке ширины.",
          "inheritedFrom": "ChipGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shape",
          "type": "\"default\" | \"segmented\"",
          "required": false,
          "description": "Скругления для чипов внутри группы",
          "default": "default",
          "inheritedFrom": "ChipGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"m\" | \"xs\"",
          "required": false,
          "description": "Размер группы",
          "inheritedFrom": "ChipGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\"",
          "required": false,
          "description": "Вид группы",
          "inheritedFrom": "ChipGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ChipGroup } from '@daisforge/ui';",
      "minimalUsage": "<ChipGroup />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React from 'react';\nimport { ChipGroup, Chip } from '@daisforge/ui';\nexport function App() {\n    return (\n        <ChipGroup>\n            {Array(5)\n                .fill(true)\n                .map((_, i) => (\n                    <Chip text={`Chip ${i}`} />\n                ))}\n        </ChipGroup>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Управление внешним видом",
          "type": "vendor",
          "code": "import React from 'react';\nimport { ChipGroup, Chip } from '@daisforge/ui';\nexport function App() {\n    return (\n        <ChipGroup size=\"s\" view=\"secondary\">\n            {Array(5)\n                .fill(true)\n                .map((_, i) => (\n                    <Chip text={`Chip ${i}`} />\n                ))}\n        </ChipGroup>\n    );\n}"
        }
      ]
    },
    "CodeField": {
      "name": "CodeField",
      "group": "components",
      "folderName": "CodeField",
      "role": "primary",
      "description": "Поле ввода одноразового OTP-кода с подписью и обработкой ошибок",
      "props": [
        {
          "name": "enableWebOTP",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "React.HTMLInputTypeAttribute | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof CodeField>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/CodeField/CodeField.d.ts",
      "type": "wrapper",
      "atomicBase": "CodeField",
      "category": "Локальные компоненты",
      "keywords": [
        "ввод кода подтверждения",
        "OTP поле",
        "смс-код"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "allowedSymbols",
          "type": "string | RegExp",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "autoFocus",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "caption",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "captionAlign",
          "type": "\"center\" | \"left\"",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "codeErrorBehavior",
          "type": "CodeErrorBehavior",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "codeLength",
          "type": "4 | 5 | 6",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isError",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "itemErrorBehavior",
          "type": "ItemErrorBehavior",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "((value: string) => void)",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onFullCodeEnter",
          "type": "((code: string) => void)",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placeholder",
          "type": "string",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "setIsError",
          "type": "Dispatch<SetStateAction<boolean>>",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shape",
          "type": "\"default\" | \"segmented\"",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"l\" | \"m\" | \"xl\"",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "width",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "CodeField",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { CodeField } from '@daisforge/ui';",
      "minimalUsage": "<CodeField />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Web OTP API",
          "type": "vendor",
          "code": "Ваш код подтверждения: 123456.\n@example.com #123456"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Поведение при вводе",
          "type": "vendor",
          "code": "import React from 'react';\nimport { CodeField } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>\n            <CodeField itemErrorBehavior=\"remove-symbol\" caption=\"remove-symbol\" />\n            <CodeField itemErrorBehavior=\"keep\" caption=\"keep\" />\n            <CodeField itemErrorBehavior=\"forbid-enter\" caption=\"forbid-enter\" />\n        </div>\n    );\n}"
        }
      ]
    },
    "CodeInput": {
      "name": "CodeInput",
      "group": "components",
      "folderName": "CodeInput",
      "role": "primary",
      "description": "Посимвольный ввод одноразового OTP-кода без обёртки поля",
      "props": [
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof CodeInput>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/CodeInput/CodeInput.d.ts",
      "type": "wrapper",
      "atomicBase": "CodeInput",
      "category": "Локальные компоненты",
      "keywords": [
        "ввод кода подтверждения",
        "OTP ячейки",
        "смс-код"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "allowedSymbols",
          "type": "string | RegExp",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "autoFocus",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "caption",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "captionAlign",
          "type": "\"center\" | \"left\"",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "codeErrorBehavior",
          "type": "CodeErrorBehavior",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "codeLength",
          "type": "4 | 5 | 6",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hidden",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isError",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "itemErrorBehavior",
          "type": "ItemErrorBehavior",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "((value: string) => void)",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onFullCodeEnter",
          "type": "((code: string) => void)",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placeholder",
          "type": "string",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "setIsError",
          "type": "Dispatch<SetStateAction<boolean>>",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\"",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "width",
          "type": "Width<string | number>",
          "required": false,
          "inheritedFrom": "CodeInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { CodeInput } from '@daisforge/ui';",
      "minimalUsage": "<CodeInput />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Работа с OTP-кодом из СМС",
          "type": "vendor",
          "code": "Ваш код подтверждения: 123456.\n@plasma.sberdevices.ru #123456"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React from 'react';\nimport { CodeInput } from '@daisforge/ui';\nexport function App() {\n    return (\n        <CodeInput\n            caption=\"Введите код из СМС\"\n            captionAlign=\"center\"\n        />\n    );\n}"
        }
      ]
    },
    "Collapse": {
      "name": "Collapse",
      "group": "components",
      "folderName": "Collapse",
      "role": "primary",
      "description": "Сворачиваемый блок с анимацией высоты/ширины для скрытия контента",
      "props": [
        {
          "name": "animation",
          "type": "Property.TransitionTimingFunction | { open: Property.TransitionTimingFunction; close: Property.TransitionTimingFunction; } | undefined",
          "required": false,
          "description": "Тип анимации [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-timing-function)",
          "default": "'linear'"
        },
        {
          "name": "duration",
          "type": "number | undefined",
          "required": false,
          "description": "Длительность анимации в секундах",
          "default": "0.5"
        },
        {
          "name": "extContainerCss",
          "type": "CSSObject | undefined",
          "required": false,
          "description": "CSS стили внешнего контейнера"
        },
        {
          "name": "intContainerCss",
          "type": "{ always?: CSSObject | undefined; onOpen?: CSSObject | undefined; } | undefined",
          "required": false,
          "description": "CSS стили внутреннего контейнера. `always` - применение стилей в любом состоянии.\n`onOpen` - применение стилей в открытом состоянии."
        },
        {
          "name": "isOpen",
          "type": "boolean | undefined",
          "required": false,
          "description": "Состояние открытия/закрытия"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\" | undefined",
          "required": false,
          "description": "Ориентация анимации",
          "default": "'vertical'"
        },
        {
          "name": "sizeOnClose",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "Размер контейнера в закрытом состоянии",
          "default": "'0px'"
        },
        {
          "name": "sizeOnOpen",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "Размер контейнера в открытом состоянии"
        },
        {
          "name": "unMountOnClose",
          "type": "boolean | undefined",
          "required": false,
          "description": "Размонтирование элемента при закрытии"
        }
      ],
      "propsTypeName": "CollapseProps",
      "sourceFile": "packages/ui-kit/src/components/Collapse/Collapse.tsx",
      "type": "wrapper",
      "category": "Локальные компоненты",
      "keywords": [
        "сворачиваемый блок",
        "показать/скрыть",
        "аккордеон-анимация"
      ],
      "docs": "# Collapse\n\nКомпонент анимированного сворачивания/разворачивания контента. Поддерживает вертикальную и горизонтальную ориентацию, настраиваемую длительность и тип анимации.\n\n## Ключевые особенности\n\n- Анимация open/close с настраиваемой длительностью и easing\n- Вертикальная и горизонтальная ориентация\n- Возможность размонтирования контента при закрытии (`unMountOnClose`)\n- Настраиваемые размеры в открытом и закрытом состоянии\n- CSS-стили для внешнего и внутреннего контейнеров (`extContainerCss`, `intContainerCss`)\n\n## Особенности\n\n- Пропс `animation` может быть строкой (одинаковая анимация для open/close) или объектом `{ open, close }` для разных анимаций\n- Пропс `intContainerCss` принимает объект с ключами `always` (стили в любом состоянии) и `onOpen` (стили только при открытии)\n- По умолчанию контент остаётся в DOM при закрытии. Для размонтирования используйте `unMountOnClose`\n\n> Подробнее о типах и пропсах — [Collapse API](?path=/docs/локальные-компоненты-collapse-api--docs)",
      "apiDocs": "# Collapse API\n\n## CollapseProps\n\n```typescript\ntype CollapseProps = PropsWithChildren & {\n  /**\n   * Состояние открытия/закрытия\n   */\n  isOpen?: boolean;\n  /**\n   * Длительность анимации в секундах\n   */\n  duration?: number;\n  /**\n   * Тип анимации [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-timing-function)\n   */\n  animation?:\n    | Property.TransitionTimingFunction\n    | {\n        open: Property.TransitionTimingFunction;\n        close: Property.TransitionTimingFunction;\n      };\n  /**\n   * Размер контейнера в закрытом состоянии\n   */\n  sizeOnClose?: CSSProperties['width'];\n  /**\n   * Размер контейнера в открытом состоянии\n   */\n  sizeOnOpen?: CSSProperties['width'];\n  /**\n   * Размонтирование элемента при закрытии\n   */\n  unMountOnClose?: boolean;\n  /**\n   * Ориентация анимации\n   */\n  orientation?: 'vertical' | 'horizontal';\n  /**\n   * CSS стили внешнего контейнера\n   */\n  extContainerCss?: CSSObject;\n  /**\n   * CSS стили внутреннего контейнера. `always` - применение стилей в любом состоянии.\n   * `onOpen` - применение стилей в открытом состоянии.\n   */\n  intContainerCss?: { always?: CSSObject; onOpen?: CSSObject };\n};\n```",
      "curatedStories": [
        {
          "exportName": "Default",
          "displayName": "Collapse",
          "type": "full-code",
          "code": "const StoryRender: FC<CollapseProps> = (args) => {\n  const [isOpen, setIsOpen] = useState(false);\n  return (\n    <Box display=\"flex\" flexDirection=\"column\" gap={16}>\n      <Button onClick={() => setIsOpen((p) => !p)}>\n        {isOpen ? 'Закрыть' : 'Открыть'}\n      </Button>\n      <Collapse isOpen={isOpen} {...args}>\n        <Button onClick={() => setIsOpen((p) => !p)}>\n          {isOpen ? 'Закрыть' : 'Открыть'}\n        </Button>\n      </Collapse>\n    </Box>\n  );\n}"
        },
        {
          "exportName": "Horizontal",
          "displayName": "Горизонтальная ориентация",
          "type": "full-code",
          "code": "const StoryRender: FC<CollapseProps> = (args) => {\n  const [isOpen, setIsOpen] = useState(false);\n  return (\n    <Box display=\"flex\" flexDirection=\"column\" gap={16}>\n      <Button onClick={() => setIsOpen((p) => !p)}>\n        {isOpen ? 'Закрыть' : 'Открыть'}\n      </Button>\n      <Collapse isOpen={isOpen} {...args}>\n        <Button onClick={() => setIsOpen((p) => !p)}>\n          {isOpen ? 'Закрыть' : 'Открыть'}\n        </Button>\n      </Collapse>\n    </Box>\n  );\n}\n\n// Props:\n{\n    orientation: 'horizontal',\n  }"
        },
        {
          "exportName": "Unmount",
          "displayName": "Unmount",
          "type": "full-code",
          "code": "const StoryRender: FC<CollapseProps> = (args) => {\n  const [isOpen, setIsOpen] = useState(false);\n  return (\n    <Box display=\"flex\" flexDirection=\"column\" gap={16}>\n      <Button onClick={() => setIsOpen((p) => !p)}>\n        {isOpen ? 'Закрыть' : 'Открыть'}\n      </Button>\n      <Collapse isOpen={isOpen} {...args}>\n        <Button onClick={() => setIsOpen((p) => !p)}>\n          {isOpen ? 'Закрыть' : 'Открыть'}\n        </Button>\n      </Collapse>\n    </Box>\n  );\n}\n\n// Props:\n{\n    unMountOnClose: true,\n  }"
        },
        {
          "exportName": "Duration",
          "displayName": "Длительность анимации",
          "type": "full-code",
          "code": "const StoryRender: FC<CollapseProps> = (args) => {\n  const [isOpen, setIsOpen] = useState(false);\n  return (\n    <Box display=\"flex\" flexDirection=\"column\" gap={16}>\n      <Button onClick={() => setIsOpen((p) => !p)}>\n        {isOpen ? 'Закрыть' : 'Открыть'}\n      </Button>\n      <Collapse isOpen={isOpen} {...args}>\n        <Button onClick={() => setIsOpen((p) => !p)}>\n          {isOpen ? 'Закрыть' : 'Открыть'}\n        </Button>\n      </Collapse>\n    </Box>\n  );\n}\n\n// Props:\n{\n    duration: 5,\n  }"
        },
        {
          "exportName": "Animation",
          "displayName": "Тип анимации",
          "type": "full-code",
          "code": "const StoryRender: FC<CollapseProps> = (args) => {\n  const [isOpen, setIsOpen] = useState(false);\n  return (\n    <Box display=\"flex\" flexDirection=\"column\" gap={16}>\n      <Button onClick={() => setIsOpen((p) => !p)}>\n        {isOpen ? 'Закрыть' : 'Открыть'}\n      </Button>\n      <Collapse isOpen={isOpen} {...args}>\n        <Button onClick={() => setIsOpen((p) => !p)}>\n          {isOpen ? 'Закрыть' : 'Открыть'}\n        </Button>\n      </Collapse>\n    </Box>\n  );\n}\n\n// Props:\n{\n    animation: {\n      open: 'steps(3)',\n      close: 'cubic-bezier(.29, 1.01, 1, -0.68)',\n    },\n    duration: 2,\n  }"
        },
        {
          "exportName": "OpenedSize",
          "displayName": "Размер открытого контейнера",
          "type": "full-code",
          "code": "const StoryRender: FC<CollapseProps> = (args) => {\n  const [isOpen, setIsOpen] = useState(false);\n  return (\n    <Box display=\"flex\" flexDirection=\"column\" gap={16}>\n      <Button onClick={() => setIsOpen((p) => !p)}>\n        {isOpen ? 'Закрыть' : 'Открыть'}\n      </Button>\n      <Collapse isOpen={isOpen} {...args}>\n        <Button onClick={() => setIsOpen((p) => !p)}>\n          {isOpen ? 'Закрыть' : 'Открыть'}\n        </Button>\n      </Collapse>\n    </Box>\n  );\n}\n\n// Props:\n{\n    sizeOnOpen: 20,\n  }"
        },
        {
          "exportName": "ClosedSize",
          "displayName": "Размер закрытого контейнера",
          "type": "full-code",
          "code": "const StoryRender: FC<CollapseProps> = (args) => {\n  const [isOpen, setIsOpen] = useState(false);\n  return (\n    <Box display=\"flex\" flexDirection=\"column\" gap={16}>\n      <Button onClick={() => setIsOpen((p) => !p)}>\n        {isOpen ? 'Закрыть' : 'Открыть'}\n      </Button>\n      <Collapse isOpen={isOpen} {...args}>\n        <Button onClick={() => setIsOpen((p) => !p)}>\n          {isOpen ? 'Закрыть' : 'Открыть'}\n        </Button>\n      </Collapse>\n    </Box>\n  );\n}\n\n// Props:\n{\n    sizeOnClose: 20,\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Collapse } from '@daisforge/ui';",
      "minimalUsage": "<Collapse />",
      "examples": [
        {
          "exportName": "Default",
          "displayName": "Collapse",
          "type": "full-code",
          "code": "const StoryRender: FC<CollapseProps> = (args) => {\n  const [isOpen, setIsOpen] = useState(false);\n  return (\n    <Box display=\"flex\" flexDirection=\"column\" gap={16}>\n      <Button onClick={() => setIsOpen((p) => !p)}>\n        {isOpen ? 'Закрыть' : 'Открыть'}\n      </Button>\n      <Collapse isOpen={isOpen} {...args}>\n        <Button onClick={() => setIsOpen((p) => !p)}>\n          {isOpen ? 'Закрыть' : 'Открыть'}\n        </Button>\n      </Collapse>\n    </Box>\n  );\n}"
        },
        {
          "exportName": "Horizontal",
          "displayName": "Горизонтальная ориентация",
          "type": "full-code",
          "code": "const StoryRender: FC<CollapseProps> = (args) => {\n  const [isOpen, setIsOpen] = useState(false);\n  return (\n    <Box display=\"flex\" flexDirection=\"column\" gap={16}>\n      <Button onClick={() => setIsOpen((p) => !p)}>\n        {isOpen ? 'Закрыть' : 'Открыть'}\n      </Button>\n      <Collapse isOpen={isOpen} {...args}>\n        <Button onClick={() => setIsOpen((p) => !p)}>\n          {isOpen ? 'Закрыть' : 'Открыть'}\n        </Button>\n      </Collapse>\n    </Box>\n  );\n}\n\n// Props:\n{\n    orientation: 'horizontal',\n  }"
        },
        {
          "exportName": "Unmount",
          "displayName": "Unmount",
          "type": "full-code",
          "code": "const StoryRender: FC<CollapseProps> = (args) => {\n  const [isOpen, setIsOpen] = useState(false);\n  return (\n    <Box display=\"flex\" flexDirection=\"column\" gap={16}>\n      <Button onClick={() => setIsOpen((p) => !p)}>\n        {isOpen ? 'Закрыть' : 'Открыть'}\n      </Button>\n      <Collapse isOpen={isOpen} {...args}>\n        <Button onClick={() => setIsOpen((p) => !p)}>\n          {isOpen ? 'Закрыть' : 'Открыть'}\n        </Button>\n      </Collapse>\n    </Box>\n  );\n}\n\n// Props:\n{\n    unMountOnClose: true,\n  }"
        },
        {
          "exportName": "Duration",
          "displayName": "Длительность анимации",
          "type": "full-code",
          "code": "const StoryRender: FC<CollapseProps> = (args) => {\n  const [isOpen, setIsOpen] = useState(false);\n  return (\n    <Box display=\"flex\" flexDirection=\"column\" gap={16}>\n      <Button onClick={() => setIsOpen((p) => !p)}>\n        {isOpen ? 'Закрыть' : 'Открыть'}\n      </Button>\n      <Collapse isOpen={isOpen} {...args}>\n        <Button onClick={() => setIsOpen((p) => !p)}>\n          {isOpen ? 'Закрыть' : 'Открыть'}\n        </Button>\n      </Collapse>\n    </Box>\n  );\n}\n\n// Props:\n{\n    duration: 5,\n  }"
        }
      ]
    },
    "Combobox": {
      "name": "Combobox",
      "group": "components",
      "folderName": "Combobox",
      "role": "primary",
      "description": "Выпадающий список с поиском и мультивыбором значений в виде чипов",
      "props": [
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "React.HTMLInputTypeAttribute | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComboboxProps",
      "rawType": "export type Props<T extends ComboboxItemOption> = DistributiveOmit<ComboboxProps<T>, PropsFromConfig> & DistributivePick<ComponentProps<typeof ComboboxDefault>, PropsFromConfig> & {\n    appearance?: 'default' | 'viewMode';\n};",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/components/Combobox/Combobox.tsx",
      "type": "wrapper",
      "atomicBase": "Combobox",
      "formVariant": "FormCombobox",
      "category": "Локальные компоненты",
      "keywords": [
        "автокомплит",
        "мультиselect",
        "поиск по списку"
      ],
      "chooseWhen": "Вне react-hook-form — самостоятельный компонент с value/onChange для мультивыбора с поиском.",
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "items",
          "type": "T[]",
          "required": true,
          "description": "Список элементов.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "afterList",
          "type": "ReactNode",
          "required": false,
          "description": "Ячейка для контента в конце выпадающего списка.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "alwaysOpened",
          "type": "boolean",
          "required": false,
          "description": "Дропдаун открыт всегда.",
          "default": "false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "arrowPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Сторона расположения стрелки скрытия/раскрытия.",
          "default": "left",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "beforeList",
          "type": "ReactNode",
          "required": false,
          "description": "Ячейка для контента в начале выпадающего списка.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeAfterSelect",
          "type": "boolean",
          "required": false,
          "description": "Закрывать ли выпадающий список после выбора элемента.",
          "default": "если single, то true; если multiple, то false; если передан alwaysOpened, то false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента слева.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента справа.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "emptyStateDescription",
          "type": "ReactNode",
          "required": false,
          "description": "Текст для состояния когда нет результата.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "filter",
          "type": "((item: T, textValue: string) => boolean)",
          "required": false,
          "description": "Функция фильтрации элементов.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "filterValue",
          "type": "((value: string) => boolean)",
          "required": false,
          "description": "Функция валидации вводимых значений.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "flip",
          "type": "boolean",
          "required": false,
          "description": "Коррекция placement, если выпадающий список находится за пределами экрана.",
          "default": "false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "helperText",
          "type": "string",
          "required": false,
          "description": "Вспомогательный текст снизу слева для поля ввода.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintContentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean",
          "required": false,
          "description": "Видимость стрелки (хвоста).",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOffset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "description": "Направление раскрытия тултипа.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPortal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "Портал для окна подсказки. Принимает id контейнера или ref.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetIcon",
          "type": "ReactNode",
          "required": false,
          "description": "Иконка, рядом с которым произойдет вызов всплывающего окна.\nЕсли свойство не задано, применится иконка по умолчанию.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение иконки подсказки, когда отсутствует label\nили же он имеет labelPlacement='inner'.",
          "default": "`outer`",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintText",
          "type": "string",
          "required": false,
          "description": "Текст тултипа",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\"",
          "required": false,
          "description": "Способ открытия тултипа - наведение или клик мышью",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintWidth",
          "type": "string",
          "required": false,
          "description": "Ширина окна (в rem).",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение лейбла.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "listMaxHeight",
          "type": "Height<string | number>",
          "required": false,
          "description": "Максимальная высота выпадающего списка.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "listWidth",
          "type": "Width<string | number>",
          "required": false,
          "description": "Значение css width для выпадающего списка.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "mode",
          "type": "\"radio\" | \"default\"",
          "required": false,
          "description": "Режим работы взаимодействия с элементами.\n- default: элемент можно выбрать и можно отменить его выбор.\n- radio: если элемент выбран, то отменить его выбор нельзя. Только для single-режима.",
          "default": "default",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeValue",
          "type": "((value: string) => void)",
          "required": false,
          "description": "Обработчик изменения значения в строке поиска.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onScroll",
          "type": "((e: UIEvent<HTMLElement, UIEvent>) => void)",
          "required": false,
          "description": "Коллбэк, срабатывающий при скролле.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean) => void)",
          "required": false,
          "description": "Событие сворачивания/разворачивания выпадающего списка.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optional",
          "type": "boolean",
          "required": false,
          "description": "Флаг необязательности поля",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optionalText",
          "type": "string",
          "required": false,
          "description": "Подпись для указания необязательности поля",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "Placement",
          "required": false,
          "description": "Сторона открытия дропдауна относительно target элемента.",
          "default": "bottom-start",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "portal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "Портал для выпадающего списка. Принимает id контейнера или ref.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderItem",
          "type": "((item: T) => ReactNode)",
          "required": false,
          "description": "Callback для кастомной настройки элемента в выпадающем списке.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderSelectionIcon",
          "type": "((selected: boolean | \"indeterminate\") => ReactNode)",
          "required": false,
          "description": "Callback для кастомной настройки иконки выбранного элемента.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "requiredPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shift",
          "type": "boolean",
          "required": false,
          "description": "Смещение выпадающего списка при соприкосновении с границами экрана.",
          "default": "false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "singleLine",
          "type": "boolean",
          "required": false,
          "description": "Label в элементе выпадающего списка в одну строку или с переносом строк.",
          "default": "true",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textAfter",
          "type": "string",
          "required": false,
          "description": "Слот для вспомогательного текста слева.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textBefore",
          "type": "string",
          "required": false,
          "description": "Слот для вспомогательного текста справа.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "treeView",
          "type": "boolean",
          "required": false,
          "description": "Режим отображения выпадающего списка в виде дерева.",
          "default": "false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "variant",
          "type": "\"normal\" | \"tight\"",
          "required": false,
          "description": "Вариант: обычный или сжатый",
          "default": "normal",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "virtual",
          "type": "boolean",
          "required": false,
          "description": "Виртуализация в выпадающем списке.\nНе поддерживается в многоуровневых списках.",
          "default": "false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "ZIndex",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего списка.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "_offset",
          "type": "[number, number]",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"viewMode\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipClickArea",
          "type": "\"full\" | \"close-icon\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"accent\" | \"secondary\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultValue",
          "type": "string | string[]",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintView",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isTargetAmount",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "multiple",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "ChangeEventHandler<HTMLSelectElement> | ((value: string, item: T | null) => void) | ((value: string[], item: T | null) => void)",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placeholder",
          "type": "string",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderValue",
          "type": "((item: T) => string)",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "required",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "selectAllOptions",
          "type": "SelectAllProps",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "targetAmount",
          "type": "number",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | string[]",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Combobox } from '@daisforge/ui';",
      "minimalUsage": "<Combobox items={[]} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FiltersActions.stories.tsx",
          "type": "usage",
          "code": "<Combobox\n                    size=\"s\"\n                    multiple\n                    isTargetAmount\n                    placeholder=\"Блок\"\n                    value={blocks}\n                    onChange={setBlocks}\n                    items={blocksOptions}\n                    listMaxHeight=\"350px\"\n                    portal={popoverRef}\n                    zIndex=\"9001\"\n                  />",
          "sourceFile": "packages/storybook/src/stories/FiltersActions/FiltersActions.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvas.filtering.stories.tsx",
          "type": "usage",
          "code": "<Combobox\n                        multiple\n                        size=\"s\"\n                        items={sidebarIssueTypeOptions}\n                        value={draftValue}\n                        onChange={(next: string[]) => setDraftValue(next)}\n                        closeAfterSelect={false}\n                        placeholder=\"Выберите Issue Type\"\n                        afterList={\n                          <Box $css=\"display: grid; gap: 4px; margin-top: 4px;\">\n                            <Divider />\n                            <Button\n                              size=\"xs\"\n                              view=\"accent\"\n                              style={{ marginLeft: 'auto' }}\n                              onClick={() =>\n                                setFilters((prev) => ({\n                                  ...prev,\n                                  issueTypeCustom: draftValue,\n                                }))\n                              }\n                            >\n                              Применить\n                            </Button>\n                          </Box>\n                        }\n                      />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Filtering/TableCanvas.filtering.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Appearance Appearance appearance=\"viewMode\"  — режим просмотра.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Combobox } from '@daisforge/ui';\nexport function App() {\n    const items = [\n        { value: 'option_1', label: 'Опция 1' },\n        { value: 'option_2', label: 'Опция 2' },\n    ];\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '20px', maxWidth: '350px', height: '200px' }}>\n            <Combobox items={items} appearance=\"default\" label=\"Default\" placeholder=\"Placeholder\" />\n            <Combobox items={items} appearance=\"viewMode\" value=\"option_1\" readOnly label=\"ViewMode\" placeholder=\"Placeholder\" />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Использование Использование Обязательным параметром является только  items . Внутри items может быть такой же вложенный массив items. Формат следующий",
          "type": "vendor",
          "code": "type Items = Array<{\n    /**\n     * Значение у item.\n     */\n    value: string;\n    /**\n     * Метка-подпись к item.\n     */\n    label: string;\n    /**\n     * Сторона открытия вложенного дропдауна относительно текущего элемента.\n     * @default bottom-start\n     */\n    placement?: Placement;\n    /**\n     * Список дочерних items.\n     */\n    items?: Array<ItemOption>;\n    /**\n     * Item не активен.\n     */\n    disabled?: boolean;\n    /**\n     * Слот для контента слева.\n     */\n    contentLeft?: ReactNode;\n    /**\n     * Слот для контента справа.\n     */\n    contentRight?: ReactNode;\n    /**\n     * Classname для item.\n     */\n    className?: string;\n    /**\n     * Максимальная высота дочернего выпадающего списка.\n     */\n    listMaxHeight?: CSSProperties['height'];\n}>;"
        }
      ]
    },
    "Counter": {
      "name": "Counter",
      "group": "components",
      "folderName": "Counter",
      "role": "primary",
      "description": "Числовой бейдж для отображения количества (например, уведомлений)",
      "props": [],
      "propsTypeName": "CounterProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Counter/Counter.d.ts",
      "type": "wrapper",
      "atomicBase": "Counter",
      "category": "Локальные компоненты",
      "keywords": [
        "бейдж числа",
        "счётчик уведомлений",
        "badge"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "count",
          "type": "number",
          "required": true,
          "description": "Отображаемое число. Не может быть меньше 1.",
          "inheritedFrom": "Counter",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maxCount",
          "type": "number",
          "required": false,
          "description": "Максимальное отображаемое число. Не может быть меньше 1.",
          "inheritedFrom": "Counter",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\" | \"xs\" | \"xxs\"",
          "required": false,
          "description": "Размер Counter",
          "default": "xs",
          "inheritedFrom": "Counter",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"light\"",
          "required": false,
          "description": "Вид Counter",
          "default": "default",
          "inheritedFrom": "Counter",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Counter } from '@daisforge/ui';",
      "minimalUsage": "<Counter count={0} />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в Widget.stories.tsx",
          "type": "usage",
          "code": "<Counter count={5} view=\"accent\" size=\"xs\" />",
          "sourceFile": "packages/storybook/src/stories/Widget/Widget.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Размер числового badge",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Counter } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Counter count={10} size=\"xs\" />\n            <Counter count={10} size=\"xxs\" />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Максимальное значение числового badge",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Counter } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Counter count={10} maxCount={9} />\n            <Counter count={100} maxCount={99} />\n        </div>\n    );\n}"
        }
      ]
    },
    "DatePicker": {
      "name": "DatePicker",
      "group": "components",
      "folderName": "DatePicker",
      "role": "primary",
      "description": "Поле выбора одной даты со встроенным календарём и иконкой",
      "props": [
        {
          "name": "onChangeVisibleDate",
          "type": "((date: Date) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
        }
      ],
      "propsTypeName": "DatePickerProps",
      "sourceFile": "packages/ui-kit/src/components/DatePicker/DatePicker.tsx",
      "type": "wrapper",
      "atomicBase": "DatePicker",
      "formVariant": "FormDatePicker",
      "category": "Локальные компоненты",
      "keywords": [
        "выбор даты",
        "календарь",
        "date input"
      ],
      "chooseWhen": "Вне react-hook-form — самостоятельный выбор даты с value/onChange.",
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "appearance",
          "type": "\"default\" | \"viewMode\"",
          "required": false,
          "description": "Вид компонента",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "calendarContainerHeight",
          "type": "string | number",
          "required": false,
          "description": "Высота календаря",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "calendarContainerWidth",
          "type": "string | number",
          "required": false,
          "description": "Ширина календаря",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeAfterDateSelect",
          "type": "boolean",
          "required": false,
          "description": "Закрыть календарь после выбора дат",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnEsc",
          "type": "boolean",
          "required": false,
          "description": "Закрывать календарь при нажатии Escape.",
          "default": "true",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean",
          "required": false,
          "description": "Закрывать календарь при нажатии вне области элемента.",
          "default": "true",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента слева.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента справа.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dateShortcuts",
          "type": "DateShortcutItem[]",
          "required": false,
          "description": "Список предустановленных дат,\nкоторые можно выбрать в выпадающем календаре",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dateShortcutsPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Положение списка предустановленных дат",
          "default": "'left'",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dateShortcutsWidth",
          "type": "Width<string | number>",
          "required": false,
          "description": "Ширина списка предустановленных дат",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultDate",
          "type": "Date",
          "required": false,
          "description": "Выбранное значение по умолчанию.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabledList",
          "type": "DisabledDay[]",
          "required": false,
          "description": "Список отключенных дней.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabledMonthList",
          "type": "DisabledDay[]",
          "required": false,
          "description": "Список отключенных месяцев.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabledQuarterList",
          "type": "DisabledDay[]",
          "required": false,
          "description": "Список отключенных кварталов.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabledYearList",
          "type": "DisabledDay[]",
          "required": false,
          "description": "Список отключенных годов.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disableFlip",
          "type": "boolean",
          "required": false,
          "description": "Отключить автоматическое переворачивание дропдауна при нехватке места",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventList",
          "type": "EventDay[]",
          "required": false,
          "description": "Список событий.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventMonthList",
          "type": "EventDay[]",
          "required": false,
          "description": "Список событий по месяцам.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventQuarterList",
          "type": "EventDay[]",
          "required": false,
          "description": "Список событий по кварталам.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventTooltipOptions",
          "type": "EventTooltipOptions",
          "required": false,
          "description": "Свойства всплывающей подсказки для событий.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventYearList",
          "type": "EventDay[]",
          "required": false,
          "description": "Список событий по годам.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "format",
          "type": "string",
          "required": false,
          "description": "Формат даты.",
          "default": "`DD.MM.YYYY`",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "frame",
          "type": "string | RefObject<HTMLElement>",
          "required": false,
          "description": "В каком контейнере позиционируется(по умолчанию document), можно также указать id элемента или ref для него.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasClearDivider",
          "type": "boolean",
          "required": false,
          "description": "Флаг наличия разделителя для clear appearance",
          "default": "false",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintContentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean",
          "required": false,
          "description": "Видимость стрелки (хвоста).",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOffset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "description": "Направление раскрытия тултипа.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPortal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "Портал для окна подсказки. Принимает id контейнера или ref.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "description": "Размер тултипа",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetIcon",
          "type": "ReactNode",
          "required": false,
          "description": "Иконка, рядом с которым произойдет вызов всплывающего окна.\nЕсли свойство не задано, применится иконка по умолчанию.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение иконки подсказки, когда отсутствует label\nили же он имеет labelPlacement='inner'.",
          "default": "`outer`",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintText",
          "type": "string",
          "required": false,
          "description": "Текст тултипа",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\"",
          "required": false,
          "description": "Способ открытия тултипа - наведение или клик мышью",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintView",
          "type": "\"default\"",
          "required": false,
          "description": "Вид тултипа",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintWidth",
          "type": "string",
          "required": false,
          "description": "Ширина окна (в rem).",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "includeEdgeDates",
          "type": "boolean",
          "required": false,
          "description": "Должны ли значения минимального и максимального дня включаться в диапазон.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "required": false,
          "description": "Видимость календаря.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "string",
          "required": false,
          "description": "Расположение лейбла.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "lang",
          "type": "\"ru\" | \"en\"",
          "required": false,
          "description": "Язык в маске ввода",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "leftHelper",
          "type": "string",
          "required": false,
          "description": "Вспомогательный текст снизу слева для поля ввода.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maskWithFormat",
          "type": "boolean",
          "required": false,
          "description": "Формат применяется в качестве маски ввода.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "max",
          "type": "Date",
          "required": false,
          "description": "Максимальное значение даты.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "min",
          "type": "Date",
          "required": false,
          "description": "Минимальное значение даты.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ календаря относительно поля ввода.",
          "default": "[0, 0]",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "(((event: { target: { value?: string; name?: string; originalDate?: DateType; isoDate?: string | undefined; }; }) => void) & FormEventHandler<HTMLDivElement>) | undefined",
          "required": false,
          "description": "Свойство устарело, используется формой. Вместо используйте onChangeValue и onCommitDate",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeValue",
          "type": "((event: SyntheticEvent<HTMLInputElement, Event> | null, value?: string, originalDate?: DateType, isoDate?: string) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения значения.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onCommitDate",
          "type": "OnCommitDateCallback",
          "required": false,
          "description": "Callback по нажатию Enter в поле ввода или выборе дня на календаре.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean, event?: Event | SyntheticEvent<Element, Event>) => void)",
          "required": false,
          "description": "Событие сворачивания/разворачивания календаря.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": false,
          "description": "Видимость календаря.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "DatePickerPlacement | DatePickerPlacementBasic[]",
          "required": false,
          "description": "Сторона открытия календаря относительно поля ввода.",
          "default": "[\"bottom\", \"top\"]",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "preserveInvalidOnBlur",
          "type": "boolean",
          "required": false,
          "description": "Сохранять невалидное значение после блюра поля ввода",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderFromDate",
          "type": "Date",
          "required": false,
          "description": "Дата с которой начинается календарная сетка.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "requiredPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "description": "Размер контрола.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretched",
          "type": "boolean",
          "required": false,
          "description": "Растянуть поле ввода на всю доступную ширину, а календарь — на всю доступную ширину и высоту",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textAfter",
          "type": "string",
          "required": false,
          "description": "Слот для вспомогательного текста слева.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textBefore",
          "type": "string",
          "required": false,
          "description": "Слот для вспомогательного текста справа.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "titleCaption",
          "type": "ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу справа.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "type",
          "type": "\"Days\" | \"Months\" | \"Years\" | \"Quarters\"",
          "required": false,
          "description": "Тип отображения календаря: дни, месяца, года.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "usePortal",
          "type": "boolean",
          "required": false,
          "description": "Находится ли в портале.",
          "default": "false",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | Date | null",
          "required": false,
          "description": "Выбранное значение.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "valueEdited",
          "type": "boolean",
          "required": false,
          "description": "Отредактированное значение даты",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "valueError",
          "type": "boolean",
          "required": false,
          "description": "Некорректное значение даты",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "valueSuccess",
          "type": "boolean",
          "required": false,
          "description": "Корректное значение даты",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "description": "Вид контрола.",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "string",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего календаря",
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "autoComplete",
          "type": "string",
          "required": false,
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventTooltipSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "name",
          "type": "string",
          "required": false,
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placeholder",
          "type": "string",
          "required": false,
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "required",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "DatePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { DatePicker } from '@daisforge/ui';",
      "minimalUsage": "<DatePicker />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в Table.filtering.stories.tsx",
          "type": "usage",
          "code": "<DatePicker\n                      value={filters?.['date']}\n                      onCommitDate={(v) => {\n                        if (setFilters && !(v instanceof Date))\n                          setFilters((prev) => ({\n                            ...prev,\n                            date: v,\n                          }));\n                      }}\n                      size=\"s\"\n                      style={{\n                        width: '100%',\n                      }}\n                    />",
          "sourceFile": "packages/storybook/src/stories/Table/Table.filtering/Table.filtering.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Всплывающая подсказка для событий календаря",
          "type": "vendor",
          "code": "type EventDay {\n        date: Date;\n        color?: string;\n        eventInfo?: ReactNode;\n    }"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Независимый выбор дат",
          "type": "vendor",
          "code": "import React from 'react';\nimport { DatePickerRange } from '@daisforge/ui';\nexport function App() {\n    return (\n        <DatePickerRange\n            label=\"Независимый выбор\"\n            leftHelper=\"Попробуйте заполнить второй инпут раньше первого\"\n            format=\"DD.MM.YYYY\"\n            lang=\"ru\"\n            placement=\"bottom\"\n            usePortal\n        />\n    );\n}"
        }
      ]
    },
    "DatePickerRange": {
      "name": "DatePickerRange",
      "group": "components",
      "folderName": "DatePicker",
      "role": "primary",
      "description": "Выбор диапазона дат (от-до) с ярлыками-шорткатами и двойным календарём",
      "props": [
        {
          "name": "dateShortcuts",
          "type": "DateShortcutItem[] | undefined",
          "required": false,
          "description": "Список предустановленных дат,\nкоторые можно выбрать в выпадающем календаре"
        },
        {
          "name": "defaultFirstDate",
          "type": "Date | undefined",
          "required": false,
          "description": "Значение по умолчанию для первого поля."
        },
        {
          "name": "defaultSecondDate",
          "type": "Date | undefined",
          "required": false,
          "description": "Значение по умолчанию для второго поля."
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false"
        },
        {
          "name": "isCalendarPositionedByInput",
          "type": "boolean | undefined",
          "required": false,
          "description": "Позиционировать одиночный календарь относительно активного поля ввода",
          "default": "false"
        },
        {
          "name": "isDoubleCalendar",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отобразить двойной календарь"
        },
        {
          "name": "onChangeFirstValue",
          "type": "ChangeInstanceCallback | undefined",
          "required": false,
          "description": "Коллбэк, вызываемый при изменении первого поля ввода"
        },
        {
          "name": "onChangeSecondValue",
          "type": "ChangeInstanceCallback | undefined",
          "required": false,
          "description": "Коллбэк, вызываемый при изменении второго поля ввода"
        },
        {
          "name": "onCommitFirstDate",
          "type": "CommitInstanceCallback | undefined",
          "required": false,
          "description": "Callback по нажатию Enter в поле ввода или выборе дня на календаре для первой даты."
        },
        {
          "name": "onCommitSecondDate",
          "type": "CommitInstanceCallback | undefined",
          "required": false,
          "description": "Callback по нажатию Enter в поле ввода или выборе дня на календаре для второй даты."
        },
        {
          "name": "placement",
          "type": "DatePickerRangePlacement | DatePickerRangePlacementBasic[] | undefined",
          "required": false,
          "description": "Сторона открытия календаря относительно поля ввода.",
          "default": "[\"bottom\", \"top\"]"
        },
        {
          "name": "preserveInvalidOnBlur",
          "type": "boolean | undefined",
          "required": false,
          "description": "Сохранять невалидное значение после блюра полей ввода"
        },
        {
          "name": "requiredPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right"
        },
        {
          "name": "value",
          "type": "[string | DateType, string | DateType] | undefined",
          "required": false,
          "description": "Выбранные значения."
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"clear\" | undefined",
          "required": false,
          "description": "Вид компонента\nСтиль для UI конфигурации\nВлияет на выбор предустановленого набора токенов"
        },
        {
          "name": "calendarContainerHeight",
          "type": "string | number | undefined",
          "required": false,
          "description": "Высота календаря"
        },
        {
          "name": "calendarContainerWidth",
          "type": "string | number | undefined",
          "required": false,
          "description": "Ширина календаря"
        },
        {
          "name": "closeAfterDateSelect",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрыть календарь после выбора дат"
        },
        {
          "name": "closeOnEsc",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрывать календарь при нажатии Escape.",
          "default": "true"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрывать календарь при нажатии вне области элемента.",
          "default": "true"
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для контента слева"
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для контента справа"
        },
        {
          "name": "dateShortcutsPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Положение списка предустановленных дат",
          "default": "'left'"
        },
        {
          "name": "dateShortcutsWidth",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "Ширина списка предустановленных дат"
        },
        {
          "name": "disabledList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных дней."
        },
        {
          "name": "disabledMonthList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных месяцев."
        },
        {
          "name": "disabledQuarterList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных кварталов."
        },
        {
          "name": "disabledYearList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных годов."
        },
        {
          "name": "disableFlip",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отключить автоматическое переворачивание дропдауна при нехватке места"
        },
        {
          "name": "eventList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий."
        },
        {
          "name": "eventMonthList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по месяцам."
        },
        {
          "name": "eventQuarterList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по кварталам."
        },
        {
          "name": "eventTooltipOptions",
          "type": "EventTooltipOptions | undefined",
          "required": false,
          "description": "Свойства всплывающей подсказки для событий."
        },
        {
          "name": "eventYearList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по годам."
        },
        {
          "name": "firstPlaceholder",
          "type": "string | undefined",
          "required": false,
          "description": "Значение первого поля ввода"
        },
        {
          "name": "firstTextfieldContentLeft",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": "Слот для контента слева для первого поля ввода"
        },
        {
          "name": "firstTextfieldContentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": "Слот для контента справа для второго поля ввода"
        },
        {
          "name": "firstTextfieldTextAfter",
          "type": "string | undefined",
          "required": false,
          "description": "Слот для вспомогательного текста справа для первого поля ввода"
        },
        {
          "name": "firstValueEdited",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отредактированное значение первого поля ввода"
        },
        {
          "name": "firstValueError",
          "type": "boolean | undefined",
          "required": false,
          "description": "Некорректное значение первого поля ввода"
        },
        {
          "name": "firstValueSuccess",
          "type": "boolean | undefined",
          "required": false,
          "description": "Корректное значение первого поля ввода"
        },
        {
          "name": "format",
          "type": "string | undefined",
          "required": false,
          "description": "Формат даты.",
          "default": "`DD.MM.YYYY`"
        },
        {
          "name": "frame",
          "type": "string | React.RefObject<HTMLElement> | undefined",
          "required": false,
          "description": "В каком контейнере позиционируется(по умолчанию document), можно также указать id элемента или ref для него."
        },
        {
          "name": "hasClearDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг наличия разделителя для clear appearance\nОтображение разделителя для `appearance='clear'`",
          "default": "false"
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`."
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": "Видимость стрелки (хвоста)."
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": "Направление раскрытия тултипа."
        },
        {
          "name": "hintSize",
          "type": "string | undefined",
          "required": false,
          "description": "Размер тултипа"
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": "Иконка, рядом с которым произойдет вызов всплывающего окна.\nЕсли свойство не задано, применится иконка по умолчанию."
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": "Расположение иконки подсказки, когда отсутствует label\nили же он имеет labelPlacement='inner'.",
          "default": "`outer`"
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": "Текст тултипа"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": "Способ открытия тултипа - наведение или клик мышью"
        },
        {
          "name": "hintView",
          "type": "string | undefined",
          "required": false,
          "description": "Вид тултипа"
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": "Ширина окна (в rem)."
        },
        {
          "name": "includeEdgeDates",
          "type": "boolean | undefined",
          "required": false,
          "description": "Должны ли значения минимального и максимального дня включаться в диапазон."
        },
        {
          "name": "inputWrapperRef",
          "type": "React.Ref<HTMLDivElement> | undefined",
          "required": false,
          "description": "Ссылка на обертку полей ввода"
        },
        {
          "name": "lang",
          "type": "\"ru\" | \"en\" | undefined",
          "required": false,
          "description": "Язык в маске ввода"
        },
        {
          "name": "leftHelper",
          "type": "string | undefined",
          "required": false,
          "description": "Вспомогательный текст снизу слева для поля ввода."
        },
        {
          "name": "maskWithFormat",
          "type": "boolean | undefined",
          "required": false,
          "description": "Формат применяется в качестве маски ввода."
        },
        {
          "name": "max",
          "type": "Date | undefined",
          "required": false,
          "description": "Максимальное значение даты."
        },
        {
          "name": "min",
          "type": "Date | undefined",
          "required": false,
          "description": "Минимальное значение даты."
        },
        {
          "name": "offset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": "Отступ календаря относительно поля ввода.",
          "default": "[0, 0]"
        },
        {
          "name": "onBlurFirstTextfield",
          "type": "((event: React.FocusEvent<HTMLInputElement, Element>) => void) | undefined",
          "required": false,
          "description": "Коллбэк, вызываемый при потере фокуса первым полем ввода"
        },
        {
          "name": "onBlurSecondTextfield",
          "type": "((event: React.FocusEvent<HTMLInputElement, Element>) => void) | undefined",
          "required": false,
          "description": "Коллбэк, вызываемый при потере фокуса вторым полем ввода"
        },
        {
          "name": "onChangeVisibleDate",
          "type": "((date: Date) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
        },
        {
          "name": "onFocusFirstTextfield",
          "type": "((event: React.FocusEvent<HTMLInputElement, Element>) => void) | undefined",
          "required": false,
          "description": "Коллбэк, вызываемый при фокусе на первое поле ввода"
        },
        {
          "name": "onFocusSecondTextfield",
          "type": "((event: React.FocusEvent<HTMLInputElement, Element>) => void) | undefined",
          "required": false,
          "description": "Коллбэк, вызываемый при фокусе на второе поле ввода"
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean, event?: Event | React.SyntheticEvent<Element, Event> | undefined) => void) | undefined",
          "required": false,
          "description": "Событие сворачивания/разворачивания календаря."
        },
        {
          "name": "opened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Видимость календаря."
        },
        {
          "name": "renderFromDate",
          "type": "Date | undefined",
          "required": false,
          "description": "Дата с которой начинается календарная сетка."
        },
        {
          "name": "requiredIndicatorPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right"
        },
        {
          "name": "secondPlaceholder",
          "type": "string | undefined",
          "required": false,
          "description": "Значение второго поля ввода"
        },
        {
          "name": "secondTextfieldContentLeft",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": "Слот для контента слева для первого поля ввода"
        },
        {
          "name": "secondTextfieldContentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": "Слот для контента справа для второго поля ввода"
        },
        {
          "name": "secondTextfieldTextAfter",
          "type": "string | undefined",
          "required": false,
          "description": "Слот для вспомогательного текста справа для второго поля ввода"
        },
        {
          "name": "secondValueEdited",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отредактированное значение второго поля ввода"
        },
        {
          "name": "secondValueError",
          "type": "boolean | undefined",
          "required": false,
          "description": "Некорректное значение второго поля ввода"
        },
        {
          "name": "secondValueSuccess",
          "type": "boolean | undefined",
          "required": false,
          "description": "Корректное значение второго поля ввода"
        },
        {
          "name": "size",
          "type": "string | undefined",
          "required": false,
          "description": "Размер контрола.\nРазмер компонента"
        },
        {
          "name": "stretched",
          "type": "boolean | undefined",
          "required": false,
          "description": "Растянуть поле ввода на всю доступную ширину, а календарь — на всю доступную ширину и высоту"
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу справа"
        },
        {
          "name": "type",
          "type": "\"Days\" | \"Months\" | \"Years\" | \"Quarters\" | undefined",
          "required": false,
          "description": "Тип отображения календаря: дни, месяца, года."
        },
        {
          "name": "usePortal",
          "type": "boolean | undefined",
          "required": false,
          "description": "Находится ли в портале.",
          "default": "false"
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": "Вид контрола.\nВариант отображения"
        },
        {
          "name": "zIndex",
          "type": "string | undefined",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего календаря"
        },
        {
          "name": "dividerIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "dividerVariant",
          "type": "\"none\" | \"dash\" | \"icon\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "firstTextfieldTextBefore",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "secondTextfieldTextBefore",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChange",
          "type": "(((event: { target: { value?: string | undefined; name?: string | undefined; }; }) => void) & React.FormEventHandler<HTMLDivElement>) | undefined",
          "required": false,
          "description": "Свойство устарело, используется формой. Вместо используйте onCommitFirstDate и onCommitSecondDate",
          "deprecated": true
        },
        {
          "name": "isOpen",
          "type": "boolean | undefined",
          "required": false,
          "description": "Видимость календаря.",
          "deprecated": true
        }
      ],
      "propsTypeName": "DatePickerRangeProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/DatePicker/DatePicker.d.ts",
      "type": "wrapper",
      "atomicBase": "DatePickerRange",
      "formVariant": "FormDatePickerRange",
      "category": "Локальные компоненты",
      "keywords": [
        "диапазон дат",
        "date range",
        "период от и до"
      ],
      "chooseWhen": "Вне react-hook-form — самостоятельный выбор диапазона дат с value/onChange.",
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { DatePickerRange } from '@daisforge/ui';",
      "minimalUsage": "<DatePickerRange />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Независимый выбор дат",
          "type": "vendor",
          "code": "import React from 'react';\nimport { DatePickerRange } from '@daisforge/ui';\nexport function App() {\n    return (\n        <DatePickerRange\n            label=\"Независимый выбор\"\n            leftHelper=\"Попробуйте заполнить второй инпут раньше первого\"\n            format=\"DD.MM.YYYY\"\n            lang=\"ru\"\n            placement=\"bottom\"\n            usePortal\n        />\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Ограничение диапазона дат",
          "type": "vendor",
          "code": "import React from 'react';\nimport { DatePickerRange } from '@daisforge/ui';\nexport function App() {\n    const today = new Date();\n    const nextMonth = new Date(today.getFullYear(), today.getMonth() + 1, today.getDate());\n    return (\n        <DatePickerRange\n            label=\"С ограничением дат\"\n            leftHelper=\"Доступны даты от сегодня до следующего месяца включительно\"\n            format=\"DD.MM.YYYY\"\n            lang=\"ru\"\n            min={today}\n            max={nextMonth}\n            includeEdgeDates\n            placement=\"bottom\"\n            usePortal\n        />\n    );\n}"
        }
      ]
    },
    "DateTimePicker": {
      "name": "DateTimePicker",
      "group": "components",
      "folderName": "DateTimePicker",
      "role": "primary",
      "description": "Поле для ввода даты и времени одновременно в одном контроле",
      "props": [
        {
          "name": "onChangeVisibleDate",
          "type": "((date: Date) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
        },
        {
          "name": "hasTimeFormat",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChange",
          "type": "React.ChangeEventHandler<HTMLInputElement> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof DateTimePicker>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/DateTimePicker/DateTimePicker.d.ts",
      "type": "wrapper",
      "atomicBase": "DateTimePicker",
      "category": "Локальные компоненты",
      "keywords": [
        "выбор даты и времени",
        "datetime input",
        "дата время"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "calendarContainerHeight",
          "type": "string | number",
          "required": false,
          "description": "Высота календаря",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "calendarContainerWidth",
          "type": "string | number",
          "required": false,
          "description": "Ширина календаря",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnEsc",
          "type": "boolean",
          "required": false,
          "description": "Закрывать календарь при нажатии Escape.",
          "default": "true",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean",
          "required": false,
          "description": "Закрывать календарь при нажатии вне области элемента.",
          "default": "true",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента слева.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента справа.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dateShortcuts",
          "type": "DateShortcutItem[]",
          "required": false,
          "description": "Список предустановленных дат,\nкоторые можно выбрать в выпадающем календаре",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dateShortcutsPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Положение списка предустановленных дат",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dateShortcutsWidth",
          "type": "Width<string | number>",
          "required": false,
          "description": "Ширина списка предустановленных дат",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultDate",
          "type": "Date",
          "required": false,
          "description": "Выбранное значение по умолчанию.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabledList",
          "type": "DisabledDay[]",
          "required": false,
          "description": "Список отключенных дней.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabledMonthList",
          "type": "DisabledDay[]",
          "required": false,
          "description": "Список отключенных месяцев.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabledQuarterList",
          "type": "DisabledDay[]",
          "required": false,
          "description": "Список отключенных кварталов.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabledYearList",
          "type": "DisabledDay[]",
          "required": false,
          "description": "Список отключенных годов.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disableFlip",
          "type": "boolean",
          "required": false,
          "description": "Отключить автоматическое переворачивание дропдауна при нехватке места",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventList",
          "type": "EventDay[]",
          "required": false,
          "description": "Список событий.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventMonthList",
          "type": "EventDay[]",
          "required": false,
          "description": "Список событий по месяцам.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventQuarterList",
          "type": "EventDay[]",
          "required": false,
          "description": "Список событий по кварталам.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventTooltipOptions",
          "type": "EventTooltipOptions",
          "required": false,
          "description": "Свойства всплывающей подсказки для событий.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventYearList",
          "type": "EventDay[]",
          "required": false,
          "description": "Список событий по годам.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "frame",
          "type": "string | RefObject<HTMLElement>",
          "required": false,
          "description": "В каком контейнере позиционируется(по умолчанию document), можно также указать id элемента или ref для него.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "includeEdgeDates",
          "type": "boolean",
          "required": false,
          "description": "Должны ли значения минимального и максимального дня включаться в диапазон.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "string",
          "required": false,
          "description": "Расположение лейбла.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "lang",
          "type": "\"ru\" | \"en\"",
          "required": false,
          "description": "Язык в маске ввода",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "leftHelper",
          "type": "string",
          "required": false,
          "description": "Вспомогательный текст снизу слева для поля ввода.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "max",
          "type": "(Date & (string | number))",
          "required": false,
          "description": "Максимальное значение даты.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "min",
          "type": "(Date & (string | number))",
          "required": false,
          "description": "Минимальное значение даты.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ календаря относительно поля ввода.",
          "default": "[0, 0]",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean, event?: Event | SyntheticEvent<Element, Event>) => void)",
          "required": false,
          "description": "Событие сворачивания/разворачивания календаря.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": false,
          "description": "Видимость календаря.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "DatePickerPlacement | DatePickerPlacementBasic[]",
          "required": false,
          "description": "Сторона открытия календаря относительно поля ввода.",
          "default": "[\"bottom\", \"top\"]",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "preserveInvalidOnBlur",
          "type": "boolean",
          "required": false,
          "description": "Сохранять невалидное значение после блюра поля ввода",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderFromDate",
          "type": "Date",
          "required": false,
          "description": "Дата с которой начинается календарная сетка.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "requiredPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretched",
          "type": "boolean",
          "required": false,
          "description": "Растянуть поле ввода на всю доступную ширину, а календарь — на всю доступную ширину и высоту",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textAfter",
          "type": "string",
          "required": false,
          "description": "Слот для вспомогательного текста слева.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textBefore",
          "type": "string",
          "required": false,
          "description": "Слот для вспомогательного текста справа.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "titleCaption",
          "type": "ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу справа.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "type",
          "type": "\"Days\" | \"Months\" | \"Years\" | \"Quarters\"",
          "required": false,
          "description": "Тип отображения календаря: дни, месяца, года.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "usePortal",
          "type": "boolean",
          "required": false,
          "description": "Находится ли в портале.",
          "default": "false",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | Date | null",
          "required": false,
          "description": "Выбранное значение.",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "valueEdited",
          "type": "boolean",
          "required": false,
          "description": "Отредактированное значение даты",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "valueError",
          "type": "boolean",
          "required": false,
          "description": "Некорректное значение даты",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "valueSuccess",
          "type": "boolean",
          "required": false,
          "description": "Корректное значение даты",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "string",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего календаря",
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"clear\" | \"default\" | \"viewMode\"",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "autoComplete",
          "type": "string",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dateFormat",
          "type": "string",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dateOnTimeSelectOnly",
          "type": "Date",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dateTimeSeparator",
          "type": "string",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "eventTooltipSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasClearDivider",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintContentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOffset",
          "type": "[number, number]",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPortal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetIcon",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintText",
          "type": "string",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\"",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintView",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintWidth",
          "type": "string",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isDouble",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maskWithFormat",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "name",
          "type": "string",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeValue",
          "type": "((event: SyntheticEvent<HTMLInputElement, Event> | null, value?: string, formattedValues?: Omit<FormattedValues, \"quarterInfo\">) => void) | undefined",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onCommitDate",
          "type": "((value: string, formattedValues: FormattedValues) => void)",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onSearch",
          "type": "((event?: KeyboardEvent<HTMLInputElement>, value?: string) => void) | undefined",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placeholder",
          "type": "string",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "required",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "timeFormat",
          "type": "string",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "DateTimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { DateTimePicker } from '@daisforge/ui';",
      "minimalUsage": "<DateTimePicker />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Всплывающая подсказка для событий календаря",
          "type": "vendor",
          "code": "type EventDay {\n        date: Date;\n        color?: string;\n        eventInfo?: ReactNode;\n    }"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Подсказки Подсказки Для вывода подсказки снизу от поля используйте свойство  leftHelper ,",
          "type": "vendor",
          "code": "import React from 'react';\nimport { DateTimePicker } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <DateTimePicker\n                placeholder=\"Введите дату\"\n                leftHelper=\"Подсказка снизу\"\n                hintText=\"Подсказка в виде Tooltip\"\n                hintView=\"default\"\n                hintSize=\"m\"\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "Divider": {
      "name": "Divider",
      "group": "components",
      "folderName": "Divider",
      "role": "primary",
      "description": "Разделительная линия между блоками контента, гориз. или верт.",
      "props": [
        {
          "name": "length",
          "type": "string | number | undefined",
          "required": false,
          "description": "Размер разделителя",
          "default": "'100%'"
        },
        {
          "name": "orientation",
          "type": "string | undefined",
          "required": false,
          "description": "Направление разделителя",
          "default": "'horizontal'"
        },
        {
          "name": "size",
          "type": "string | undefined",
          "required": false,
          "description": "Размер разделителя",
          "default": "'m'"
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": "Вид разделителя",
          "default": "'default'"
        }
      ],
      "propsTypeName": "DividerProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Divider/Divider.d.ts",
      "type": "wrapper",
      "atomicBase": "Divider",
      "category": "Локальные компоненты",
      "keywords": [
        "разделитель блоков",
        "линия-сепаратор",
        "отступ между секциями"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { Divider } from '@daisforge/ui';",
      "minimalUsage": "<Divider />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в SplitView.stories.tsx",
          "type": "usage",
          "code": "<Divider orientation=\"vertical\" />",
          "sourceFile": "packages/storybook/src/stories/SplitView/SplitView.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в MessageBubble.tsx",
          "type": "usage",
          "code": "<Divider className=\"no-info-divider\" />",
          "sourceFile": "packages/storybook/src/stories/AiChatDAIS/components/MessageBubble.tsx"
        }
      ]
    },
    "Drawer": {
      "name": "Drawer",
      "group": "components",
      "folderName": "Drawer",
      "role": "primary",
      "description": "Базовая выезжающая боковая панель поверх контента страницы",
      "props": [
        {
          "name": "overlayProps",
          "type": "DrawerOverlayProps | undefined",
          "required": false,
          "description": "Настройки подложки.\nПо умолчанию `position` равен `fixed` для document и `absolute` для остальных frame."
        }
      ],
      "propsTypeName": "DrawerProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Drawer/Drawer.d.ts",
      "type": "wrapper",
      "atomicBase": "Drawer",
      "category": "Локальные компоненты",
      "keywords": [
        "боковая панель",
        "side panel",
        "выезжающая шторка"
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "DrawerContent",
        "DrawerFooter",
        "DrawerHeader"
      ],
      "inheritedProps": [
        {
          "name": "animationInfo",
          "type": "DrawerAnimationInfo",
          "required": false,
          "description": "Информация об анимации.\nСвойство может содержать поля `enter` и `exit`",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "asModal",
          "type": "boolean",
          "required": false,
          "description": "Поведение аналогичное Modal.",
          "default": "true",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "borderRadius",
          "type": "\"none\" | \"default\"",
          "required": false,
          "description": "Скругление компонента.",
          "default": "none",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnEsc",
          "type": "boolean",
          "required": false,
          "description": "Закрывать модальное окно при нажатии на ESC(по умолчанию true).",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean",
          "required": false,
          "description": "Закрывать модальное окно при нажатии вне области модального окна(по умолчанию true),",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customBackgroundColor",
          "type": "string",
          "required": false,
          "description": "Пользовательский цвет фона Panel.",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customContentBackgroundColor",
          "type": "string",
          "required": false,
          "description": "Пользовательский цвет фона контента Panel.",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focusAfterRef",
          "type": "RefObject<HTMLElement>",
          "required": false,
          "description": "Элемент для фокуса после закрытия модального окна\n(по умолчанию фокус на последнем перед открытием активном элементе).",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "frame",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "В каком контейнере позиционируется (по умолчанию document), можно также указать id элемента или ref для него.",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "initialFocusRef",
          "type": "RefObject<HTMLElement>",
          "required": false,
          "description": "Первый элемент для фокуса внутри модального окна.",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number] | [string, string]",
          "required": false,
          "description": "Смещение относительно текущей позиции.\n(x, y) - [number, number], [string, string].\nПри передаче number расчёт в rem.",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onClose",
          "type": "(() => void)",
          "required": false,
          "description": "Общий обработчик клика по кнопке \"закрыть\".",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onEscKeyDown",
          "type": "((event: KeyboardEvent) => void)",
          "required": false,
          "description": "Обработчик клика при нажатии на ESC(если не передан, то при нажатии используется onClose).",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onOverlayClick",
          "type": "((event: MouseEvent<HTMLDivElement, MouseEvent>) => void)",
          "required": false,
          "description": "Обработчик клика при нажатии вне области модального окна\n(если не передан, то при нажатии используется onClose).",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": false,
          "description": "Отображение Popup.",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "overlay",
          "type": "ReactNode",
          "required": false,
          "description": "Соседний элемент для окна в портале.",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "\"top\" | \"bottom\" | \"right\" | \"left\"",
          "required": false,
          "description": "Позиция на экране\ncenter - по умолчанию\nleft, right, top, bottom и их комбинации\nРасположение Drawer.",
          "default": "left",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "popupInfo",
          "type": "PopupInfo",
          "required": false,
          "description": "Дополнительная информация для программного взаимодействия с окном через контекст.",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "positionFixed",
          "type": "boolean",
          "required": false,
          "description": "Если `frame` отличается от `document` применяет `position='fixed'`",
          "default": "false",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"m\"",
          "required": false,
          "description": "Размер компонента.",
          "default": "m",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "description": "Вид компонента.",
          "default": "default",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withAnimation",
          "type": "boolean",
          "required": false,
          "description": "Использовать ли анимацию.",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withBlur",
          "type": "boolean",
          "required": false,
          "description": "Нужно ли применять blur для подложки.",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "string",
          "required": false,
          "description": "Значение z-index для Popup.",
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "children",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "height",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "width",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "Drawer",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Drawer } from '@daisforge/ui';",
      "minimalUsage": "<Drawer />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Перед использованием убедитесь, что  PopupProvider  подключен.",
          "type": "vendor",
          "code": "import ReactDOM from 'react-dom';\nimport { PopupProvider } from '@daisforge/ui';\nimport { App } from './App';\nReactDOM.render(\n    <PopupProvider>\n        <App />\n    </PopupProvider>,\n    document.getElementById('root')\n);"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Анимация Анимация Для работы с анимацией необходимо использовать свойство  animationInfo .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconDone } from '@salutejs/plasma-icons';\nimport { createGlobalStyle } from 'styled-components';\nimport { H3, Button, Drawer, DrawerHeader, DrawerContent, DrawerFooter, PopupProvider } from '@daisforge/ui';\nexport function App() {\n    const [isOpenA, setIsOpenA] = React.useState(false);\n    const [isOpenB, setIsOpenB] = React.useState(false);\n    const animationInfo = {\n        enter: 'enterAnimation 0.2s forwards',\n        exit: 'exitAnimation 0.2s forwards',\n    }\n    const GlobalAnimations = createGlobalStyle`\n        @keyframes enterAnimation {\n            from {\n                transform: translate(100%, -150%);\n                opacity: 0;\n            }\n            to {\n                transform: translate(0, -50%);\n                opacity: 1;\n            }\n        }\n        @keyframes exitAnimation {\n            from {\n                transform: translate(0, -50%);\n                opacity: 1;\n            }\n            to {\n                transform: translate(100%, -150%);\n                opacity: 0;\n            }\n        }\n    `;\n    return (\n        <>\n            <GlobalAnimations />\n            <PopupProvider>\n                <div style={{height: \"500px\"}}>\n                    <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n                        <Button\n                            text=\"Открыть в document\"\n                            onClick={() => setIsOpenA(true)}\n                            style={{\n                                marginTop: \"1rem\",\n                                width: \"15rem\"\n                            }}\n                        />\n                    </div>\n                    <Drawer\n                        animationInfo={animationInfo}\n                        id=\"drawerA\"\n                        opened={isOpenA}\n                        onClose={() => setIsOpenA(false)}\n                        placement=\"right\"\n                        withBlur={false}\n                        closeOnEsc={true}\n                        closeOnOverlayClick={true}\n                        asModal={true}\n                        width=\"25vw\"\n                        height=\"100vh\"\n                    >\n                        <DrawerHeader\n                            hasClose={true}\n                            closePlacement=\"right\"\n                            actions={(\n                             \n// … (обрезано)"
        }
      ]
    },
    "DrawerContent": {
      "name": "DrawerContent",
      "group": "components",
      "folderName": "Drawer",
      "role": "part",
      "description": "Прокручиваемая область основного контента шторки Drawer.",
      "props": [
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "DrawerContentProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Drawer/Drawer.d.ts",
      "type": "wrapper",
      "atomicBase": "DrawerContent",
      "category": "Локальные компоненты",
      "keywords": [
        "контент шторки",
        "drawer slot",
        "тело панели"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Drawer",
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { DrawerContent } from '@daisforge/ui';",
      "minimalUsage": "<DrawerContent />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Анимация Анимация Для работы с анимацией необходимо использовать свойство  animationInfo .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconDone } from '@salutejs/plasma-icons';\nimport { createGlobalStyle } from 'styled-components';\nimport { H3, Button, Drawer, DrawerHeader, DrawerContent, DrawerFooter, PopupProvider } from '@daisforge/ui';\nexport function App() {\n    const [isOpenA, setIsOpenA] = React.useState(false);\n    const [isOpenB, setIsOpenB] = React.useState(false);\n    const animationInfo = {\n        enter: 'enterAnimation 0.2s forwards',\n        exit: 'exitAnimation 0.2s forwards',\n    }\n    const GlobalAnimations = createGlobalStyle`\n        @keyframes enterAnimation {\n            from {\n                transform: translate(100%, -150%);\n                opacity: 0;\n            }\n            to {\n                transform: translate(0, -50%);\n                opacity: 1;\n            }\n        }\n        @keyframes exitAnimation {\n            from {\n                transform: translate(0, -50%);\n                opacity: 1;\n            }\n            to {\n                transform: translate(100%, -150%);\n                opacity: 0;\n            }\n        }\n    `;\n    return (\n        <>\n            <GlobalAnimations />\n            <PopupProvider>\n                <div style={{height: \"500px\"}}>\n                    <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n                        <Button\n                            text=\"Открыть в document\"\n                            onClick={() => setIsOpenA(true)}\n                            style={{\n                                marginTop: \"1rem\",\n                                width: \"15rem\"\n                            }}\n                        />\n                    </div>\n                    <Drawer\n                        animationInfo={animationInfo}\n                        id=\"drawerA\"\n                        opened={isOpenA}\n                        onClose={() => setIsOpenA(false)}\n                        placement=\"right\"\n                        withBlur={false}\n                        closeOnEsc={true}\n                        closeOnOverlayClick={true}\n                        asModal={true}\n                        width=\"25vw\"\n                        height=\"100vh\"\n                    >\n                        <DrawerHeader\n                            hasClose={true}\n                            closePlacement=\"right\"\n                            actions={(\n                             \n// … (обрезано)"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Отображения Drawer",
          "type": "vendor",
          "code": "import React, { useRef } from 'react';\nimport { IconDone } from '@salutejs/plasma-icons';\nimport { surfaceSolidSecondary } from '@salutejs/sdds-themes/tokens';\nimport { H3, Button, Drawer, DrawerHeader, DrawerContent, DrawerFooter, PopupProvider } from '@daisforge/ui';\nexport function App() {\n    const [isOpenA, setIsOpenA] = React.useState(false);\n    const [isOpenB, setIsOpenB] = React.useState(false);\n    const ref = useRef();\n    return (\n        <PopupProvider>\n            <div style={{height: \"500px\"}}>\n                <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n                    <Button\n                        text=\"Открыть в document\"\n                        onClick={() => setIsOpenA(true)}\n                        style={{\n                            marginTop: \"1rem\",\n                            width: \"15rem\"\n                        }}\n                    />\n                    <Button\n                        text=\"Открыть во Frame\"\n                        onClick={() => setIsOpenB(true)}\n                        style={{\n                            marginTop: \"1rem\",\n                            width: \"15rem\"\n                        }}\n                    />\n                </div>\n                <Drawer\n                    id=\"drawerA\"\n                    opened={isOpenA}\n                    onClose={() => setIsOpenA(false)}\n                    placement=\"right\"\n                    withBlur={false}\n                    closeOnEsc={true}\n                    closeOnOverlayClick={true}\n                    asModal={true}\n                    width=\"25vw\"\n                    height=\"100vh\"\n                >\n                        <DrawerHeader\n                            hasClose={true}\n                            closePlacement=\"right\"\n                            actions={(\n                                <Button size=\"s\" view=\"clear\" style={{\n                                    position: \"relative\",\n                                    width: \"1.5rem\",\n                                    height: \"1.5rem\"\n                                }}>\n                                    <IconDone size=\"s\" />\n                                </Button>\n                            )}\n                            onClose={() => setIsOpenA(false)}\n                        >\n                            <H3>Header</H3>\n                        </DrawerHeader\n// … (обрезано)"
        }
      ]
    },
    "DrawerFooter": {
      "name": "DrawerFooter",
      "group": "components",
      "folderName": "Drawer",
      "role": "part",
      "description": "Нижняя панель шторки Drawer — для кнопок действий и итогов.",
      "props": [
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "DrawerFooterProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Drawer/Drawer.d.ts",
      "type": "wrapper",
      "atomicBase": "DrawerFooter",
      "category": "Локальные компоненты",
      "keywords": [
        "футер шторки",
        "панель действий",
        "итоговая панель"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Drawer",
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { DrawerFooter } from '@daisforge/ui';",
      "minimalUsage": "<DrawerFooter />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Анимация Анимация Для работы с анимацией необходимо использовать свойство  animationInfo .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconDone } from '@salutejs/plasma-icons';\nimport { createGlobalStyle } from 'styled-components';\nimport { H3, Button, Drawer, DrawerHeader, DrawerContent, DrawerFooter, PopupProvider } from '@daisforge/ui';\nexport function App() {\n    const [isOpenA, setIsOpenA] = React.useState(false);\n    const [isOpenB, setIsOpenB] = React.useState(false);\n    const animationInfo = {\n        enter: 'enterAnimation 0.2s forwards',\n        exit: 'exitAnimation 0.2s forwards',\n    }\n    const GlobalAnimations = createGlobalStyle`\n        @keyframes enterAnimation {\n            from {\n                transform: translate(100%, -150%);\n                opacity: 0;\n            }\n            to {\n                transform: translate(0, -50%);\n                opacity: 1;\n            }\n        }\n        @keyframes exitAnimation {\n            from {\n                transform: translate(0, -50%);\n                opacity: 1;\n            }\n            to {\n                transform: translate(100%, -150%);\n                opacity: 0;\n            }\n        }\n    `;\n    return (\n        <>\n            <GlobalAnimations />\n            <PopupProvider>\n                <div style={{height: \"500px\"}}>\n                    <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n                        <Button\n                            text=\"Открыть в document\"\n                            onClick={() => setIsOpenA(true)}\n                            style={{\n                                marginTop: \"1rem\",\n                                width: \"15rem\"\n                            }}\n                        />\n                    </div>\n                    <Drawer\n                        animationInfo={animationInfo}\n                        id=\"drawerA\"\n                        opened={isOpenA}\n                        onClose={() => setIsOpenA(false)}\n                        placement=\"right\"\n                        withBlur={false}\n                        closeOnEsc={true}\n                        closeOnOverlayClick={true}\n                        asModal={true}\n                        width=\"25vw\"\n                        height=\"100vh\"\n                    >\n                        <DrawerHeader\n                            hasClose={true}\n                            closePlacement=\"right\"\n                            actions={(\n                             \n// … (обрезано)"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Отображения Drawer",
          "type": "vendor",
          "code": "import React, { useRef } from 'react';\nimport { IconDone } from '@salutejs/plasma-icons';\nimport { surfaceSolidSecondary } from '@salutejs/sdds-themes/tokens';\nimport { H3, Button, Drawer, DrawerHeader, DrawerContent, DrawerFooter, PopupProvider } from '@daisforge/ui';\nexport function App() {\n    const [isOpenA, setIsOpenA] = React.useState(false);\n    const [isOpenB, setIsOpenB] = React.useState(false);\n    const ref = useRef();\n    return (\n        <PopupProvider>\n            <div style={{height: \"500px\"}}>\n                <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n                    <Button\n                        text=\"Открыть в document\"\n                        onClick={() => setIsOpenA(true)}\n                        style={{\n                            marginTop: \"1rem\",\n                            width: \"15rem\"\n                        }}\n                    />\n                    <Button\n                        text=\"Открыть во Frame\"\n                        onClick={() => setIsOpenB(true)}\n                        style={{\n                            marginTop: \"1rem\",\n                            width: \"15rem\"\n                        }}\n                    />\n                </div>\n                <Drawer\n                    id=\"drawerA\"\n                    opened={isOpenA}\n                    onClose={() => setIsOpenA(false)}\n                    placement=\"right\"\n                    withBlur={false}\n                    closeOnEsc={true}\n                    closeOnOverlayClick={true}\n                    asModal={true}\n                    width=\"25vw\"\n                    height=\"100vh\"\n                >\n                        <DrawerHeader\n                            hasClose={true}\n                            closePlacement=\"right\"\n                            actions={(\n                                <Button size=\"s\" view=\"clear\" style={{\n                                    position: \"relative\",\n                                    width: \"1.5rem\",\n                                    height: \"1.5rem\"\n                                }}>\n                                    <IconDone size=\"s\" />\n                                </Button>\n                            )}\n                            onClose={() => setIsOpenA(false)}\n                        >\n                            <H3>Header</H3>\n                        </DrawerHeader\n// … (обрезано)"
        }
      ]
    },
    "DrawerHeader": {
      "name": "DrawerHeader",
      "group": "components",
      "folderName": "Drawer",
      "role": "part",
      "description": "Шапка шторки Drawer с заголовком, действиями и кнопкой закрытия.",
      "props": [
        {
          "name": "actions",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для отображения кнопок-обработчиков каких-либо действий."
        },
        {
          "name": "closePlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Расположение кнопки закрытия."
        },
        {
          "name": "hasClose",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отображать ли кнопку закрытия."
        },
        {
          "name": "onClose",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Обработчик клика по кнопке закрытия."
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": "Вид верхней части Panel."
        }
      ],
      "propsTypeName": "DrawerHeaderProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Drawer/Drawer.d.ts",
      "type": "wrapper",
      "atomicBase": "DrawerHeader",
      "category": "Локальные компоненты",
      "keywords": [
        "заголовок шторки",
        "drawer header",
        "кнопка закрытия"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Drawer",
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { DrawerHeader } from '@daisforge/ui';",
      "minimalUsage": "<DrawerHeader />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Анимация Анимация Для работы с анимацией необходимо использовать свойство  animationInfo .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconDone } from '@salutejs/plasma-icons';\nimport { createGlobalStyle } from 'styled-components';\nimport { H3, Button, Drawer, DrawerHeader, DrawerContent, DrawerFooter, PopupProvider } from '@daisforge/ui';\nexport function App() {\n    const [isOpenA, setIsOpenA] = React.useState(false);\n    const [isOpenB, setIsOpenB] = React.useState(false);\n    const animationInfo = {\n        enter: 'enterAnimation 0.2s forwards',\n        exit: 'exitAnimation 0.2s forwards',\n    }\n    const GlobalAnimations = createGlobalStyle`\n        @keyframes enterAnimation {\n            from {\n                transform: translate(100%, -150%);\n                opacity: 0;\n            }\n            to {\n                transform: translate(0, -50%);\n                opacity: 1;\n            }\n        }\n        @keyframes exitAnimation {\n            from {\n                transform: translate(0, -50%);\n                opacity: 1;\n            }\n            to {\n                transform: translate(100%, -150%);\n                opacity: 0;\n            }\n        }\n    `;\n    return (\n        <>\n            <GlobalAnimations />\n            <PopupProvider>\n                <div style={{height: \"500px\"}}>\n                    <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n                        <Button\n                            text=\"Открыть в document\"\n                            onClick={() => setIsOpenA(true)}\n                            style={{\n                                marginTop: \"1rem\",\n                                width: \"15rem\"\n                            }}\n                        />\n                    </div>\n                    <Drawer\n                        animationInfo={animationInfo}\n                        id=\"drawerA\"\n                        opened={isOpenA}\n                        onClose={() => setIsOpenA(false)}\n                        placement=\"right\"\n                        withBlur={false}\n                        closeOnEsc={true}\n                        closeOnOverlayClick={true}\n                        asModal={true}\n                        width=\"25vw\"\n                        height=\"100vh\"\n                    >\n                        <DrawerHeader\n                            hasClose={true}\n                            closePlacement=\"right\"\n                            actions={(\n                             \n// … (обрезано)"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Отображения Drawer",
          "type": "vendor",
          "code": "import React, { useRef } from 'react';\nimport { IconDone } from '@salutejs/plasma-icons';\nimport { surfaceSolidSecondary } from '@salutejs/sdds-themes/tokens';\nimport { H3, Button, Drawer, DrawerHeader, DrawerContent, DrawerFooter, PopupProvider } from '@daisforge/ui';\nexport function App() {\n    const [isOpenA, setIsOpenA] = React.useState(false);\n    const [isOpenB, setIsOpenB] = React.useState(false);\n    const ref = useRef();\n    return (\n        <PopupProvider>\n            <div style={{height: \"500px\"}}>\n                <div style={{ display: \"flex\", flexDirection: \"column\" }}>\n                    <Button\n                        text=\"Открыть в document\"\n                        onClick={() => setIsOpenA(true)}\n                        style={{\n                            marginTop: \"1rem\",\n                            width: \"15rem\"\n                        }}\n                    />\n                    <Button\n                        text=\"Открыть во Frame\"\n                        onClick={() => setIsOpenB(true)}\n                        style={{\n                            marginTop: \"1rem\",\n                            width: \"15rem\"\n                        }}\n                    />\n                </div>\n                <Drawer\n                    id=\"drawerA\"\n                    opened={isOpenA}\n                    onClose={() => setIsOpenA(false)}\n                    placement=\"right\"\n                    withBlur={false}\n                    closeOnEsc={true}\n                    closeOnOverlayClick={true}\n                    asModal={true}\n                    width=\"25vw\"\n                    height=\"100vh\"\n                >\n                        <DrawerHeader\n                            hasClose={true}\n                            closePlacement=\"right\"\n                            actions={(\n                                <Button size=\"s\" view=\"clear\" style={{\n                                    position: \"relative\",\n                                    width: \"1.5rem\",\n                                    height: \"1.5rem\"\n                                }}>\n                                    <IconDone size=\"s\" />\n                                </Button>\n                            )}\n                            onClose={() => setIsOpenA(false)}\n                        >\n                            <H3>Header</H3>\n                        </DrawerHeader\n// … (обрезано)"
        }
      ]
    },
    "DrawerDF": {
      "name": "DrawerDF",
      "group": "components",
      "folderName": "DrawerDF",
      "role": "primary",
      "description": "Боковая панель с готовыми слотами шапки, контента, футера и кнопкой назад",
      "props": [
        {
          "name": "borderRadius",
          "type": "\"default\" | \"none\" | undefined",
          "required": false,
          "description": "Скругление компонента."
        },
        {
          "name": "customBackgroundColor",
          "type": "string | undefined",
          "required": false,
          "description": "Пользовательский цвет фона Panel."
        },
        {
          "name": "customContentBackgroundColor",
          "type": "string | undefined",
          "required": false,
          "description": "Пользовательский цвет фона контента Panel."
        },
        {
          "name": "frame",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "В каком контейнере позиционируется (по умолчанию document), можно также указать id элемента или ref для него."
        },
        {
          "name": "offset",
          "type": "[number, number] | [string, string] | undefined",
          "required": false,
          "description": "Смещение относительно текущей позиции.\n(x, y) - [number, number], [string, string].\nПри передаче number расчёт в rem."
        },
        {
          "name": "opened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отображение Popup."
        },
        {
          "name": "overlay",
          "type": "React.ReactNode",
          "required": false,
          "description": "Соседний элемент для окна в портале."
        },
        {
          "name": "placement",
          "type": "\"left\" | \"right\" | \"top\" | \"bottom\" | undefined",
          "required": false,
          "description": "Позиция на экране\ncenter - по умолчанию\nleft, right, top, bottom и их комбинации"
        },
        {
          "name": "popupInfo",
          "type": "PopupInfo | undefined",
          "required": false,
          "description": "Дополнительная информация для программного взаимодействия с окном через контекст."
        },
        {
          "name": "positionFixed",
          "type": "boolean | undefined",
          "required": false,
          "description": "Если `frame` отличается от `document` применяет `position='fixed'`",
          "default": "false"
        },
        {
          "name": "size",
          "type": "\"m\" | undefined",
          "required": false,
          "description": "Размер компонента."
        },
        {
          "name": "view",
          "type": "\"default\" | undefined",
          "required": false,
          "description": "Вид компонента."
        },
        {
          "name": "withAnimation",
          "type": "boolean | undefined",
          "required": false,
          "description": "Использовать ли анимацию."
        },
        {
          "name": "zIndex",
          "type": "string | undefined",
          "required": false,
          "description": "Значение z-index для Popup."
        },
        {
          "name": "footer",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "header",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "main",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "onBackClick",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "showBackButton",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "animationInfo",
          "type": "DrawerAnimationInfo | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "asModal",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "closeOnEsc",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "focusAfterRef",
          "type": "React.RefObject<HTMLElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "initialFocusRef",
          "type": "React.RefObject<HTMLElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onClose",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onEscKeyDown",
          "type": "((event: KeyboardEvent) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onOverlayClick",
          "type": "((event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "overlayProps",
          "type": "DrawerOverlayProps | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "withBlur",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isOpen",
          "type": "boolean | undefined",
          "required": false,
          "description": "",
          "deprecated": true
        }
      ],
      "propsTypeName": "DrawerDFProps",
      "compoundParts": [
        {
          "name": "Content",
          "typeName": "DrawerDFContentProps",
          "props": [
            {
              "name": "$css",
              "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
              "required": false,
              "description": "Кастомные стили styled-components для Box-контейнера"
            },
            {
              "name": "as",
              "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"label\" | \"form\" | \"pattern\" | \"slot\" | \"style\" | \"title\" | \"view\" | \"s\" | \"button\" | \"image\" | \"search\" | \"text\" | \"time\" | \"article\" | \"dialog\" | \"figure\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"switch\" | \"table\" | \"center\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"…",
              "required": false,
              "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
            },
            {
              "name": "background",
              "type": "Property.Background<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "backgroundColor",
              "type": "Property.BackgroundColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "border",
              "type": "Property.Border<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderColor",
              "type": "Property.BorderColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderRadius",
              "type": "Property.BorderRadius<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
            },
            {
              "name": "borderStyle",
              "type": "Property.BorderStyle | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderWidth",
              "type": "Property.BorderWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "bottom",
              "type": "Property.Bottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "boxSizing",
              "type": "Property.BoxSizing | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
            },
            {
              "name": "cursor",
              "type": "Property.Cursor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
            },
            {
              "name": "display",
              "type": "Property.Display | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "flexDirection",
              "type": "Property.FlexDirection | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
            },
            {
              "name": "flexGrow",
              "type": "Property.FlexGrow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
            },
            {
              "name": "flexShrink",
              "type": "Property.FlexShrink | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
            },
            {
              "name": "flexWrap",
              "type": "Property.FlexWrap | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "gap",
              "type": "Property.Gap<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
            },
            {
              "name": "height",
              "type": "Property.Height<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "justifyContent",
              "type": "Property.JustifyContent | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "justifyItems",
              "type": "Property.JustifyItems | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
            },
            {
              "name": "justifySelf",
              "type": "Property.JustifySelf | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
            },
            {
              "name": "left",
              "type": "Property.Left<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "margin",
              "type": "Property.Margin<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginBottom",
              "type": "Property.MarginBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginLeft",
              "type": "Property.MarginLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginRight",
              "type": "Property.MarginRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginTop",
              "type": "Property.MarginTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "maxHeight",
              "type": "Property.MaxHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "maxWidth",
              "type": "Property.MaxWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "minHeight",
              "type": "Property.MinHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "minWidth",
              "type": "Property.MinWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "opacity",
              "type": "Property.Opacity | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
            },
            {
              "name": "overflow",
              "type": "Property.Overflow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "padding",
              "type": "Property.Padding<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingBottom",
              "type": "Property.PaddingBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingLeft",
              "type": "Property.PaddingLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingRight",
              "type": "Property.PaddingRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingTop",
              "type": "Property.PaddingTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "position",
              "type": "Property.Position | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "right",
              "type": "Property.Right<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "top",
              "type": "Property.Top<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "width",
              "type": "Property.Width<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "zIndex",
              "type": "Property.ZIndex | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "$isFirstSingleContent",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "$isLastSingleContent",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "fixedWidth",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "refEl",
              "type": "React.Ref<HTMLDivElement> | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Header",
          "typeName": "DrawerDFHeaderProps",
          "props": [
            {
              "name": "$css",
              "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
              "required": false,
              "description": "Кастомные стили styled-components для Box-контейнера"
            },
            {
              "name": "as",
              "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"label\" | \"form\" | \"pattern\" | \"slot\" | \"style\" | \"title\" | \"view\" | \"s\" | \"button\" | \"image\" | \"search\" | \"text\" | \"time\" | \"article\" | \"dialog\" | \"figure\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"switch\" | \"table\" | \"center\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"…",
              "required": false,
              "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
            },
            {
              "name": "background",
              "type": "Property.Background<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "backgroundColor",
              "type": "Property.BackgroundColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "border",
              "type": "Property.Border<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderColor",
              "type": "Property.BorderColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderRadius",
              "type": "Property.BorderRadius<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
            },
            {
              "name": "borderStyle",
              "type": "Property.BorderStyle | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderWidth",
              "type": "Property.BorderWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "bottom",
              "type": "Property.Bottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "boxSizing",
              "type": "Property.BoxSizing | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
            },
            {
              "name": "cursor",
              "type": "Property.Cursor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
            },
            {
              "name": "display",
              "type": "Property.Display | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "flexDirection",
              "type": "Property.FlexDirection | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
            },
            {
              "name": "flexGrow",
              "type": "Property.FlexGrow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
            },
            {
              "name": "flexShrink",
              "type": "Property.FlexShrink | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
            },
            {
              "name": "flexWrap",
              "type": "Property.FlexWrap | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "gap",
              "type": "Property.Gap<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
            },
            {
              "name": "height",
              "type": "Property.Height<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "justifyContent",
              "type": "Property.JustifyContent | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "justifyItems",
              "type": "Property.JustifyItems | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
            },
            {
              "name": "justifySelf",
              "type": "Property.JustifySelf | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
            },
            {
              "name": "left",
              "type": "Property.Left<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "margin",
              "type": "Property.Margin<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginBottom",
              "type": "Property.MarginBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginLeft",
              "type": "Property.MarginLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginRight",
              "type": "Property.MarginRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginTop",
              "type": "Property.MarginTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "maxHeight",
              "type": "Property.MaxHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "maxWidth",
              "type": "Property.MaxWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "minHeight",
              "type": "Property.MinHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "minWidth",
              "type": "Property.MinWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "opacity",
              "type": "Property.Opacity | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
            },
            {
              "name": "overflow",
              "type": "Property.Overflow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "padding",
              "type": "Property.Padding<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingBottom",
              "type": "Property.PaddingBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingLeft",
              "type": "Property.PaddingLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingRight",
              "type": "Property.PaddingRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingTop",
              "type": "Property.PaddingTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "position",
              "type": "Property.Position | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "right",
              "type": "Property.Right<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "top",
              "type": "Property.Top<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "width",
              "type": "Property.Width<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "zIndex",
              "type": "Property.ZIndex | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "badge",
              "type": "(((((Omit<Omit<PropsType<{ view: { default: PolymorphicClassName; accent: PolymorphicClassName; positive: PolymorphicClassName; warning: PolymorphicClassName; negative: PolymorphicClassName; dark: PolymorphicClassName; light: PolymorphicClassName; }; size: { l: PolymorphicClassName; m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; pilled: { true: PolymorphicClassName;…",
              "required": false,
              "description": ""
            },
            {
              "name": "footerBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "refEl",
              "type": "React.LegacyRef<HTMLDivElement> | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "rightBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "subTitle",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "title",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "DotsIconButton",
          "typeName": "DrawerDFDotsIconButtonProps",
          "props": [
            {
              "name": "as",
              "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
              "required": false,
              "description": "Сменить рендер на другой тип компонента."
            },
            {
              "name": "dropdownProps",
              "type": "(Omit<DropdownProps<ItemOption>, \"size\" | \"view\"> & Pick<PropsType<{ size: { m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; view: { default: PolymorphicClassName; }; }> & { items: ItemOption[]; trigger?: DropdownTrigger | undefined; placement?: DropdownPlacement | undefined; children?: React.ReactNode; variant?: \"normal\" | \"tight\" | undefined; zIndex?: Property.ZInd…",
              "required": false,
              "description": ""
            },
            {
              "name": "iconSize",
              "type": "\"s\" | \"xs\" | \"m\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "additionalContent",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "appearance",
              "type": "\"default\" | \"outline\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "blur",
              "type": "\"small\" | \"medium\" | \"large\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentLeft",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "contentPlacing",
              "type": "\"default\" | \"relaxed\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentRight",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "focused",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "isLoading",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "loader",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "outlined",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "pin",
              "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftLeft",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftRight",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "size",
              "type": "\"s\" | \"xs\" | \"xxs\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "square",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretch",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretching",
              "type": "\"auto\" | \"fixed\" | \"filled\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "text",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "type",
              "type": "\"button\" | \"reset\" | \"submit\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "value",
              "type": "string | number | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "view",
              "type": "\"default\" | \"clear\" | \"black\" | \"white\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"secondary\" | \"gradient\" | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Footer",
          "typeName": "DrawerDFFooterProps",
          "props": [
            {
              "name": "$css",
              "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
              "required": false,
              "description": "Кастомные стили styled-components для Box-контейнера"
            },
            {
              "name": "as",
              "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"label\" | \"form\" | \"pattern\" | \"slot\" | \"style\" | \"title\" | \"view\" | \"s\" | \"button\" | \"image\" | \"search\" | \"text\" | \"time\" | \"article\" | \"dialog\" | \"figure\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"switch\" | \"table\" | \"center\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"…",
              "required": false,
              "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
            },
            {
              "name": "background",
              "type": "Property.Background<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "backgroundColor",
              "type": "Property.BackgroundColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "border",
              "type": "Property.Border<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderColor",
              "type": "Property.BorderColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderRadius",
              "type": "Property.BorderRadius<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
            },
            {
              "name": "borderStyle",
              "type": "Property.BorderStyle | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderWidth",
              "type": "Property.BorderWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "bottom",
              "type": "Property.Bottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "boxSizing",
              "type": "Property.BoxSizing | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
            },
            {
              "name": "cursor",
              "type": "Property.Cursor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
            },
            {
              "name": "display",
              "type": "Property.Display | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "flexDirection",
              "type": "Property.FlexDirection | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
            },
            {
              "name": "flexGrow",
              "type": "Property.FlexGrow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
            },
            {
              "name": "flexShrink",
              "type": "Property.FlexShrink | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
            },
            {
              "name": "flexWrap",
              "type": "Property.FlexWrap | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "gap",
              "type": "Property.Gap<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
            },
            {
              "name": "height",
              "type": "Property.Height<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "justifyContent",
              "type": "Property.JustifyContent | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "justifyItems",
              "type": "Property.JustifyItems | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
            },
            {
              "name": "justifySelf",
              "type": "Property.JustifySelf | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
            },
            {
              "name": "left",
              "type": "Property.Left<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "margin",
              "type": "Property.Margin<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginBottom",
              "type": "Property.MarginBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginLeft",
              "type": "Property.MarginLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginRight",
              "type": "Property.MarginRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginTop",
              "type": "Property.MarginTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "maxHeight",
              "type": "Property.MaxHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "maxWidth",
              "type": "Property.MaxWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "minHeight",
              "type": "Property.MinHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "minWidth",
              "type": "Property.MinWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "opacity",
              "type": "Property.Opacity | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
            },
            {
              "name": "overflow",
              "type": "Property.Overflow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "padding",
              "type": "Property.Padding<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingBottom",
              "type": "Property.PaddingBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingLeft",
              "type": "Property.PaddingLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingRight",
              "type": "Property.PaddingRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingTop",
              "type": "Property.PaddingTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "position",
              "type": "Property.Position | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "right",
              "type": "Property.Right<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "top",
              "type": "Property.Top<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "width",
              "type": "Property.Width<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "zIndex",
              "type": "Property.ZIndex | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "refEl",
              "type": "React.LegacyRef<HTMLDivElement> | undefined",
              "required": false,
              "description": ""
            }
          ]
        }
      ],
      "sourceFile": "packages/ui-kit/src/components/DrawerDF/DrawerDF.tsx",
      "type": "wrapper",
      "category": "Локальные компоненты",
      "keywords": [
        "боковая панель с разметкой",
        "side panel layout",
        "шторка с шапкой и футером"
      ],
      "docs": "# DrawerDF\n\nРасширенный `Drawer` ([документация SDDS](https://plasma.sberdevices.ru/sdds-finai/components/drawer/)) с готовыми layout-ами для шапки/контента/футера, кнопкой «назад» и сервисными элементами. Из блоков можно собрать как простой выезжающий сайдбар, так и сложные многоколоночные сценарии.\n\n## Ключевые особенности\n\n- Набор compound-компонентов (`Header`, `Content`, `Footer`, `DotsIconButton`, `BackIconButton`)\n- Поддержка множественных контентных колонок с автоматическими отступами\n- Управление кнопкой «назад» на уровне родительского компонента (`showBackButton`, `onBackClick`)\n- Готовые стили для бейджей, правого блока действий и табов в шапке\n\n## Compound-компоненты\n\n```ts\nDrawerDF.Header; // Шапка: заголовок, подзаголовок, бейдж, правый блок, футер-блок (табы)\nDrawerDF.Content; // Контейнер контента с поддержкой фиксированной ширины\nDrawerDF.Footer; // Футер с преднастроенными отступами\nDrawerDF.DotsIconButton; // Иконка «три точки» с Dropdown\nDrawerDF.BackIconButton; // Кнопка «назад»\n```\n\n- `DrawerDF.Header` — автоматически выстраивает заголовок, подзаголовок, бейдж, правый блок и нижний блок (табы)\n- `DrawerDF.Content` — поддерживает `fixedWidth` для формирования колонок\n- `DrawerDF.Footer` — имеет преднастроенные отступы, принимает любые элементы управления\n- `DrawerDF.DotsIconButton` — иконка меню с `dropdownProps`\n- `DrawerDF.BackIconButton` — используется в кнопке «назад», доступен для произвольного использования\n\n## Особенности\n\n- `main` принимает одиночный `DrawerDF.Content` или массив — при массиве автоматически формируются колонки\n- `showBackButton` заменяет крестик закрытия на кнопку «назад»\n\nОписание типов и compound-пропсов — в разделе [API](/docs/локальные-компоненты-drawerdf-api--docs).",
      "apiDocs": "# DrawerDF API\n\n## DrawerDFProps\n\n```typescript\ntype DrawerDFProps = {\n  main?: ReactNode;\n  footer?: ReactNode;\n  header?: ReactNode;\n  showBackButton?: boolean;\n  onBackClick?: () => void;\n} & Omit<DrawerProps, 'children'>;\n```\n\n## Compound types\n\n### DrawerDF.Header\n\n```typescript\ntype DrawerDFHeaderProps = BoxProps & {\n  refEl?: LegacyRef<HTMLDivElement>;\n  title?: ReactNode;\n  subTitle?: ReactNode;\n  badge?: (BadgeCompProps & { text: string }) | undefined;\n  rightBlock?: ReactNode;\n  footerBlock?: ReactNode;\n};\n```\n\n### DrawerDF.Content\n\n```typescript\ntype DrawerDFContentProps = BoxProps & {\n  fixedWidth?: string;\n  refEl?: Ref<HTMLDivElement>;\n  $isFirstSingleContent?: boolean;\n  $isLastSingleContent?: boolean;\n};\n```\n\n### DrawerDF.Footer\n\n```typescript\ntype DrawerDFFooterProps = BoxProps & {\n  refEl?: LegacyRef<HTMLDivElement>;\n};\n```\n\n### DrawerDF.DotsIconButton\n\n```typescript\ntype DrawerDFDotsIconButtonProps = ComponentProps<typeof IconButton> & {\n  dropdownProps?: ComponentProps<typeof Dropdown>;\n  iconSize?: ComponentProps<typeof IconDotsHorizontalOutline>['size'];\n};\n```\n\n### DrawerDF.BackIconButton\n\n```typescript\ntype DrawerDFBackIconButtonProps = ComponentProps<typeof IconButton> & {\n  iconSize?: ComponentProps<typeof IconChevronLeft>['size'];\n};\n```",
      "curatedStories": [
        {
          "exportName": "DrawerWithOneMainContent",
          "displayName": "DrawerDF with one content",
          "type": "full-code",
          "code": "import { Button, DrawerDF, Flow } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { longLorem } from './data';\nimport { TabsComp } from './Tabs';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx',\n  'DrawerWithOneMainContentExample',\n)}"
        },
        {
          "exportName": "DrawerDFWithMultipleMainContent",
          "displayName": "DrawerDF with multiple content",
          "type": "full-code",
          "code": "import { Button, DrawerDF, Flow } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { longLorem, shortLorem } from './data';\nimport { TabsComp } from './Tabs';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx',\n  'DrawerWithMultipleContentExample',\n)}"
        },
        {
          "exportName": "DrawerWithSingleContentNoHeaderNoFooter",
          "displayName": "DrawerDF with single content (no header, no footer)",
          "type": "full-code",
          "code": "import { Button, DrawerDF } from '@daisforge/ui';\nimport { longLorem } from './data';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx',\n  'DrawerSingleContentNoHeaderExample',\n)}"
        },
        {
          "exportName": "DrawerWithBackButton",
          "displayName": "DrawerDF with back button",
          "type": "full-code",
          "code": "import { Button, DrawerDF, Flow } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { longLorem } from './data';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx',\n  'DrawerWithBackButtonExample',\n)}"
        }
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "DrawerDFContent",
        "DrawerDFFooter",
        "DrawerDFHeader"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { DrawerDF } from '@daisforge/ui';",
      "minimalUsage": "<DrawerDF>\n  {/* части: DrawerDF.Content, DrawerDF.Header, DrawerDF.DotsIconButton, DrawerDF.Footer */}\n</DrawerDF>",
      "examples": [
        {
          "exportName": "DrawerWithOneMainContent",
          "displayName": "DrawerDF with one content",
          "type": "full-code",
          "code": "import { Button, DrawerDF, Flow } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { longLorem } from './data';\nimport { TabsComp } from './Tabs';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx',\n  'DrawerWithOneMainContentExample',\n)}"
        },
        {
          "exportName": "DrawerDFWithMultipleMainContent",
          "displayName": "DrawerDF with multiple content",
          "type": "full-code",
          "code": "import { Button, DrawerDF, Flow } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { longLorem, shortLorem } from './data';\nimport { TabsComp } from './Tabs';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx',\n  'DrawerWithMultipleContentExample',\n)}"
        },
        {
          "exportName": "DrawerWithSingleContentNoHeaderNoFooter",
          "displayName": "DrawerDF with single content (no header, no footer)",
          "type": "full-code",
          "code": "import { Button, DrawerDF } from '@daisforge/ui';\nimport { longLorem } from './data';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx',\n  'DrawerSingleContentNoHeaderExample',\n)}"
        },
        {
          "exportName": "DrawerWithBackButton",
          "displayName": "DrawerDF with back button",
          "type": "full-code",
          "code": "import { Button, DrawerDF, Flow } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { longLorem } from './data';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx',\n  'DrawerWithBackButtonExample',\n)}"
        }
      ]
    },
    "DrawerDFContent": {
      "name": "DrawerDFContent",
      "group": "components",
      "folderName": "DrawerDF",
      "role": "part",
      "description": "Прокручиваемая область содержимого DrawerDF с отступами и фиксированной шириной блока",
      "props": [
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные стили styled-components для Box-контейнера"
        },
        {
          "name": "as",
          "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"label\" | \"form\" | \"pattern\" | \"slot\" | \"style\" | \"title\" | \"view\" | \"s\" | \"button\" | \"image\" | \"search\" | \"text\" | \"time\" | \"article\" | \"dialog\" | \"figure\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"switch\" | \"table\" | \"center\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"…",
          "required": false,
          "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
        },
        {
          "name": "background",
          "type": "Property.Background<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "backgroundColor",
          "type": "Property.BackgroundColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "border",
          "type": "Property.Border<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderColor",
          "type": "Property.BorderColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderRadius",
          "type": "Property.BorderRadius<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
        },
        {
          "name": "borderStyle",
          "type": "Property.BorderStyle | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderWidth",
          "type": "Property.BorderWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "bottom",
          "type": "Property.Bottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "boxSizing",
          "type": "Property.BoxSizing | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
        },
        {
          "name": "cursor",
          "type": "Property.Cursor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
        },
        {
          "name": "display",
          "type": "Property.Display | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "flexDirection",
          "type": "Property.FlexDirection | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
        },
        {
          "name": "flexGrow",
          "type": "Property.FlexGrow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
        },
        {
          "name": "flexShrink",
          "type": "Property.FlexShrink | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
        },
        {
          "name": "flexWrap",
          "type": "Property.FlexWrap | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "gap",
          "type": "Property.Gap<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
        },
        {
          "name": "height",
          "type": "Property.Height<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "justifyContent",
          "type": "Property.JustifyContent | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "justifyItems",
          "type": "Property.JustifyItems | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
        },
        {
          "name": "justifySelf",
          "type": "Property.JustifySelf | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
        },
        {
          "name": "left",
          "type": "Property.Left<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "margin",
          "type": "Property.Margin<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginBottom",
          "type": "Property.MarginBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginLeft",
          "type": "Property.MarginLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginRight",
          "type": "Property.MarginRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginTop",
          "type": "Property.MarginTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "maxHeight",
          "type": "Property.MaxHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "maxWidth",
          "type": "Property.MaxWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "minHeight",
          "type": "Property.MinHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "minWidth",
          "type": "Property.MinWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "opacity",
          "type": "Property.Opacity | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
        },
        {
          "name": "overflow",
          "type": "Property.Overflow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "padding",
          "type": "Property.Padding<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingBottom",
          "type": "Property.PaddingBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingLeft",
          "type": "Property.PaddingLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingRight",
          "type": "Property.PaddingRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingTop",
          "type": "Property.PaddingTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "position",
          "type": "Property.Position | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "right",
          "type": "Property.Right<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "top",
          "type": "Property.Top<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "width",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "$isFirstSingleContent",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "$isLastSingleContent",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "fixedWidth",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "refEl",
          "type": "React.Ref<HTMLDivElement> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "DrawerDFContentProps",
      "sourceFile": "packages/ui-kit/src/components/DrawerDF/DrawerDFCompounds.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "контент шторки",
        "scrollable content",
        "тело drawer"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "DrawerDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "DrawerDF",
        "part": "Content"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { DrawerDFContent } from '@daisforge/ui';",
      "minimalUsage": "<DrawerDFContent />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в DrawerDF.stories.tsx",
          "type": "usage",
          "code": "<DrawerDF.Content key=\"middle\" fixedWidth=\"50%\">\n            {longLorem}\n          </DrawerDF.Content>",
          "sourceFile": "packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в DrawerDF.stories.tsx",
          "type": "usage",
          "code": "<DrawerDF.Content key=\"left\" fixedWidth=\"150px\">\n            <Button view=\"accent\" size=\"xs\">\n              Обосновать\n            </Button>\n            {shortLorem}\n          </DrawerDF.Content>",
          "sourceFile": "packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx"
        }
      ]
    },
    "DrawerDFFooter": {
      "name": "DrawerDFFooter",
      "group": "components",
      "folderName": "DrawerDF",
      "role": "part",
      "description": "Нижний блок DrawerDF для кнопок и действий, закреплённый под содержимым",
      "props": [
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные стили styled-components для Box-контейнера"
        },
        {
          "name": "as",
          "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"label\" | \"form\" | \"pattern\" | \"slot\" | \"style\" | \"title\" | \"view\" | \"s\" | \"button\" | \"image\" | \"search\" | \"text\" | \"time\" | \"article\" | \"dialog\" | \"figure\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"switch\" | \"table\" | \"center\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"…",
          "required": false,
          "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
        },
        {
          "name": "background",
          "type": "Property.Background<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "backgroundColor",
          "type": "Property.BackgroundColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "border",
          "type": "Property.Border<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderColor",
          "type": "Property.BorderColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderRadius",
          "type": "Property.BorderRadius<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
        },
        {
          "name": "borderStyle",
          "type": "Property.BorderStyle | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderWidth",
          "type": "Property.BorderWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "bottom",
          "type": "Property.Bottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "boxSizing",
          "type": "Property.BoxSizing | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
        },
        {
          "name": "cursor",
          "type": "Property.Cursor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
        },
        {
          "name": "display",
          "type": "Property.Display | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "flexDirection",
          "type": "Property.FlexDirection | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
        },
        {
          "name": "flexGrow",
          "type": "Property.FlexGrow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
        },
        {
          "name": "flexShrink",
          "type": "Property.FlexShrink | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
        },
        {
          "name": "flexWrap",
          "type": "Property.FlexWrap | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "gap",
          "type": "Property.Gap<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
        },
        {
          "name": "height",
          "type": "Property.Height<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "justifyContent",
          "type": "Property.JustifyContent | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "justifyItems",
          "type": "Property.JustifyItems | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
        },
        {
          "name": "justifySelf",
          "type": "Property.JustifySelf | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
        },
        {
          "name": "left",
          "type": "Property.Left<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "margin",
          "type": "Property.Margin<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginBottom",
          "type": "Property.MarginBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginLeft",
          "type": "Property.MarginLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginRight",
          "type": "Property.MarginRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginTop",
          "type": "Property.MarginTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "maxHeight",
          "type": "Property.MaxHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "maxWidth",
          "type": "Property.MaxWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "minHeight",
          "type": "Property.MinHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "minWidth",
          "type": "Property.MinWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "opacity",
          "type": "Property.Opacity | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
        },
        {
          "name": "overflow",
          "type": "Property.Overflow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "padding",
          "type": "Property.Padding<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingBottom",
          "type": "Property.PaddingBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingLeft",
          "type": "Property.PaddingLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingRight",
          "type": "Property.PaddingRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingTop",
          "type": "Property.PaddingTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "position",
          "type": "Property.Position | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "right",
          "type": "Property.Right<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "top",
          "type": "Property.Top<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "width",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "refEl",
          "type": "React.LegacyRef<HTMLDivElement> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "DrawerDFFooterProps",
      "sourceFile": "packages/ui-kit/src/components/DrawerDF/DrawerDFCompounds.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "футер шторки",
        "кнопки внизу панели",
        "drawer footer"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "DrawerDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "DrawerDF",
        "part": "Footer"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { DrawerDFFooter } from '@daisforge/ui';",
      "minimalUsage": "<DrawerDFFooter />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в DrawerDF.stories.tsx",
          "type": "usage",
          "code": "<DrawerDF.Footer\n            $css={{ display: 'flex', justifyContent: 'space-between' }}\n          >\n            <Button view=\"clear\" size=\"xs\">\n              Очистить\n            </Button>\n            <div>\n              <Button view=\"secondary\" size=\"xs\">\n                Действие 1\n              </Button>\n              <Button view=\"accent\" size=\"xs\" style={{ marginLeft: 8 }}>\n                Действие 2\n              </Button>\n            </div>\n          </DrawerDF.Footer>",
          "sourceFile": "packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в DrawerDF.stories.tsx",
          "type": "usage",
          "code": "<DrawerDF.Footer\n            $css={{ display: 'flex', justifyContent: 'space-between' }}\n          >\n            <Button view=\"clear\" size=\"xs\">\n              Очистить\n            </Button>\n            <div>\n              <Button view=\"secondary\" size=\"xs\">\n                Действие 1\n              </Button>\n              <Button view=\"accent\" size=\"xs\" style={{ marginLeft: 8 }}>\n                Главная кнопка\n              </Button>\n            </div>\n          </DrawerDF.Footer>",
          "sourceFile": "packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx"
        }
      ]
    },
    "DrawerDFHeader": {
      "name": "DrawerDFHeader",
      "group": "components",
      "folderName": "DrawerDF",
      "role": "part",
      "description": "Шапка DrawerDF: заголовок, подзаголовок, бейдж и дополнительный блок справа",
      "props": [
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные стили styled-components для Box-контейнера"
        },
        {
          "name": "as",
          "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"label\" | \"form\" | \"pattern\" | \"slot\" | \"style\" | \"title\" | \"view\" | \"s\" | \"button\" | \"image\" | \"search\" | \"text\" | \"time\" | \"article\" | \"dialog\" | \"figure\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"switch\" | \"table\" | \"center\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"…",
          "required": false,
          "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
        },
        {
          "name": "background",
          "type": "Property.Background<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "backgroundColor",
          "type": "Property.BackgroundColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "border",
          "type": "Property.Border<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderColor",
          "type": "Property.BorderColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderRadius",
          "type": "Property.BorderRadius<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
        },
        {
          "name": "borderStyle",
          "type": "Property.BorderStyle | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderWidth",
          "type": "Property.BorderWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "bottom",
          "type": "Property.Bottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "boxSizing",
          "type": "Property.BoxSizing | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
        },
        {
          "name": "cursor",
          "type": "Property.Cursor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
        },
        {
          "name": "display",
          "type": "Property.Display | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "flexDirection",
          "type": "Property.FlexDirection | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
        },
        {
          "name": "flexGrow",
          "type": "Property.FlexGrow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
        },
        {
          "name": "flexShrink",
          "type": "Property.FlexShrink | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
        },
        {
          "name": "flexWrap",
          "type": "Property.FlexWrap | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "gap",
          "type": "Property.Gap<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
        },
        {
          "name": "height",
          "type": "Property.Height<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "justifyContent",
          "type": "Property.JustifyContent | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "justifyItems",
          "type": "Property.JustifyItems | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
        },
        {
          "name": "justifySelf",
          "type": "Property.JustifySelf | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
        },
        {
          "name": "left",
          "type": "Property.Left<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "margin",
          "type": "Property.Margin<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginBottom",
          "type": "Property.MarginBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginLeft",
          "type": "Property.MarginLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginRight",
          "type": "Property.MarginRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginTop",
          "type": "Property.MarginTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "maxHeight",
          "type": "Property.MaxHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "maxWidth",
          "type": "Property.MaxWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "minHeight",
          "type": "Property.MinHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "minWidth",
          "type": "Property.MinWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "opacity",
          "type": "Property.Opacity | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
        },
        {
          "name": "overflow",
          "type": "Property.Overflow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "padding",
          "type": "Property.Padding<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingBottom",
          "type": "Property.PaddingBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingLeft",
          "type": "Property.PaddingLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingRight",
          "type": "Property.PaddingRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingTop",
          "type": "Property.PaddingTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "position",
          "type": "Property.Position | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "right",
          "type": "Property.Right<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "top",
          "type": "Property.Top<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "width",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "badge",
          "type": "(((((Omit<Omit<PropsType<{ view: { default: PolymorphicClassName; accent: PolymorphicClassName; positive: PolymorphicClassName; warning: PolymorphicClassName; negative: PolymorphicClassName; dark: PolymorphicClassName; light: PolymorphicClassName; }; size: { l: PolymorphicClassName; m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; pilled: { true: PolymorphicClassName;…",
          "required": false,
          "description": ""
        },
        {
          "name": "footerBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "refEl",
          "type": "React.LegacyRef<HTMLDivElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rightBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "subTitle",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "title",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "DrawerDFHeaderProps",
      "sourceFile": "packages/ui-kit/src/components/DrawerDF/DrawerDFCompounds.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "шапка шторки",
        "заголовок панели",
        "drawer header"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "DrawerDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "DrawerDF",
        "part": "Header"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { DrawerDFHeader } from '@daisforge/ui';",
      "minimalUsage": "<DrawerDFHeader />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в DrawerDF.stories.tsx",
          "type": "usage",
          "code": "<DrawerDF.Header\n            title=\"Заголовок дровера\"\n            subTitle=\"Подзаголовок здесь\"\n            badge={{ text: 'Label' }}\n            rightBlock={\n              <Flow\n                mainAxisGap={s.x1}\n                style={{ flexWrap: 'nowrap', gap: s.x4 }}\n              >\n                <DrawerDF.DotsIconButton />\n                <Button text=\"Вторичная 1\" size=\"xs\" view=\"secondary\" />\n              </Flow>\n            }\n            footerBlock={<TabsComp stretch />}\n          />",
          "sourceFile": "packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в DrawerDF.stories.tsx",
          "type": "usage",
          "code": "<DrawerDF.Header\n            title=\"Заголовок дровера\"\n            subTitle=\"Подзаголовок здесь\"\n            badge={{ text: 'Label' }}\n            rightBlock={\n              <Flow\n                mainAxisGap={s.x1}\n                style={{ flexWrap: 'nowrap', gap: s.x4 }}\n              >\n                <DrawerDF.DotsIconButton />\n                <Button text=\"Вторичная 1\" size=\"xs\" view=\"secondary\" />\n                <Button text=\"Главная кнопка\" size=\"xs\" view=\"accent\" />\n              </Flow>\n            }\n            footerBlock={<TabsComp stretch />}\n          />",
          "sourceFile": "packages/storybook/src/stories/DrawerDF/DrawerDF.stories.tsx"
        }
      ]
    },
    "Dropdown": {
      "name": "Dropdown",
      "group": "components",
      "folderName": "Dropdown",
      "role": "primary",
      "description": "Выпадающее меню с многоуровневым списком пунктов",
      "props": [],
      "propsTypeName": "DropdownProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Dropdown/Dropdown.d.ts",
      "type": "wrapper",
      "atomicBase": "Dropdown",
      "category": "Локальные компоненты",
      "keywords": [
        "выпадающее меню",
        "контекстное меню",
        "многоуровневый список"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "items",
          "type": "T[]",
          "required": true,
          "description": "Список элементов.",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "afterList",
          "type": "ReactNode",
          "required": false,
          "description": "Ячейка для контента в конце выпадающего списка.",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "alwaysOpened",
          "type": "boolean",
          "required": false,
          "description": "Выпадающий список открыт всегда.",
          "default": "false",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "beforeList",
          "type": "ReactNode",
          "required": false,
          "description": "Ячейка для контента в начале выпадающего списка.",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean",
          "required": false,
          "description": "Закрывать окно при нажатии вне области Dropdown.",
          "default": "true",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnSelect",
          "type": "boolean",
          "required": false,
          "description": "Закрыть выпадающий список после выбора.",
          "default": "true",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "itemRole",
          "type": "string",
          "required": false,
          "description": "WAI-ARIA role элемента меню.",
          "default": "option",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "listMaxHeight",
          "type": "Height<string | number>",
          "required": false,
          "description": "Максимальная высота выпадающего списка.",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "listWidth",
          "type": "Width<string | number>",
          "required": false,
          "description": "Значение css width для выпадающего списка.",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ выпадающего списка относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onHover",
          "type": "((index: number, item: T) => void)",
          "required": false,
          "description": "Обработчик наведения на item.",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onItemSelect",
          "type": "((item: T, event: SyntheticEvent<Element, Event>) => void)",
          "required": false,
          "description": "Обработчик выбора item.",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean, event?: Event | SyntheticEvent<Element, Event>) => void)",
          "required": false,
          "description": "Событие сворачивания/разворачивания Dropdown.",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "openByRightClick",
          "type": "boolean",
          "required": false,
          "description": "Открывает выпадающий список окно по правому клику мышью",
          "default": "false",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "DropdownPlacement",
          "required": false,
          "description": "Сторона открытия Dropdown относительно target элемента.",
          "default": "bottom",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "portal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "Портал для выпадающего списка. Принимает id контейнера или ref.",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderItem",
          "type": "((item: T) => ReactNode)",
          "required": false,
          "description": "Callback для кастомной настройки айтема в выпадающем списке.",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "trigger",
          "type": "DropdownTrigger",
          "required": false,
          "description": "Способ открытия Dropdown окна - наведение или клик мышью.",
          "default": "click",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "variant",
          "type": "\"normal\" | \"tight\"",
          "required": false,
          "description": "Вариант: обычный или сжатый",
          "default": "normal",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "ZIndex",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего списка.",
          "default": "1000",
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "children",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"m\" | \"xs\"",
          "required": false,
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "Dropdown",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Dropdown } from '@daisforge/ui';",
      "minimalUsage": "<Dropdown items={[]} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в PageLayout.stories.tsx",
          "type": "usage",
          "code": "<Dropdown items={navItems} portal=\"document\">\n      <IconButton size=\"s\" view=\"secondary\">\n        <IconHierarchy />\n      </IconButton>\n    </Dropdown>",
          "sourceFile": "packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в LeftPanel.stories.tsx",
          "type": "usage",
          "code": "<Dropdown items={contentItems} portal=\"document\">\n                <IconButton size={buttonSize} view=\"secondary\">\n                  <IconHierarchy />\n                </IconButton>\n              </Dropdown>",
          "sourceFile": "packages/storybook/src/stories/LeftPanel/LeftPanel.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Example 4",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Breadcrumbs, Dropdown } from '@daisforge/ui';\nexport function App() {\n    const items = [\n        { title: 'Home', href: '/' },\n        { title: 'About as', href: '/' },\n        {\n            renderItem: () => {\n                const itemsDropdown = [\n                    {\n                        value: 'Custom Item 1',\n                        label: 'Custom Item 1',\n                    },\n                    {\n                        value: 'Custom Item 2',\n                        label: 'Custom Item 2',\n                    },\n                ];\n                return (\n                    <Dropdown variant=\"tight\" placement=\"bottom\" items={itemsDropdown} trigger=\"hover\">\n                        <span>...</span>\n                    </Dropdown>\n                );\n            },\n        },\n        { title: 'Contacts' },\n    ];\n    return (\n        <div style={{height: '200px'}}>\n            <Breadcrumbs items={items} />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Примеры Примеры",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Button, Dropdown } from '@daisforge/ui';\nexport function App() {\n    const items = [\n        {\n            value: 'north_america',\n            label: 'Северная Америка',\n        },\n        {\n            value: 'south_america',\n            label: 'Южная Америка',\n            items: [\n                {\n                    value: 'brazil',\n                    label: 'Бразилия',\n                    items: [\n                        {\n                            value: 'rio_de_janeiro',\n                            label: 'Рио-де-Жанейро',\n                        },\n                        {\n                            value: 'sao_paulo',\n                            label: 'Сан-Паулу',\n                        },\n                    ],\n                },\n                {\n                    value: 'argentina',\n                    label: 'Аргентина',\n                },\n            ],\n        },\n    ];\n    return (\n        <div style={{ height:\"300px\" }}>\n            <Dropdown\n                items={items}\n            >\n                <Button text=\"Список стран\" />\n            </Dropdown>\n        </div>\n    );\n}"
        }
      ]
    },
    "Dropzone": {
      "name": "Dropzone",
      "group": "components",
      "folderName": "Dropzone",
      "role": "primary",
      "description": "Зона перетаскивания (drag-and-drop) файлов для загрузки",
      "props": [
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChange",
          "type": "React.ChangeEventHandler<HTMLInputElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "React.HTMLInputTypeAttribute | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "DropzoneProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Dropzone/Dropzone.d.ts",
      "type": "wrapper",
      "atomicBase": "Dropzone",
      "category": "Локальные компоненты",
      "keywords": [
        "загрузка файлов",
        "drag and drop",
        "перетаскивание файла"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "description",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "files",
          "type": "File[]",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "icon",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "iconPlacement",
          "type": "\"top\" | \"left\"",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChoseFiles",
          "type": "FileProcessHandler",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onDragEnter",
          "type": "((event: DragEvent<HTMLDivElement>) => void)",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onDragLeave",
          "type": "((event: DragEvent<HTMLDivElement>) => void)",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onDragOver",
          "type": "((event: DragEvent<HTMLDivElement>) => void)",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onDrop",
          "type": "FileProcessHandler",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"m\"",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "title",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "validator",
          "type": "((files: File[]) => ValidatorReturnType)",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "Dropzone",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Dropzone } from '@daisforge/ui';",
      "minimalUsage": "<Dropzone />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Растягивание Растягивание С помощью свойства  stretch  компонент растягивается на всю доступную ширину",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Dropzone } from '@daisforge/ui';\nexport function App() {\n    return (\n        <Dropzone\n            stretch\n            height={200}\n            iconPlacement=\"top\"\n            title=\"Click to upload\"\n            description=\"or drag and drop files here\"\n        />\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Множественный выбор",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Dropzone } from '@daisforge/ui';\nexport function App() {\n    return (\n        <Dropzone\n            multiple\n            iconPlacement=\"top\"\n            width={400}\n            height={280}\n            title=\"Click to upload\"\n            description=\"or drag and drop files here\"\n            onChoseFiles={({ acceptedFiles }) => console.log('Выбрано файлов:', acceptedFiles.length)}\n        />\n    );\n}"
        }
      ]
    },
    "EmbedIconButton": {
      "name": "EmbedIconButton",
      "group": "components",
      "folderName": "EmbedIconButton",
      "role": "primary",
      "description": "Компактная кнопка только с иконкой — для встраивания в текст, таблицы и плотные блоки UI",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "type",
          "type": "\"submit\" | \"reset\" | \"button\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof EmbedIconButton>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/EmbedIconButton/EmbedIconButton.d.ts",
      "type": "wrapper",
      "atomicBase": "EmbedIconButton",
      "category": "Локальные компоненты",
      "keywords": [
        "иконка-кнопка",
        "inline button",
        "компактное действие"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "additionalContent",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\"",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\"",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentPlacing",
          "type": "ContentPlacing",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focused",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isLoading",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "loader",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "outlined",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\"",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftLeft",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftRight",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\"",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "square",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretching",
          "type": "Stretching",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "string",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"info\"",
          "required": false,
          "inheritedFrom": "EmbedIconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { EmbedIconButton } from '@daisforge/ui';",
      "minimalUsage": "<EmbedIconButton />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в TableCanvas.multipleFeatures.stories.tsx",
          "type": "usage",
          "code": "<EmbedIconButton\n                      size=\"m\"\n                      onClick={() => {\n                        alert('Click on statusSelect in ControlBlock');\n                      }}\n                      title=\"custom feature status\"\n                      style={{\n                        width: '40px',\n                        height: '40px',\n                        display: 'flex',\n                        alignItems: 'center',\n                        justifyContent: 'center',\n                      }}\n                    >\n                      <IconSb size=\"s\" />\n                    </EmbedIconButton>",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.MultipleFeatures/TableCanvas.multipleFeatures.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в Table.multipleFeatures.stories.tsx",
          "type": "usage",
          "code": "<EmbedIconButton\n                      size=\"m\"\n                      onClick={() => {\n                        // eslint-disable-next-line no-alert\n                        alert('Click on customFeatureLabel2 in ControlBlock');\n                      }}\n                      title=\"custom feature 2\"\n                      style={{\n                        width: '40px',\n                        height: '40px',\n                        display: 'flex',\n                        alignItems: 'center',\n                        justifyContent: 'center',\n                      }}\n                    >\n                      <IconSber size=\"s\" />\n                    </EmbedIconButton>",
          "sourceFile": "packages/storybook/src/stories/Table/Table.multipleFeatures.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Компонент  EmbedIconButton  может содержать иконку, которая указывается напрямую через  children .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { EmbedIconButton } from '@daisforge/ui';\nimport { IconClose } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <EmbedIconButton>\n                <IconClose color=\"inherit\" />\n            </EmbedIconButton>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Размер кнопки",
          "type": "vendor",
          "code": "import React from 'react';\nimport { EmbedIconButton } from '@daisforge/ui';\nimport { IconClose } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <EmbedIconButton size=\"l\">\n                <IconClose color=\"inherit\" />\n            </EmbedIconButton>\n            <EmbedIconButton size=\"m\">\n                <IconClose color=\"inherit\" />\n            </EmbedIconButton>\n            <EmbedIconButton size=\"s\">\n                <IconClose color=\"inherit\" />\n            </EmbedIconButton>\n        </div>\n    );\n}"
        }
      ]
    },
    "EmbeddedButtonBeta": {
      "name": "EmbeddedButtonBeta",
      "group": "components",
      "folderName": "EmbeddedButtonBeta",
      "role": "primary",
      "description": "Кнопка-иконка для встраивания в поле ввода, карточку или контейнер (beta)",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "isLoading",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "loader",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "position",
          "type": "any",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"l\" | \"m\" | \"s\" | \"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"submit\" | \"reset\" | \"button\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"secondary\" | \"positive\" | \"warning\" | \"negative\" | \"info\" | \"gradient\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "EmbeddedButtonBetaCompProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/dist/beta/types/EmbeddedButton/EmbeddedButton.d.ts",
      "type": "wrapper",
      "atomicBase": "EmbeddedButton",
      "atomicSubpath": "beta",
      "category": "Локальные компоненты",
      "keywords": [
        "кнопка внутри поля",
        "icon button",
        "встроенная кнопка"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { EmbeddedButtonBeta } from '@daisforge/ui';",
      "minimalUsage": "<EmbeddedButtonBeta />",
      "examples": []
    },
    "EmptyState": {
      "name": "EmptyState",
      "group": "components",
      "folderName": "EmptyState",
      "role": "primary",
      "description": "Экран-заглушка с иллюстрацией, заголовком и кнопками для пустых или ошибочных состояний",
      "props": [
        {
          "name": "size",
          "type": "\"l\" | \"m\" | \"s\"",
          "required": true,
          "description": "Размер компонента (small, medium, large)"
        },
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные CSS-стили для контейнера"
        },
        {
          "name": "buttons",
          "type": "EmptyStateButtonProps[] | undefined",
          "required": false,
          "description": "Массив кнопок (до 2 для size='l', до 1 для других размеров)",
          "default": "[]"
        },
        {
          "name": "centered",
          "type": "boolean | undefined",
          "required": false,
          "description": "Центрировать контент по вертикали и горизонтали",
          "default": "false"
        },
        {
          "name": "classes",
          "type": "EmptyStateClasses | undefined",
          "required": false,
          "description": "Объект с классами для внутренних элементов",
          "default": "{}"
        },
        {
          "name": "extraButton",
          "type": "EmptyStateButtonProps | undefined",
          "required": false,
          "description": "Дополнительная кнопка (только для size='l')"
        },
        {
          "name": "subtitle",
          "type": "React.ReactNode",
          "required": false,
          "description": "Дополнительный поясняющий текст"
        },
        {
          "name": "title",
          "type": "React.ReactNode",
          "required": false,
          "description": "Основной заголовок состояния"
        },
        {
          "name": "variant",
          "type": "EmptyStateImageVariant | undefined",
          "required": false,
          "description": "Вариант изображения для отображения\nПоддерживаются варианты EmptyState (loading, life-circle, need-access, no-access, no-content, not-found, not-result)\nи варианты ErrorPage (400, 401, 403, 404, 500, 502, 503, unidentified)"
        },
        {
          "name": "icon",
          "type": "React.FC<IconProps> | undefined",
          "required": false,
          "description": "",
          "deprecated": true
        },
        {
          "name": "iconProps",
          "type": "Omit<IconProps, \"size\"> | undefined",
          "required": false,
          "description": "",
          "deprecated": true
        }
      ],
      "propsTypeName": "EmptyStateProps",
      "sourceFile": "packages/ui-kit/src/components/EmptyState/EmptyState.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "пустое состояние",
        "no data placeholder",
        "заглушка контента"
      ],
      "docs": "# EmptyState\n\nКомпонент для отображения состояния пустого контента с вариациями размеров и действий.\n\n## Ключевые особенности\n\n- Три размера: `s` (компактный, без иконки), `m`, `l` (с кнопками и доп. действиями)\n- Варианты: `loading`, `need-access`, `no-access`, `no-content`, `not-found`, `success`\n- Поддержка кнопок и ссылок через массив `buttons`\n- Дополнительная кнопка `extraButton` (только для размера `l`)\n- Кастомизация через `classes` и `$css`\n- Режим центрирования (`centered`)\n\n## Особенности\n\n- Картинки подставляются в зависимости от варианта на продуктовых сборках. В Storybook при смене вариантов картинка не меняется\n- Вариант `not-result` устарел (deprecated) — используйте `not-found`\n- Для размера `l` доступно до 2 кнопок в `buttons` и 1 `extraButton`\n- Для остальных размеров — максимум 1 кнопка\n- Пропсы `icon` и `iconProps` устарели — используйте `variant` для выбора картинки\n\nОписание типов — в разделе [API](/docs/композиции-emptystate-api--docs).",
      "apiDocs": "# EmptyState API\n\n## EmptyStateProps\n\n```typescript\ntype EmptyStateProps = {\n  /**\n   * Размер компонента (small, medium, large)\n   *   */\n  size: 's' | 'm' | 'l';\n  /**\n   * Основной заголовок состояния\n   *   */\n  title?: ReactNode;\n  /**\n   * Дополнительный поясняющий текст\n   *   */\n  subtitle?: ReactNode;\n  /**\n   * Вариант изображения для отображения\n   * Поддерживаются варианты EmptyState (loading, life-circle, need-access, no-access, no-content, not-found, not-result)\n   * и варианты ErrorPage (400, 401, 403, 404, 500, 502, 503, unidentified)\n   */\n  variant?: EmptyStateImageVariant;\n  /**\n   * @deprecated Используйте prop `variant` для отображения изображений.\n   * Компонент иконки (только для size='m' или для size='s')\n   * Оставлено для обратной совместимости.\n   */\n  icon?: React.FC<IconProps>;\n  /**\n   * @deprecated Используйте prop `variant` для отображения изображений.\n   * Дополнительные пропсы для иконки\n   * Оставлено для обратной совместимости.\n   */\n  iconProps?: Omit<IconProps, 'size'>;\n  /**\n   * Массив кнопок (до 2 для size='l', до 1 для других размеров)\n   */\n  buttons?: EmptyStateButtonProps[];\n  /**\n   * Дополнительная кнопка (только для size='l')\n   */\n  extraButton?: EmptyStateButtonProps;\n  /**\n   * Дополнительный класс для корневого элемента\n   */\n  className?: string;\n  /**\n   * Объект с классами для внутренних элементов\n   */\n  classes?: EmptyStateClasses;\n  /**\n   * Центрировать контент по вертикали и горизонтали\n   */\n  centered?: boolean;\n  /**\n   * Кастомные CSS-стили для контейнера\n   */\n  $css?: string | CSSObject | FlattenSimpleInterpolation;\n};\n```\n\n## EmptyStateVariant\n\n```typescript\ntype EmptyStateVariant =\n  | 'loading'\n  | 'life-circle'\n  | 'need-access'\n  | 'no-access'\n  | 'no-content'\n  | 'not-found'\n  /** @deprecated Используйте `'not-found'` */\n  | 'not-result'\n  | 'success';\n```\n\n## EmptyStateClasses\n\n```typescript\ntype EmptyStateClasses = {\n  root?: string;\n  icon?: string;\n  title?: string;\n  subtitle?: string;\n  buttons?: string;\n  extraButton?: string;\n};\n```\n\n## EmptyStateButtonProps\n\n```typescript\ntype EmptyStateButtonProps = ButtonVariant | LinkButtonVariant;\n```",
      "curatedStories": [
        {
          "exportName": "SizeS",
          "displayName": "Small (s)",
          "type": "args-only",
          "code": "{\n    size: 's',\n    title: 'Ничего не нашлось',\n    subtitle: 'Попробуйте изменить или сбросить фильтры',\n    variant: 'no-content',\n    buttons: [\n      {\n        type: 'link',\n        props: {\n          text: 'Сбросить фильтры',\n          view: 'accent',\n        },\n      },\n    ],\n  }"
        },
        {
          "exportName": "SizeM",
          "displayName": "Medium (m)",
          "type": "args-only",
          "code": "{\n    size: 'm',\n    title: 'Ничего не нашлось',\n    subtitle: 'Попробуйте изменить параметры поиска',\n    variant: 'not-found',\n    buttons: [\n      {\n        type: 'button',\n        props: {\n          text: 'Сбросить фильтры',\n          view: 'secondary', // Кнопка secondary\n        },\n      },\n    ],\n  }"
        },
        {
          "exportName": "SizeL",
          "displayName": "Large (l)",
          "type": "args-only",
          "code": "{\n    size: 'l',\n    title: 'Отчётов пока нет',\n    variant: 'no-content',\n    subtitle: 'Здесь вы можете создавать отчёты и работать над ними   ',\n    buttons: [\n      {\n        type: 'button',\n        props: {\n          text: 'Обновить',\n          view: 'secondary', // Первая кнопка secondary\n        },\n      },\n      {\n        type: 'button',\n        props: {\n          text: 'Создать отчёт',\n          view: 'accent', // Вторая кнопка accent\n        },\n      },\n    ],\n    extraButton: {\n      type: 'link',\n      props: {\n        text: 'Справка',\n        view: 'default',\n      },\n    },\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { EmptyState } from '@daisforge/ui';",
      "minimalUsage": "<EmptyState size={\"l\"} />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в TableCanvasContextMenu.stories.tsx",
          "type": "usage",
          "code": "<EmptyState\n                  size=\"s\"\n                  variant=\"no-content\"\n                  title=\"Не удалось загрузить\"\n                  subtitle=\"Проверьте соединение и повторите\"\n                  buttons={[\n                    {\n                      type: 'button',\n                      props: {\n                        text: 'Обновить',\n                        view: 'secondary',\n                        onClick: () =>\n                          menu.row && menu.key && load(menu.row, menu.key),\n                      },\n                    },\n                  ]}\n                />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.ContextMenu/TableCanvasContextMenu.stories.tsx"
        },
        {
          "exportName": "Vendor",
          "displayName": "Примеры Примеры",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Autocomplete, EmptyState, Spinner } from '@daisforge/ui';\nimport { IconRefresh } from '@salutejs/plasma-icons';\nexport function App() {\n    const mockData = [\n        { label: 'Алексей Смирнов' },\n        { label: 'Екатерина Иванова' },\n        { label: 'Дмитрий Петров' },\n        { label: 'Ольга Васильева' },\n        { label: 'Сергей Сидоров' },\n        { label: 'Мария Кузнецова' },\n        { label: 'Андрей Попов' },\n        { label: 'Анна Николаева' },\n        { label: 'Иван Федоров' },\n        { label: 'Наталья Морозова' },\n        { label: 'Михаил Павлов' },\n        { label: 'Елена Романова' },\n        { label: 'Владимир Киселев' },\n        { label: 'Татьяна Захарова' },\n        { label: 'Николай Семенов' },\n        { label: 'Юлия Белова' },\n        { label: 'Александр Гусев' },\n        { label: 'Оксана Яковлева' },\n        { label: 'Игорь Егорова' },\n        { label: 'Вера Тихомирова' },\n        { label: 'Артем Григорьев' },\n        { label: 'Евгения Козлова' },\n        { label: 'Максим Лебедев' },\n        { label: 'Виктория Калашникова' },\n        { label: 'Константин Абрамов' },\n        { label: 'Светлана Новикова' },\n        { label: 'Юрий Волков' },\n        { label: 'Валентина Воробьева' },\n        { label: 'Павел Сергеев' },\n        { label: 'Людмила Виноградова' },\n        { label: 'Антон Соловьев' },\n        { label: 'Маргарита Цветкова' },\n        { label: 'Роман Трофимов' },\n        { label: 'Лариса Зайцева' },\n        { label: 'Евгений Никитин' },\n        { label: 'Галина Михайлова' },\n        { label: 'Владислав Антонов' },\n        { label: 'Дарья Филатова' },\n        { label: 'Олег Буров' },\n        { label: 'Инна Медведева' },\n        { label: 'Вячеслав Крылов' },\n        { label: 'Тамара Беляева' },\n        { label: 'Кирилл Марков' },\n        { label: 'Марина Пономарева' },\n        { label: 'Борис Захаров' },\n        { label: 'Жанна Савельева' },\n        { label: 'Федор Жуков' },\n        { label: 'Елизавета Логинова' },\n        { label: 'Виктор Рыбаков' },\n        { label: 'Лилия Макарова' },\n    ];\n    const getData = async () => {\n        return new Promise((resolve) => {\n            setTimeout(() => {\n                resolve(mockData)\n            }, 1500)\n        })\n    }\n    const [isError, setIsError] = useState(true)\n    const [isLoading, setIsLoading] = useState(false)\n    const [value, setValue] \n// … (обрезано)"
        },
        {
          "exportName": "SizeS",
          "displayName": "Small (s)",
          "type": "args-only",
          "code": "{\n    size: 's',\n    title: 'Ничего не нашлось',\n    subtitle: 'Попробуйте изменить или сбросить фильтры',\n    variant: 'no-content',\n    buttons: [\n      {\n        type: 'link',\n        props: {\n          text: 'Сбросить фильтры',\n          view: 'accent',\n        },\n      },\n    ],\n  }"
        },
        {
          "exportName": "SizeM",
          "displayName": "Medium (m)",
          "type": "args-only",
          "code": "{\n    size: 'm',\n    title: 'Ничего не нашлось',\n    subtitle: 'Попробуйте изменить параметры поиска',\n    variant: 'not-found',\n    buttons: [\n      {\n        type: 'button',\n        props: {\n          text: 'Сбросить фильтры',\n          view: 'secondary', // Кнопка secondary\n        },\n      },\n    ],\n  }"
        }
      ]
    },
    "Flow": {
      "name": "Flow",
      "group": "components",
      "folderName": "Flow",
      "role": "primary",
      "description": "Гибкий контейнер для упорядоченного размещения карточек, медиа и блоков контента",
      "props": [
        {
          "name": "minColWidth",
          "type": "string | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof Flow>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Flow/Flow.d.ts",
      "type": "wrapper",
      "atomicBase": "Flow",
      "category": "Локальные компоненты",
      "keywords": [
        "flex layout",
        "автоматическая раскладка",
        "responsive контейнер"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "alignment",
          "type": "\"center\" | \"end\" | \"start\"",
          "required": false,
          "description": "Выравнивание элементов внутри строк по вертикали при горизонтальной ориентации,\nили внутри столбцов по горизонтали при вертикальной",
          "inheritedFrom": "Flow",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "arrangement",
          "type": "\"center\" | \"end\" | \"start\" | \"spaceBetween\" | \"spaceAround\"",
          "required": false,
          "description": "Расположение элементов относительно выбранной ориентации",
          "inheritedFrom": "Flow",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "crossAxisGap",
          "type": "string | number",
          "required": false,
          "description": "Фиксированный отступ между элементами по второстепенной оси",
          "inheritedFrom": "Flow",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "itemsPerLine",
          "type": "number",
          "required": false,
          "description": "Количество элементов по главной оси в отображении grid, при itemsPerLine > 0,\nиначе используется flex и flex-wrap",
          "inheritedFrom": "Flow",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "mainAxisGap",
          "type": "string | number",
          "required": false,
          "description": "Фиксированный отступ между элементами по главной оси",
          "inheritedFrom": "Flow",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\"",
          "required": false,
          "description": "Ориентация элементов",
          "default": "`horizontal`",
          "inheritedFrom": "Flow",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "className",
          "type": "string",
          "required": false,
          "inheritedFrom": "Flow",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "style",
          "type": "CSSProperties",
          "required": false,
          "inheritedFrom": "Flow",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Flow } from '@daisforge/ui';",
      "minimalUsage": "<Flow />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в Layout.stories.tsx",
          "type": "usage",
          "code": "<Flow crossAxisGap={10} mainAxisGap={10} orientation=\"horizontal\">\n        <Box $css={{ minWidth: '150px', background: '#ffffdf' }}>Текст 1</Box>\n        <Box $css={{ minWidth: '150px', background: '#ffffdf' }}>Текст 2</Box>\n        <Box $css={{ minWidth: '150px', background: '#ffffdf' }}>Текст 3</Box>\n      </Flow>",
          "sourceFile": "packages/storybook/src/stories/Layout/Layout.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в WidgetL.tsx",
          "type": "usage",
          "code": "<Flow\n                alignment=\"center\"\n                mainAxisGap=\"8px\"\n                style={{\n                  flexWrap: 'nowrap',\n                }}\n              >\n                <SegmentGroup hasBackground size=\"xs\">\n                  {someItems.map((_, i) => (\n                    <SegmentItem\n                      // eslint-disable-next-line react/no-array-index-key\n                      key={`item:${i}`}\n                      value={`item_${i}`}\n                      label={`Label${i + 1}`}\n                      size=\"xs\"\n                      view=\"secondary\"\n                    />\n                  ))}\n                </SegmentGroup>\n              </Flow>",
          "sourceFile": "packages/storybook/src/stories/AnalyticalWidget/components/WidgetL.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Горизонтальное отображение с переполнением",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Flow } from '@daisforge/ui';\nexport function App() {\n    const numbers = ['one', 'two', 'three', 'four', 'five', 'six'];\n    const style = (index) => ({\n        display: 'flex',\n        alignItems: 'center',\n        justifyContent: 'center',\n        width: `${2 + numbers[index].length}ch`,\n        height: '25px',\n        backgroundColor: '#999',\n        borderRadius: '10px',\n    });\n    return (\n        <div>\n            <Flow mainAxisGap=\"0.5ch\" crossAxisGap=\"1ch\" style={{ width: '15ch' }} >\n                {Array(6)\n                    .fill(0)\n                    .map((_, i) => (<div key={i} style={style(i)}>{numbers[i]}</div>))}\n            </Flow>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Отображение с разбиением на строки",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Flow } from '@daisforge/ui';\nexport function App() {\n    const numbers = ['one', 'two', 'three', 'four', 'five', 'six'];\n    const style = (index) => ({\n        display: 'flex',\n        alignItems: 'center',\n        justifyContent: 'center',\n        width: `${2 + numbers[index].length}ch`,\n        height: '25px',\n        backgroundColor: '#999',\n        borderRadius: '10px',\n    });\n    return (\n        <div>\n            <Flow\n                arrangement=\"end\"\n                itemsPerLine={2}\n                mainAxisGap=\"0.5ch\"\n                crossAxisGap=\"1ch\"\n            >\n                {Array(6)\n                    .fill(0)\n                    .map((_, i) => (<div key={i} style={style(i)}>{numbers[i]}</div>))}\n            </Flow>\n        </div>\n    );\n}"
        }
      ]
    },
    "Col": {
      "name": "Col",
      "group": "components",
      "folderName": "Grid",
      "role": "primary",
      "description": "Колонка адаптивной сетки: ширина и отступ настраиваются по брейкпоинтам",
      "props": [
        {
          "name": "offset",
          "type": "number | undefined",
          "required": false,
          "description": "Отступ ячейки, сдвинет ее на n ячеек вправо.\nБудет применен на всех вьюпортах, если не задать адаптивные отступы.\nНапример через smallM={{offset: 2}} или offsetS={2}"
        },
        {
          "name": "largeL",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "largeM",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "largeS",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "largeXL",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "largeXS",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "largeXXL",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "largeXXS",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mediumL",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mediumM",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mediumS",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mediumXL",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mediumXS",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mediumXXL",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mediumXXS",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "smallL",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "smallM",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "smallS",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "smallXL",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "smallXS",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "smallXXL",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "smallXXS",
          "type": "ScreenConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "offsetL",
          "type": "ColCount | undefined",
          "required": false,
          "description": "Отступ ячейки при разрешении L",
          "deprecated": true
        },
        {
          "name": "offsetM",
          "type": "ColCount | undefined",
          "required": false,
          "description": "Отступ ячейки при разрешении M",
          "deprecated": true
        },
        {
          "name": "offsetS",
          "type": "ColCount | undefined",
          "required": false,
          "description": "Отступ ячейки при разрешении S",
          "deprecated": true
        },
        {
          "name": "offsetXL",
          "type": "ColCount | undefined",
          "required": false,
          "description": "Отступ ячейки при разрешении XL",
          "deprecated": true
        },
        {
          "name": "offsetXXL",
          "type": "ColCount | undefined",
          "required": false,
          "description": "Отступ ячейки при разрешении XXL",
          "deprecated": true
        },
        {
          "name": "sizeL",
          "type": "ColCount | undefined",
          "required": false,
          "description": "Размер ячейки при разрешении L",
          "deprecated": true
        },
        {
          "name": "sizeM",
          "type": "ColCount | undefined",
          "required": false,
          "description": "Размер ячейки при разрешении M",
          "deprecated": true
        },
        {
          "name": "sizeS",
          "type": "ColCount | undefined",
          "required": false,
          "description": "Размер ячейки при разрешении S",
          "deprecated": true
        },
        {
          "name": "sizeXL",
          "type": "ColCount | undefined",
          "required": false,
          "description": "Размер ячейки при разрешении XL",
          "deprecated": true
        },
        {
          "name": "sizeXXL",
          "type": "ColCount | undefined",
          "required": false,
          "description": "Размер ячейки при разрешении XXL",
          "deprecated": true
        }
      ],
      "propsTypeName": "ColProps",
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Grid/ui/Col/Col.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "grid column",
        "адаптивная колонка",
        "responsive layout"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Col } from '@daisforge/ui';",
      "minimalUsage": "<Col />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Адаптивные размеры и отступы колонок",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Grid, Row, Col } from '@daisforge/ui';\nexport function App() {\n    const Filler = ({children}) => {\n        return (\n            <div\n                style={{\n                    display: 'flex',\n                    alignItems: 'center',\n                    justifyContent: 'center',\n                    width: '100%',\n                    padding: '0.5rem 1rem',\n                    backgroundColor: '#f0f0f0',\n                }}\n            >\n                {children}\n            </div>\n        )\n    };\n    return (\n        <Grid>\n            <Row>\n                <Col smallM={{ size: 1 }} mediumS={{ size: 2 }} mediumM={{ size: 3 }} largeM={{ size: 4 }}>\n                    <Filler>1</Filler>\n                </Col>\n                <Col size={2} largeM={{ size: 4 }}>\n                    <Filler>2</Filler>\n                </Col>\n            </Row>\n            <Row>\n                <Col size={4} smallM={{ offset: 1 }} mediumS={{ offset: 2 }} mediumM={{ offset: 3 }} largeM={{ offset: 4 }}>\n                    <Filler>4 offset 1</Filler>\n                </Col>\n                <Col size={6} offset={2} largeM={{ offset: 4 }}>\n                    <Filler>6 offset 2</Filler>\n                </Col>\n            </Row>\n        </Grid>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Базовое применение",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Grid, Row, Col } from '@daisforge/ui';\nexport function App() {\n    const Filler = ({children}) => {\n        return (\n            <div\n                style={{\n                    display: 'flex',\n                    alignItems: 'center',\n                    justifyContent: 'center',\n                    width: '100%',\n                    padding: '0.5rem 1rem',\n                    backgroundColor: '#f0f0f0',\n                }}\n            >\n                {children}\n            </div>\n        )\n    };\n    return (\n        <Grid>\n            <Row>\n                <Col size={3}>\n                    <Filler>3</Filler>\n                </Col>\n                <Col size={2}>\n                    <Filler>2</Filler>\n                </Col>\n                <Col size={3}>\n                    <Filler>3</Filler>\n                </Col>\n                <Col size={4}>\n                    <Filler>4</Filler>\n                </Col>\n                <Col size={6}>\n                    <Filler>6</Filler>\n                </Col>\n            </Row>\n            <Row>\n                <Col size={4} offset={1}>\n                    <Filler>4 offset 1</Filler>\n                </Col>\n                <Col size={6} offset={2}>\n                    <Filler>6 offset 2</Filler>\n                </Col>\n            </Row>\n        </Grid>\n    );\n}"
        }
      ]
    },
    "Grid": {
      "name": "Grid",
      "group": "components",
      "folderName": "Grid",
      "role": "primary",
      "description": "Контейнер сетки (Row/Col) для построения адаптивных раскладок страницы",
      "props": [],
      "propsTypeName": "GridProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Grid/Grid.d.ts",
      "type": "wrapper",
      "atomicBase": "Grid",
      "category": "Локальные компоненты",
      "keywords": [
        "grid system",
        "сетка страницы",
        "layout grid"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "description": "Вид сетки.",
          "inheritedFrom": "Grid",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maxWidth",
          "type": "string",
          "required": false,
          "inheritedFrom": "Grid",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Grid } from '@daisforge/ui';",
      "minimalUsage": "<Grid />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Адаптивные размеры и отступы колонок",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Grid, Row, Col } from '@daisforge/ui';\nexport function App() {\n    const Filler = ({children}) => {\n        return (\n            <div\n                style={{\n                    display: 'flex',\n                    alignItems: 'center',\n                    justifyContent: 'center',\n                    width: '100%',\n                    padding: '0.5rem 1rem',\n                    backgroundColor: '#f0f0f0',\n                }}\n            >\n                {children}\n            </div>\n        )\n    };\n    return (\n        <Grid>\n            <Row>\n                <Col smallM={{ size: 1 }} mediumS={{ size: 2 }} mediumM={{ size: 3 }} largeM={{ size: 4 }}>\n                    <Filler>1</Filler>\n                </Col>\n                <Col size={2} largeM={{ size: 4 }}>\n                    <Filler>2</Filler>\n                </Col>\n            </Row>\n            <Row>\n                <Col size={4} smallM={{ offset: 1 }} mediumS={{ offset: 2 }} mediumM={{ offset: 3 }} largeM={{ offset: 4 }}>\n                    <Filler>4 offset 1</Filler>\n                </Col>\n                <Col size={6} offset={2} largeM={{ offset: 4 }}>\n                    <Filler>6 offset 2</Filler>\n                </Col>\n            </Row>\n        </Grid>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Базовое применение",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Grid, Row, Col } from '@daisforge/ui';\nexport function App() {\n    const Filler = ({children}) => {\n        return (\n            <div\n                style={{\n                    display: 'flex',\n                    alignItems: 'center',\n                    justifyContent: 'center',\n                    width: '100%',\n                    padding: '0.5rem 1rem',\n                    backgroundColor: '#f0f0f0',\n                }}\n            >\n                {children}\n            </div>\n        )\n    };\n    return (\n        <Grid>\n            <Row>\n                <Col size={3}>\n                    <Filler>3</Filler>\n                </Col>\n                <Col size={2}>\n                    <Filler>2</Filler>\n                </Col>\n                <Col size={3}>\n                    <Filler>3</Filler>\n                </Col>\n                <Col size={4}>\n                    <Filler>4</Filler>\n                </Col>\n                <Col size={6}>\n                    <Filler>6</Filler>\n                </Col>\n            </Row>\n            <Row>\n                <Col size={4} offset={1}>\n                    <Filler>4 offset 1</Filler>\n                </Col>\n                <Col size={6} offset={2}>\n                    <Filler>6 offset 2</Filler>\n                </Col>\n            </Row>\n        </Grid>\n    );\n}"
        }
      ]
    },
    "Row": {
      "name": "Row",
      "group": "components",
      "folderName": "Grid",
      "role": "primary",
      "description": "Строка сетки для горизонтального размещения колонок внутри Grid",
      "props": [],
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Grid/ui/Row/Row.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "grid row",
        "строка сетки",
        "horizontal layout"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Row } from '@daisforge/ui';",
      "minimalUsage": "<Row />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Адаптивные размеры и отступы колонок",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Grid, Row, Col } from '@daisforge/ui';\nexport function App() {\n    const Filler = ({children}) => {\n        return (\n            <div\n                style={{\n                    display: 'flex',\n                    alignItems: 'center',\n                    justifyContent: 'center',\n                    width: '100%',\n                    padding: '0.5rem 1rem',\n                    backgroundColor: '#f0f0f0',\n                }}\n            >\n                {children}\n            </div>\n        )\n    };\n    return (\n        <Grid>\n            <Row>\n                <Col smallM={{ size: 1 }} mediumS={{ size: 2 }} mediumM={{ size: 3 }} largeM={{ size: 4 }}>\n                    <Filler>1</Filler>\n                </Col>\n                <Col size={2} largeM={{ size: 4 }}>\n                    <Filler>2</Filler>\n                </Col>\n            </Row>\n            <Row>\n                <Col size={4} smallM={{ offset: 1 }} mediumS={{ offset: 2 }} mediumM={{ offset: 3 }} largeM={{ offset: 4 }}>\n                    <Filler>4 offset 1</Filler>\n                </Col>\n                <Col size={6} offset={2} largeM={{ offset: 4 }}>\n                    <Filler>6 offset 2</Filler>\n                </Col>\n            </Row>\n        </Grid>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Базовое применение",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Grid, Row, Col } from '@daisforge/ui';\nexport function App() {\n    const Filler = ({children}) => {\n        return (\n            <div\n                style={{\n                    display: 'flex',\n                    alignItems: 'center',\n                    justifyContent: 'center',\n                    width: '100%',\n                    padding: '0.5rem 1rem',\n                    backgroundColor: '#f0f0f0',\n                }}\n            >\n                {children}\n            </div>\n        )\n    };\n    return (\n        <Grid>\n            <Row>\n                <Col size={3}>\n                    <Filler>3</Filler>\n                </Col>\n                <Col size={2}>\n                    <Filler>2</Filler>\n                </Col>\n                <Col size={3}>\n                    <Filler>3</Filler>\n                </Col>\n                <Col size={4}>\n                    <Filler>4</Filler>\n                </Col>\n                <Col size={6}>\n                    <Filler>6</Filler>\n                </Col>\n            </Row>\n            <Row>\n                <Col size={4} offset={1}>\n                    <Filler>4 offset 1</Filler>\n                </Col>\n                <Col size={6} offset={2}>\n                    <Filler>6 offset 2</Filler>\n                </Col>\n            </Row>\n        </Grid>\n    );\n}"
        }
      ]
    },
    "GridDND": {
      "name": "GridDND",
      "group": "components",
      "folderName": "GridDND",
      "role": "primary",
      "description": "Адаптивная сетка карточек-виджетов с drag-and-drop и изменением порядка/размера",
      "props": [
        {
          "name": "items",
          "type": "GridDNDItems[]",
          "required": true,
          "description": "Линейная последовательность виджетов (источник истины)"
        },
        {
          "name": "dragActivationDelay",
          "type": "number | undefined",
          "required": false,
          "description": "Задержка (мс) перед активацией режима перетаскивания.\nПри зажатии карточки запускается таймер, по истечении которого\nактивируется D&D, блокируется выделение текста (user-select: none).\nПри отпускании режим деактивируется.",
          "default": "0 (без задержки, D&D активен сразу)"
        },
        {
          "name": "allowOverlap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoSize",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "breakpoints",
          "type": "Record<string, number> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "children",
          "type": "React.ReactNode | ((item: GridDNDItemConfig, onRemove: () => void, onResize: (type: \"s\" | \"m\" | \"l\") => void) => React.ReactNode)",
          "required": false,
          "description": ""
        },
        {
          "name": "cols",
          "type": "Record<string, number> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "compactType",
          "type": "\"horizontal\" | \"vertical\" | null | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "containerPadding",
          "type": "[number, number] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "containerStyle",
          "type": "React.CSSProperties | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "draggableCancel",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "draggableHandle",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enableLogs",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "gridItemComponent",
          "type": "React.ComponentType<{ children: React.ReactNode; isDraggable: boolean; className?: string | undefined; }> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "gridStyle",
          "type": "React.CSSProperties | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isBounded",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isDraggable",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isResizable",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "margin",
          "type": "[number, number] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "maxRows",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onBreakpointChange",
          "type": "((breakpoint: string, layout: GridDNDLayout) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onDrag",
          "type": "ReactGridLayout.ItemCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onDragStart",
          "type": "ReactGridLayout.ItemCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onDragStop",
          "type": "ReactGridLayout.ItemCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onItemsChange",
          "type": "((items: GridDNDItemConfig[]) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onLayoutChange",
          "type": "((layout: GridDNDLayout, allLayouts: Record<string, ReactGridLayout.Layout[]>, meta: GridDNDMeta) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onResize",
          "type": "ReactGridLayout.ItemCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onResizeStart",
          "type": "ReactGridLayout.ItemCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onResizeStop",
          "type": "ReactGridLayout.ItemCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onWidthChange",
          "type": "((containerWidth: number, margin: [number, number], cols: number, containerPadding: [number, number]) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "preventCollision",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "resizeHandles",
          "type": "ResizeHandle[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rowHeights",
          "type": "Record<string, number> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "smartCompact",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "transformScale",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "useCSSTransforms",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "GridDNDProps",
      "compoundParts": [
        {
          "name": "ItemWrapper",
          "typeName": "GridDNDItemWrapperProps",
          "props": [
            {
              "name": "item",
              "type": "GridDNDItemConfig",
              "required": true,
              "description": ""
            },
            {
              "name": "actionsSlot",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            }
          ]
        }
      ],
      "sourceFile": "packages/ui-kit/src/components/GridDND/GridDND.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "drag and drop grid",
        "перетаскивание карточек",
        "dashboard widgets"
      ],
      "scope": "internal",
      "docs": "# GridDND\n\nКомпонент для создания адаптивных сеток с поддержкой перетаскивания элементов и автоматическим переносом между брейкпоинтами.\n\n## Ключевые особенности\n\n- Единый пропс `items` как источник истины (без сложной инициализации)\n- Три типа виджетов: `s` (1x1), `m` (2x1), `l` (2x2) с автоматической адаптацией\n- Мутации через `ref.api`: добавление, удаление, смена типа, переупорядочивание\n- Кастомные брейкпоинты и колонки\n- Алгоритм `packByItemsOrder` для предсказуемого размещения\n- Drag Handle и No-Drag Zones через CSS-классы\n\n## Быстрый старт\n\n### Базовое использование\n\n```tsx\n\nconst MyGrid = () => (\n  <GridDND\n    items={[\n      { id: 'widget-1', type: 's' },\n      { id: 'widget-2', type: 'm' },\n      { id: 'widget-3', type: 'l' },\n    ]}\n  >\n    {(item, onRemove) => (\n      <div key={item.id}>\n        <h3>Виджет {item.id}</h3>\n        <button onClick={onRemove}>Удалить</button>\n      </div>\n    )}\n  </GridDND>\n);\n```\n\n### Единый источник истины\n\nПропс `items` передаётся **один раз** — это начальный снимок (порядок + типы).\nВсе runtime-мутации идут через `ref.api.*`. После маунта изменения `items`\nв props игнорируются — это сделано специально, чтобы не было гонок с\nпользовательскими действиями (D&D, add/remove).\n\n```tsx\n// ПРАВИЛЬНО — передаём один раз при маунте\n<GridDND items={initialItems} />\n\n// НЕПРАВИЛЬНО — изменения после маунта не подхватятся\n<GridDND items={dynamicItems} />\n```\n\n### Мутации через `ref.api`\n\n- **Добавить** — `api.addItem({ id, type }, index?)`\n- **Удалить** — `api.removeItem(id)`\n- **Изменить type** — `api.setItemType(id, 's' | 'm' | 'l')`\n- **Переупорядочить** — `api.setOrder(ids)`\n- **Получить состояние** — `api.getOrder()`, `api.getOrderDetailed()`, `api.getCurrentLayout()`, `api.getAllLayouts()`\n\n```tsx\nconst gridRef = useRef<GridDNDRef>(null);\n\n// Пример: «вырастить» виджет w1 до L\ngridRef.current?.api.setItemType('w1', 'l');\n```\n\n### Для виджета, который сам меняет свой размер\n\nRender-prop получает 3 аргумента: `(item, onRemove, onResize)`. Функции\n`onRemove` и `onResize` уже пре-каррированы к `item.id` — под капотом вызывают\n`api.removeItem(id)` и `api.setItemType(id, type)` соответственно.\n\n```tsx\n<GridDND items={initialItems}>\n  {(item, onRemove, onResize) => (\n    <GridDND.ItemWrapper item={item}>\n      <MyWidget\n        type={item.type}\n        onResize={onResize} // onResize('l') — виджет сам себя растит\n        onRemove={onRemove}\n      />\n    </GridDND.ItemWrapper>\n  )}\n</GridDND>\n```\n\n> Важно: React-ключ по `item.id` стабилен, поэтому при `setItemType`/reflow\n> **React-инстанс виджета не размонтируется** — внутренний `useState`,\n> ссылки, фокусы сохраняются. Визуально меняется только размер ячейки.\n\n## Типы виджетов и размеры\n\nКомпонент поддерживает три типа виджетов:\n\n- **'s'** (small) - 1x1 ячейка\n- **'m'** (medium) - 2x1 ячейки\n- **'l'** (large) - 2x2 ячейки\n\nРазмеры автоматически адаптируются под количество колонок в брейкпоинте.\n\n## Адаптивность и брейкпоинты\n\n### Стандартные брейкпоинты\n\n```ts\n{\n  lg: 1857,  // 6 колонок\n  md: 1377,  // 6 колонок\n  sm: 1145,  // 5 колонок\n  xs: 913,   // 4 колонки\n  xxs: 0     // 4 колонки\n}\n```\n\n### Кастомные брейкпоинты\n\n```tsx\n<GridDND\n  breakpoints={{ desktop: 1440, tablet: 1024, mobile: 768 }}\n  cols={{ desktop: 8, tablet: 6, mobile: 4 }}\n  rowHeights={{ desktop: 200, tablet: 150, mobile: 100 }}\n/>\n```\n\n## Алгоритмы размещения\n\n### 1. Алгоритм packByItemsOrder\n\nОсновной алгоритм размещения элементов в порядке их следования:\n\n```tsx\n// Псевдокод алгоритма\nfunction packByItemsOrder(order, sizes, cols) {\n  // 1. Создаётся виртуальная сетка для отслеживания занятых ячеек\n  // 2. Для каждого элемента в порядке order:\n  // - Определяются размеры элемента (w x h)\n  // - Поиск начинается с текущей \"границы чтения\" (fy, fx)\n  // - Сначала проверяется текущая строка fy, начиная с позиции fx\n  // - Если не помещается - ищется ниже, начиная со строки fy+1\n  // 3. Найденное место занимается в виртуальной сетке\n  // 4. \"Граница чтения\" обновляется для следующего элемента\n}\n```\n\nКлючевые особенности алгоритма:\n\n- Сохраняет порядок чтения (слева направо, сверху вниз)\n- После перехода на новую строку возврат к предыдущим строкам невозможен\n- Оптимизирован для минимального количества \"дырок\" в сетке\n- Гарантирует предсказуемое расположение при изменении порядка элементов\n\n### 2. Алгоритм первого подходящего места (placeRectFirstFit)\n\nПри добавлении новых элементов используется алгоритм First Fit:\n\n- Создается виртуальная карта занятых ячеек\n- Поиск ведется от стартовой позиции (0,0 по умолчанию)\n- Находится первое свободное место нужного размера\n\n## Управление перетаскиванием\n\n### Drag Handle\n\nДля создания области перетаскивания добавьте класс `grid-dnd__drag-handle`:\n\n```tsx\n<div className=\"grid-dnd__drag-handle\">Перетаскивайте за эту область</div>\n```\n\n### No-Drag Zones\n\nЧтобы запретить перетаскивание за определенные элементы, используйте класс `grid-dnd__no-drag`:\n\n```tsx\n<button className=\"grid-dnd__no-drag\">\n  Эта кнопка не будет запускать перетаскивание\n</button>\n```\n\n### Кастомные handles\n\n```tsx\n<GridDND draggableHandle=\".my-drag-handle\">\n  <div className=\"my-drag-handle\">Перетаскивайте меня</div>\n</GridDND>\n```\n\n### Конфигурация отступов\n\n```tsx\n<GridDND\n  margin={[16, 16]} // Отступы между элементами [x, y]\n  containerPadding={[24, 24]} // Внутренние отступы контейнера\n/>\n```\n\n### Настройка поведения\n\n```tsx\n<GridDND\n  isDraggable={true} // Включить перетаскивание\n  isResizable={false} // Отключить изменение размера\n  preventCollision={true} // Предотвращать пересечения\n  compactType=\"vertical\" // Тип сжатия: 'vertical', 'horizontal', null\n  verticalCompact={true} // Вертикальное сжатие\n/>\n```\n\n> Подробнее о типах и пропсах — [GridDND API](?path=/docs/локальные-компоненты-griddnd-api--docs)",
      "apiDocs": "# GridDND API\n\n## GridDNDProps\n\n```typescript\ntype GridDNDProps = {\n  /** Линейная последовательность виджетов (источник истины) */\n  items: GridDNDItems[];\n\n  // Адаптивность\n  breakpoints?: Record<string, number>;\n  cols?: Record<string, number>;\n  rowHeights?: Record<string, number>;\n\n  // Поведение RGL\n  isDraggable?: boolean;\n  isResizable?: boolean;\n  margin?: [number, number];\n  containerPadding?: [number, number];\n  preventCollision?: boolean;\n  allowOverlap?: boolean;\n  isBounded?: boolean;\n  autoSize?: boolean;\n  useCSSTransforms?: boolean;\n  compactType?: ReactGridLayoutProps['compactType']; // default: \"horizontal\"\n  smartCompact?: boolean; // default: true\n  resizeHandles?: ReactGridLayoutProps['resizeHandles'];\n  draggableHandle?: string;\n  draggableCancel?: string;\n  maxRows?: ReactGridLayoutProps['maxRows'];\n  transformScale?: ReactGridLayoutProps['transformScale'];\n\n  // Колбеки\n  onLayoutChange?: (\n    layout: GridDNDLayout,\n    allLayouts: Record<string, Layout[]>,\n    meta: GridDNDMeta,\n  ) => void;\n  onBreakpointChange?: (breakpoint: string, layout: GridDNDLayout) => void;\n  onItemsChange?: (items: GridDNDItemConfig[]) => void;\n  onWidthChange?: ResponsiveProps['onWidthChange'];\n  onDrag?: ReactGridLayoutProps['onDrag'];\n  onDragStart?: ReactGridLayoutProps['onDragStart'];\n  onDragStop?: ReactGridLayoutProps['onDragStop'];\n  onResize?: ReactGridLayoutProps['onResize'];\n  onResizeStart?: ReactGridLayoutProps['onResizeStart'];\n  onResizeStop?: ReactGridLayoutProps['onResizeStop'];\n\n  // Контент\n  children?:\n    | React.ReactNode\n    | ((\n        item: GridDNDItemConfig,\n        onRemove: () => void,\n        onResize: (type: 's' | 'm' | 'l') => void,\n      ) => React.ReactNode);\n\n  /**\n   * Задержка (мс) перед активацией режима перетаскивания.\n   * При зажатии карточки запускается таймер, по истечении которого\n   * активируется D&D, блокируется выделение текста (user-select: none).\n   * При отпускании режим деактивируется.\n   * @default 0 (без задержки, D&D активен сразу)\n   */\n  dragActivationDelay?: number;\n\n  // Стили\n  gridItemComponent?: React.ComponentType<{\n    children: React.ReactNode;\n    isDraggable: boolean;\n    className?: string;\n  }>;\n  containerStyle?: React.CSSProperties;\n  gridStyle?: React.CSSProperties;\n  enableLogs?: boolean;\n};\n```\n\n## GridDNDItems\n\n```typescript\ntype GridDNDItems = {\n  id: string;\n  /** Размер по типу: s(1x1), m(2x1), l(2x2) */\n  type: 's' | 'm' | 'l';\n};\n```\n\n## GridDNDItemConfig\n\n```typescript\ntype GridDNDItemConfig = {\n  id: string;\n  type: 's' | 'm' | 'l';\n  position: { x: number; y: number; w: number; h: number };\n};\n```\n\n## GridDNDRef\n\n```typescript\ntype GridDNDRef = {\n  api: {\n    /** Текущий порядок id (канонический) */\n    getOrder: () => string[];\n    /** Текущий порядок id + type элемента */\n    getOrderDetailed: () => GridDNDItems[];\n    /** Установить порядок и переложить всё */\n    setOrder: (order: string[]) => void;\n    /** Добавить в конец (или с индексом) и переложить */\n    addItem: (spec: GridDNDItems, index?: number) => void;\n    /** Удалить и переложить */\n    removeItem: (id: string) => void;\n    /** Изменить type (и размер) существующего виджета и переложить */\n    setItemType: (id: string, type: 's' | 'm' | 'l') => void;\n    /** Сырые layouts RGL по всем брейкпоинтам */\n    getAllLayouts: () => Record<string, Layout[]>;\n    /** Текущий GridDNDLayout (для активного BP) */\n    getCurrentLayout: () => GridDNDLayout;\n  };\n};\n```",
      "curatedStories": [
        {
          "exportName": "DragDelay",
          "displayName": "Задержка активации D&D (dragActivationDelay)",
          "type": "full-code",
          "code": "render() {\n    const gridRef = useRef<GridDNDRef>(null);\n    const [items] = useState<GridDNDItems[]>([\n      { id: 'w1', type: 'm' },\n      { id: 'w2', type: 's' },\n      { id: 'w3', type: 's' },\n      { id: 'w4', type: 'm' },\n      { id: 'w5', type: 's' },\n    ]);\n\n    const renderItem = useCallback(\n      (item: GridDNDItemConfig, onRemove: () => void) => (\n        <GridDND.ItemWrapper\n          item={item}\n          actionsSlot={\n            <AnalyticalWidget.DotsIconButton\n              absolute\n              dropdownProps={{\n                items: [{ label: 'Удалить', value: 'Удалить' }],\n                onItemSelect() {\n                  onRemove();\n                },\n              }}\n            />\n          }\n        >\n          {item.type === 's' && <WidgetS id={item.id} onRemove={onRemove} />}\n          {item.type === 'm' && <WidgetM id={item.id} onRemove={onRemove} />}\n        </GridDND.ItemWrapper>\n      ),\n      [],\n    );\n\n    return (\n      <div>\n        <div style={{ marginBottom: 12, color: '#666', fontSize: 14 }}>\n          Зажмите карточку на 500мс для активации перетаскивания. Обводка\n          появится только у зажатой карточки.\n        </div>\n        <div style={{ width: 1200, background: 'lightGray' }}>\n          <GridDND\n            ref={gridRef}\n            items={items}\n            isDraggable\n            dragActivationDelay={500}\n            compactType=\"horizontal\"\n            // eslint-disable-next-line react/no-children-prop\n            children={renderItem}\n            onLayoutChange={(layout, _allAreas, meta) => {\n              console.debug('Layout changed:', layout, meta);\n            }}\n          />\n        </div>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "GridDNDClassic",
          "displayName": "GridDND Classic",
          "type": "full-code",
          "code": "import { GridDND } from '@daisforge/ui';\n\nrender() {\n    const gridRef = useRef<GridDNDRef>(null);\n    const [items, setItems] = useState<GridDNDItems[]>([]);\n    const [width, setWidth] = useState(1660);\n    const [drag, setDrag] = useState(true);\n    const [loading, setLoading] = useState(true);\n    const [smartCompact, setSmartCompact] = useState(true);\n    const [compactType, setCompactType] = useState<\n      'vertical' | 'horizontal' | null\n    >('horizontal');\n\n    const renderItem = useCallback(\n      (item: GridDNDItemConfig, onRemove: () => void) => (\n        <GridDND.ItemWrapper\n          item={item}\n          actionsSlot={\n            <AnalyticalWidget.DotsIconButton\n              absolute\n              dropdownProps={{\n                items: [{ label: 'Удалить', value: 'Удалить' }],\n                onItemSelect(m) {\n                  if (m.value?.toString().toLowerCase() === 'удалить')\n                    onRemove();\n                },\n              }}\n            />\n          }\n        >\n          {item.type === 's' && <WidgetS id={item.id} onRemove={onRemove} />}\n          {item.type === 'm' && <WidgetM id={item.id} onRemove={onRemove} />}\n          {item.type === 'l' && <WidgetL id={item.id} onRemove={onRemove} />}\n        </GridDND.ItemWrapper>\n      ),\n      [],\n    );\n\n    const handleReorder = () => {\n      const currentOrder = gridRef.current?.api.getOrder() || [];\n      // Перевернуть порядок\n      gridRef.current?.api.setOrder([...currentOrder].reverse());\n    };\n\n    const saveItems = useCallback(async (newItems: GridDNDItems[]) => {\n      try {\n        console.log('💾 Saving items to server:', newItems);\n        await fetch(gridDndRoutes.ENDPOINTS.PUT_ITEMS, {\n          method: 'PUT',\n          headers: { 'Content-Type': 'application/json' },\n          body: JSON.stringify({ items: newItems }),\n        });\n        console.log('✅ Items saved successfully');\n      } catch (error) {\n        console.error('❌ Failed to save items:', error);\n      }\n    }, []);\n\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    const debouncedSave = useCallback(\n      debounce((newItems: GridDNDItems[]) => {\n        saveItems(newItems);\n      }, 800),\n      [saveItems],\n    );\n\n    // Загрузка initial items с сервера\n    useEffect(() => {\n      const fetchInitialItems = async () => {\n        try {\n          const response = await fetch(gridDndRoutes.ENDPOINTS.GET_ITEMS);\n          const data = await response.json();\n          setItems(data.items);\n        } catch (error) {\n          console.error('Failed to fetch items:', error);\n        } finally {\n          setLoading(false);\n        }\n      };\n\n      fetchInitialItems();\n    }, []);\n\n    if (loading) {\n      return <div>Loading...</div>;\n    }\n\n    return (\n      <div>\n        <div\n          style={{\n            display: 'flex',\n            gap: 8,\n            alignItems: 'center',\n            marginBottom: 12,\n          }}\n        >\n          <span>Width: {width}px</span>\n          <input\n            type=\"range\"\n            min={600}\n            max={1890}\n            step={10}\n            value={width}\n            onChange={(e) => setWidth(+e.target.value)}\n          />\n          <Switch\n            onChange={(e) => setDrag(e.target.checked)}\n            label=\"Activate DND\"\n            checked={drag}\n          />\n          <Switch\n            onChange={(e) => setSmartCompact(e.target.checked)}\n            label=\"Activate Smart Compact\"\n            checked={smartCompact}\n          />\n          <Switch\n            onChange={(e) =>\n              setCompactType(e.target.checked ? 'vertical' : null)\n            }\n            label=\"Activate Compact Type Vertical\"\n            checked={compactType === 'vertical'}\n          />\n          <Switch\n            onChange={(e) =>\n              setCompactType(e.target.checked ? 'horizontal' : null)\n            }\n            label=\"Activate Compact Type Horizontal\"\n            checked={compactType === 'horizontal'}\n          />\n        </div>\n        <div\n          style={{\n            marginBottom: '30px',\n            display: 'flex',\n            gap: '8px',\n          }}\n        >\n          <Button\n            onClick={() => {\n              console.debug(gridRef.current?.api.getOrderDetailed());\n            }}\n          >\n            Get Order Detail\n          </Button>\n          <Button\n            onClick={() =>\n              console.debug('Current layout:', gridRef.current?.api.getOrder())\n            }\n          >\n            Get Order\n          </Button>\n          <Button\n            onClick={() =>\n              console.debug(\n                'Current template area:',\n                gridRef.current?.api.getCurrentLayout(),\n              )\n            }\n          >\n            Get Current Layout\n          </Button>\n          <Button\n            onClick={() =>\n              console.debug(\n                'All template areas:',\n                gridRef.current?.api.getAllLayouts(),\n              )\n            }\n          >\n            Get All Layouts\n          </Button>\n          <Button\n            onClick={() => {\n              const id = prompt('Enter id');\n              const type = prompt('Enter type (s, m, l)');\n              if (\n                !id ||\n                !type ||\n                !gridRef.current ||\n                (type !== 's' && type !== 'm' && type !== 'l')\n              )\n                return;\n              gridRef.current?.api.addItem({\n                id,\n                type,\n              });\n            }}\n          >\n            + Add widget\n          </Button>\n          <Button onClick={() => handleReorder()}>Reorder</Button>\n        </div>\n\n        <div style={{ width, background: 'lightGray' }}>\n          <GridDND\n            ref={gridRef}\n            items={items}\n            compactType=\"horizontal\"\n            smartCompact={smartCompact}\n            // eslint-disable-next-line react/no-children-prop\n            children={renderItem}\n            onItemsChange={(items) =>\n              console.debug('📦 Template Items changed:', items)\n            }\n            onLayoutChange={(layout, allAreas, meta) => {\n              console.group('📐 Template Layout changed:');\n              console.debug('Layout:', layout);\n              console.debug('All areas:', allAreas);\n              console.debug('Meta:', meta);\n              if (meta.itemsOrderTyped) {\n                console.debug('🔄 Items order changed, saving...');\n                debouncedSave(meta.itemsOrderTyped);\n              }\n              console.groupEnd();\n            }}\n            onBreakpointChange={(breakpoint: string, layout: unknown) => {\n              console.group('📱 Template Breakpoint changed:');\n              console.debug('Breakpoint:', breakpoint);\n              console.debug('Layout:', layout);\n              console.groupEnd();\n            }}\n            isDraggable={drag}\n          />\n        </div>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "SelfResize",
          "displayName": "Самоизменение типа виджета (через onResize)",
          "type": "full-code",
          "code": "render() {\n    const gridRef = useRef<GridDNDRef>(null);\n    const [items] = useState<GridDNDItems[]>([\n      { id: 'w1', type: 's' },\n      { id: 'w2', type: 's' },\n      { id: 'w3', type: 'm' },\n      { id: 'w4', type: 's' },\n      { id: 'w5', type: 's' },\n      { id: 'w6', type: 's' },\n    ]);\n\n    const renderItem = useCallback(\n      (\n        item: GridDNDItemConfig,\n        onRemove: () => void,\n        onResize: (type: 's' | 'm' | 'l') => void,\n      ) => (\n        <GridDND.ItemWrapper item={item}>\n          <ResizableAnalyticalWidget\n            id={item.id}\n            type={item.type}\n            onResize={onResize}\n            onRemove={onRemove}\n          />\n        </GridDND.ItemWrapper>\n      ),\n      [],\n    );\n\n    return (\n      <div style={{ padding: 12 }}>\n        <div style={{ marginBottom: 12, color: '#444', fontSize: 13 }}>\n          Зажми карточку на 500мс — активируется D&D. Кнопки «→ S/M/L» внутри\n          виджета вызывают <code>onResize(type)</code> (3-й аргумент\n          render-prop, пре-каррирован к <code>cfg.id</code>). GridDND через\n          <code> api.setItemType </code> меняет размер и делает reflow. Счётчик\n          не сбрасывается — React-инстансы не размонтируются.\n        </div>\n        <div style={{ width: 1200, background: 'lightGray' }}>\n          <GridDND\n            ref={gridRef}\n            items={items}\n            isDraggable\n            dragActivationDelay={500}\n            compactType=\"horizontal\"\n            // eslint-disable-next-line react/no-children-prop\n            children={renderItem}\n            onItemsChange={(next) => console.debug('📦 items', next)}\n            onLayoutChange={(layout, _all, meta) =>\n              console.debug('📐 layout', layout, meta)\n            }\n          />\n        </div>\n      </div>\n    );\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { GridDND } from '@daisforge/ui';",
      "minimalUsage": "<GridDND items={[]}>\n  {/* части: GridDND.ItemWrapper */}\n</GridDND>",
      "examples": [
        {
          "exportName": "DragDelay",
          "displayName": "Задержка активации D&D (dragActivationDelay)",
          "type": "full-code",
          "code": "render() {\n    const gridRef = useRef<GridDNDRef>(null);\n    const [items] = useState<GridDNDItems[]>([\n      { id: 'w1', type: 'm' },\n      { id: 'w2', type: 's' },\n      { id: 'w3', type: 's' },\n      { id: 'w4', type: 'm' },\n      { id: 'w5', type: 's' },\n    ]);\n\n    const renderItem = useCallback(\n      (item: GridDNDItemConfig, onRemove: () => void) => (\n        <GridDND.ItemWrapper\n          item={item}\n          actionsSlot={\n            <AnalyticalWidget.DotsIconButton\n              absolute\n              dropdownProps={{\n                items: [{ label: 'Удалить', value: 'Удалить' }],\n                onItemSelect() {\n                  onRemove();\n                },\n              }}\n            />\n          }\n        >\n          {item.type === 's' && <WidgetS id={item.id} onRemove={onRemove} />}\n          {item.type === 'm' && <WidgetM id={item.id} onRemove={onRemove} />}\n        </GridDND.ItemWrapper>\n      ),\n      [],\n    );\n\n    return (\n      <div>\n        <div style={{ marginBottom: 12, color: '#666', fontSize: 14 }}>\n          Зажмите карточку на 500мс для активации перетаскивания. Обводка\n          появится только у зажатой карточки.\n        </div>\n        <div style={{ width: 1200, background: 'lightGray' }}>\n          <GridDND\n            ref={gridRef}\n            items={items}\n            isDraggable\n            dragActivationDelay={500}\n            compactType=\"horizontal\"\n            // eslint-disable-next-line react/no-children-prop\n            children={renderItem}\n            onLayoutChange={(layout, _allAreas, meta) => {\n              console.debug('Layout changed:', layout, meta);\n            }}\n          />\n        </div>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "GridDNDClassic",
          "displayName": "GridDND Classic",
          "type": "full-code",
          "code": "import { GridDND } from '@daisforge/ui';\n\nrender() {\n    const gridRef = useRef<GridDNDRef>(null);\n    const [items, setItems] = useState<GridDNDItems[]>([]);\n    const [width, setWidth] = useState(1660);\n    const [drag, setDrag] = useState(true);\n    const [loading, setLoading] = useState(true);\n    const [smartCompact, setSmartCompact] = useState(true);\n    const [compactType, setCompactType] = useState<\n      'vertical' | 'horizontal' | null\n    >('horizontal');\n\n    const renderItem = useCallback(\n      (item: GridDNDItemConfig, onRemove: () => void) => (\n        <GridDND.ItemWrapper\n          item={item}\n          actionsSlot={\n            <AnalyticalWidget.DotsIconButton\n              absolute\n              dropdownProps={{\n                items: [{ label: 'Удалить', value: 'Удалить' }],\n                onItemSelect(m) {\n                  if (m.value?.toString().toLowerCase() === 'удалить')\n                    onRemove();\n                },\n              }}\n            />\n          }\n        >\n          {item.type === 's' && <WidgetS id={item.id} onRemove={onRemove} />}\n          {item.type === 'm' && <WidgetM id={item.id} onRemove={onRemove} />}\n          {item.type === 'l' && <WidgetL id={item.id} onRemove={onRemove} />}\n        </GridDND.ItemWrapper>\n      ),\n      [],\n    );\n\n    const handleReorder = () => {\n      const currentOrder = gridRef.current?.api.getOrder() || [];\n      // Перевернуть порядок\n      gridRef.current?.api.setOrder([...currentOrder].reverse());\n    };\n\n    const saveItems = useCallback(async (newItems: GridDNDItems[]) => {\n      try {\n        console.log('💾 Saving items to server:', newItems);\n        await fetch(gridDndRoutes.ENDPOINTS.PUT_ITEMS, {\n          method: 'PUT',\n          headers: { 'Content-Type': 'application/json' },\n          body: JSON.stringify({ items: newItems }),\n        });\n        console.log('✅ Items saved successfully');\n      } catch (error) {\n        console.error('❌ Failed to save items:', error);\n      }\n    }, []);\n\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n    const debouncedSave = useCallback(\n      debounce((newItems: GridDNDItems[]) => {\n        saveItems(newItems);\n      }, 800),\n      [saveItems],\n    );\n\n    // Загрузка initial items с сервера\n    useEffect(() => {\n      const fetchInitialItems = async () => {\n        try {\n          const response = await fetch(gridDndRoutes.ENDPOINTS.GET_ITEMS);\n          const data = await response.json();\n          setItems(data.items);\n        } catch (error) {\n          console.error('Failed to fetch items:', error);\n        } finally {\n          setLoading(false);\n        }\n      };\n\n      fetchInitialItems();\n    }, []);\n\n    if (loading) {\n      return <div>Loading...</div>;\n    }\n\n    return (\n      <div>\n        <div\n          style={{\n            display: 'flex',\n            gap: 8,\n            alignItems: 'center',\n            marginBottom: 12,\n          }}\n        >\n          <span>Width: {width}px</span>\n          <input\n            type=\"range\"\n            min={600}\n            max={1890}\n            step={10}\n            value={width}\n            onChange={(e) => setWidth(+e.target.value)}\n          />\n          <Switch\n            onChange={(e) => setDrag(e.target.checked)}\n            label=\"Activate DND\"\n            checked={drag}\n          />\n          <Switch\n            onChange={(e) => setSmartCompact(e.target.checked)}\n            label=\"Activate Smart Compact\"\n            checked={smartCompact}\n          />\n          <Switch\n            onChange={(e) =>\n              setCompactType(e.target.checked ? 'vertical' : null)\n            }\n            label=\"Activate Compact Type Vertical\"\n            checked={compactType === 'vertical'}\n          />\n          <Switch\n            onChange={(e) =>\n              setCompactType(e.target.checked ? 'horizontal' : null)\n            }\n            label=\"Activate Compact Type Horizontal\"\n            checked={compactType === 'horizontal'}\n          />\n        </div>\n        <div\n          style={{\n            marginBottom: '30px',\n            display: 'flex',\n            gap: '8px',\n          }}\n        >\n          <Button\n            onClick={() => {\n              console.debug(gridRef.current?.api.getOrderDetailed());\n            }}\n          >\n            Get Order Detail\n          </Button>\n          <Button\n            onClick={() =>\n              console.debug('Current layout:', gridRef.current?.api.getOrder())\n            }\n          >\n            Get Order\n          </Button>\n          <Button\n            onClick={() =>\n              console.debug(\n                'Current template area:',\n                gridRef.current?.api.getCurrentLayout(),\n              )\n            }\n          >\n            Get Current Layout\n          </Button>\n          <Button\n            onClick={() =>\n              console.debug(\n                'All template areas:',\n                gridRef.current?.api.getAllLayouts(),\n              )\n            }\n          >\n            Get All Layouts\n          </Button>\n          <Button\n            onClick={() => {\n              const id = prompt('Enter id');\n              const type = prompt('Enter type (s, m, l)');\n              if (\n                !id ||\n                !type ||\n                !gridRef.current ||\n                (type !== 's' && type !== 'm' && type !== 'l')\n              )\n                return;\n              gridRef.current?.api.addItem({\n                id,\n                type,\n              });\n            }}\n          >\n            + Add widget\n          </Button>\n          <Button onClick={() => handleReorder()}>Reorder</Button>\n        </div>\n\n        <div style={{ width, background: 'lightGray' }}>\n          <GridDND\n            ref={gridRef}\n            items={items}\n            compactType=\"horizontal\"\n            smartCompact={smartCompact}\n            // eslint-disable-next-line react/no-children-prop\n            children={renderItem}\n            onItemsChange={(items) =>\n              console.debug('📦 Template Items changed:', items)\n            }\n            onLayoutChange={(layout, allAreas, meta) => {\n              console.group('📐 Template Layout changed:');\n              console.debug('Layout:', layout);\n              console.debug('All areas:', allAreas);\n              console.debug('Meta:', meta);\n              if (meta.itemsOrderTyped) {\n                console.debug('🔄 Items order changed, saving...');\n                debouncedSave(meta.itemsOrderTyped);\n              }\n              console.groupEnd();\n            }}\n            onBreakpointChange={(breakpoint: string, layout: unknown) => {\n              console.group('📱 Template Breakpoint changed:');\n              console.debug('Breakpoint:', breakpoint);\n              console.debug('Layout:', layout);\n              console.groupEnd();\n            }}\n            isDraggable={drag}\n          />\n        </div>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "SelfResize",
          "displayName": "Самоизменение типа виджета (через onResize)",
          "type": "full-code",
          "code": "render() {\n    const gridRef = useRef<GridDNDRef>(null);\n    const [items] = useState<GridDNDItems[]>([\n      { id: 'w1', type: 's' },\n      { id: 'w2', type: 's' },\n      { id: 'w3', type: 'm' },\n      { id: 'w4', type: 's' },\n      { id: 'w5', type: 's' },\n      { id: 'w6', type: 's' },\n    ]);\n\n    const renderItem = useCallback(\n      (\n        item: GridDNDItemConfig,\n        onRemove: () => void,\n        onResize: (type: 's' | 'm' | 'l') => void,\n      ) => (\n        <GridDND.ItemWrapper item={item}>\n          <ResizableAnalyticalWidget\n            id={item.id}\n            type={item.type}\n            onResize={onResize}\n            onRemove={onRemove}\n          />\n        </GridDND.ItemWrapper>\n      ),\n      [],\n    );\n\n    return (\n      <div style={{ padding: 12 }}>\n        <div style={{ marginBottom: 12, color: '#444', fontSize: 13 }}>\n          Зажми карточку на 500мс — активируется D&D. Кнопки «→ S/M/L» внутри\n          виджета вызывают <code>onResize(type)</code> (3-й аргумент\n          render-prop, пре-каррирован к <code>cfg.id</code>). GridDND через\n          <code> api.setItemType </code> меняет размер и делает reflow. Счётчик\n          не сбрасывается — React-инстансы не размонтируются.\n        </div>\n        <div style={{ width: 1200, background: 'lightGray' }}>\n          <GridDND\n            ref={gridRef}\n            items={items}\n            isDraggable\n            dragActivationDelay={500}\n            compactType=\"horizontal\"\n            // eslint-disable-next-line react/no-children-prop\n            children={renderItem}\n            onItemsChange={(next) => console.debug('📦 items', next)}\n            onLayoutChange={(layout, _all, meta) =>\n              console.debug('📐 layout', layout, meta)\n            }\n          />\n        </div>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в GridDND.stories.tsx",
          "type": "usage",
          "code": "<GridDND\n            ref={gridRef}\n            items={items}\n            compactType=\"horizontal\"\n            smartCompact={smartCompact}\n            // eslint-disable-next-line react/no-children-prop\n            children={renderItem}\n            onItemsChange={(items) =>\n              console.debug('📦 Template Items changed:', items)\n            }\n            onLayoutChange={(layout, allAreas, meta) => {\n              console.group('📐 Template Layout changed:');\n              console.debug('Layout:', layout);\n              console.debug('All areas:', allAreas);\n              console.debug('Meta:', meta);\n              if (meta.itemsOrderTyped) {\n                console.debug('🔄 Items order changed, saving...');\n                debouncedSave(meta.itemsOrderTyped);\n              }\n              console.groupEnd();\n            }}\n            onBreakpointChange={(breakpoint: string, layout: unknown) => {\n              console.group('📱 Template Breakpoint changed:');\n              console.debug('Breakpoint:', breakpoint);\n              console.debug('Layout:', layout);\n              console.groupEnd();\n            }}\n            isDraggable={drag}\n          />",
          "sourceFile": "packages/storybook/src/stories/GridDND/GridDND.stories.tsx"
        }
      ]
    },
    "IconButton": {
      "name": "IconButton",
      "group": "components",
      "folderName": "IconButton",
      "role": "primary",
      "description": "Кнопка только с иконкой без текста, разных размеров и цветовых вариантов",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "type",
          "type": "\"button\" | \"submit\" | \"reset\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "IconButtonProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/IconButton/IconButton.d.ts",
      "type": "wrapper",
      "atomicBase": "IconButton",
      "category": "Локальные компоненты",
      "keywords": [
        "icon-only button",
        "кнопка-иконка",
        "compact action button"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "additionalContent",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentPlacing",
          "type": "ContentPlacing",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focused",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isLoading",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "loader",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "outlined",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftLeft",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftRight",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "square",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretching",
          "type": "Stretching",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "string",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"secondary\" | \"black\" | \"white\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { IconButton } from '@daisforge/ui';",
      "minimalUsage": "<IconButton />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в AiChatDAIS.tsx",
          "type": "usage",
          "code": "<IconButton\n                  view=\"accent\"\n                  size=\"xs\"\n                  id=\"send\"\n                  onClick={() => send()}\n                  type=\"button\"\n                  disabled={isSending}\n                >\n                  <IconSendOutline size=\"xs\" color=\"inherit\" />\n                </IconButton>",
          "sourceFile": "packages/storybook/src/stories/AiChatDAIS/AiChatDAIS.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в CopyCodeAbsoluteButton.tsx",
          "type": "usage",
          "code": "<IconButton\n        size=\"xxs\"\n        view=\"clear\"\n        onClick={handleCopy}\n        title={copied ? 'Скопировано' : 'Скопировать код'}\n        onMouseEnter={(e) => {\n          (e.currentTarget as HTMLButtonElement).style.opacity = '1';\n        }}\n        onMouseLeave={(e) => {\n          (e.currentTarget as HTMLButtonElement).style.opacity = '0.6';\n        }}\n      >\n        {copied ? (\n          <IconDone size=\"xs\" color=\"inherit\" />\n        ) : (\n          <IconCopyFill size=\"xs\" color=\"inherit\" />\n        )}\n      </IconButton>",
          "sourceFile": "packages/storybook/src/stories/AiChatDAIS/components/CopyCodeAbsoluteButton.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Компонент  IconButton  может содержать иконку, которая указывается напрямую через  children .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconButton } from '@daisforge/ui';\nimport { IconClose } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <IconButton>\n                <IconClose color=\"inherit\" />\n            </IconButton>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Границы кнопки",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconButton } from '@daisforge/ui';\nimport { IconClose } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexWrap: 'wrap' }}>\n            <IconButton pin=\"square-square\">\n                <IconClose color=\"inherit\" />\n            </IconButton>\n            <IconButton pin=\"circle-circle\">\n                <IconClose color=\"inherit\" />\n            </IconButton>\n        </div>\n    );\n}"
        }
      ]
    },
    "IconButtonDots": {
      "name": "IconButtonDots",
      "group": "components",
      "folderName": "IconButton",
      "role": "primary",
      "description": "Кнопка с троеточием, открывающая выпадающее меню действий (Dropdown)",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "dropdownProps",
          "type": "(Omit<DropdownProps<ItemOption>, \"view\" | \"size\"> & Pick<PropsType<{ size: { m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; view: { default: PolymorphicClassName; }; }> & { items: ItemOption[]; trigger?: DropdownTrigger | undefined; placement?: DropdownPlacement | undefined; children?: React.ReactNode; variant?: \"normal\" | \"tight\" | undefined; zIndex?: Property.ZInd…",
          "required": false,
          "description": ""
        },
        {
          "name": "iconOrientation",
          "type": "\"horizontal\" | \"vertical\" | undefined",
          "required": false,
          "description": "",
          "default": "'horizontal'"
        },
        {
          "name": "iconSize",
          "type": "\"s\" | \"m\" | \"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "additionalContent",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentPlacing",
          "type": "\"default\" | \"relaxed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isLoading",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "loader",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "outlined",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftLeft",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftRight",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "square",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretch",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretching",
          "type": "\"auto\" | \"filled\" | \"fixed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "text",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"button\" | \"submit\" | \"reset\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "value",
          "type": "string | number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"secondary\" | \"clear\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"black\" | \"white\" | \"gradient\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "IconButtonDotsProps",
      "sourceFile": "packages/ui-kit/src/components/IconButton/IconButtonDots.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "меню действий",
        "context menu button",
        "dropdown trigger"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { IconButtonDots } from '@daisforge/ui';",
      "minimalUsage": "<IconButtonDots />",
      "examples": []
    },
    "IconButtonFilter": {
      "name": "IconButtonFilter",
      "group": "components",
      "folderName": "IconButton",
      "role": "primary",
      "description": "Кнопка-иконка фильтра с индикатором активности и выпадающим меню фильтров",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "dropdownProps",
          "type": "(Omit<DropdownProps<ItemOption>, \"view\" | \"size\"> & Pick<PropsType<{ size: { m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; view: { default: PolymorphicClassName; }; }> & { items: ItemOption[]; trigger?: DropdownTrigger | undefined; placement?: DropdownPlacement | undefined; children?: React.ReactNode; variant?: \"normal\" | \"tight\" | undefined; zIndex?: Property.ZInd…",
          "required": false,
          "description": ""
        },
        {
          "name": "iconSize",
          "type": "\"s\" | \"m\" | \"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "redSquare",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "additionalContent",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentPlacing",
          "type": "\"default\" | \"relaxed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isLoading",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "loader",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "outlined",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftLeft",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftRight",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "square",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretch",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretching",
          "type": "\"auto\" | \"filled\" | \"fixed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "text",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"button\" | \"submit\" | \"reset\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "value",
          "type": "string | number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"secondary\" | \"clear\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"black\" | \"white\" | \"gradient\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "IconButtonFilterProps",
      "sourceFile": "packages/ui-kit/src/components/IconButton/IconButtonFilter/IconButtonFilter.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "filter button",
        "кнопка фильтра",
        "индикатор активных фильтров"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { IconButtonFilter } from '@daisforge/ui';",
      "minimalUsage": "<IconButtonFilter />",
      "examples": []
    },
    "IconSvgSprite": {
      "name": "IconSvgSprite",
      "group": "components",
      "folderName": "IconSvgSprite",
      "role": "primary",
      "description": "Иконка из SVG-спрайта по URL с поддержкой размеров xs/s/m",
      "props": [
        {
          "name": "iconUrl",
          "type": "string",
          "required": true,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"m\" | \"xs\" | undefined",
          "required": false,
          "description": "",
          "default": "'s'"
        }
      ],
      "propsTypeName": "IconSvgSpriteProps",
      "sourceFile": "packages/ui-kit/src/components/IconSvgSprite/IconSvgSprite.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "иконка из спрайта",
        "svg sprite icon",
        "кастомная иконка"
      ],
      "docs": "# IconSvgSprite\n\n### Компонент для отрисовки SVG спрайтов\n\n---\n\n#### Использование\n\nВ `iconUrl` передается url `https://cdn.dddd.ru/FileWithSprites.svg` на файл содержащий спрайты иконок и ссылка на необходимую иконку `#IconId`.\nИспользуется в finai-admin, finai-header, finai-platform.\nДля этих микрофронтов url к картинке приходит в формате `/pl/static-res/finai_icons/sprite-{size}-1.svg#IconAvatar-{size}`,\nв которых плейсхолдер `{size}` в компоненте заменяется пропсом `size`. При отсутствии плейсхолдеров будет использоваться исходный url к спрайту.\n\n```jsx\n\n<IconSprite iconUrl=\"https://cdn.dddd.ru/FileWithSprites.svg#IconId\" />;\n```\n\n### Пропсы\n\n```js\ntype Props = {\n  // url иконки\n  iconUrl: string,\n  // размер иконки, default = 's'\n  size?: 'xs' | 's' | 'm',\n  // цвет иконки\n  color?: string,\n  // css класс\n  className?: string\n};\n```\n\n### Механизм работы SVG спрайтов\n\nДокументация [\\<symbol\\>](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol) [\\<use\\>](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use)\n\n    - `<symbol id=\"Icon-1\">` - определяем иконку внутри тэга `symbol`, атрибут `id` используется в качестве ссылки на иконку\n\n```svg\n<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" style=\"display: none;\" ... >\n  <symbol id=\"Icon1\" width=\"100%\" viewBox=\"0 0 24 24\" ... >\n    <g><path ... </g>\n  </symbol>\n  <symbol id=\"Icon2\" width=\"100%\" viewBox=\"0 0 24 24\" ... >\n     <g><path ... </g>\n  </symbol>\n</svg>\n```\n\n    - Используем иконку с помощью тэга `<use>`\n\n```svg\n<svg width=\"100%\" viewBox=\"0 0 16 16\" ... >\n  <use xlinkHref=\"https://cdn.dddd.ru/FileWithSprites.svg#Icon1\" />\n</svg>\n\n```",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { IconSvgSprite } from '@daisforge/ui';",
      "minimalUsage": "<IconSvgSprite iconUrl={'значение'} />",
      "examples": []
    },
    "Image": {
      "name": "Image",
      "group": "components",
      "folderName": "Image",
      "role": "primary",
      "description": "Изображение с управлением соотношением сторон и ленивой загрузкой",
      "props": [
        {
          "name": "decoding",
          "type": "\"auto\" | \"async\" | \"sync\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "fetchPriority",
          "type": "\"auto\" | \"high\" | \"low\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "loading",
          "type": "\"eager\" | \"lazy\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "referrerPolicy",
          "type": "React.HTMLAttributeReferrerPolicy | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ImageProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Image/Image.d.ts",
      "type": "wrapper",
      "atomicBase": "Image",
      "category": "Локальные компоненты",
      "keywords": [
        "картинка",
        "aspect ratio",
        "lazy loading",
        "изображение с рамкой"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "base",
          "type": "\"img\" | \"div\"",
          "required": false,
          "inheritedFrom": "Image",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customRatio",
          "type": "string",
          "required": false,
          "inheritedFrom": "Image",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "ratio",
          "type": "\"1 / 1\" | \"1/1\" | \"3 / 4\" | \"3/4\" | \"4 / 3\" | \"4/3\" | \"9 / 16\" | \"9/16\" | \"16 / 9\" | \"16/9\" | \"1 / 2\" | \"1/2\" | \"2 / 1\" | \"2/1\"",
          "required": false,
          "inheritedFrom": "Image",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Image } from '@daisforge/ui';",
      "minimalUsage": "<Image />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Example 1",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Image } from '@daisforge/ui';\nexport function App() {\n    return (\n        <Image\n            src=\"/sdds-finai/images/320_320_9.jpg\"\n            width=\"320px\"\n            height=\"320px\"\n            alt=\"Картинка для примера фоном\"\n        />\n    );\n}"
        }
      ]
    },
    "Indicator": {
      "name": "Indicator",
      "group": "components",
      "folderName": "Indicator",
      "role": "primary",
      "description": "Маленький цветной индикатор статуса разных размеров и цветов",
      "props": [],
      "propsTypeName": "IndicatorProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Indicator/Indicator.d.ts",
      "type": "wrapper",
      "atomicBase": "Indicator",
      "category": "Локальные компоненты",
      "keywords": [
        "индикатор статуса",
        "status dot",
        "точка-бейдж"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\"",
          "required": true,
          "description": "Размер индикатора",
          "default": "m",
          "inheritedFrom": "Indicator",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"inactive\" | \"black\" | \"white\"",
          "required": true,
          "description": "Вид индикатора",
          "default": "default",
          "inheritedFrom": "Indicator",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Indicator } from '@daisforge/ui';",
      "minimalUsage": "<Indicator size={\"s\"} view={\"default\"} />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Базовое использование",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Indicator } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <div style={{ display: 'flex' }}>\n                <Indicator size=\"s\" view=\"default\" />\n                <Indicator size=\"m\" view=\"default\" />\n                <Indicator size=\"l\" view=\"default\" />\n            </div>\n            <div style={{ display: 'flex' }}>\n                <Indicator size=\"s\" view=\"accent\" />\n                <Indicator size=\"m\" view=\"accent\" />\n                <Indicator size=\"l\" view=\"accent\" />\n            </div>\n            <div style={{ display: 'flex' }}>\n                <Indicator size=\"s\" view=\"inactive\" />\n                <Indicator size=\"m\" view=\"inactive\" />\n                <Indicator size=\"l\" view=\"inactive\" />\n            </div>\n            <div style={{ display: 'flex' }}>\n                <Indicator size=\"s\" view=\"positive\" />\n                <Indicator size=\"m\" view=\"positive\" />\n                <Indicator size=\"l\" view=\"positive\" />\n            </div>\n            <div style={{ display: 'flex' }}>\n                <Indicator size=\"s\" view=\"warning\" />\n                <Indicator size=\"m\" view=\"warning\" />\n                <Indicator size=\"l\" view=\"warning\" />\n            </div>\n            <div style={{ display: 'flex' }}>\n                <Indicator size=\"s\" view=\"negative\" />\n                <Indicator size=\"m\" view=\"negative\" />\n                <Indicator size=\"l\" view=\"negative\" />\n            </div>\n            <div style={{ display: 'flex' }}>\n                <Indicator size=\"s\" view=\"black\" />\n                <Indicator size=\"m\" view=\"black\" />\n                <Indicator size=\"l\" view=\"black\" />\n            </div>\n            <div style={{ display: 'flex' }}>\n                <Indicator size=\"s\" view=\"white\" />\n                <Indicator size=\"m\" view=\"white\" />\n                <Indicator size=\"l\" view=\"white\" />\n            </div>\n        </div>\n    );\n}"
        }
      ]
    },
    "InformationWrapper": {
      "name": "InformationWrapper",
      "group": "components",
      "folderName": "InformationWrapper",
      "role": "primary",
      "description": "Обёртка для поля формы: лейбл, подсказка, признак обязательности",
      "props": [],
      "propsTypeName": "ComponentProps<typeof InformationWrapper>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/InformationWrapper/InformationWrapper.d.ts",
      "type": "wrapper",
      "atomicBase": "InformationWrapper",
      "category": "Локальные компоненты",
      "keywords": [
        "лейбл поля",
        "field label wrapper",
        "подсказка к полю",
        "обязательное поле"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintContentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOffset",
          "type": "[number, number]",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOpened",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetIcon",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintText",
          "type": "string",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\"",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintView",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintWidth",
          "type": "string",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelHtmlFor",
          "type": "string",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "\"top\" | \"left\"",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "leftHelper",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optional",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optionalText",
          "type": "string",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "requiredIndicatorPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "rightHelper",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "titleCaption",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\"",
          "required": false,
          "inheritedFrom": "InformationWrapper",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { InformationWrapper } from '@daisforge/ui';",
      "minimalUsage": "<InformationWrapper />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Размер компонента",
          "type": "vendor",
          "code": "import React from 'react';\nimport { InformationWrapper } from '@daisforge/ui';\nexport function App() {\n    const commonProps = {\n        label: 'Лейбл',\n        titleCaption: 'Подпись к полю',\n        leftHelper: 'Подсказка слева',\n        rightHelper: 'Подсказка справа',\n        hintText: 'Текст тултипа',\n    };\n    const SvgPlaceholder = () => {\n        return (\n            <div\n                style={{\n                    height: '3rem',\n                    background:\n                        'linear-gradient(to right, #9747FF 0.063rem, transparent 0.063rem) 0 0, linear-gradient(to right, #9747FF 0.063rem, transparent 0.063rem) 0 100%, linear-gradient(to left, #9747FF 0.063rem, transparent 0.063rem) 100% 0, linear-gradient(to left, #9747FF 0.063rem, transparent 0.063rem) 100% 100%, linear-gradient(to bottom, #9747FF 0.063rem, transparent 0.063rem) 0 0, linear-gradient(to bottom, #9747FF 0.063rem, transparent 0.063rem) 100% 0, linear-gradient(to top, #9747FF 0.063rem, transparent 0.063rem) 0 100%, linear-gradient(to top, #9747FF 0.063rem, transparent 0.063rem) 100% 100%',\n                    backgroundRepeat: 'no-repeat',\n                    backgroundSize: '3rem 1rem',\n                }}\n            />\n        );\n    };\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '2rem', padding: '2rem' }}>\n            <InformationWrapper\n                {...commonProps}\n                size=\"s\"\n                hasRequiredIndicator\n            >\n                <SvgPlaceholder />\n            </InformationWrapper>\n            <InformationWrapper\n                {...commonProps}\n                size=\"xs\"\n                hasRequiredIndicator\n            >\n                <SvgPlaceholder />\n            </InformationWrapper>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Положение label",
          "type": "vendor",
          "code": "import React from 'react';\nimport { InformationWrapper } from '@daisforge/ui';\nexport function App() {\n    const commonProps = {\n        label: 'Лейбл',\n        titleCaption: 'Подпись к полю',\n        leftHelper: 'Подсказка слева',\n        rightHelper: 'Подсказка справа',\n        hintText: 'Текст тултипа',\n    };\n    const SvgPlaceholder = () => {\n        return (\n            <div\n                style={{\n                    height: '3rem',\n                    background:\n                        'linear-gradient(to right, #9747FF 0.063rem, transparent 0.063rem) 0 0, linear-gradient(to right, #9747FF 0.063rem, transparent 0.063rem) 0 100%, linear-gradient(to left, #9747FF 0.063rem, transparent 0.063rem) 100% 0, linear-gradient(to left, #9747FF 0.063rem, transparent 0.063rem) 100% 100%, linear-gradient(to bottom, #9747FF 0.063rem, transparent 0.063rem) 0 0, linear-gradient(to bottom, #9747FF 0.063rem, transparent 0.063rem) 100% 0, linear-gradient(to top, #9747FF 0.063rem, transparent 0.063rem) 0 100%, linear-gradient(to top, #9747FF 0.063rem, transparent 0.063rem) 100% 100%',\n                    backgroundRepeat: 'no-repeat',\n                    backgroundSize: '3rem 1rem',\n                }}\n            />\n        );\n    };\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '2rem', padding: '2rem' }}>\n            <InformationWrapper\n                {...commonProps}\n                labelPlacement=\"top\"\n                hasRequiredIndicator\n            >\n                <SvgPlaceholder />\n            </InformationWrapper>\n            <InformationWrapper\n                {...commonProps}\n                labelPlacement=\"left\"\n                hasRequiredIndicator\n            >\n                <SvgPlaceholder />\n            </InformationWrapper>\n        </div>\n    );\n}"
        }
      ]
    },
    "LeftPanel": {
      "name": "LeftPanel",
      "group": "components",
      "folderName": "LeftPanel",
      "role": "primary",
      "description": "Сворачиваемая и растягиваемая боковая панель навигации с ресайзом",
      "props": [
        {
          "name": "collapsedContent",
          "type": "LeftPanelAdaptiveSlot",
          "required": false,
          "description": "Кастомный класс для Content body элемента в закрытом состоянии\nМожно передать ReactNode или callback с размерами для адаптива."
        },
        {
          "name": "collapsedContentProps",
          "type": "PanelCollapsedContentProps | undefined",
          "required": false,
          "description": "Свойства для content закрытой панели"
        },
        {
          "name": "collapsedFooterContent",
          "type": "LeftPanelAdaptiveSlot",
          "required": false,
          "description": "Кастомный класс для Content footer элемента в закрытом состоянии\nМожно передать ReactNode или callback с размерами для адаптива."
        },
        {
          "name": "collapseState",
          "type": "[boolean, React.Dispatch<React.SetStateAction<boolean>>] | undefined",
          "required": false,
          "description": "Состояние открытости или закрытости панели"
        },
        {
          "name": "containerProps",
          "type": "({ [x: string]: any; [x: number]: any; [x: symbol]: any; } & { theme?: DefaultTheme | undefined; } & { as?: string | React.ComponentType<any> | undefined; forwardedAs?: string | React.ComponentType<any> | undefined; }) | undefined",
          "required": false,
          "description": "Свойства для container элемента"
        },
        {
          "name": "contentProps",
          "type": "Omit<{ [x: string]: any; [x: number]: any; [x: symbol]: any; } & { theme?: DefaultTheme | undefined; } & { as?: string | React.ComponentType<any> | undefined; forwardedAs?: string | React.ComponentType<any> | undefined; }, \"$active\"> | undefined",
          "required": false,
          "description": "Свойства для content открытой панели"
        },
        {
          "name": "expandedContent",
          "type": "LeftPanelAdaptiveSlot",
          "required": false,
          "description": "Кастомный класс для Content body элемента в открытом состоянии\nМожно передать ReactNode или callback с размерами для адаптива."
        },
        {
          "name": "maxWidth",
          "type": "number | undefined",
          "required": false,
          "description": "Максимальная ширина",
          "default": "MAX_WIDTH"
        },
        {
          "name": "minWidth",
          "type": "number | undefined",
          "required": false,
          "description": "Минимальная ширина",
          "default": "72, на viewport <= 1280px — 56"
        },
        {
          "name": "onResize",
          "type": "((width: number) => void) | undefined",
          "required": false,
          "description": "Callback, который срабатывает при изменении ширины (только когда панель раскрыта)"
        },
        {
          "name": "onToggleCollapse",
          "type": "((next: boolean) => void) | undefined",
          "required": false,
          "description": "Callback, который срабатывает в моменте изменения"
        },
        {
          "name": "showResizeable",
          "type": "boolean | undefined",
          "required": false,
          "description": "Скрытие сепаратора у resize",
          "default": "true"
        },
        {
          "name": "showToggleButton",
          "type": "boolean | undefined",
          "required": false,
          "description": "Скрытие кнопки открытия/закрытия панели",
          "default": "true"
        },
        {
          "name": "widthState",
          "type": "[number | undefined, React.Dispatch<React.SetStateAction<number | undefined>>] | undefined",
          "required": false,
          "description": "Состояние ширины панели панели"
        },
        {
          "name": "disableMediaAdaptive",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отключает принудительный адаптив компонента на viewport <= 1280px.",
          "deprecated": true,
          "default": "false"
        }
      ],
      "propsTypeName": "LeftPanelProps",
      "compoundParts": [
        {
          "name": "LeftPanelToggleButton",
          "typeName": "LeftPanelToggleButtonProps",
          "props": [
            {
              "name": "as",
              "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
              "required": false,
              "description": "Сменить рендер на другой тип компонента."
            },
            {
              "name": "additionalContent",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "appearance",
              "type": "\"default\" | \"outline\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "blur",
              "type": "\"small\" | \"medium\" | \"large\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "collapsed",
              "type": "boolean | undefined",
              "required": false,
              "description": "",
              "default": "false"
            },
            {
              "name": "contentLeft",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "contentPlacing",
              "type": "\"default\" | \"relaxed\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentRight",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "focused",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "isAbsolute",
              "type": "boolean | undefined",
              "required": false,
              "description": "",
              "default": "false"
            },
            {
              "name": "isAdaptive1280",
              "type": "boolean | undefined",
              "required": false,
              "description": "",
              "default": "false"
            },
            {
              "name": "isLoading",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "loader",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "onClick",
              "type": "(React.MouseEventHandler<HTMLElement> & (() => void)) | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "outlined",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "pin",
              "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftLeft",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftRight",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "size",
              "type": "\"s\" | \"xs\" | \"xxs\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "square",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretch",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretching",
              "type": "\"auto\" | \"fixed\" | \"filled\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "text",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "type",
              "type": "\"button\" | \"submit\" | \"reset\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "value",
              "type": "string | number | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "view",
              "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"black\" | \"white\" | \"accent\" | \"secondary\" | \"clear\" | \"dark\" | \"gradient\" | undefined",
              "required": false,
              "description": ""
            }
          ]
        }
      ],
      "sourceFile": "packages/ui-kit/src/components/LeftPanel/LeftPanel.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "боковая панель",
        "sidebar",
        "сворачиваемое меню",
        "ресайз панели"
      ],
      "docs": "# LeftPanel\n\nВыдвижная левая панель с анимацией открытия/закрытия и поддержкой ресайза.\n\n## Ключевые особенности\n\n- Анимация сворачивания/разворачивания\n- Ресайз через разделитель (`showResizeable`)\n- Кнопка сворачивания (`showToggleButton`)\n- Раздельный контент для развёрнутого и свёрнутого состояний\n- Управляемые состояния ширины и свёрнутости через пары из `useState`\n- Настраиваемые min/max ширина\n\n## Особенности\n\n- Для управления состоянием передайте `collapseState` и `widthState` — пары `[value, setter]` из `useState`\n- `expandedContent` отображается в развёрнутом состоянии, `collapsedContent` — в свёрнутом\n- `collapsedFooterContent` — дополнительный футер для свёрнутого состояния\n- Слоты `expandedContent`, `collapsedContent` и `collapsedFooterContent` принимают `ReactNode` или callback с размерами для адаптива\n- По умолчанию адаптив на viewport `<= 1280px` включен; временно отключить его можно через deprecated-проп `disableMediaAdaptive`\n\n## Использование адаптивных слотов\n\nЕсли слот не должен менять размеры, передавайте обычный `ReactNode`:\n\n```tsx\n<LeftPanel\n  expandedContent={<Widget />}\n  collapsedContent={<IconButton size=\"s\" view=\"secondary\" />}\n/>\n```\n\nЕсли внутри слота есть Button, IconButton, TextFieldSearch или Segment, которые должны уменьшаться на 1280px, передавайте callback и используйте `buttonSize` из аргумента:\n\n```tsx\n<LeftPanel\n  expandedContent={({ buttonSize }) => (\n    <Widget>\n      <Widget.Header\n        bottomBlock={\n          <>\n            <TextFieldSearch size={buttonSize} />\n            <SegmentGroup size={buttonSize}>\n              <SegmentItem size={buttonSize} label=\"Label\" value=\"label\" />\n            </SegmentGroup>\n          </>\n        }\n      />\n      <Widget.Footer>\n        <Button size={buttonSize} view=\"secondary\">\n          Действие\n        </Button>\n      </Widget.Footer>\n    </Widget>\n  )}\n  collapsedContent={({ buttonSize }) => (\n    <IconButton size={buttonSize} view=\"secondary\" />\n  )}\n/>\n```\n\nРазмер, который приходит в callback:\n\n```\nbuttonSize\n| viewport <= 1280px | viewport > 1280px |\n| xs                 | s                 |\n```\n\nДефолтная ширина свёрнутой панели:\n\n```\ncollapsed width\n| viewport <= 1280px  | viewport > 1280px |\n| 56px                | 72px              |\n```\n\nОписание типов — в разделе [API](/docs/композиции-leftpanel-api--docs).",
      "apiDocs": "# LeftPanel API\n\n## LeftPanelProps\n\n```typescript\ntype LeftPanelProps = {\n  /**\n   * Минимальная ширина\n   * @default 72, на viewport <= 1280px — 56\n   */\n  minWidth?: number;\n  /**\n   * Максимальная ширина\n   */\n  maxWidth?: number;\n  /**\n   * Отключает принудительный адаптив компонента на viewport <= 1280px.\n   *\n   * @deprecated Используйте только в крайних случаях, когда команда временно не готова адаптировать вёрстку под 1280px.\n   *\n   * @remarks\n   * При `true` компонент использует desktop-размеры для слотов, кнопки сворачивания и свёрнутой панели, если `minWidth` не передан.\n   * Поведение сохраняется даже на viewport <= 1280px.\n   * Это временный escape hatch, не основной сценарий использования.\n   *\n   * @default false\n   */\n  disableMediaAdaptive?: boolean;\n  /**\n   * Состояние открытости или закрытости панели\n   */\n  collapseState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Состояние ширины панели панели\n   */\n  widthState?: [\n    number | undefined,\n    React.Dispatch<React.SetStateAction<number | undefined>>,\n  ];\n  /**\n   * Свойства для container элемента\n   */\n  containerProps?: ComponentProps<typeof Box>;\n  /**\n   * Свойства для content открытой панели\n   */\n  contentProps?: Omit<ComponentProps<typeof PanelContent>, '$active'>;\n  /**\n   * Свойства для content закрытой панели\n   */\n  collapsedContentProps?: PanelCollapsedContentProps;\n  /**\n   * Скрытие кнопки открытия/закрытия панели\n   */\n  showToggleButton?: boolean;\n  /**\n   * Скрытие сепаратора у resize\n   */\n  showResizeable?: boolean;\n  /**\n   * Кастомный класс для Content body элемента в открытом состоянии\n   * Можно передать ReactNode или callback с размерами для адаптива.\n   */\n  expandedContent?: LeftPanelAdaptiveSlot;\n  /**\n   * Кастомный класс для Content body элемента в закрытом состоянии\n   * Можно передать ReactNode или callback с размерами для адаптива.\n   */\n  collapsedContent?: LeftPanelAdaptiveSlot;\n  /**\n   * Кастомный класс для Content footer элемента в закрытом состоянии\n   * Можно передать ReactNode или callback с размерами для адаптива.\n   */\n  collapsedFooterContent?: LeftPanelAdaptiveSlot;\n  /**\n   * Callback, который срабатывает при изменении ширины (только когда панель раскрыта)\n   */\n  onResize?: (width: number) => void;\n  /**\n   * Callback, который срабатывает в моменте изменения\n   */\n  onToggleCollapse?: (next: boolean) => void;\n};\n\ntype ToggleButtonBaseProps = ComponentProps<typeof IconButton>;\n\nexport type ToggleButtonProps = ToggleButtonBaseProps & {\n  collapsed?: boolean;\n  isAbsolute?: boolean;\n  isAdaptive1280?: boolean;\n  onClick?: () => void;\n};\n\nexport type HookResizeProps = {\n  setWidth: React.Dispatch<React.SetStateAction<number | undefined>>;\n  isResizingRef: React.MutableRefObject<boolean>;\n  setIsResizing: React.Dispatch<React.SetStateAction<boolean>>;\n  panelRef: RefObject<HTMLDivElement | null>;\n  minWidth: number;\n  maxWidth: number;\n  parentRef: RefObject<HTMLElement | null>;\n  isCollapsed: boolean;\n  onResize?: (width: number) => void;\n};\n```\n\n## LeftPanelSlotSizesProps\n\n```typescript\ntype LeftPanelSlotSizesProps = {\n  /**\n   * Размер кнопок, поиска и сегментов в кастомных слотах\n   */\n  buttonSize: 's' | 'xs';\n};\n```\n\n## LeftPanelAdaptiveSlot\n\n```typescript\ntype LeftPanelAdaptiveSlot =\n  | ReactNode\n  | ((props: LeftPanelSlotSizesProps) => ReactNode);\n```",
      "curatedStories": [
        {
          "exportName": "LeftPanelSlots",
          "displayName": "LeftPanel со слотами",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n    } from '@daisforge/ui/icons';\n    import {\n        Box,\n        Button,\n        H2,\n        IconButton,\n        LeftPanel,\n        Widget,\n    } from '@daisforge/ui';\n    import type { LeftPanelSlotSizesProps } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n\n() => {\n    // Состояние отвечает за открытие/закрытие панели\n    const [isCollapsed, setIsCollapsed] = useState(false);\n    const [width, setWidth] = useState<number | undefined>(360);\n\n    // Вызывается при переключении панели\n    const handleToggle = (next: boolean) => {\n      setIsCollapsed(next);\n      if (next) {\n        setWidth(undefined);\n      } else {\n        setWidth(360);\n      }\n    };\n\n    // Вызывается для получения изменений ширины\n    const handleResize = (width: number) => {\n      setWidth(width);\n    };\n\n    return (\n      <div\n        style={{\n          height: '100vh',\n          padding: '20px',\n          display: 'flex',\n          backgroundColor: '#f5f5f5',\n        }}\n      >\n        <LeftPanel\n          // Максимальная ширина\n          maxWidth={360}\n          // State для управления ширины\n          widthState={[width, setWidth]}\n          // Коллбэк, вызывается при смене состояния\n          onResize={handleResize}\n          // Коллбэк, вызывается при смене состояния\n          onToggleCollapse={handleToggle}\n          // Управление состоянием панели\n          collapseState={[isCollapsed, setIsCollapsed]}\n          // Slot для раскрытой панели (рекомендуется использовать widget)\n          expandedContent={\n            <Widget $css={{ overflow: 'hidden' }}>\n              {/* Заголовок виджета */}\n              <Widget.Header\n                title=\"Title\"\n                $css={{\n                  overflow: 'hidden',\n                }}\n                bottomBlock={\n                  <Box\n                    style={{\n                      padding: s.x8,\n                      borderRadius: br.s,\n                      border: `1px solid ${surfaceInfo}`,\n                      color: surfaceInfo,\n                      backgroundColor: surfaceAccentMinor,\n                    }}\n                  >\n                    <BodyS>Widget.Header bottomBlock</BodyS>\n                  </Box>\n                }\n              />\n              {/* Основной контент со скроллом */}\n              <Widget.Content>\n                <Box\n                  style={{\n                    padding: s.x8,\n                    borderRadius: br.s,\n                    border: `1px solid ${surfaceInfo}`,\n                    color: surfaceInfo,\n                    backgroundColor: surfaceAccentMinor,\n                    height: '800px',\n                  }}\n                >\n                  <BodyS>Widget.Content</BodyS>\n                </Box>\n              </Widget.Content>\n              {/* Нижняя часть виджета */}\n              <Widget.Footer>\n                <Box\n                  style={{\n                    padding: s.x8,\n                    borderRadius: br.s,\n                    border: `1px solid ${surfaceInfo}`,\n                    color: surfaceInfo,\n                    width: '100%',\n                    backgroundColor: surfaceAccentMinor,\n                  }}\n                >\n                  <BodyS>Widget.Footer</BodyS>\n                </Box>\n              </Widget.Footer>\n            </Widget>\n          }\n          // Контент в свернутом состоянии\n          collapsedContent={({ buttonSize }: LeftPanelSlotSizesProps) => (\n            <>\n              <IconButton\n                size={buttonSize}\n                view=\"accent\"\n                style={{\n                  border: `1px solid ${surfaceInfo}`,\n                  backgroundColor: surfaceAccentMinor,\n                  color: surfaceInfo,\n                }}\n              >\n                <IconGroupOutline />\n              </IconButton>\n              <IconButton\n                size={buttonSize}\n                view=\"accent\"\n                style={{\n                  border: `1px solid ${surfaceInfo}`,\n                  backgroundColor: surfaceAccentMinor,\n                  color: surfaceInfo,\n                }}\n              >\n                <IconGroupOutline />\n              </IconButton>\n              <IconButton\n                size={buttonSize}\n                view=\"accent\"\n                style={{\n                  border: `1px solid ${surfaceInfo}`,\n                  backgroundColor: surfaceAccentMinor,\n                  color: surfaceInfo,\n                }}\n              >\n                <IconGroupOutline />\n              </IconButton>\n            </>\n          )}\n          // Нижняя часть в свернутом состоянии\n          collapsedFooterContent={({ buttonSize }: LeftPanelSlotSizesProps) => (\n            <IconButton\n              size={buttonSize}\n              view=\"accent\"\n              style={{\n                border: `1px solid ${surfaceInfo}`,\n                backgroundColor: surfaceAccentMinor,\n                color: surfaceInfo,\n              }}\n            >\n              <IconGroupOutline />\n            </IconButton>\n          )}\n        />\n        <div\n          style={{\n            flex: 1,\n            padding: s.x8,\n            boxShadow:\n              'var(--shadow-down-soft-s, 0px 4px 14px -4px #08080814,0px 1px 4px -1px #0000000A)',\n            backgroundColor: surfaceSolidCard,\n            borderRadius: s.x8,\n          }}\n        >\n          <div\n            style={{\n              display: 'flex',\n              justifyContent: 'space-between',\n              alignItems: 'center',\n            }}\n          >\n            <H2 style={{ marginBottom: s.x8 }}>Контент</H2>\n            {/* Кнопка управления панелью */}\n            <div\n              style={{\n                display: 'flex',\n                justifyContent: 'space-between',\n                alignItems: 'center',\n              }}\n            >\n              {width && <H4 style={{ marginRight: s.x8 }}>{width}px</H4>}\n              <Button onClick={() => handleToggle(!isCollapsed)}>\n                Открыть/Закрыть\n              </Button>\n            </div>\n          </div>\n        </div>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "LeftPanelExample",
          "displayName": "Example",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Box,\n        Button,\n        Dropdown,\n        H2,\n        IconButton,\n        LeftPanel,\n        LeftPanelProps,\n        List,\n        ListItem,\n        SegmentGroup,\n        SegmentItem,\n        SegmentProvider,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n     import type { LeftPanelSlotSizesProps } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n     import styled from 'styled-components';\n\n() => {\n    // Данные для кнопок\n    const items = [\n      {\n        label: 'label',\n        value: 'label1',\n      },\n      {\n        label: 'label',\n        value: 'label2',\n      },\n    ];\n\n    // Данные для списка\n    const contentItems = [\n      {\n        label: 'Основной план',\n        value: 'label1',\n      },\n      {\n        label: 'План блока',\n        value: 'label2',\n      },\n      {\n        label: 'Персональный план',\n        value: 'label3',\n      },\n      {\n        label: 'Журнал публикаций',\n        value: 'label4',\n      },\n    ];\n\n    // Состояние отвечает за открытие/закрытие панели\n    const [isCollapsed, setIsCollapsed] = useState(false);\n    const [width, setWidth] = useState<number | undefined>(360);\n\n    // Реф для поля поиска\n    const searchRef = useRef<HTMLInputElement>(null);\n\n    // Вызывается при переключении панели\n    const handleToggle = (next: boolean) => {\n      setIsCollapsed(next);\n      if (next) {\n        setWidth(undefined);\n      } else {\n        setWidth(360);\n      }\n    };\n\n    // Открывает панель и фокусирует поле поиска\n    const handleSearchClick = () => {\n      handleToggle(false);\n\n      requestAnimationFrame(() => {\n        searchRef.current?.focus();\n      });\n    };\n\n    return (\n      <div\n        style={{\n          height: '100vh',\n          padding: '20px',\n          display: 'flex',\n          backgroundColor: '#f5f5f5',\n        }}\n      >\n        <LeftPanel\n          // Максимальная ширина\n          maxWidth={360}\n          widthState={[width, setWidth]}\n          // Коллбэк, вызывается при смене состояния\n          onToggleCollapse={handleToggle}\n          // Управление состоянием панели\n          collapseState={[isCollapsed, setIsCollapsed]}\n          // Slot для раскрытой панели (рекомендуется использовать widget)\n          expandedContent={({ buttonSize }: LeftPanelSlotSizesProps) => (\n            <Widget $css={{ overflow: 'hidden' }}>\n              <Widget.Header\n                title=\"Title\"\n                badge={{ text: 'badge', size: 's' }}\n                $css={{\n                  overflow: 'hidden',\n                  columnGap: '56px !important',\n                }}\n                subTitle={<BodyS>description</BodyS>}\n                bottomBlock={\n                  <>\n                    {/* Группа переключателей */}\n                    <SegmentProvider defaultSelected={['item_0']}>\n                      <SegmentGroup\n                        style={{ marginBottom: s.x8 }}\n                        hasBackground\n                        size={buttonSize}\n                        stretch\n                      >\n                        {items.map((_, i) => (\n                          <SegmentItem\n                            view=\"secondary\"\n                            // eslint-disable-next-line react/no-array-index-key\n                            key={`item:${i}`}\n                            value={`item_${i}`}\n                            label={`Label ${i + 1}`}\n                            size={buttonSize}\n                          />\n                        ))}\n                      </SegmentGroup>\n                    </SegmentProvider>\n\n                    <div\n                      style={{\n                        display: 'flex',\n                        gap: s.x4,\n                      }}\n                    >\n                      {/* Поле поиска и кнопки */}\n                      <TextFieldSearch size={buttonSize} ref={searchRef} />\n                      <IconButton\n                        size={buttonSize}\n                        view=\"secondary\"\n                        style={{ aspectRatio: '1 / 1' }}\n                      >\n                        <IconGroupOutline />\n                      </IconButton>\n                      <IconButton\n                        size={buttonSize}\n                        view=\"secondary\"\n                        style={{ aspectRatio: '1 / 1' }}\n                      >\n                        <IconGroupOutline />\n                      </IconButton>\n                    </div>\n                  </>\n                }\n              />\n              {/* Основной список */}\n              <Widget.Content>\n                <List>\n                  {contentItems.map((_, index) => (\n                    <FullWidthListItem>\n                      <div\n                        style={{\n                          display: 'flex',\n                          flexDirection: 'column',\n                          flexGrow: 1,\n                        }}\n                      >\n                        <div\n                          style={{\n                            display: 'flex',\n                            justifyContent: 'space-between',\n                          }}\n                        >\n                          <Typography variant=\"BodyM\">Текст</Typography>\n                          <EmbedIconButton size=\"s\" view=\"default\">\n                            <IconPinFill size=\"xs\" />\n                          </EmbedIconButton>\n                        </div>\n                        <Accordion size=\"s\" view=\"clear\" stretching=\"filled\">\n                          <AccordionItem\n                            type=\"arrow\"\n                            title=\"Короткий текст тут\"\n                          >\n                            <List view=\"default\" size=\"s\" variant=\"tight\">\n                              <ListItem>\n                                Aaa +{' '}\n                                {index % 2 === 0\n                                  ? 'aaaaa aaaaaaaaa aaaaaaa aaaaaaaaa'.repeat(\n                                      // eslint-disable-next-line prettier/prettier\n                                      10,\n                                    )\n                                  : ''}\n                              </ListItem>\n                            </List>\n                          </AccordionItem>\n                        </Accordion>\n                      </div>\n                    </FullWidthListItem>\n                  ))}\n                </List>\n              </Widget.Content>\n              {/* Нижняя часть виджета */}\n              <Widget.Footer>\n                <Button size={buttonSize} view=\"secondary\" stretching=\"filled\">\n                  Какая-то кнопка\n                </Button>\n              </Widget.Footer>\n            </Widget>\n          )}\n          // Slot для контента закрытой панели\n          collapsedContent={({ buttonSize }: LeftPanelSlotSizesProps) => (\n            <>\n              <IconButton\n                size={buttonSize}\n                view=\"secondary\"\n                onClick={handleSearchClick}\n              >\n                <IconSearch />\n              </IconButton>\n              <IconButton size={buttonSize} view=\"secondary\">\n                <IconGroupOutline />\n              </IconButton>\n              <IconButton size={buttonSize} view=\"secondary\">\n                <IconGroupOutline />\n              </IconButton>\n              <Dropdown items={contentItems} portal=\"document\">\n                <IconButton size={buttonSize} view=\"secondary\">\n                  <IconHierarchy />\n                </IconButton>\n              </Dropdown>\n            </>\n          )}\n          //   Slot для ниженй части закрытой панели\n          collapsedFooterContent={({ buttonSize }: LeftPanelSlotSizesProps) => (\n            <IconButton size={buttonSize} view=\"secondary\">\n              <IconGroupOutline />\n            </IconButton>\n          )}\n        />\n        <div\n          style={{\n            flex: 1,\n            padding: s.x8,\n            boxShadow:\n              'var(--shadow-down-soft-s, 0px 4px 14px -4px #08080814,0px 1px 4px -1px #0000000A)',\n            backgroundColor: surfaceSolidCard,\n            borderRadius: s.x8,\n          }}\n        >\n          <div\n            style={{\n              display: 'flex',\n              justifyContent: 'space-between',\n              alignItems: 'center',\n            }}\n          >\n            <H2 style={{ marginBottom: s.x8 }}>Контент</H2>\n            {/* Кнопка управления панелью */}\n            <Button onClick={() => handleToggle(!isCollapsed)}>\n              Открыть/Закрыть\n            </Button>\n          </div>\n        </div>\n      </div>\n    );\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "LeftPanelToggleButton"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LeftPanel } from '@daisforge/ui';",
      "minimalUsage": "<LeftPanel>\n  {/* части: LeftPanel.LeftPanelToggleButton */}\n</LeftPanel>",
      "examples": [
        {
          "exportName": "LeftPanelSlots",
          "displayName": "LeftPanel со слотами",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n    } from '@daisforge/ui/icons';\n    import {\n        Box,\n        Button,\n        H2,\n        IconButton,\n        LeftPanel,\n        Widget,\n    } from '@daisforge/ui';\n    import type { LeftPanelSlotSizesProps } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n\n() => {\n    // Состояние отвечает за открытие/закрытие панели\n    const [isCollapsed, setIsCollapsed] = useState(false);\n    const [width, setWidth] = useState<number | undefined>(360);\n\n    // Вызывается при переключении панели\n    const handleToggle = (next: boolean) => {\n      setIsCollapsed(next);\n      if (next) {\n        setWidth(undefined);\n      } else {\n        setWidth(360);\n      }\n    };\n\n    // Вызывается для получения изменений ширины\n    const handleResize = (width: number) => {\n      setWidth(width);\n    };\n\n    return (\n      <div\n        style={{\n          height: '100vh',\n          padding: '20px',\n          display: 'flex',\n          backgroundColor: '#f5f5f5',\n        }}\n      >\n        <LeftPanel\n          // Максимальная ширина\n          maxWidth={360}\n          // State для управления ширины\n          widthState={[width, setWidth]}\n          // Коллбэк, вызывается при смене состояния\n          onResize={handleResize}\n          // Коллбэк, вызывается при смене состояния\n          onToggleCollapse={handleToggle}\n          // Управление состоянием панели\n          collapseState={[isCollapsed, setIsCollapsed]}\n          // Slot для раскрытой панели (рекомендуется использовать widget)\n          expandedContent={\n            <Widget $css={{ overflow: 'hidden' }}>\n              {/* Заголовок виджета */}\n              <Widget.Header\n                title=\"Title\"\n                $css={{\n                  overflow: 'hidden',\n                }}\n                bottomBlock={\n                  <Box\n                    style={{\n                      padding: s.x8,\n                      borderRadius: br.s,\n                      border: `1px solid ${surfaceInfo}`,\n                      color: surfaceInfo,\n                      backgroundColor: surfaceAccentMinor,\n                    }}\n                  >\n                    <BodyS>Widget.Header bottomBlock</BodyS>\n                  </Box>\n                }\n              />\n              {/* Основной контент со скроллом */}\n              <Widget.Content>\n                <Box\n                  style={{\n                    padding: s.x8,\n                    borderRadius: br.s,\n                    border: `1px solid ${surfaceInfo}`,\n                    color: surfaceInfo,\n                    backgroundColor: surfaceAccentMinor,\n                    height: '800px',\n                  }}\n                >\n                  <BodyS>Widget.Content</BodyS>\n                </Box>\n              </Widget.Content>\n              {/* Нижняя часть виджета */}\n              <Widget.Footer>\n                <Box\n                  style={{\n                    padding: s.x8,\n                    borderRadius: br.s,\n                    border: `1px solid ${surfaceInfo}`,\n                    color: surfaceInfo,\n                    width: '100%',\n                    backgroundColor: surfaceAccentMinor,\n                  }}\n                >\n                  <BodyS>Widget.Footer</BodyS>\n                </Box>\n              </Widget.Footer>\n            </Widget>\n          }\n          // Контент в свернутом состоянии\n          collapsedContent={({ buttonSize }: LeftPanelSlotSizesProps) => (\n            <>\n              <IconButton\n                size={buttonSize}\n                view=\"accent\"\n                style={{\n                  border: `1px solid ${surfaceInfo}`,\n                  backgroundColor: surfaceAccentMinor,\n                  color: surfaceInfo,\n                }}\n              >\n                <IconGroupOutline />\n              </IconButton>\n              <IconButton\n                size={buttonSize}\n                view=\"accent\"\n                style={{\n                  border: `1px solid ${surfaceInfo}`,\n                  backgroundColor: surfaceAccentMinor,\n                  color: surfaceInfo,\n                }}\n              >\n                <IconGroupOutline />\n              </IconButton>\n              <IconButton\n                size={buttonSize}\n                view=\"accent\"\n                style={{\n                  border: `1px solid ${surfaceInfo}`,\n                  backgroundColor: surfaceAccentMinor,\n                  color: surfaceInfo,\n                }}\n              >\n                <IconGroupOutline />\n              </IconButton>\n            </>\n          )}\n          // Нижняя часть в свернутом состоянии\n          collapsedFooterContent={({ buttonSize }: LeftPanelSlotSizesProps) => (\n            <IconButton\n              size={buttonSize}\n              view=\"accent\"\n              style={{\n                border: `1px solid ${surfaceInfo}`,\n                backgroundColor: surfaceAccentMinor,\n                color: surfaceInfo,\n              }}\n            >\n              <IconGroupOutline />\n            </IconButton>\n          )}\n        />\n        <div\n          style={{\n            flex: 1,\n            padding: s.x8,\n            boxShadow:\n              'var(--shadow-down-soft-s, 0px 4px 14px -4px #08080814,0px 1px 4px -1px #0000000A)',\n            backgroundColor: surfaceSolidCard,\n            borderRadius: s.x8,\n          }}\n        >\n          <div\n            style={{\n              display: 'flex',\n              justifyContent: 'space-between',\n              alignItems: 'center',\n            }}\n          >\n            <H2 style={{ marginBottom: s.x8 }}>Контент</H2>\n            {/* Кнопка управления панелью */}\n            <div\n              style={{\n                display: 'flex',\n                justifyContent: 'space-between',\n                alignItems: 'center',\n              }}\n            >\n              {width && <H4 style={{ marginRight: s.x8 }}>{width}px</H4>}\n              <Button onClick={() => handleToggle(!isCollapsed)}>\n                Открыть/Закрыть\n              </Button>\n            </div>\n          </div>\n        </div>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "LeftPanelExample",
          "displayName": "Example",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Box,\n        Button,\n        Dropdown,\n        H2,\n        IconButton,\n        LeftPanel,\n        LeftPanelProps,\n        List,\n        ListItem,\n        SegmentGroup,\n        SegmentItem,\n        SegmentProvider,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n     import type { LeftPanelSlotSizesProps } from '@daisforge/ui';\n     import { br, s } from '@daisforge/ui/constants';\n     import styled from 'styled-components';\n\n() => {\n    // Данные для кнопок\n    const items = [\n      {\n        label: 'label',\n        value: 'label1',\n      },\n      {\n        label: 'label',\n        value: 'label2',\n      },\n    ];\n\n    // Данные для списка\n    const contentItems = [\n      {\n        label: 'Основной план',\n        value: 'label1',\n      },\n      {\n        label: 'План блока',\n        value: 'label2',\n      },\n      {\n        label: 'Персональный план',\n        value: 'label3',\n      },\n      {\n        label: 'Журнал публикаций',\n        value: 'label4',\n      },\n    ];\n\n    // Состояние отвечает за открытие/закрытие панели\n    const [isCollapsed, setIsCollapsed] = useState(false);\n    const [width, setWidth] = useState<number | undefined>(360);\n\n    // Реф для поля поиска\n    const searchRef = useRef<HTMLInputElement>(null);\n\n    // Вызывается при переключении панели\n    const handleToggle = (next: boolean) => {\n      setIsCollapsed(next);\n      if (next) {\n        setWidth(undefined);\n      } else {\n        setWidth(360);\n      }\n    };\n\n    // Открывает панель и фокусирует поле поиска\n    const handleSearchClick = () => {\n      handleToggle(false);\n\n      requestAnimationFrame(() => {\n        searchRef.current?.focus();\n      });\n    };\n\n    return (\n      <div\n        style={{\n          height: '100vh',\n          padding: '20px',\n          display: 'flex',\n          backgroundColor: '#f5f5f5',\n        }}\n      >\n        <LeftPanel\n          // Максимальная ширина\n          maxWidth={360}\n          widthState={[width, setWidth]}\n          // Коллбэк, вызывается при смене состояния\n          onToggleCollapse={handleToggle}\n          // Управление состоянием панели\n          collapseState={[isCollapsed, setIsCollapsed]}\n          // Slot для раскрытой панели (рекомендуется использовать widget)\n          expandedContent={({ buttonSize }: LeftPanelSlotSizesProps) => (\n            <Widget $css={{ overflow: 'hidden' }}>\n              <Widget.Header\n                title=\"Title\"\n                badge={{ text: 'badge', size: 's' }}\n                $css={{\n                  overflow: 'hidden',\n                  columnGap: '56px !important',\n                }}\n                subTitle={<BodyS>description</BodyS>}\n                bottomBlock={\n                  <>\n                    {/* Группа переключателей */}\n                    <SegmentProvider defaultSelected={['item_0']}>\n                      <SegmentGroup\n                        style={{ marginBottom: s.x8 }}\n                        hasBackground\n                        size={buttonSize}\n                        stretch\n                      >\n                        {items.map((_, i) => (\n                          <SegmentItem\n                            view=\"secondary\"\n                            // eslint-disable-next-line react/no-array-index-key\n                            key={`item:${i}`}\n                            value={`item_${i}`}\n                            label={`Label ${i + 1}`}\n                            size={buttonSize}\n                          />\n                        ))}\n                      </SegmentGroup>\n                    </SegmentProvider>\n\n                    <div\n                      style={{\n                        display: 'flex',\n                        gap: s.x4,\n                      }}\n                    >\n                      {/* Поле поиска и кнопки */}\n                      <TextFieldSearch size={buttonSize} ref={searchRef} />\n                      <IconButton\n                        size={buttonSize}\n                        view=\"secondary\"\n                        style={{ aspectRatio: '1 / 1' }}\n                      >\n                        <IconGroupOutline />\n                      </IconButton>\n                      <IconButton\n                        size={buttonSize}\n                        view=\"secondary\"\n                        style={{ aspectRatio: '1 / 1' }}\n                      >\n                        <IconGroupOutline />\n                      </IconButton>\n                    </div>\n                  </>\n                }\n              />\n              {/* Основной список */}\n              <Widget.Content>\n                <List>\n                  {contentItems.map((_, index) => (\n                    <FullWidthListItem>\n                      <div\n                        style={{\n                          display: 'flex',\n                          flexDirection: 'column',\n                          flexGrow: 1,\n                        }}\n                      >\n                        <div\n                          style={{\n                            display: 'flex',\n                            justifyContent: 'space-between',\n                          }}\n                        >\n                          <Typography variant=\"BodyM\">Текст</Typography>\n                          <EmbedIconButton size=\"s\" view=\"default\">\n                            <IconPinFill size=\"xs\" />\n                          </EmbedIconButton>\n                        </div>\n                        <Accordion size=\"s\" view=\"clear\" stretching=\"filled\">\n                          <AccordionItem\n                            type=\"arrow\"\n                            title=\"Короткий текст тут\"\n                          >\n                            <List view=\"default\" size=\"s\" variant=\"tight\">\n                              <ListItem>\n                                Aaa +{' '}\n                                {index % 2 === 0\n                                  ? 'aaaaa aaaaaaaaa aaaaaaa aaaaaaaaa'.repeat(\n                                      // eslint-disable-next-line prettier/prettier\n                                      10,\n                                    )\n                                  : ''}\n                              </ListItem>\n                            </List>\n                          </AccordionItem>\n                        </Accordion>\n                      </div>\n                    </FullWidthListItem>\n                  ))}\n                </List>\n              </Widget.Content>\n              {/* Нижняя часть виджета */}\n              <Widget.Footer>\n                <Button size={buttonSize} view=\"secondary\" stretching=\"filled\">\n                  Какая-то кнопка\n                </Button>\n              </Widget.Footer>\n            </Widget>\n          )}\n          // Slot для контента закрытой панели\n          collapsedContent={({ buttonSize }: LeftPanelSlotSizesProps) => (\n            <>\n              <IconButton\n                size={buttonSize}\n                view=\"secondary\"\n                onClick={handleSearchClick}\n              >\n                <IconSearch />\n              </IconButton>\n              <IconButton size={buttonSize} view=\"secondary\">\n                <IconGroupOutline />\n              </IconButton>\n              <IconButton size={buttonSize} view=\"secondary\">\n                <IconGroupOutline />\n              </IconButton>\n              <Dropdown items={contentItems} portal=\"document\">\n                <IconButton size={buttonSize} view=\"secondary\">\n                  <IconHierarchy />\n                </IconButton>\n              </Dropdown>\n            </>\n          )}\n          //   Slot для ниженй части закрытой панели\n          collapsedFooterContent={({ buttonSize }: LeftPanelSlotSizesProps) => (\n            <IconButton size={buttonSize} view=\"secondary\">\n          \n// … (обрезано)"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в LeftPanel.stories.tsx",
          "type": "usage",
          "code": "<LeftPanel\n          // Максимальная ширина\n          maxWidth={360}\n          // State для управления ширины\n          widthState={[width, setWidth]}\n          // Коллбэк, вызывается при смене состояния\n          onResize={handleResize}\n          // Коллбэк, вызывается при смене состояния\n          onToggleCollapse={handleToggle}\n          // Управление состоянием панели\n          collapseState={[isCollapsed, setIsCollapsed]}\n          // Slot для раскрытой панели (рекомендуется использовать widget)\n          expandedContent={\n            <Widget $css={{ overflow: 'hidden' }}>\n              {/* Заголовок виджета */}\n              <Widget.Header\n                title=\"Title\"\n                $css={{\n                  overflow: 'hidden',\n                }}\n                bottomBlock={\n                  <Box\n                    style={{\n                      padding: s.x8,\n                      borderRadius: br.s,\n                      border: `1px solid ${surfaceInfo}`,\n                      color: surfaceInfo,\n                      backgroundColor: surfaceAccentMinor,\n                    }}\n                  >\n                    <BodyS>Widget.Header bottomBlock</BodyS>\n                  </Box>\n                }\n              />\n              {/* Основной контент со скроллом */}\n              <Widget.Content>\n                <Box\n                  style={{\n                    padding: s.x8,\n                    borderRadius: br.s,\n                    border: `1px solid ${surfaceInfo}`,\n                    color: surfaceInfo,\n                    backgroundColor: surfaceAccentMinor,\n                    height: '800px',\n                  }}\n                >\n                  <BodyS>Widget.Content</BodyS>\n                </Box>\n              </Widget.Content>\n              {/* Нижняя часть виджета */}\n              <Widget.Footer>\n                <Box\n                  style={{\n                    padding: s.x8,\n                    borderRadius: br.s,\n                    border: `1px solid ${surfaceInfo}`,\n                    color: surfaceInfo,\n                    width: '100%',\n                    backgroundColor: surfaceAccentMinor,\n                  }}\n                >\n                  <BodyS>Widget.Footer</BodyS>\n                </Box>\n              </Widget.Footer>\n            </Widget>\n          }\n          // Контент в свернутом состоянии\n          col\n// … (обрезано)",
          "sourceFile": "packages/storybook/src/stories/LeftPanel/LeftPanel.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в PageLayout.stories.tsx",
          "type": "usage",
          "code": "<LeftPanel\n                collapseState={[collapsed, setCollapsed]}\n                widthState={[width, setWidth]}\n                maxWidth={360}\n                expandedContent={<LeftPanelExpandedContent />}\n                collapsedContent={<LeftPanelCollapsedContent />}\n                collapsedFooterContent={\n                  <IconButton size=\"s\" view=\"secondary\">\n                    <IconGroupOutline />\n                  </IconButton>\n                }\n              />",
          "sourceFile": "packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx"
        }
      ]
    },
    "LeftPanelToggleButton": {
      "name": "LeftPanelToggleButton",
      "group": "components",
      "folderName": "LeftPanel",
      "role": "part",
      "description": "Кнопка сворачивания и разворачивания бокового меню LeftPanel",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "additionalContent",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "collapsed",
          "type": "boolean | undefined",
          "required": false,
          "description": "",
          "default": "false"
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentPlacing",
          "type": "\"default\" | \"relaxed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isAbsolute",
          "type": "boolean | undefined",
          "required": false,
          "description": "",
          "default": "false"
        },
        {
          "name": "isAdaptive1280",
          "type": "boolean | undefined",
          "required": false,
          "description": "",
          "default": "false"
        },
        {
          "name": "isLoading",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "loader",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "onClick",
          "type": "(React.MouseEventHandler<HTMLElement> & (() => void)) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "outlined",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftLeft",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftRight",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "square",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretch",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretching",
          "type": "\"auto\" | \"fixed\" | \"filled\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "text",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"button\" | \"submit\" | \"reset\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "value",
          "type": "string | number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"black\" | \"white\" | \"accent\" | \"secondary\" | \"clear\" | \"dark\" | \"gradient\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "LeftPanelToggleButtonProps",
      "sourceFile": "packages/ui-kit/src/components/LeftPanel/components/LeftPanelToggleButton.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "свернуть меню",
        "collapse sidebar",
        "кнопка сворачивания"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "LeftPanel",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LeftPanelToggleButton } from '@daisforge/ui';",
      "minimalUsage": "<LeftPanelToggleButton />",
      "examples": []
    },
    "Link": {
      "name": "Link",
      "group": "components",
      "folderName": "Link",
      "role": "primary",
      "description": "Гиперссылка с вариантами подчёркивания, размеров и состояний",
      "props": [
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": "Компонент может фокусироваться."
        },
        {
          "name": "ping",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "referrerPolicy",
          "type": "React.HTMLAttributeReferrerPolicy | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "target",
          "type": "React.HTMLAttributeAnchorTarget | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "LinkProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Link/Link.d.ts",
      "type": "wrapper",
      "atomicBase": "Link",
      "category": "Локальные компоненты",
      "keywords": [
        "ссылка",
        "hyperlink",
        "переход по ссылке"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "size",
          "type": "string",
          "required": false,
          "description": "Размер компонента.",
          "inheritedFrom": "Link",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "underline",
          "type": "\"none\" | \"hover\" | \"always\"",
          "required": false,
          "description": "Режим подчёркивания ссылки:\n- `none` — без подчёркивания\n- `hover` — подчёркивание при наведении\n- `always` — всегда подчёркнута",
          "default": "'none'",
          "inheritedFrom": "Link",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"tertiary\" | \"paragraph\"",
          "required": false,
          "description": "Вид компонента.",
          "inheritedFrom": "Link",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Link",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Link } from '@daisforge/ui';",
      "minimalUsage": "<Link />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в MDComponents.tsx",
          "type": "usage",
          "code": "<Link view=\"accent\" target=\"_blank\" rel=\"noopener noreferrer\" {...props}>\n      {children}\n    </Link>",
          "sourceFile": "packages/storybook/src/stories/AiChatDAIS/components/MDComponents.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в ModalDF.stories.tsx",
          "type": "usage",
          "code": "<Link href={window.location.href} view=\"accent\">\n                      ссылка\n                    </Link>",
          "sourceFile": "packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TextS, Link } from '@daisforge/ui';\nexport function App() {\n    return (\n        <TextS>\n            Скачайте <Link href=\"/\" target=\"_blank\">приложение.</Link>\n        </TextS>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Подчёркивание Подчёркивание Prop  underline  управляет режимом подчёркивания ссылки",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TextS, Link } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n            <TextS><Link href=\"/\" underline=\"none\">Без подчёркивания</Link></TextS>\n            <TextS><Link href=\"/\" underline=\"hover\">Подчёркивание при наведении</Link></TextS>\n            <TextS><Link href=\"/\" underline=\"always\">Всегда подчёркнута</Link></TextS>\n        </div>\n    );\n}"
        }
      ]
    },
    "LinkButton": {
      "name": "LinkButton",
      "group": "components",
      "folderName": "LinkButton",
      "role": "primary",
      "description": "Кнопка в виде ссылки для второстепенных действий с иконкой и текстом",
      "props": [
        {
          "name": "ping",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "referrerPolicy",
          "type": "React.HTMLAttributeReferrerPolicy | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "target",
          "type": "React.HTMLAttributeAnchorTarget | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "LinkButtonCompProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/LinkButton/LinkButton.d.ts",
      "type": "wrapper",
      "atomicBase": "LinkButton",
      "category": "Локальные компоненты",
      "keywords": [
        "кнопка-ссылка",
        "второстепенное действие",
        "text button"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "additionalContent",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "LinkButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "LinkButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "LinkButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "LinkButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isLoading",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "LinkButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "loader",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "LinkButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\"",
          "required": false,
          "inheritedFrom": "LinkButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "string",
          "required": false,
          "inheritedFrom": "LinkButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"info\"",
          "required": false,
          "inheritedFrom": "LinkButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LinkButton } from '@daisforge/ui';",
      "minimalUsage": "<LinkButton />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в Table.tsx",
          "type": "usage",
          "code": "<LinkButton\n                    contentLeft={<IconResetOutline size=\"xs\" />}\n                    view=\"secondary\"\n                    onClick={() => alert('Вид по умолчанию')}\n                    size=\"xs\"\n                  >\n                    Вид по умолчанию\n                  </LinkButton>",
          "sourceFile": "packages/vite-project/src/pages/Table.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в Table.multipleFeatures.stories.tsx",
          "type": "usage",
          "code": "<LinkButton\n                      contentLeft={<IconResetOutline size=\"xs\" />}\n                      view=\"secondary\"\n                      onClick={() => alert('Вид по умолчанию')}\n                      size=\"xs\"\n                    >\n                      Вид по умолчанию\n                    </LinkButton>",
          "sourceFile": "packages/storybook/src/stories/Table/Table.multipleFeatures.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Размер кнопки",
          "type": "vendor",
          "code": "import React from 'react';\nimport { LinkButton } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <LinkButton text=\"Кнопка\" size=\"s\" />\n            <LinkButton text=\"Кнопка\" size=\"xs\" />\n            <LinkButton text=\"Кнопка\" size=\"xxs\" />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Использование Использование Компонент  LinkButton  может содержать текст, который указывается в",
          "type": "vendor",
          "code": "import React from 'react';\nimport { LinkButton } from '@daisforge/ui';\nimport { IconDownload } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <LinkButton text=\"Текст\" />\n            <LinkButton text=\"Текст\" contentLeft={<IconDownload color=\"inherit\" />} />\n            <LinkButton text=\"Текст\" contentRight={<IconDownload color=\"inherit\" />} />\n            <LinkButton text=\"Текст\" isLoading />\n            <LinkButton text=\"Текст\" isLoading loader={<div>Loader...</div>} />\n        </div>\n    );\n}"
        }
      ]
    },
    "List": {
      "name": "List",
      "group": "components",
      "folderName": "List",
      "role": "primary",
      "description": "Список элементов с фоном, разделителями и вариантами отображения",
      "props": [],
      "propsTypeName": "ListProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/List/List.d.ts",
      "type": "wrapper",
      "atomicBase": "List",
      "category": "Локальные компоненты",
      "keywords": [
        "список",
        "перечень элементов",
        "list view"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "hasBackground",
          "type": "boolean",
          "required": false,
          "description": "Добавляет фон контейнеру списка",
          "inheritedFrom": "List",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasDivider",
          "type": "boolean",
          "required": false,
          "description": "Добавляет разделители между элементами списка",
          "inheritedFrom": "List",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasItemBackground",
          "type": "boolean",
          "required": false,
          "description": "Добавляет фон каждому элементу списка",
          "inheritedFrom": "List",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\" | \"xs\"",
          "required": false,
          "description": "Размер",
          "inheritedFrom": "List",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "variant",
          "type": "\"normal\" | \"tight\"",
          "required": false,
          "description": "Вариант List",
          "inheritedFrom": "List",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "description": "Тип отображения для accordion",
          "inheritedFrom": "List",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "List",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { List } from '@daisforge/ui';",
      "minimalUsage": "<List />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в LeftPanel.stories.tsx",
          "type": "usage",
          "code": "<List view=\"default\" size=\"s\" variant=\"tight\">\n                              <ListItem>\n                                Aaa +{' '}\n                                {index % 2 === 0\n                                  ? 'aaaaa aaaaaaaaa aaaaaaa aaaaaaaaa'.repeat(\n                                      // eslint-disable-next-line prettier/prettier\n                                      10,\n                                    )\n                                  : ''}\n                              </ListItem>\n                            </List>",
          "sourceFile": "packages/storybook/src/stories/LeftPanel/LeftPanel.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в PageLayout.stories.tsx",
          "type": "usage",
          "code": "<List>\n        {navItems.map((item) => (\n          <ListItem key={item.value}>{item.label}</ListItem>\n        ))}\n      </List>",
          "sourceFile": "packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Базовое использование",
          "type": "vendor",
          "code": "import React from 'react';\nimport { List, ListItem } from '@daisforge/ui';\nimport { IconChevronRight } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <List view=\"default\" size=\"s\" variant=\"normal\">\n                <ListItem contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>Test Item 1</ListItem>\n                <ListItem contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>Test Item 2</ListItem>\n                <ListItem disabled contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>\n                    Test Item 3\n                </ListItem>\n                <ListItem contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>Test Item 4</ListItem>\n            </List>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Разделители между элементами",
          "type": "vendor",
          "code": "import React from 'react';\nimport { List, ListItem } from '@daisforge/ui';\nimport { IconChevronRight } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <List view=\"default\" size=\"s\" variant=\"normal\" hasDivider>\n                <ListItem contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>Test Item 1</ListItem>\n                <ListItem contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>Test Item 2</ListItem>\n                <ListItem disabled contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>\n                    Test Item 3\n                </ListItem>\n                <ListItem contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>Test Item 4</ListItem>\n            </List>\n        </div>\n    );\n}"
        }
      ]
    },
    "ListItem": {
      "name": "ListItem",
      "group": "components",
      "folderName": "List",
      "role": "primary",
      "description": "Элемент списка с иконками или контентом слева и справа",
      "props": [
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof ListItem>",
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/List/ui/ListItem.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "пункт списка",
        "строка списка",
        "list row"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ListItem } from '@daisforge/ui';",
      "minimalUsage": "<ListItem />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в LeftPanelBlock.tsx",
          "type": "usage",
          "code": "<ListItem key={item.value} style={{ cursor: 'pointer' }}>\n                  {item.label}\n                </ListItem>",
          "sourceFile": "packages/storybook/src/stories/BlockTitle/components/LeftPanelBlock.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в PageLayout.stories.tsx",
          "type": "usage",
          "code": "<ListItem key={item.value}>{item.label}</ListItem>",
          "sourceFile": "packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Базовое использование",
          "type": "vendor",
          "code": "import React from 'react';\nimport { List, ListItem } from '@daisforge/ui';\nimport { IconChevronRight } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <List view=\"default\" size=\"s\" variant=\"normal\">\n                <ListItem contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>Test Item 1</ListItem>\n                <ListItem contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>Test Item 2</ListItem>\n                <ListItem disabled contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>\n                    Test Item 3\n                </ListItem>\n                <ListItem contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>Test Item 4</ListItem>\n            </List>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Разделители между элементами",
          "type": "vendor",
          "code": "import React from 'react';\nimport { List, ListItem } from '@daisforge/ui';\nimport { IconChevronRight } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <List view=\"default\" size=\"s\" variant=\"normal\" hasDivider>\n                <ListItem contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>Test Item 1</ListItem>\n                <ListItem contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>Test Item 2</ListItem>\n                <ListItem disabled contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>\n                    Test Item 3\n                </ListItem>\n                <ListItem contentRight={<IconChevronRight color=\"inherit\" size=\"xs\" />}>Test Item 4</ListItem>\n            </List>\n        </div>\n    );\n}"
        }
      ]
    },
    "ListOfFilters": {
      "name": "ListOfFilters",
      "group": "components",
      "folderName": "ListOfFilters",
      "role": "primary",
      "description": "Панель применённых фильтров в виде чипов с сворачиванием и сбросом",
      "props": [
        {
          "name": "clearAll",
          "type": "() => void",
          "required": true,
          "description": ""
        },
        {
          "name": "items",
          "type": "ItemOrGroup[]",
          "required": true,
          "description": ""
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": true,
          "description": ""
        },
        {
          "name": "ellipsisLabel",
          "type": "boolean | undefined",
          "required": false,
          "description": "Обрезает название группы фильтров в одну строку с троеточием.",
          "default": "false"
        },
        {
          "name": "showResetAllFiltersButton",
          "type": "boolean | undefined",
          "required": false,
          "description": "Показывать ли кнопку \"Сбросить все\" в блоке примененных фильтров",
          "default": "true"
        },
        {
          "name": "chipStyle",
          "type": "((itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "extraCss",
          "type": "React.CSSProperties | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "leftSlot",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "maxHeight",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "maxLengthInGroup",
          "type": "number | undefined",
          "required": false,
          "description": "",
          "default": "maxLengthInGroup=2"
        },
        {
          "name": "paddingInline",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "paddingTop",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "renderChipLabel",
          "type": "((group: Group | null, item: Item) => string) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "renderGroupLabel",
          "type": "((group: Group) => string) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "sizeOnOpen",
          "type": "number | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ListOfFiltersProps",
      "sourceFile": "packages/ui-kit/src/components/ListOfFilters/ListOfFilters.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "применённые фильтры",
        "filter chips",
        "сброс фильтров"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ListOfFilters } from '@daisforge/ui';",
      "minimalUsage": "<ListOfFilters clearAll={() => {}} items={[]} opened={true} />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в SplitViewAndListOfFilters.tsx",
          "type": "usage",
          "code": "<ListOfFilters\n                opened={filterListOpened}\n                items={filterList}\n                clearAll={clearAll}\n              />",
          "sourceFile": "packages/vite-project/src/pages/SplitViewAndListOfFilters.tsx"
        }
      ]
    },
    "Mask": {
      "name": "Mask",
      "group": "components",
      "folderName": "Mask",
      "role": "primary",
      "description": "Текстовое поле с маской ввода (телефон, паспорт и т.п.)",
      "props": [
        {
          "name": "defaultValue",
          "type": "string | (readonly string[] & string) | undefined",
          "required": false,
          "description": "Значение по умолчанию."
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof Mask>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Mask/Mask.d.ts",
      "type": "wrapper",
      "atomicBase": "Mask",
      "formVariant": "FormMask",
      "category": "Локальные компоненты",
      "keywords": [
        "маска ввода",
        "input mask",
        "форматированное поле"
      ],
      "chooseWhen": "Вне react-hook-form — поле с маской ввода на value/onChange напрямую.",
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "alwaysShowMask",
          "type": "boolean",
          "required": false,
          "description": "Отображать ли маску всегда.",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение лейбла.",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "mask",
          "type": "string",
          "required": false,
          "description": "Маска.\nПоддерживаются следующие символы:\n* 0 — любая цифра 0-9\n* \\* — любой символ\n* a — A-Z, a-z\n* я — А-Я, а-я, ё, Ё\n* q — буква \"q\"\n* 2 — цифра \"2\"\n* \\a — \"\\\\\" - символ экранирования; \"a\" - буква",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maskChar",
          "type": "string",
          "required": false,
          "description": "Символ маскирования.",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maskFormat",
          "type": "IMaskItem[]",
          "required": false,
          "description": "Набор соответствий маски и маскируемого значения.",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maskString",
          "type": "string",
          "required": false,
          "description": "Строка, которая будет отображена в незаполненную часть маски.\nЕсли передать maskString, то maskChar игнорируется.",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "ChangeEventHandler<HTMLInputElement>",
          "required": false,
          "description": "Обработчик изменения элемента формы",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onValueChange",
          "type": "((params: { maskedValue: string; value: string; }) => void)",
          "required": false,
          "description": "Callback при изменении значения маски с дополнительной информацией.",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optional",
          "type": "boolean",
          "required": false,
          "description": "Флаг необязательности поля",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optionalText",
          "type": "string",
          "required": false,
          "description": "Подпись для указания необязательности поля",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "reformat",
          "type": "((params: { value: string | IInputValue[]; selection: ISelectRange; input?: string; }) => IInputState)",
          "required": false,
          "description": "Функция форматирования, которая позволяет задать собственные правила форматирования.",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "requiredPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "showMask",
          "type": "boolean",
          "required": false,
          "description": "Отображать ли маску во время ввода.",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "showStartChars",
          "type": "boolean",
          "required": false,
          "description": "Отображать ли префикс маски. Например у маски телефона \"+7\"",
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"clear\" | \"default\" | \"viewMode\"",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "checked",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chips",
          "type": "TextFieldPrimitiveValue[]",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipType",
          "type": "\"text\" | \"default\"",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipValidator",
          "type": "((value: string) => ChipValidatorReturn)",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\"",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "clear",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "enumerationType",
          "type": "\"plain\" | \"chip\"",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasDivider",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintContentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOffset",
          "type": "[number, number]",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPortal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetIcon",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintText",
          "type": "string",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\"",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintView",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintWidth",
          "type": "string",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "leftHelper",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maxLength",
          "type": "number",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "minLength",
          "type": "number",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "name",
          "type": "string",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onBlur",
          "type": "FocusEventHandler<HTMLInputElement>",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeChips",
          "type": "((value: TextFieldPrimitiveValue[]) => void)",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onFocus",
          "type": "FocusEventHandler<HTMLInputElement>",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onSearch",
          "type": "(((value: string, event?: KeyboardEvent<HTMLInputElement>) => void) & ((value: string, event?: KeyboardEvent<HTMLInputElement>) => void)) | undefined",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placeholder",
          "type": "string",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "required",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "rightHelper",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textAfter",
          "type": "string",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textBefore",
          "type": "string",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "titleCaption",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "type",
          "type": "string",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | number | readonly string[]",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\"",
          "required": false,
          "inheritedFrom": "Mask",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Mask } from '@daisforge/ui';",
      "minimalUsage": "<Mask />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Маска Маска Маска задается с помощью свойства  mask .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Mask } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Mask\n                label=\"Маска телефона\"\n                placeholder=\"Введите телефон\"\n                mask=\"+7 (000) 000 - 00 - 00\"\n                maskChar=\"_\"\n                size=\"s\"\n                alwaysShowMask\n            />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Использование Использование Компонент  Mask  представляет собой поле ввода с возможностью маскирования значения.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Mask } from '@daisforge/ui';\nimport { IconDone } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <Mask\n                label=\"Лейбл\"\n                leftHelper=\"Подсказка к полю\"\n                placeholder=\"Введите дату\"\n                mask=\"00/00/0000\"\n                maskString=\"DD/MM/YYYY\"\n                size=\"s\"\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "MassActions": {
      "name": "MassActions",
      "group": "components",
      "folderName": "MassActions",
      "role": "primary",
      "description": "Панель массовых действий с чекбоксом, счётчиком и кнопками",
      "props": [
        {
          "name": "containerRef",
          "type": "React.RefObject<HTMLElement> | React.MutableRefObject<HTMLElement | null> | (() => HTMLElement | null)",
          "required": true,
          "description": "Ref на контейнер относительно которого будет позиционироваться панель\nМожет быть RefObject, MutableRefObject или функция возвращающая элемент"
        },
        {
          "name": "leftSection",
          "type": "React.ReactNode",
          "required": true,
          "description": "Левая секция панели (чекбокс + счетчик или кастомный контент)"
        },
        {
          "name": "selectedCount",
          "type": "number",
          "required": true,
          "description": "Количество выбранных элементов\nИспользуется для внутренней логики видимости панели (если show не указан)\nЕсли selectedCount === 0 и show не указан, панель не отображается"
        },
        {
          "name": "bottom",
          "type": "number | undefined",
          "required": false,
          "description": "Отступ снизу от контейнера (в пикселях)\nПо умолчанию: 16px для standalone, 24px для таблицы",
          "default": "16"
        },
        {
          "name": "buttons",
          "type": "MassActionsButtonProps[] | undefined",
          "required": false,
          "description": "Кнопки действий"
        },
        {
          "name": "collapsedDropdownProps",
          "type": "TableDropdownConfigProps | undefined",
          "required": false,
          "description": "Конфигурация dropdown для скрытых кнопок"
        },
        {
          "name": "enableDebugLogs",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включить отладочное логирование в консоль\nПолезно для отладки проблем с компрессией и позиционированием\nПо умолчанию false",
          "default": "false"
        },
        {
          "name": "isHaveSomeFeatureInSidebar",
          "type": "boolean | undefined",
          "required": false,
          "description": "Есть ли какая-то фича в сайдбаре (влияет на расчет ширины)",
          "default": "false"
        },
        {
          "name": "middleSection",
          "type": "React.ReactNode",
          "required": false,
          "description": "Средняя секция (например, кнопка \"Сбросить всё\")\nОпционально - для standalone версии не используется"
        },
        {
          "name": "minPadding",
          "type": "number | undefined",
          "required": false,
          "description": "Минимальный отступ панели от краев контейнера (в пикселях)\nИспользуется для:\n- CSS padding панели (симметрично: minPadding слева и справа)\n- Расчетов компрессии (максимальная ширина панели с учетом отступов)\n- Позиционирования (гарантирует минимальный отступ от левого края контейнера)\nПо умолчанию: 16px для standalone, 24px для таблицы",
          "default": "16"
        },
        {
          "name": "show",
          "type": "boolean | undefined",
          "required": false,
          "description": "Явный контроль видимости панели\nЕсли указан, имеет приоритет над автоматической логикой на основе selectedCount\nПозволяет показывать панель даже при selectedCount === 0\nПо умолчанию: undefined (используется логика selectedCount > 0)"
        },
        {
          "name": "sidebarConfig",
          "type": "MassActionsSidebarConfig | undefined",
          "required": false,
          "description": "Конфигурация сайдбара (если есть)"
        },
        {
          "name": "size",
          "type": "MassActionsSize | undefined",
          "required": false,
          "description": "Статический размер панели (для использования ВНУТРИ таблиц).\nЕсли задан — перекрывает viewport-логику (медиазапрос 1280 не используется):\n`m`/`s` = обычный размер (кнопки `s`), `xs` = уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS, свои паддинги).\nНЕ задавать для standalone — там компактность определяется по ширине вьюпорта (`down('xl')`)."
        },
        {
          "name": "useTableDropdown",
          "type": "boolean | undefined",
          "required": false,
          "description": "Использовать TableDropdown (для таблиц) вместо обычного Dropdown\nПо умолчанию false (используется обычный Dropdown)",
          "default": "false"
        }
      ],
      "propsTypeName": "MassActionsProps",
      "compoundParts": [
        {
          "name": "Counter",
          "typeName": "MassActionsCounterProps",
          "props": [
            {
              "name": "selectedCount",
              "type": "number",
              "required": true,
              "description": "Количество выбранных элементов"
            },
            {
              "name": "indeterminate",
              "type": "boolean | undefined",
              "required": false,
              "description": "Indeterminate состояние чекбокса"
            },
            {
              "name": "onCheckboxChange",
              "type": "((event: React.ChangeEvent<HTMLInputElement>) => void) | undefined",
              "required": false,
              "description": "Колбэк при изменении чекбокса"
            },
            {
              "name": "showCheckbox",
              "type": "boolean | undefined",
              "required": false,
              "description": "Показывать ли чекбокс",
              "default": "false"
            }
          ]
        }
      ],
      "sourceFile": "packages/ui-kit/src/components/MassActions/MassActions.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "массовые действия",
        "bulk actions",
        "панель выбора строк"
      ],
      "docs": "# MassActions\n\nБазовый адаптивный компонент панели массовых действий. Независим от таблицы - может использоваться с любым контейнером. Поддерживает автоматическую компрессию кнопок при нехватке места, сворачивание/разворачивание, удобное позиционирование и другие возможности.\n\n## Ключевые особенности\n\n- Автоматическая компрессия кнопок при нехватке места\n- Accent-кнопки всегда остаются видимыми\n- Автоцентрирование относительно контейнера\n- Поддержка двух типов кнопок: Button и LinkButton\n- Размеры кнопок подбираются автоматически — передавать `size` кнопкам не нужно (если задан, используется как есть)\n\n## Compound-компоненты\n\n### Counter\n\n`MassActions.Counter` — компонент счетчика выбранных элементов. Может отображать чекбокс, текст и анимированный badge с количеством.\n\n#### Логика работы чекбокса\n\nЧекбокс в Counter имеет три состояния:\n\n- **checked = true** — когда все элементы выбраны (`selectedCount === totalCount`)\n- **indeterminate = true** — когда выбрано частично (`0 < selectedCount < totalCount`)\n- **checked = false, indeterminate = false** — когда ничего не выбрано (`selectedCount === 0`)\n\n**Важно:** Состояние чекбокса должно вычисляться на основе `selectedCount` и общего количества элементов, а не храниться в отдельном состоянии. Это обеспечивает синхронизацию между ручным выделением элементов и состоянием чекбокса.\n\n```tsx\n// Правильная реализация логики чекбокса\nconst items = [...]; // массив всех элементов\nconst [selectedItems, setSelectedItems] = useState<Set<number>>(new Set());\n\n// Вычисляем состояние на основе selectedItems\nconst allSelected = selectedItems.size === items.length;\nconst someSelected = selectedItems.size > 0 && selectedItems.size < items.length;\nconst checked = allSelected;\nconst indeterminate = someSelected;\n\nconst handleCheckboxChange = (isChecked: boolean) => {\n  if (isChecked) {\n    // Выделяем все элементы\n    setSelectedItems(new Set(items.map((item) => item.id)));\n  } else {\n    // Снимаем выделение со всех элементов\n    setSelectedItems(new Set());\n  }\n};\n\n<MassActions.Counter\n  selectedCount={selectedItems.size}\n  showCheckbox\n  checked={checked}\n  indeterminate={indeterminate}\n  onCheckboxChange={(e) => handleCheckboxChange(e.target.checked)}\n/>\n```\n\n## MassActionsStatic\n\nСтатический компонент панели действий без адаптивной компрессии. Предназначен для использования в местах, где не требуется автоматическое скрытие кнопок (например, в боковых панелях LeftPanel).\n\nВ отличие от `MassActions`, `MassActionsStatic` не поддерживает компрессию кнопок и позиционирование относительно контейнера. Поддерживает блочное отображение через проп `position` (`static` или `relative`), что позволяет использовать компонент как обычный блок без абсолютного позиционирования.\n\n## Особенности\n\n### Компрессия кнопок\n\nПри нехватке места кнопки автоматически скрываются в дропдауне скрытых действий:\n\n1. Все accent-кнопки всегда видимы\n2. Обычные кнопки добавляются по порядку, пока помещаются\n3. Остальные кнопки идут в дропдаун скрытых действий\n\n### Позиционирование\n\nПанель автоматически центрируется относительно переданного контейнера (`containerRef`). В большинстве сценариев достаточно просто передать корректный контейнер, дополнительная настройка через `sidebarConfig` нужна только для продвинутых кейсов.\n\n### Размеры кнопок\n\nРазмеры кнопок и дропдаунов панель подбирает сама — по режиму отображения. В обычном режиме кнопки рендерятся размером `s`, в компактном (узкий вьюпорт, до 1280px включительно) — `xs`. Передавать `size` кнопкам отдельно **не нужно**. Если `size` всё же задан — он используется как есть.\n\n## Типы кнопок\n\nКаждый элемент массива `buttons` — это либо обычная кнопка (`type: 'button'`, компонент `Button`), либо кнопка-ссылка (`type: 'linkButton'`, компонент `LinkButton`). Кнопки с `view: 'accent'` никогда не скрываются в дропдауне скрытых действий.\n\n```tsx\nbuttons={[\n  {\n    type: 'button',\n    text: 'Действие',\n    view: 'secondary', // 'accent' / 'critical' / 'primary' и т.д.\n    onClick: () => {},\n  },\n  {\n    type: 'linkButton',\n    text: 'Ссылка-действие',\n    view: 'linkSecondary', // link-стили: 'linkAccent' / 'linkDefault' и т.д.\n    onClick: () => {},\n  },\n]}\n```\n\n## Disabled-состояние\n\nЕсли у кнопки `disabled: true`, можно передать `disabledTooltipProps` — подсказку, которая покажется при наведении на неактивную кнопку:\n\n```tsx\n{\n  type: 'button',\n  text: 'Действие',\n  view: 'secondary',\n  disabled: true,\n  disabledTooltipProps: {\n    text: 'Выберите элементы для выполнения действия',\n  },\n  onClick: () => {},\n}\n```\n\n**Важно:** disabled-кнопка остаётся неактивной и после ухода в дропдаун скрытых действий — `disabled` пробрасывается на пункт меню. Подсказка `disabledTooltipProps` при этом показывается только у кнопок на самой панели, в меню её нет.\n\n## Dropdown в кнопках\n\nКнопка может открывать вложенный dropdown:\n\n```tsx\n{\n  type: 'button',\n  text: 'Действие с меню',\n  view: 'secondary',\n  dropdown: {\n    items: [\n      { label: 'Опция 1', value: '1' },\n      { label: 'Опция 2', value: '2' },\n    ],\n    onItemSelect: (item) => {},\n  },\n}\n```\n\n> Подробнее о типах и пропсах — [MassActions API](?path=/docs/локальные-компоненты-massactions-api--docs)",
      "apiDocs": "# MassActions API\n\n## MassActionsProps\n\n```typescript\ntype MassActionsProps = {\n  /**\n   * Ref на контейнер относительно которого будет позиционироваться панель\n   * Может быть RefObject, MutableRefObject или функция возвращающая элемент\n   */\n  containerRef:\n    | RefObject<HTMLElement>\n    | MutableRefObject<HTMLElement | null>\n    | (() => HTMLElement | null);\n\n  /**\n   * Левая секция панели (чекбокс + счетчик или кастомный контент)\n   */\n  leftSection: ReactNode;\n\n  /**\n   * Средняя секция (например, кнопка \"Сбросить всё\")\n   * Опционально - для standalone версии не используется\n   */\n  middleSection?: ReactNode;\n\n  /**\n   * Кнопки действий\n   */\n  buttons?: MassActionsButtonProps[];\n\n  /**\n   * Конфигурация сайдбара (если есть)\n   */\n  sidebarConfig?: MassActionsSidebarConfig;\n\n  /**\n   * Есть ли какая-то фича в сайдбаре (влияет на расчет ширины)\n   */\n  isHaveSomeFeatureInSidebar?: boolean;\n\n  /**\n   * Конфигурация dropdown для скрытых кнопок\n   */\n  collapsedDropdownProps?: TableDropdownConfigProps;\n\n  /**\n   * Количество выбранных элементов\n   * Используется для внутренней логики видимости панели (если show не указан)\n   * Если selectedCount === 0 и show не указан, панель не отображается\n   */\n  selectedCount: number;\n\n  /**\n   * Явный контроль видимости панели\n   * Если указан, имеет приоритет над автоматической логикой на основе selectedCount\n   * Позволяет показывать панель даже при selectedCount === 0\n   * По умолчанию: undefined (используется логика selectedCount > 0)\n   */\n  show?: boolean;\n\n  /**\n   * Использовать TableDropdown (для таблиц) вместо обычного Dropdown\n   * По умолчанию false (используется обычный Dropdown)\n   */\n  useTableDropdown?: boolean;\n  /**\n   * Включить отладочное логирование в консоль\n   * Полезно для отладки проблем с компрессией и позиционированием\n   * По умолчанию false\n   */\n  enableDebugLogs?: boolean;\n  /**\n   * Отступ снизу от контейнера (в пикселях)\n   * По умолчанию: 16px для standalone, 24px для таблицы\n   */\n  bottom?: number;\n\n  /**\n   * Минимальный отступ панели от краев контейнера (в пикселях)\n   * Используется для:\n   * - CSS padding панели (симметрично: minPadding слева и справа)\n   * - Расчетов компрессии (максимальная ширина панели с учетом отступов)\n   * - Позиционирования (гарантирует минимальный отступ от левого края контейнера)\n   * По умолчанию: 16px для standalone, 24px для таблицы\n   */\n  minPadding?: number;\n\n  /**\n   * Статический размер панели (для использования ВНУТРИ таблиц).\n   * Если задан — перекрывает viewport-логику (медиазапрос 1280 не используется):\n   * `m`/`s` = обычный размер (кнопки `s`), `xs` = уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS, свои паддинги).\n   * НЕ задавать для standalone — там компактность определяется по ширине вьюпорта (`down('xl')`).\n   */\n  size?: MassActionsSize;\n};\n```\n\n## MassActionsButtonProps\n\n```typescript\ntype MassActionsButtonPropsButton = DataAttributes &\n  Partial<ButtonCompProps> & {\n    type: 'button';\n    view?: ButtonCompProps['view'];\n    /**\n     * Dropdown для кнопки.\n     * Используется универсальный DropdownProps, который работает и с обычным Dropdown, и с TableDropdown\n     */\n    dropdown?: DropdownProps & { $css?: CSSObject };\n    disabledTooltipProps?: TooltipProps;\n  };\n```\n\n## Compound types\n\n### MassActions.Counter\n\n```typescript\ntype MassActionsCounterProps = {\n  /** Количество выбранных элементов */\n  selectedCount: number;\n  /** Текст метки (по умолчанию \"Выбрано\") */\n  label?: string;\n  /** Показывать ли чекбокс */\n  showCheckbox?: boolean;\n  /** Состояние чекбокса */\n  checked?: boolean;\n  /** Indeterminate состояние чекбокса */\n  indeterminate?: boolean;\n  /** Колбэк при изменении чекбокса */\n  onCheckboxChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;\n  /** Кастомный className */\n  className?: string;\n};\n```\n\n## MassActionsStatic\n\n```typescript\ntype MassActionsStaticProps = {\n  children: ReactNode;\n  className?: string;\n  style?: CSSProperties;\n  /**\n   * Позиционирование компонента\n   * - 'absolute' - абсолютное позиционирование (по умолчанию)\n   * - 'static' - обычный блок без абсолютного позиционирования\n   * - 'relative' - относительное позиционирование\n   */\n  position?: 'absolute' | 'static' | 'relative';\n  /**\n   * Явный контроль видимости компонента\n   * Если не указан, компонент всегда виден\n   * Если указан, компонент отображается только при show === true\n   */\n  show?: boolean;\n  /**\n   * Включить/отключить анимацию появления/исчезновения\n   * @default true\n   */\n  animate?: boolean;\n};\n```",
      "curatedStories": [
        {
          "exportName": "Standalone",
          "displayName": "Standalone MassActions",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport { MassActions } from '@ui-kit/components/MassActions';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/MassActions/MassActions.stories.tsx',\n  'StandaloneExample',\n)}"
        },
        {
          "exportName": "WithShowProp",
          "displayName": "С явным контролем видимости (show)",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport { Button } from '@ui-kit/components/Button';\nimport { MassActions } from '@ui-kit/components/MassActions';\nimport { s } from '@ui-kit/constants';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/MassActions/MassActions.stories.tsx',\n  'ShowPropExample',\n)}"
        },
        {
          "exportName": "NarrowContainer",
          "displayName": "Узкий контейнер (компрессия)",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport { MassActions } from '@ui-kit/components/MassActions';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/MassActions/MassActions.stories.tsx',\n  'NarrowContainerExample',\n)}"
        },
        {
          "exportName": "WithLeftPanel",
          "displayName": "В комбинации с LeftPanel",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport { Button } from '@ui-kit/components/Button';\nimport { IconButton } from '@ui-kit/components/IconButton';\nimport { LeftPanel } from '@ui-kit/components/LeftPanel';\nimport { MassActions } from '@ui-kit/components/MassActions';\nimport { StaticMassActionsPanel } from '@ui-kit/components/StaticMassActionsPanel';\nimport { s } from '@ui-kit/constants';\nimport { IconDotsVerticalCenteredOutline, IconPlasma } from '@ui-kit/icons';\nimport { surfaceSolidCard } from '@ui-kit/tokens';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/MassActions/MassActions.stories.tsx',\n  'WithLeftPanelExample',\n)}"
        },
        {
          "exportName": "Adaptive1280",
          "displayName": "1280 Адаптив",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport { MassActions } from '@ui-kit/components/MassActions';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/MassActions/MassActions.stories.tsx',\n  'StandaloneExample',\n)}"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { MassActions } from '@daisforge/ui';",
      "minimalUsage": "<MassActions containerRef={() => {}} leftSection={'Контент'} selectedCount={0}>\n  {/* части: MassActions.Counter */}\n</MassActions>",
      "examples": [
        {
          "exportName": "Standalone",
          "displayName": "Standalone MassActions",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport { MassActions } from '@ui-kit/components/MassActions';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/MassActions/MassActions.stories.tsx',\n  'StandaloneExample',\n)}"
        },
        {
          "exportName": "WithShowProp",
          "displayName": "С явным контролем видимости (show)",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport { Button } from '@ui-kit/components/Button';\nimport { MassActions } from '@ui-kit/components/MassActions';\nimport { s } from '@ui-kit/constants';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/MassActions/MassActions.stories.tsx',\n  'ShowPropExample',\n)}"
        },
        {
          "exportName": "NarrowContainer",
          "displayName": "Узкий контейнер (компрессия)",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport { MassActions } from '@ui-kit/components/MassActions';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/MassActions/MassActions.stories.tsx',\n  'NarrowContainerExample',\n)}"
        },
        {
          "exportName": "WithLeftPanel",
          "displayName": "В комбинации с LeftPanel",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport { Button } from '@ui-kit/components/Button';\nimport { IconButton } from '@ui-kit/components/IconButton';\nimport { LeftPanel } from '@ui-kit/components/LeftPanel';\nimport { MassActions } from '@ui-kit/components/MassActions';\nimport { StaticMassActionsPanel } from '@ui-kit/components/StaticMassActionsPanel';\nimport { s } from '@ui-kit/constants';\nimport { IconDotsVerticalCenteredOutline, IconPlasma } from '@ui-kit/icons';\nimport { surfaceSolidCard } from '@ui-kit/tokens';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/MassActions/MassActions.stories.tsx',\n  'WithLeftPanelExample',\n)}"
        }
      ]
    },
    "MassActionsButton": {
      "name": "MassActionsButton",
      "group": "components",
      "folderName": "MassActions",
      "role": "primary",
      "description": "Кнопка действия для панели MassActions с поддержкой выпадающего меню",
      "props": [
        {
          "name": "dropdown",
          "type": "(Omit<DropdownProps<ItemOption>, \"size\" | \"view\"> & Pick<PropsType<{ size: { m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; view: { default: PolymorphicClassName; }; }> & { items: ItemOption[]; trigger?: DropdownTrigger | undefined; placement?: DropdownPlacement | undefined; children?: React.ReactNode; variant?: \"normal\" | \"tight\" | undefined; zIndex?: Property.ZInd…",
          "required": false,
          "description": "Dropdown для кнопки.\nИспользуется универсальный DropdownProps, который работает и с обычным Dropdown, и с TableDropdown"
        },
        {
          "name": "disabledTooltipProps",
          "type": "TooltipProps | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "additionalContent",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "isLoading",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "loader",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "text",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"button\" | \"linkButton\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"accent\" | \"clear\" | \"dark\" | \"black\" | \"white\" | \"gradient\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "MassActionsButtonProps",
      "sourceFile": "packages/ui-kit/src/components/MassActions/MassActionsButton.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "кнопка массового действия",
        "action button dropdown"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { MassActionsButton } from '@daisforge/ui';",
      "minimalUsage": "<MassActionsButton />",
      "examples": []
    },
    "MassActionsCounter": {
      "name": "MassActionsCounter",
      "group": "components",
      "folderName": "MassActions",
      "role": "primary",
      "description": "Счётчик выбранных строк с чекбоксом для панели MassActions",
      "props": [
        {
          "name": "selectedCount",
          "type": "number",
          "required": true,
          "description": "Количество выбранных элементов"
        },
        {
          "name": "indeterminate",
          "type": "boolean | undefined",
          "required": false,
          "description": "Indeterminate состояние чекбокса"
        },
        {
          "name": "onCheckboxChange",
          "type": "((event: React.ChangeEvent<HTMLInputElement>) => void) | undefined",
          "required": false,
          "description": "Колбэк при изменении чекбокса"
        },
        {
          "name": "showCheckbox",
          "type": "boolean | undefined",
          "required": false,
          "description": "Показывать ли чекбокс",
          "default": "false"
        }
      ],
      "propsTypeName": "MassActionsCounterProps",
      "sourceFile": "packages/ui-kit/src/components/MassActions/MassActionsCounter.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "счётчик выбранных",
        "selection counter",
        "чекбокс выбора всех"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "MassActions",
        "part": "Counter"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { MassActionsCounter } from '@daisforge/ui';",
      "minimalUsage": "<MassActionsCounter selectedCount={0} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в MassActions.stories.tsx",
          "type": "usage",
          "code": "<MassActions.Counter\n              selectedCount={selectedItems.size}\n              showCheckbox\n              checked={checked}\n              indeterminate={indeterminate}\n              onCheckboxChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n                handleCheckboxChange(e.target.checked)\n              }\n            />",
          "sourceFile": "packages/storybook/src/stories/MassActions/MassActions.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в MassActions.stories.tsx",
          "type": "usage",
          "code": "<MassActions.Counter\n                selectedCount={selectedItems.size}\n                showCheckbox\n                checked={checked}\n                indeterminate={indeterminate}\n                onCheckboxChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n                  handleCheckboxChange(e.target.checked)\n                }\n              />",
          "sourceFile": "packages/storybook/src/stories/MassActions/MassActions.stories.tsx"
        }
      ]
    },
    "MassActionsStatic": {
      "name": "MassActionsStatic",
      "group": "components",
      "folderName": "MassActionsStatic",
      "role": "primary",
      "description": "Фиксированный контейнер для закрепления MassActions при скролле",
      "props": [
        {
          "name": "animate",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включить/отключить анимацию появления/исчезновения",
          "default": "true"
        },
        {
          "name": "position",
          "type": "\"absolute\" | \"static\" | \"relative\" | undefined",
          "required": false,
          "description": "Позиционирование компонента\n- 'absolute' - абсолютное позиционирование (по умолчанию)\n- 'static' - обычный блок без абсолютного позиционирования\n- 'relative' - относительное позиционирование",
          "default": "'absolute'"
        },
        {
          "name": "show",
          "type": "boolean | undefined",
          "required": false,
          "description": "Явный контроль видимости компонента\nЕсли не указан, компонент всегда виден\nЕсли указан, компонент отображается только при show === true"
        }
      ],
      "propsTypeName": "MassActionsStaticProps",
      "sourceFile": "packages/ui-kit/src/components/MassActionsStatic/MassActionsStatic.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "закрепление панели",
        "sticky container",
        "fixed position"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { MassActionsStatic } from '@daisforge/ui';",
      "minimalUsage": "<MassActionsStatic />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в MassActions.stories.tsx",
          "type": "usage",
          "code": "<MassActionsStatic show={isShowMassActionsStatic}>\n              <IconButton size=\"s\" view=\"secondary\">\n                <IconDotsVerticalCenteredOutline />\n              </IconButton>\n              <Button\n                text=\"Label 1\"\n                contentLeft={<IconPlasma />}\n                size=\"s\"\n                view=\"secondary\"\n                onClick={() => alert('Label 1')}\n                style={{\n                  flexGrow: 1,\n                }}\n              />\n              <Button\n                text=\"Label 2\"\n                size=\"s\"\n                contentLeft={<IconPlasma />}\n                view=\"secondary\"\n                onClick={() => alert('Label 2')}\n                style={{\n                  flexGrow: 1,\n                }}\n              />\n            </MassActionsStatic>",
          "sourceFile": "packages/storybook/src/stories/MassActions/MassActions.stories.tsx"
        }
      ]
    },
    "Modal": {
      "name": "Modal",
      "group": "components",
      "folderName": "Modal",
      "role": "primary",
      "description": "Базовое модальное окно поверх контента без готовых layout-слотов",
      "props": [
        {
          "name": "focusTrapSelectors",
          "type": "string[] | undefined",
          "required": false,
          "description": "Селекторы дополнительных DOM-поддеревьев, которые считаются частью модального окна для focus trap.\nИспользуется для элементов, отрисованных через Portal или вне DOM-поддерева модального окна."
        }
      ],
      "propsTypeName": "ModalProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Modal/Modal.d.ts",
      "type": "wrapper",
      "atomicBase": "Modal",
      "category": "Локальные компоненты",
      "keywords": [
        "модальное окно",
        "overlay dialog",
        "попап"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "closeOnEsc",
          "type": "boolean",
          "required": false,
          "description": "Закрывать модальное окно при нажатии на ESC(по умолчанию true).",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean",
          "required": false,
          "description": "Закрывать модальное окно при нажатии вне области модального окна(по умолчанию true),",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "draggable",
          "type": "boolean",
          "required": false,
          "description": "Настройка draggable-режима.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focusAfterRef",
          "type": "RefObject<HTMLElement>",
          "required": false,
          "description": "Элемент для фокуса после закрытия модального окна\n(по умолчанию фокус на последнем перед открытием активном элементе).",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "frame",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "В каком контейнере позиционируется (по умолчанию document), можно также указать id элемента или ref для него.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasBody",
          "type": "boolean",
          "required": false,
          "description": "Оборачивает children в стилизованную обертку",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasClose",
          "type": "boolean",
          "required": false,
          "description": "Отображает кнопку с крестиком для закрытия",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "initialFocusRef",
          "type": "RefObject<HTMLElement>",
          "required": false,
          "description": "Первый элемент для фокуса внутри модального окна.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isFocusTrapped",
          "type": "boolean",
          "required": false,
          "description": "Фокус элементов будет происходить только внутри модального окна",
          "default": "true",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number] | [string, string]",
          "required": false,
          "description": "Смещение относительно текущей позиции.\n(x, y) - [number, number], [string, string].\nПри передаче number расчёт в rem.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onClose",
          "type": "(() => void)",
          "required": false,
          "description": "Общий обработчик клика по кнопке \"закрыть\".",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onEscKeyDown",
          "type": "((event: KeyboardEvent) => void)",
          "required": false,
          "description": "Обработчик клика при нажатии на ESC(если не передан, то при нажатии используется onClose).",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onOverlayClick",
          "type": "((event: MouseEvent<HTMLDivElement, MouseEvent>) => void)",
          "required": false,
          "description": "Обработчик клика при нажатии вне области модального окна(если не передан, то при нажатии используется onClose).",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": false,
          "description": "Отображение Popup.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "overlay",
          "type": "ReactNode",
          "required": false,
          "description": "Соседний элемент для окна в портале.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "PopupPlacement",
          "required": false,
          "description": "Позиция на экране\ncenter - по умолчанию\nleft, right, top, bottom и их комбинации",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "popupInfo",
          "type": "PopupInfo",
          "required": false,
          "description": "Дополнительная информация для программного взаимодействия с окном через контекст.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "positionFixed",
          "type": "boolean",
          "required": false,
          "description": "Если `frame` отличается от `document` применяет `position='fixed'`",
          "default": "false",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "resizable",
          "type": "boolean | { disabled?: boolean; directions?: ResizeDirections; defaultSize?: { width?: number | undefined; height?: number | undefined; } | undefined; ... 8 more ...; onResizeEnd?: ((resizableContainer?: RefObject<...> | undefined) => void) | undefined; } | undefined",
          "required": false,
          "description": "Настройка resizable-режима.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withAnimation",
          "type": "boolean",
          "required": false,
          "description": "Использовать ли анимацию.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withBlur",
          "type": "boolean",
          "required": false,
          "description": "Нужно ли применять blur для подложки.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "string",
          "required": false,
          "description": "Значение z-index для Popup.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "children",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "string",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Modal } from '@daisforge/ui';",
      "minimalUsage": "<Modal />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Подключение анимации",
          "type": "vendor",
          "code": "import styled from 'styled-components';\nimport { Modal } from '@daisforge/ui';\nconst StyledModal = styled(Modal)`\n    && > .${popupClasses.root}, .${modalClasses.overlay} {\n        animation: fadeIn 1s forwards;\n    }\n    &&.${popupClasses.endAnimation} .${popupClasses.root} {\n        animation: fadeOut 1s forwards;\n    }\n    &&.${popupClasses.endAnimation} .${modalClasses.overlay} {\n        animation: fadeOut 1s forwards;\n    }\n    @keyframes fadeIn {\n        from {\n            opacity: 0;\n        }\n        to {\n            opacity: 1;\n        }\n    }\n    @keyframes fadeOut {\n        from {\n            opacity: 1;\n        }\n        to {\n            opacity: 0;\n        }\n    }\n`;"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Resizable Resizable Чтобы иметь возможность растягивать Popup нужно настроить свойство  resizable . Формат следующий",
          "type": "vendor",
          "code": "/**\n * Настройка resizable-режима.\n */\nresizable?: {\n      /**\n       * Включение/выключение ресайза.\n       * @default false\n       */\n      disabled?: boolean;\n      /**\n       * Направления для ресайза.\n       */\n      directions?: ResizeDirections;\n      /**\n       * Начальный размер окна ресайза.\n       */\n      defaultSize?: { width?: number; height?: number };\n      /**\n       * Минимальная ширина ресайза в px.\n       */\n      minWidth?: number;\n      /**\n       * Минимальная высота ресайза в px.\n       */\n      minHeight?: number;\n      /**\n       * Максимальная ширина ресайза в px.\n       */\n      maxWidth?: number;\n      /**\n       * Максимальная высота ресайза в px.\n       */\n      maxHeight?: number;\n      /**\n       * Кастомные иконки ресайза.\n       */\n      icons?: {\n          topRight?: ReactNode;\n          bottomRight?: ReactNode;\n          bottomLeft?: ReactNode;\n          topLeft?: ReactNode;\n      };\n      /**\n       * Размер иконки ресайза.\n       * @default s\n       */\n      iconSize?: 'xs' | 's' | 'm';\n      /**\n       * Скрывать ли иконку для ресайза.\n       * @default false\n       */\n      hiddenIcons?: PopupPlacementMixed[];\n};"
        }
      ]
    },
    "ModalDFBackIconButton": {
      "name": "ModalDFBackIconButton",
      "group": "components",
      "folderName": "ModalDF",
      "role": "part",
      "description": "Круглая кнопка «Назад» в шапке ModalDF для возврата на предыдущий шаг",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "iconSize",
          "type": "\"m\" | \"s\" | \"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "additionalContent",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentPlacing",
          "type": "\"default\" | \"relaxed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isLoading",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "loader",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "outlined",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftLeft",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftRight",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "square",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretch",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretching",
          "type": "\"fixed\" | \"auto\" | \"filled\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "text",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"button\" | \"submit\" | \"reset\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "value",
          "type": "string | number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"dark\" | \"black\" | \"white\" | \"accent\" | \"secondary\" | \"clear\" | \"positive\" | \"warning\" | \"negative\" | \"gradient\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ModalDFBackIconButtonProps",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/components/BackIconButton.tsx",
      "type": "wrapper",
      "atomicBase": "IconButton",
      "wrapsInternal": "IconButton",
      "category": "Локальные компоненты",
      "keywords": [
        "кнопка назад",
        "навигация в модалке",
        "back button"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "ModalDF",
      "inheritedProps": [
        {
          "name": "additionalContent",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentPlacing",
          "type": "ContentPlacing",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focused",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isLoading",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "loader",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "outlined",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftLeft",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftRight",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "square",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretching",
          "type": "Stretching",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "string",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"secondary\" | \"black\" | \"white\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "ModalDF",
        "part": "BackIconButton"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalDFBackIconButton } from '@daisforge/ui';",
      "minimalUsage": "<ModalDFBackIconButton />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Компонент  IconButton  может содержать иконку, которая указывается напрямую через  children .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconButton } from '@daisforge/ui';\nimport { IconClose } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <IconButton>\n                <IconClose color=\"inherit\" />\n            </IconButton>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Границы кнопки",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconButton } from '@daisforge/ui';\nimport { IconClose } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexWrap: 'wrap' }}>\n            <IconButton pin=\"square-square\">\n                <IconClose color=\"inherit\" />\n            </IconButton>\n            <IconButton pin=\"circle-circle\">\n                <IconClose color=\"inherit\" />\n            </IconButton>\n        </div>\n    );\n}"
        }
      ]
    },
    "ModalDFDivider": {
      "name": "ModalDFDivider",
      "group": "components",
      "folderName": "ModalDF",
      "role": "part",
      "description": "Вертикальный разделитель между дополнительным блоком и служебными кнопками шапки ModalDF",
      "props": [
        {
          "name": "length",
          "type": "string | number | undefined",
          "required": false,
          "description": "Размер разделителя",
          "default": "'100%'"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\" | undefined",
          "required": false,
          "description": "Направление разделителя",
          "default": "'horizontal'"
        },
        {
          "name": "size",
          "type": "\"m\" | undefined",
          "required": false,
          "description": "Размер разделителя",
          "default": "'m'"
        },
        {
          "name": "view",
          "type": "\"default\" | \"dark\" | \"light\" | \"inverse\" | undefined",
          "required": false,
          "description": "Вид разделителя",
          "default": "'default'"
        }
      ],
      "propsTypeName": "ComponentProps<typeof ModalDFDivider>",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/components/Divider.tsx",
      "type": "wrapper",
      "atomicBase": "Divider",
      "wrapsInternal": "Divider",
      "category": "Локальные компоненты",
      "keywords": [
        "разделитель шапки",
        "vertical divider",
        "разделитель кнопок"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "ModalDF",
      "atomicDataMissing": true,
      "compoundPartOf": {
        "component": "ModalDF",
        "part": "Divider"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalDFDivider } from '@daisforge/ui';",
      "minimalUsage": "<ModalDFDivider />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в ModalDF.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.Divider />",
          "sourceFile": "packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx"
        }
      ]
    },
    "ModalDFDotsIconButton": {
      "name": "ModalDFDotsIconButton",
      "group": "components",
      "folderName": "ModalDF",
      "role": "part",
      "description": "Кнопка с иконкой троеточия и выпадающим меню доп. действий в шапке ModalDF",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "dropdownProps",
          "type": "(Omit<DropdownProps<ItemOption>, \"view\" | \"size\"> & Pick<PropsType<{ size: { m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; view: { default: PolymorphicClassName; }; }> & { items: ItemOption[]; trigger?: DropdownTrigger | undefined; placement?: DropdownPlacement | undefined; children?: React.ReactNode; variant?: \"normal\" | \"tight\" | undefined; zIndex?: Property.ZInd…",
          "required": false,
          "description": ""
        },
        {
          "name": "iconSize",
          "type": "\"m\" | \"s\" | \"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "additionalContent",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentPlacing",
          "type": "\"default\" | \"relaxed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isLoading",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "loader",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "outlined",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftLeft",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftRight",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "square",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretch",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretching",
          "type": "\"fixed\" | \"auto\" | \"filled\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "text",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"button\" | \"submit\" | \"reset\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "value",
          "type": "string | number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"dark\" | \"black\" | \"white\" | \"accent\" | \"secondary\" | \"clear\" | \"positive\" | \"warning\" | \"negative\" | \"gradient\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ModalDFDotsIconButtonProps",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/components/DotsIconButton.tsx",
      "type": "wrapper",
      "atomicBase": "IconButton",
      "wrapsInternal": "IconButton",
      "category": "Локальные компоненты",
      "keywords": [
        "доп меню модалки",
        "overflow menu",
        "кнопка троеточие"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "ModalDF",
      "inheritedProps": [
        {
          "name": "additionalContent",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentPlacing",
          "type": "ContentPlacing",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focused",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isLoading",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "loader",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "outlined",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftLeft",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftRight",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "square",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretching",
          "type": "Stretching",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "string",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"secondary\" | \"black\" | \"white\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "ModalDF",
        "part": "DotsIconButton"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalDFDotsIconButton } from '@daisforge/ui';",
      "minimalUsage": "<ModalDFDotsIconButton />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в ModalDF.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.DotsIconButton size=\"s\" />",
          "sourceFile": "packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в ModalDF.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.DotsIconButton />",
          "sourceFile": "packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Компонент  IconButton  может содержать иконку, которая указывается напрямую через  children .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconButton } from '@daisforge/ui';\nimport { IconClose } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <IconButton>\n                <IconClose color=\"inherit\" />\n            </IconButton>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Границы кнопки",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconButton } from '@daisforge/ui';\nimport { IconClose } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexWrap: 'wrap' }}>\n            <IconButton pin=\"square-square\">\n                <IconClose color=\"inherit\" />\n            </IconButton>\n            <IconButton pin=\"circle-circle\">\n                <IconClose color=\"inherit\" />\n            </IconButton>\n        </div>\n    );\n}"
        }
      ]
    },
    "ModalDFFooter": {
      "name": "ModalDFFooter",
      "group": "components",
      "folderName": "ModalDF",
      "role": "part",
      "description": "Нижняя панель ModalDF с раздельными зонами для левой и правой групп кнопок",
      "props": [
        {
          "name": "leftBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "rightBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ModalDFFooterProps",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/components/Footer.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "футер модалки",
        "кнопки подтверждения",
        "modal footer"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "ModalDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "ModalDF",
        "part": "Footer"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalDFFooter } from '@daisforge/ui';",
      "minimalUsage": "<ModalDFFooter />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в ModalDF.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.Footer\n            leftBlock={\n              <Flow mainAxisGap={s.x4}>\n                <Button text=\"Кнопка 1\" size=\"s\" view=\"secondary\" />\n                <Button text=\"Кнопка 2\" size=\"s\" view=\"secondary\" />\n                <ModalDF.DotsIconButton size=\"s\" />\n              </Flow>\n            }\n            rightBlock={\n              <Flow mainAxisGap={s.x4}>\n                <Button text=\"Кнопка\" size=\"s\" view=\"secondary\" />\n                <Button text=\"Главная кнопка\" size=\"s\" view=\"accent\" />\n              </Flow>\n            }\n          />",
          "sourceFile": "packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в ModalDF.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.Footer\n            rightBlock={<Button view=\"secondary\" size=\"s\" text=\"Кнопка\" />}\n          />",
          "sourceFile": "packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx"
        }
      ]
    },
    "ModalDFHeader": {
      "name": "ModalDFHeader",
      "group": "components",
      "folderName": "ModalDF",
      "role": "part",
      "description": "Шапка ModalDF: заголовок, бейдж, кнопка назад и кнопки закрытия/полноэкрана",
      "props": [
        {
          "name": "badge",
          "type": "((((Omit<Omit<PropsType<{ view: { default: PolymorphicClassName; accent: PolymorphicClassName; positive: PolymorphicClassName; warning: PolymorphicClassName; negative: PolymorphicClassName; dark: PolymorphicClassName; light: PolymorphicClassName; }; size: { l: PolymorphicClassName; m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; pilled: { true: PolymorphicClassName; …",
          "required": false,
          "description": ""
        },
        {
          "name": "onBackClick",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rightBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "showBackButton",
          "type": "boolean | undefined",
          "required": false,
          "description": "",
          "default": "false"
        },
        {
          "name": "subTitle",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "title",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ModalDFHeaderProps",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/components/Header.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "шапка модалки",
        "заголовок окна",
        "modal header"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "ModalDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "ModalDF",
        "part": "Header"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalDFHeader } from '@daisforge/ui';",
      "minimalUsage": "<ModalDFHeader />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в ModalDF.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.Header\n            title=\"Заголовок\"\n            badge={{ text: 'Бейдж' }}\n            subTitle=\"Подзаголовок\"\n            showBackButton\n            onBackClick={() => {}}\n            rightBlock={\n              <>\n                <Flow mainAxisGap={s.x4} style={{ flexWrap: 'nowrap' }}>\n                  <TextS>\n                    <Link href={window.location.href} view=\"accent\">\n                      ссылка\n                    </Link>\n                  </TextS>\n                  <TextS>\n                    <Link href={window.location.href} view=\"accent\">\n                      ссылка\n                    </Link>\n                  </TextS>\n                </Flow>\n                <ModalDF.Divider />\n                <Flow mainAxisGap={s.x1} style={{ flexWrap: 'nowrap' }}>\n                  <ModalDF.DotsIconButton />\n                  <Button text=\"Кнопка 1\" size=\"xs\" view=\"secondary\" />\n                  <Button text=\"Кнопка 2\" size=\"xs\" view=\"secondary\" />\n                </Flow>\n              </>\n            }\n          />",
          "sourceFile": "packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в Stories.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.Header\n            title=\"Сторис внутри модалки\"\n            subTitle=\"Клик по кружку открывает вьюер поверх модалки (zIndex выше оверлея ModalDF)\"\n          />",
          "sourceFile": "packages/storybook/src/stories/Stories/Stories.stories.tsx"
        }
      ]
    },
    "ModalDFServiceButtons": {
      "name": "ModalDFServiceButtons",
      "group": "components",
      "folderName": "ModalDF",
      "role": "part",
      "description": "Группа служебных кнопок ModalDF: переключение полноэкранного режима и закрытие",
      "props": [
        {
          "name": "as",
          "type": "string | React.ComponentType<any> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ModalDFServiceButtonsProps",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/components/ServiceButtons.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "полноэкранный режим",
        "кнопка закрытия окна",
        "service buttons"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "ModalDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "ModalDF",
        "part": "ServiceButtons"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalDFServiceButtons } from '@daisforge/ui';",
      "minimalUsage": "<ModalDFServiceButtons />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в ModalDF.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.ServiceButtons\n            $css={{ marginLeft: 'auto', paddingBottom: s.x8 }}\n          />",
          "sourceFile": "packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx"
        }
      ]
    },
    "ModalDF": {
      "name": "ModalDF",
      "group": "components",
      "folderName": "ModalDF",
      "role": "primary",
      "description": "Расширенное модальное окно с compound-слотами: шапка, контент, футер, Left/Main",
      "props": [
        {
          "name": "focusTrapSelectors",
          "type": "string[] | undefined",
          "required": false,
          "description": "Селекторы дополнительных DOM-поддеревьев, которые считаются частью модального окна для focus trap.\nИспользуется для элементов, отрисованных через Portal или вне DOM-поддерева модального окна."
        },
        {
          "name": "contentContainerProps",
          "type": "Partial<ContainerProps> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "fullScreen",
          "type": "boolean | { defaultEnabled?: boolean | undefined; saveStateAfterClosing?: boolean | undefined; onFullScreen?: (() => void) | undefined; onExitFullScreen?: (() => void) | undefined; } | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "zIndexOverlay",
          "type": "string | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ModalDFProps",
      "compoundParts": [
        {
          "name": "Left",
          "typeName": "ComponentProps<typeof StyledLeft>",
          "props": [
            {
              "name": "as",
              "type": "string | React.ComponentType<any> | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Main",
          "typeName": "ComponentProps<typeof StyledMain>",
          "props": [
            {
              "name": "as",
              "type": "string | React.ComponentType<any> | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Header",
          "typeName": "ModalDFHeaderProps",
          "props": [
            {
              "name": "badge",
              "type": "((((Omit<Omit<PropsType<{ view: { default: PolymorphicClassName; accent: PolymorphicClassName; positive: PolymorphicClassName; warning: PolymorphicClassName; negative: PolymorphicClassName; dark: PolymorphicClassName; light: PolymorphicClassName; }; size: { l: PolymorphicClassName; m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; pilled: { true: PolymorphicClassName; …",
              "required": false,
              "description": ""
            },
            {
              "name": "onBackClick",
              "type": "(() => void) | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "rightBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "showBackButton",
              "type": "boolean | undefined",
              "required": false,
              "description": "",
              "default": "false"
            },
            {
              "name": "subTitle",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "title",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Footer",
          "typeName": "ModalDFFooterProps",
          "props": [
            {
              "name": "leftBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "rightBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Content",
          "typeName": "ComponentProps<typeof StyledContent>",
          "props": [
            {
              "name": "as",
              "type": "string | React.ComponentType<any> | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Divider",
          "typeName": "ComponentProps<typeof Divider>",
          "props": [
            {
              "name": "length",
              "type": "string | number | undefined",
              "required": false,
              "description": "Размер разделителя",
              "default": "'100%'"
            },
            {
              "name": "orientation",
              "type": "\"horizontal\" | \"vertical\" | undefined",
              "required": false,
              "description": "Направление разделителя",
              "default": "'horizontal'"
            },
            {
              "name": "size",
              "type": "\"m\" | undefined",
              "required": false,
              "description": "Размер разделителя",
              "default": "'m'"
            },
            {
              "name": "view",
              "type": "\"default\" | \"dark\" | \"light\" | \"inverse\" | undefined",
              "required": false,
              "description": "Вид разделителя",
              "default": "'default'"
            }
          ]
        },
        {
          "name": "ServiceButtons",
          "typeName": "ModalDFServiceButtonsProps",
          "props": [
            {
              "name": "as",
              "type": "string | React.ComponentType<any> | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "DotsIconButton",
          "typeName": "ModalDFDotsIconButtonProps",
          "props": [
            {
              "name": "as",
              "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
              "required": false,
              "description": "Сменить рендер на другой тип компонента."
            },
            {
              "name": "dropdownProps",
              "type": "(Omit<DropdownProps<ItemOption>, \"view\" | \"size\"> & Pick<PropsType<{ size: { m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; view: { default: PolymorphicClassName; }; }> & { items: ItemOption[]; trigger?: DropdownTrigger | undefined; placement?: DropdownPlacement | undefined; children?: React.ReactNode; variant?: \"normal\" | \"tight\" | undefined; zIndex?: Property.ZInd…",
              "required": false,
              "description": ""
            },
            {
              "name": "iconSize",
              "type": "\"m\" | \"s\" | \"xs\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "additionalContent",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "appearance",
              "type": "\"default\" | \"outline\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "blur",
              "type": "\"small\" | \"medium\" | \"large\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentLeft",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "contentPlacing",
              "type": "\"default\" | \"relaxed\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentRight",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "focused",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "isLoading",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "loader",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "outlined",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "pin",
              "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftLeft",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftRight",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "size",
              "type": "\"s\" | \"xs\" | \"xxs\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "square",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretch",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretching",
              "type": "\"fixed\" | \"auto\" | \"filled\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "text",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "type",
              "type": "\"button\" | \"submit\" | \"reset\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "value",
              "type": "string | number | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "view",
              "type": "\"default\" | \"dark\" | \"black\" | \"white\" | \"accent\" | \"secondary\" | \"clear\" | \"positive\" | \"warning\" | \"negative\" | \"gradient\" | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "BackIconButton",
          "typeName": "ModalDFBackIconButtonProps",
          "props": [
            {
              "name": "as",
              "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
              "required": false,
              "description": "Сменить рендер на другой тип компонента."
            },
            {
              "name": "iconSize",
              "type": "\"m\" | \"s\" | \"xs\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "additionalContent",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "appearance",
              "type": "\"default\" | \"outline\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "blur",
              "type": "\"small\" | \"medium\" | \"large\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentLeft",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "contentPlacing",
              "type": "\"default\" | \"relaxed\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentRight",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "focused",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "isLoading",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "loader",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "outlined",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "pin",
              "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftLeft",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftRight",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "size",
              "type": "\"s\" | \"xs\" | \"xxs\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "square",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretch",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretching",
              "type": "\"fixed\" | \"auto\" | \"filled\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "text",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "type",
              "type": "\"button\" | \"submit\" | \"reset\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "value",
              "type": "string | number | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "view",
              "type": "\"default\" | \"dark\" | \"black\" | \"white\" | \"accent\" | \"secondary\" | \"clear\" | \"positive\" | \"warning\" | \"negative\" | \"gradient\" | undefined",
              "required": false,
              "description": ""
            }
          ]
        }
      ],
      "sourceFile": "packages/ui-kit/src/components/ModalDF/ModalDF.tsx",
      "type": "wrapper",
      "atomicBase": "Modal",
      "wrapsInternal": "Modal",
      "category": "Локальные компоненты",
      "keywords": [
        "составное модальное окно",
        "modal с слотами",
        "шапка и футер диалога"
      ],
      "docs": "# ModalDF\n\nСтилизованный модальный компонент дизайн-системы. Собирается из набора готовых блоков — от простого модального окна до двухколоночных сценариев с дополнительной панелью.\n\n## Ключевые особенности\n\n- Поддержка полноэкранного режима с сохранением состояния\n- Гибкая настройка контейнера контента через `contentContainerProps`\n- Наличие сервисных кнопок (fullscreen / close) даже без шапки\n- Набор compound-компонентов для построения консистентных шапок и футеров\n- Двухколоночная раскладка через `ModalDF.Left` и `ModalDF.Main`\n\n## Compound-компоненты\n\n```ts\nModalDF.Left; // Левая колонка\nModalDF.Main; // Основная колонка\nModalDF.Header; // Шапка: заголовок, подзаголовок, бейдж, правый блок, кнопка «назад»\nModalDF.Footer; // Футер: левый и правый блоки кнопок\nModalDF.Content; // Контейнер контента\nModalDF.Divider; // Разделитель\nModalDF.ServiceButtons; // Кнопки fullscreen/close\nModalDF.DotsIconButton; // Иконка «троеточие» с Dropdown\nModalDF.BackIconButton; // Кнопка «назад»\n```\n\n- `ModalDF.Header` — заголовок, подзаголовок, бейдж, правый блок действий и кнопка «назад»\n- `ModalDF.Footer` — разделение кнопок и ссылок на левый и правый блоки\n- `ModalDF.ServiceButtons` — блок с кнопками fullscreen/close\n- `ModalDF.DotsIconButton` — иконка «троеточие» с поддержкой dropdown\n- `ModalDF.BackIconButton` — кнопка «назад», доступна для произвольного использования\n- `ModalDF.Left`, `ModalDF.Main`, `ModalDF.Content`, `ModalDF.Divider` — контейнеры, наследуют `BoxProps`, принимают `$css`\n\n## Особенности\n\n- `fullScreen` — включает встроенный менеджер полноэкранного режима. Можно передать callbacks и управлять сохранением состояния между открытиями\n- Ширину рекомендуется задавать через `contentContainerProps.css`\n- Базовые пропсы наследуются от `ModalCompProps` ([документация SDDS](https://plasma.sberdevices.ru/sdds-finai/components/modal/))\n\nОписание типов и compound-пропсов — в разделе [API](/docs/локальные-компоненты-modaldf-api--docs).",
      "apiDocs": "# ModalDF API\n\n## ModalDFProps\n\n```typescript\ntype ModalDFProps = {\n  fullScreen?:\n    | {\n        defaultEnabled?: boolean;\n        saveStateAfterClosing?: boolean;\n        onFullScreen?: () => void;\n        onExitFullScreen?: () => void;\n      }\n    | undefined\n    | boolean;\n  contentContainerProps?: Partial<ContainerProps>;\n  zIndexOverlay?: string;\n} & Omit<ModalCompProps, 'hasBody'>;\n```\n\n## Compound types\n\n### ModalDF.Header\n\n```typescript\ntype ModalDFHeaderProps = Omit<BoxProps, 'children'> & {\n  title?: ReactNode;\n  badge?: ComponentProps<typeof Badge>;\n  subTitle?: ReactNode;\n  rightBlock?: ReactNode;\n  onBackClick?: () => void;\n  showBackButton?: boolean;\n};\n```\n\n### ModalDF.Footer\n\n```typescript\ntype ModalDFFooterProps = Omit<BoxProps, 'children'> & {\n  leftBlock?: ReactNode;\n  rightBlock?: ReactNode;\n};\n```\n\n### ModalDF.ServiceButtons\n\n```typescript\ntype ModalDFServiceButtonsProps = ComponentProps<\n  typeof StyledServiceButtons\n>;\n```\n\n### ModalDF.DotsIconButton\n\n```typescript\ntype ModalDFDotsIconButtonProps = ComponentProps<typeof IconButton> & {\n  dropdownProps?: ComponentProps<typeof Dropdown>;\n  iconSize?: ComponentProps<typeof IconDotsVerticalCenteredOutline>['size'];\n};\n```\n\n### ModalDF.BackIconButton\n\n```typescript\ntype ModalDFBackIconButtonProps = ComponentProps<typeof IconButton> & {\n  iconSize?: ComponentProps<typeof IconArrowLeft>['size'];\n};\n```\n\n### ModalDF.Left, ModalDF.Main, ModalDF.Content, ModalDF.Divider\n\nКонтейнеры наследуют `BoxProps` и принимают `$css` для локальных правок.",
      "curatedStories": [
        {
          "exportName": "ModalDFWithOneContent",
          "displayName": "ModalDF",
          "type": "full-code",
          "code": "import {\n  Button,\n  Flow,\n  Link,\n  ModalDF,\n  TextS,\n} from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { longLorem } from '../DrawerDF/data';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx',\n  'ModalDFWithOneContentExample',\n)}"
        },
        {
          "exportName": "ModalDFWithLeftBlock",
          "displayName": "ModalDF с доп. блоком слева",
          "type": "full-code",
          "code": "import {\n  Button,\n  Flow,\n  Link,\n  ModalDF,\n  TextS,\n} from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { shortLorem } from '../DrawerDF/data';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx',\n  'ModalDFWithLeftBlockExample',\n)}"
        },
        {
          "exportName": "ModalDFWithBigContents",
          "displayName": "ModalDF с большим количеством контента",
          "type": "full-code",
          "code": "import {\n  Button,\n  Flow,\n  Link,\n  ModalDF,\n  TextS,\n} from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { longLorem } from '../DrawerDF/data';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx',\n  'ModalDFWithBigContentsExample',\n)}"
        },
        {
          "exportName": "ModalDFEmpty",
          "displayName": "ModalDF без шапки и футера",
          "type": "full-code",
          "code": "import { Button, ModalDF } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { longLorem } from '../DrawerDF/data';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx',\n  'ModalDFEmptyExample',\n)}"
        }
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "ModalDFBackIconButton",
        "ModalDFDivider",
        "ModalDFDotsIconButton",
        "ModalDFFooter",
        "ModalDFHeader",
        "ModalDFServiceButtons",
        "ModalDFLeft",
        "ModalDFMain",
        "ModalDFContent"
      ],
      "inheritedProps": [
        {
          "name": "closeOnEsc",
          "type": "boolean",
          "required": false,
          "description": "Закрывать модальное окно при нажатии на ESC(по умолчанию true).",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean",
          "required": false,
          "description": "Закрывать модальное окно при нажатии вне области модального окна(по умолчанию true),",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "draggable",
          "type": "boolean",
          "required": false,
          "description": "Настройка draggable-режима.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focusAfterRef",
          "type": "RefObject<HTMLElement>",
          "required": false,
          "description": "Элемент для фокуса после закрытия модального окна\n(по умолчанию фокус на последнем перед открытием активном элементе).",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "frame",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "В каком контейнере позиционируется (по умолчанию document), можно также указать id элемента или ref для него.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasClose",
          "type": "boolean",
          "required": false,
          "description": "Отображает кнопку с крестиком для закрытия",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "initialFocusRef",
          "type": "RefObject<HTMLElement>",
          "required": false,
          "description": "Первый элемент для фокуса внутри модального окна.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isFocusTrapped",
          "type": "boolean",
          "required": false,
          "description": "Фокус элементов будет происходить только внутри модального окна",
          "default": "true",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number] | [string, string]",
          "required": false,
          "description": "Смещение относительно текущей позиции.\n(x, y) - [number, number], [string, string].\nПри передаче number расчёт в rem.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onClose",
          "type": "(() => void)",
          "required": false,
          "description": "Общий обработчик клика по кнопке \"закрыть\".",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onEscKeyDown",
          "type": "((event: KeyboardEvent) => void)",
          "required": false,
          "description": "Обработчик клика при нажатии на ESC(если не передан, то при нажатии используется onClose).",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onOverlayClick",
          "type": "((event: MouseEvent<HTMLDivElement, MouseEvent>) => void)",
          "required": false,
          "description": "Обработчик клика при нажатии вне области модального окна(если не передан, то при нажатии используется onClose).",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": false,
          "description": "Отображение Popup.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "overlay",
          "type": "ReactNode",
          "required": false,
          "description": "Соседний элемент для окна в портале.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "PopupPlacement",
          "required": false,
          "description": "Позиция на экране\ncenter - по умолчанию\nleft, right, top, bottom и их комбинации",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "popupInfo",
          "type": "PopupInfo",
          "required": false,
          "description": "Дополнительная информация для программного взаимодействия с окном через контекст.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "positionFixed",
          "type": "boolean",
          "required": false,
          "description": "Если `frame` отличается от `document` применяет `position='fixed'`",
          "default": "false",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "resizable",
          "type": "boolean | { disabled?: boolean; directions?: ResizeDirections; defaultSize?: { width?: number | undefined; height?: number | undefined; } | undefined; ... 8 more ...; onResizeEnd?: ((resizableContainer?: RefObject<...> | undefined) => void) | undefined; } | undefined",
          "required": false,
          "description": "Настройка resizable-режима.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withAnimation",
          "type": "boolean",
          "required": false,
          "description": "Использовать ли анимацию.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withBlur",
          "type": "boolean",
          "required": false,
          "description": "Нужно ли применять blur для подложки.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "string",
          "required": false,
          "description": "Значение z-index для Popup.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "children",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasBody",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "string",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalDF } from '@daisforge/ui';",
      "minimalUsage": "<ModalDF>\n  {/* части: ModalDF.Left, ModalDF.Main, ModalDF.Header, ModalDF.Footer, ModalDF.Content, ModalDF.Divider, ModalDF.ServiceButtons, ModalDF.DotsIconButton, ModalDF.BackIconButton */}\n</ModalDF>",
      "examples": [
        {
          "exportName": "ModalDFWithOneContent",
          "displayName": "ModalDF",
          "type": "full-code",
          "code": "import {\n  Button,\n  Flow,\n  Link,\n  ModalDF,\n  TextS,\n} from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { longLorem } from '../DrawerDF/data';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx',\n  'ModalDFWithOneContentExample',\n)}"
        },
        {
          "exportName": "ModalDFWithLeftBlock",
          "displayName": "ModalDF с доп. блоком слева",
          "type": "full-code",
          "code": "import {\n  Button,\n  Flow,\n  Link,\n  ModalDF,\n  TextS,\n} from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { shortLorem } from '../DrawerDF/data';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx',\n  'ModalDFWithLeftBlockExample',\n)}"
        },
        {
          "exportName": "ModalDFWithBigContents",
          "displayName": "ModalDF с большим количеством контента",
          "type": "full-code",
          "code": "import {\n  Button,\n  Flow,\n  Link,\n  ModalDF,\n  TextS,\n} from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { longLorem } from '../DrawerDF/data';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx',\n  'ModalDFWithBigContentsExample',\n)}"
        },
        {
          "exportName": "ModalDFEmpty",
          "displayName": "ModalDF без шапки и футера",
          "type": "full-code",
          "code": "import { Button, ModalDF } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { longLorem } from '../DrawerDF/data';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx',\n  'ModalDFEmptyExample',\n)}"
        }
      ]
    },
    "ModalDFLeft": {
      "name": "ModalDFLeft",
      "group": "components",
      "folderName": "ModalDF",
      "role": "part",
      "description": "Левая боковая колонка двухпанельного макета ModalDF, например для меню шагов",
      "props": [
        {
          "name": "as",
          "type": "string | React.ComponentType<any> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof ModalDFLeft>",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/styled.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "боковая панель модалки",
        "sidebar",
        "левая колонка"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "ModalDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "ModalDF",
        "part": "Left"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalDFLeft } from '@daisforge/ui';",
      "minimalUsage": "<ModalDFLeft />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в ModalDF.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.Left>\n          <ModalDF.Header title=\"Заголовок 1\" subTitle=\"Подзаголовок 1\" />\n          <ModalDF.Content>{shortLorem}</ModalDF.Content>\n        </ModalDF.Left>",
          "sourceFile": "packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в ModalDF.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.Left>\n          <ModalDF.Header\n            title=\"Заголовок 1\"\n            badge={{ text: 'Бейдж 1' }}\n            subTitle=\"Заголовок 1\"\n          />\n\n          <ModalDF.Content>{longLorem}</ModalDF.Content>\n          <ModalDF.Footer\n            rightBlock={<Button view=\"secondary\" size=\"s\" text=\"Кнопка\" />}\n          />\n        </ModalDF.Left>",
          "sourceFile": "packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx"
        }
      ]
    },
    "ModalDFMain": {
      "name": "ModalDFMain",
      "group": "components",
      "folderName": "ModalDF",
      "role": "part",
      "description": "Основная колонка ModalDF со своим скроллом, вмещает шапку, контент и футер",
      "props": [
        {
          "name": "as",
          "type": "string | React.ComponentType<any> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof ModalDFMain>",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/styled.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "основная область модалки",
        "правая колонка",
        "main panel"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "ModalDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "ModalDF",
        "part": "Main"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalDFMain } from '@daisforge/ui';",
      "minimalUsage": "<ModalDFMain />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в ModalDF.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.Main>\n          <ModalDF.ServiceButtons\n            $css={{ marginLeft: 'auto', paddingBottom: s.x8 }}\n          />\n          <ModalDF.Content>{longLorem}</ModalDF.Content>\n        </ModalDF.Main>",
          "sourceFile": "packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в Table.filtering.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.Main>\n          <ModalDF.Header />\n          <ModalDF.Content\n            $css={{\n              '&&': {\n                overflow: 'visible',\n              },\n            }}\n          >\n            {tableJsx}\n          </ModalDF.Content>\n        </ModalDF.Main>",
          "sourceFile": "packages/storybook/src/stories/Table/Table.filtering/Table.filtering.stories.tsx"
        }
      ]
    },
    "ModalDFContent": {
      "name": "ModalDFContent",
      "group": "components",
      "folderName": "ModalDF",
      "role": "part",
      "description": "Прокручиваемая область основного содержимого ModalDF",
      "props": [
        {
          "name": "as",
          "type": "string | React.ComponentType<any> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof ModalDFContent>",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/styled.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "тело модалки",
        "скролл содержимого",
        "modal content"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "ModalDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "ModalDF",
        "part": "Content"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalDFContent } from '@daisforge/ui';",
      "minimalUsage": "<ModalDFContent />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в Table.filtering.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.Content\n            $css={{\n              '&&': {\n                overflow: 'visible',\n              },\n            }}\n          >\n            {tableJsx}\n          </ModalDF.Content>",
          "sourceFile": "packages/storybook/src/stories/Table/Table.filtering/Table.filtering.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в ModalDF.stories.tsx",
          "type": "usage",
          "code": "<ModalDF.Content>{longLorem}</ModalDF.Content>",
          "sourceFile": "packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx"
        }
      ]
    },
    "ModalDFConfirmation": {
      "name": "ModalDFConfirmation",
      "group": "components",
      "folderName": "ModalDFConfirmation",
      "role": "primary",
      "description": "Модалка подтверждения действия с иконкой и кнопками подтвердить/отменить",
      "props": [
        {
          "name": "content",
          "type": "ModalDFConfirmationContent | undefined",
          "required": false,
          "description": "основной пропс для заполнения внутреннего отображения модального окна"
        },
        {
          "name": "icon",
          "type": "React.ReactNode",
          "required": false,
          "description": "Иконка в верхней части модального окна"
        },
        {
          "name": "focusTrapSelectors",
          "type": "string[] | undefined",
          "required": false,
          "description": "Селекторы дополнительных DOM-поддеревьев, которые считаются частью модального окна для focus trap.\nИспользуется для элементов, отрисованных через Portal или вне DOM-поддерева модального окна."
        },
        {
          "name": "contentContainerProps",
          "type": "Partial<ContainerProps> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "fullScreen",
          "type": "boolean | { defaultEnabled?: boolean | undefined; saveStateAfterClosing?: boolean | undefined; onFullScreen?: (() => void) | undefined; onExitFullScreen?: (() => void) | undefined; } | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "zIndexOverlay",
          "type": "string | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ModalDFConfirmationProps",
      "compoundParts": [
        {
          "name": "Footer",
          "typeName": "ModalDFConfirmationFooterProps",
          "props": [
            {
              "name": "leftBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "rightBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            }
          ]
        }
      ],
      "sourceFile": "packages/ui-kit/src/components/ModalDFConfirmation/ModalDFConfirmation.tsx",
      "type": "wrapper",
      "atomicBase": "Modal",
      "wrapsInternal": "ModalDF",
      "category": "Локальные компоненты",
      "keywords": [
        "подтверждение действия",
        "confirm dialog",
        "диалог да/нет"
      ],
      "docs": "# ModalDFConfirmation\n\nУпрощённое модальное окно подтверждения, построенное на `ModalDF`. Используется, когда нужно попросить пользователя подтвердить важное действие (сохранение, удаление, выход и т. п.) без сборки сложного контента.\n\n## Ключевые особенности\n\n- Готовое тело окна с заголовком, описанием и двумя кнопками\n- Автоматические отступы для текстового `body`\n- Возможность передать собственный footer вместо стандартных кнопок\n- Использует все возможности `ModalDF`: `contentContainerProps`, `fullScreen`, etc.\n\n## Compound-компоненты\n\nModalDFConfirmation наследует `Footer` из `ModalDF` и переэкспортирует его для кастомных сценариев.\n\n## Особенности\n\n- `content` — основной объект для настройки содержимого. Если его не передавать, можно управлять разметкой через `children`.\n- Остальные пропсы соответствуют `ModalDF`, кроме `children`, `content` и `hasBody`.\n- `mainButton` и `secondaryButton` наследуют пропсы `Button` и автоматически получают размеры/виды по умолчанию.\n- `bodyMarginBlock` помогает выставить вертикальные отступы, если текст не строкой или нужно индивидуальное значение.\n\n> Смотрите также: [ModalDF](http://df-storybook.sh5.dev-gen1-ds.dddddd.ru/?path=/docs/%D0%BB%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%82%D1%8B-modaldf--docs) и [ModalProps](https://plasma.sberdevices.ru/sdds-finai/components/modal/).\n\n> Подробнее о типах и пропсах — [ModalDFConfirmation API](?path=/docs/локальные-компоненты-modaldfconfirmation-api--docs)",
      "apiDocs": "# ModalDFConfirmation API\n\n## ModalDFConfirmationProps\n\n```typescript\ntype ModalDFConfirmationProps = {\n  /**\n   * основной пропс для заполнения внутреннего отображения модального окна\n   */\n  content?: ModalDFConfirmationContent;\n  /**\n   * Добавление радиального градиента в верхней части модального окна(передается цвет для градиента)\n   */\n  view?: keyof typeof iconColors;\n  /**\n   * Иконка в верхней части модального окна\n   */\n  icon?: ReactNode;\n} & Omit<ModalDFProps, 'hasBody' | 'content' | 'children' | 'ref'>;\n```\n\n## ModalDFConfirmationContent\n\n```typescript\ntype ModalDFConfirmationContent = {\n  /**\n   * заголовок\n   */\n  header?: ReactNode;\n  /**\n   * информационный текст\n   */\n  body?: ReactNode;\n  /**\n   * отступы сверху и снизу информационного текста (по умолчанию: `bodyMarginBlock ?? (typeof body === 'string' ? s.x4 : undefined);`)\n   */\n  bodyMarginBlock?: string;\n  /**\n   * пропсы для самой правой главной кнопки, по умолчанию `view=\"accent\"`\n   */\n  mainButton?: ButtonCompProps;\n  /**\n   * пропсы для вторичной кнопки, по умолчанию `view=\"secondary\"`\n   */\n  secondaryButton?: ButtonCompProps;\n  /**\n   * если `mainButton` или `secondaryButton` не подходят, то можно полностью заменить footer на кастомный\n   */\n  footer?: ReactNode;\n};\n```",
      "curatedStories": [
        {
          "exportName": "SavingExample",
          "displayName": "Пример сохранения",
          "type": "full-code",
          "code": "import { Button, ModalDFConfirmation } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDFConfirmation/ModalDFConfirmation.stories.tsx',\n  'SavingExampleRender',\n)}"
        },
        {
          "exportName": "VariantsExample",
          "displayName": "Примеры разных view и иконок",
          "type": "full-code",
          "code": "import { Button, ModalDFConfirmation } from '@daisforge/ui';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDFConfirmation/ModalDFConfirmation.stories.tsx',\n  'VariantsExampleRender',\n)}"
        },
        {
          "exportName": "CustomFooterExample",
          "displayName": "Пример c кастомным footer-oм",
          "type": "full-code",
          "code": "import { Button, Flow, ModalDFConfirmation } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDFConfirmation/ModalDFConfirmation.stories.tsx',\n  'CustomFooterExampleRender',\n)}"
        }
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "ModalDFConfirmationFooter"
      ],
      "inheritedProps": [
        {
          "name": "closeOnEsc",
          "type": "boolean",
          "required": false,
          "description": "Закрывать модальное окно при нажатии на ESC(по умолчанию true).",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean",
          "required": false,
          "description": "Закрывать модальное окно при нажатии вне области модального окна(по умолчанию true),",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "draggable",
          "type": "boolean",
          "required": false,
          "description": "Настройка draggable-режима.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focusAfterRef",
          "type": "RefObject<HTMLElement>",
          "required": false,
          "description": "Элемент для фокуса после закрытия модального окна\n(по умолчанию фокус на последнем перед открытием активном элементе).",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "frame",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "В каком контейнере позиционируется (по умолчанию document), можно также указать id элемента или ref для него.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasClose",
          "type": "boolean",
          "required": false,
          "description": "Отображает кнопку с крестиком для закрытия",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "initialFocusRef",
          "type": "RefObject<HTMLElement>",
          "required": false,
          "description": "Первый элемент для фокуса внутри модального окна.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isFocusTrapped",
          "type": "boolean",
          "required": false,
          "description": "Фокус элементов будет происходить только внутри модального окна",
          "default": "true",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number] | [string, string]",
          "required": false,
          "description": "Смещение относительно текущей позиции.\n(x, y) - [number, number], [string, string].\nПри передаче number расчёт в rem.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onClose",
          "type": "(() => void)",
          "required": false,
          "description": "Общий обработчик клика по кнопке \"закрыть\".",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onEscKeyDown",
          "type": "((event: KeyboardEvent) => void)",
          "required": false,
          "description": "Обработчик клика при нажатии на ESC(если не передан, то при нажатии используется onClose).",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onOverlayClick",
          "type": "((event: MouseEvent<HTMLDivElement, MouseEvent>) => void)",
          "required": false,
          "description": "Обработчик клика при нажатии вне области модального окна(если не передан, то при нажатии используется onClose).",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": false,
          "description": "Отображение Popup.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "overlay",
          "type": "ReactNode",
          "required": false,
          "description": "Соседний элемент для окна в портале.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "PopupPlacement",
          "required": false,
          "description": "Позиция на экране\ncenter - по умолчанию\nleft, right, top, bottom и их комбинации",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "popupInfo",
          "type": "PopupInfo",
          "required": false,
          "description": "Дополнительная информация для программного взаимодействия с окном через контекст.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "positionFixed",
          "type": "boolean",
          "required": false,
          "description": "Если `frame` отличается от `document` применяет `position='fixed'`",
          "default": "false",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "resizable",
          "type": "boolean | { disabled?: boolean; directions?: ResizeDirections; defaultSize?: { width?: number | undefined; height?: number | undefined; } | undefined; ... 8 more ...; onResizeEnd?: ((resizableContainer?: RefObject<...> | undefined) => void) | undefined; } | undefined",
          "required": false,
          "description": "Настройка resizable-режима.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "string",
          "required": false,
          "description": "Добавление радиального градиента в верхней части модального окна(передается цвет для градиента)",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withAnimation",
          "type": "boolean",
          "required": false,
          "description": "Использовать ли анимацию.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withBlur",
          "type": "boolean",
          "required": false,
          "description": "Нужно ли применять blur для подложки.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "string",
          "required": false,
          "description": "Значение z-index для Popup.",
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "children",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasBody",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalDFConfirmation } from '@daisforge/ui';",
      "minimalUsage": "<ModalDFConfirmation>\n  {/* части: ModalDFConfirmation.Footer */}\n</ModalDFConfirmation>",
      "examples": [
        {
          "exportName": "SavingExample",
          "displayName": "Пример сохранения",
          "type": "full-code",
          "code": "import { Button, ModalDFConfirmation } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDFConfirmation/ModalDFConfirmation.stories.tsx',\n  'SavingExampleRender',\n)}"
        },
        {
          "exportName": "VariantsExample",
          "displayName": "Примеры разных view и иконок",
          "type": "full-code",
          "code": "import { Button, ModalDFConfirmation } from '@daisforge/ui';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDFConfirmation/ModalDFConfirmation.stories.tsx',\n  'VariantsExampleRender',\n)}"
        },
        {
          "exportName": "CustomFooterExample",
          "displayName": "Пример c кастомным footer-oм",
          "type": "full-code",
          "code": "import { Button, Flow, ModalDFConfirmation } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport React, { useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/ModalDFConfirmation/ModalDFConfirmation.stories.tsx',\n  'CustomFooterExampleRender',\n)}"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в ModalDFConfirmation.stories.tsx",
          "type": "usage",
          "code": "<ModalDFConfirmation\n        view=\"positive\"\n        icon={<IconPlasma />}\n        opened={openedPositive}\n        onClose={() => setOpenedPositive(false)}\n        contentContainerProps={{\n          css: { maxWidth: '500px' },\n        }}\n        content={{\n          header: 'Изменения сохранены',\n          body: 'Данные были сохранены. Можно закрыть форму и продолжить пользоваться услугами',\n          bodyMarginBlock: s.x4,\n          mainButton: { text: 'Далее', view: 'positive' },\n        }}\n      />",
          "sourceFile": "packages/storybook/src/stories/ModalDFConfirmation/ModalDFConfirmation.stories.tsx"
        }
      ]
    },
    "ModalDFConfirmationFooter": {
      "name": "ModalDFConfirmationFooter",
      "group": "components",
      "folderName": "ModalDFConfirmation",
      "role": "part",
      "description": "Нижняя панель кнопок подтверждающего модального окна ModalDFConfirmation",
      "props": [
        {
          "name": "leftBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "rightBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof ModalDFConfirmationFooter>",
      "sourceFile": "packages/ui-kit/src/components/ModalDFConfirmation/ModalDFConfirmation.tsx",
      "type": "wrapper",
      "atomicBase": "Modal",
      "wrapsInternal": "ModalDF",
      "category": "Локальные компоненты",
      "keywords": [
        "кнопки подтверждения",
        "footer диалога",
        "confirm dialog buttons"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "ModalDFConfirmation",
      "inheritedProps": [
        {
          "name": "children",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnEsc",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "draggable",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focusAfterRef",
          "type": "RefObject<HTMLElement>",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "frame",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasBody",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasClose",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "initialFocusRef",
          "type": "RefObject<HTMLElement>",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isFocusTrapped",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number] | [string, string]",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onClose",
          "type": "(() => void)",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onEscKeyDown",
          "type": "((event: KeyboardEvent) => void)",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onOverlayClick",
          "type": "((event: MouseEvent<HTMLDivElement, MouseEvent>) => void)",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "overlay",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "PopupPlacement",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "popupInfo",
          "type": "PopupInfo",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "positionFixed",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "resizable",
          "type": "boolean | { disabled?: boolean; directions?: ResizeDirections; defaultSize?: { width?: number | undefined; height?: number | undefined; } | undefined; ... 8 more ...; onResizeEnd?: ((resizableContainer?: RefObject<...> | undefined) => void) | undefined; } | undefined",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "string",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withAnimation",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withBlur",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "string",
          "required": false,
          "inheritedFrom": "Modal",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "ModalDFConfirmation",
        "part": "Footer"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalDFConfirmationFooter } from '@daisforge/ui';",
      "minimalUsage": "<ModalDFConfirmationFooter />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в ModalDFConfirmation.stories.tsx",
          "type": "usage",
          "code": "<ModalDFConfirmation.Footer\n              leftBlock={<Button size=\"s\" text=\"Кнопка\" view=\"clear\" />}\n              rightBlock={\n                <Flow mainAxisGap={s.x4}>\n                  <Button size=\"s\" view=\"secondary\" text=\"Кнопка 2\" />\n                  <Button size=\"s\" view=\"accent\" text=\"Кнопка 1\" />\n                </Flow>\n              }\n            />",
          "sourceFile": "packages/storybook/src/stories/ModalDFConfirmation/ModalDFConfirmation.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Подключение анимации",
          "type": "vendor",
          "code": "import styled from 'styled-components';\nimport { Modal } from '@daisforge/ui';\nconst StyledModal = styled(Modal)`\n    && > .${popupClasses.root}, .${modalClasses.overlay} {\n        animation: fadeIn 1s forwards;\n    }\n    &&.${popupClasses.endAnimation} .${popupClasses.root} {\n        animation: fadeOut 1s forwards;\n    }\n    &&.${popupClasses.endAnimation} .${modalClasses.overlay} {\n        animation: fadeOut 1s forwards;\n    }\n    @keyframes fadeIn {\n        from {\n            opacity: 0;\n        }\n        to {\n            opacity: 1;\n        }\n    }\n    @keyframes fadeOut {\n        from {\n            opacity: 1;\n        }\n        to {\n            opacity: 0;\n        }\n    }\n`;"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Resizable Resizable Чтобы иметь возможность растягивать Popup нужно настроить свойство  resizable . Формат следующий",
          "type": "vendor",
          "code": "/**\n * Настройка resizable-режима.\n */\nresizable?: {\n      /**\n       * Включение/выключение ресайза.\n       * @default false\n       */\n      disabled?: boolean;\n      /**\n       * Направления для ресайза.\n       */\n      directions?: ResizeDirections;\n      /**\n       * Начальный размер окна ресайза.\n       */\n      defaultSize?: { width?: number; height?: number };\n      /**\n       * Минимальная ширина ресайза в px.\n       */\n      minWidth?: number;\n      /**\n       * Минимальная высота ресайза в px.\n       */\n      minHeight?: number;\n      /**\n       * Максимальная ширина ресайза в px.\n       */\n      maxWidth?: number;\n      /**\n       * Максимальная высота ресайза в px.\n       */\n      maxHeight?: number;\n      /**\n       * Кастомные иконки ресайза.\n       */\n      icons?: {\n          topRight?: ReactNode;\n          bottomRight?: ReactNode;\n          bottomLeft?: ReactNode;\n          topLeft?: ReactNode;\n      };\n      /**\n       * Размер иконки ресайза.\n       * @default s\n       */\n      iconSize?: 'xs' | 's' | 'm';\n      /**\n       * Скрывать ли иконку для ресайза.\n       * @default false\n       */\n      hiddenIcons?: PopupPlacementMixed[];\n};"
        }
      ]
    },
    "Note": {
      "name": "Note",
      "group": "components",
      "folderName": "Note",
      "role": "primary",
      "description": "Блок с информационным, предупреждающим или обычным текстовым примечанием",
      "props": [],
      "propsTypeName": "ComponentProps<typeof Note>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Note/Note.d.ts",
      "type": "wrapper",
      "atomicBase": "Note",
      "category": "Локальные компоненты",
      "keywords": [
        "информационный блок",
        "callout",
        "предупреждение в тексте"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "actionContent",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Note",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentBefore",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Note",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentBeforeSizing",
          "type": "\"fixed\" | \"scalable\"",
          "required": false,
          "inheritedFrom": "Note",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasClose",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Note",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "height",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "Note",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onCloseButtonClick",
          "type": "(() => void)",
          "required": false,
          "inheritedFrom": "Note",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\"",
          "required": false,
          "inheritedFrom": "Note",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\" | \"xs\"",
          "required": false,
          "inheritedFrom": "Note",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Note",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Note",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "title",
          "type": "string | (ReactElement<any, string | JSXElementConstructor<any>> & string) | (ReactFragment & string) | (ReactPortal & string)",
          "required": false,
          "inheritedFrom": "Note",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"info\"",
          "required": false,
          "inheritedFrom": "Note",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "width",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "Note",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Note } from '@daisforge/ui';",
      "minimalUsage": "<Note />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Кнопка закрытия hasClose",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Note, Button } from '@daisforge/ui';\nimport { IconSaluteOutline } from '@salutejs/plasma-icons';\nexport function App() {\n  const [state, setState] = useState(true);\n  return (\n    <div style={{ height: '8rem', display: 'block' }}>\n      <Button\n        size=\"s\"\n        style={{ marginBottom: '0.5rem' }}\n        onClick={() => setState(!state)}\n      >\n        Открыть\n      </Button>\n      {state && (\n        <Note\n          title=\"Ваш заголовок\"\n          text=\"Пример с возможностью закрыть по control\"\n          view=\"default\"\n          size=\"s\"\n          contentBefore={<IconSaluteOutline size=\"xs\" color=\"inherit\" />}\n          hasClose\n          onCloseButtonClick={() => setState(false)}\n        />\n      )}\n    </div>\n  );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Контент contentBefore Контент  contentBefore Размерность и положение  contentBefore  задается с помощью свойства  contentBeforeSizing .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Note } from '@daisforge/ui';\nimport { IconSaluteOutline } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n            <Note\n                title=\"Title\"\n                text=\"Text\"\n                view=\"default\"\n                size=\"s\"\n                contentBefore={<IconSaluteOutline size=\"xs\" color=\"inherit\" />}\n                contentBeforeSizing=\"fixed\"\n            />\n            <Note\n                title=\"Title\"\n                text=\"Text\"\n                view=\"positive\"\n                size=\"s\"\n                contentBefore={<IconSaluteOutline size=\"m\" color=\"inherit\" />}\n                contentBeforeSizing=\"scalable\"\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "Notification": {
      "name": "Notification",
      "group": "components",
      "folderName": "Notification",
      "role": "primary",
      "description": "Всплывающее toast-уведомление со статусами и действиями",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        }
      ],
      "propsTypeName": "NotificationProps",
      "sourceFile": "packages/ui-kit/src/components/Notification/Notification.tsx",
      "type": "wrapper",
      "atomicBase": "Notification",
      "category": "Локальные компоненты",
      "keywords": [
        "toast",
        "всплывающее уведомление",
        "статус операции"
      ],
      "docs": "# Notification\n\nКомпонент `Notification` с обновленным визуальным видом для каждого view. С документацией можно ознакомиться [по ссылке](https://plasma.sberdevices.ru/sdds-finai/components/notification/).\n\n## Ключевые особенности\n\n- Обновленный визуальный вид для каждого `view`\n- Поддержка градиента для значений `view`: `\"positive\"`, `\"warning\"`, `\"negative\"`, `\"info\"`\n\n## Особенности\n\n- Градиент будет применяться, если параметр `view` указан с одним из значений: `\"positive\"` | `\"warning\"` | `\"negative\"` | `\"info\"`\n\n> Подробнее о типах и пропсах — [Notification API](?path=/docs/локальные-компоненты-notification-api--docs)",
      "apiDocs": "# Notification API\n\nКомпонент-обёртка над `Notification` из `@salutejs/sdds-finai`. Принимает все пропсы оригинального компонента.\n\n## Использование\n\nДля показа уведомлений используется `addNotification` из `NotificationsProvider`:\n\n```tsx\n\naddNotification({\n  title: 'Заголовок',\n  children: 'Текст уведомления',\n  view: 'positive',\n  timeout: 3000,\n});\n```\n\n## Пропсы addNotification\n\n- `id` (`string`) — уникальный идентификатор уведомления\n- `title` (`string`) — заголовок\n- `children` (`ReactNode`) — содержимое / текст уведомления\n- `view` (`'default' | 'positive' | 'negative' | 'warning' | 'info'`) — вид уведомления\n- `icon` (`ReactNode`) — иконка слева\n- `timeout` (`number`) — время автоскрытия (мс). `0` или `null` — не скрывать\n- `onTimeoutClose` (`() => void`) — колбэк при автоматическом закрытии\n- `titleColor` (`string`) — переопределение цвета заголовка\n- `textColor` (`string`) — переопределение цвета текста\n- `width` (`string`) — ширина компонента\n- `maxWidth` (`string`) — максимальная ширина\n\n## Пропсы NotificationsProvider\n\n- `placement` (`'center' | 'top' | 'bottom' | 'right' | 'left' | 'bottom-left' | 'top-right' | ...`) — позиция уведомлений\n- `frame` (`string | ref`) — контейнер для позиционирования (по умолчанию document)\n- `children` (`ReactNode`) — дочерние компоненты\n\nПолное описание — в документации `@salutejs/sdds-finai`: [Notification](https://plasma.sberdevices.ru/sdds-finai/components/notification/)",
      "curatedStories": [
        {
          "exportName": "Variants",
          "displayName": "Примеры разных view",
          "type": "full-code",
          "code": "import { Button, Notification, NotificationsProvider, addNotification } from '@daisforge/ui';\nimport { Typography } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { IconPlasma } from '@daisforge/ui/icons';\nimport { textPrimary } from '@daisforge/ui/tokens';\nimport React from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Notification/Notification.stories.tsx',\n  'VariantsExampleRender',\n)}"
        }
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "actions",
          "type": "ReactNode",
          "required": false,
          "description": "Кнопки снизу/справа для необходимых действий.",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "backgroundColor",
          "type": "string",
          "required": false,
          "description": "Цвет заголовка (по умолчанию берётся цвет из view)",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeIconType",
          "type": "\"default\"",
          "required": false,
          "description": "Вид закрывающей иконки в Notification.",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customCloseIcon",
          "type": "ReactNode",
          "required": false,
          "description": "Пользовательская иконка закрытия.",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "icon",
          "type": "ReactNode",
          "required": false,
          "description": "Иконка слева.",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "iconPlacement",
          "type": "\"top\" | \"left\"",
          "required": false,
          "description": "Расположение иконки слева внутри Textbox.",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "layout",
          "type": "\"horizontal\" | \"vertical\"",
          "required": false,
          "description": "Схема расположение блоков Notification.",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maxWidth",
          "type": "MaxWidth<string | number>",
          "required": false,
          "description": "Свойства для ограничения ширины уведомления",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onCloseButtonClick",
          "type": "(() => void)",
          "required": false,
          "description": "Callback при нажатии на кнопку закрытия.",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onTimeoutClose",
          "type": "(() => void)",
          "required": false,
          "description": "Callback, вызываемый при автоматическом закрытии по timeout.",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "showCloseIcon",
          "type": "boolean",
          "required": false,
          "description": "Показывать ли иконку закрытия справа.",
          "default": "true",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"xs\" | \"xxs\"",
          "required": false,
          "description": "Размер Notification (необходимо связать с размером используемых Button).",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textColor",
          "type": "string",
          "required": false,
          "description": "Цвет текста (по умолчанию берётся цвет из view)",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "title",
          "type": "ReactNode",
          "required": false,
          "description": "Заголовок.",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "titleColor",
          "type": "string",
          "required": false,
          "description": "Цвет заголовка (по умолчанию берётся цвет из view)",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"info\"",
          "required": false,
          "description": "Вид Notification.",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "width",
          "type": "Width<string | number>",
          "required": false,
          "description": "Свойства для управления шириной уведомления",
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "children",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "status",
          "type": "string",
          "required": false,
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "UNSAFE_SSR_ENABLED",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Notification",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Notification } from '@daisforge/ui';",
      "minimalUsage": "<Notification />",
      "examples": [
        {
          "exportName": "Variants",
          "displayName": "Примеры разных view",
          "type": "full-code",
          "code": "import { Button, Notification, NotificationsProvider, addNotification } from '@daisforge/ui';\nimport { Typography } from '@daisforge/ui';\nimport { s } from '@daisforge/ui/constants';\nimport { IconPlasma } from '@daisforge/ui/icons';\nimport { textPrimary } from '@daisforge/ui/tokens';\nimport React from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Notification/Notification.stories.tsx',\n  'VariantsExampleRender',\n)}"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Позиционирование Позиционирование С помощью свойства  placement  у компонента  NotificationsProvider  можно задать позиционирование для Notification.",
          "type": "vendor",
          "code": "type NotificationPlacement = 'center' | 'top' | 'bottom' | 'right' | 'left';"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Управлением внешним видом",
          "type": "vendor",
          "code": "//INFO: В данном случае значении цвета будет как во `view='positive'`\naddNotification({\n    view: 'positive',\n    icon: <IconBell color=\"inherit\" size=\"xs\" />,\n    ...\n}, 3000);"
        }
      ]
    },
    "NotificationsProvider": {
      "name": "NotificationsProvider",
      "group": "components",
      "folderName": "Notification",
      "role": "primary",
      "description": "Провайдер контейнера для показа toast-уведомлений на странице",
      "props": [
        {
          "name": "frame",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "placement",
          "type": "PopupPlacement | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "UNSAFE_SSR_ENABLED",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof NotificationsProvider>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Notification/Notification.d.ts",
      "type": "wrapper",
      "atomicBase": "NotificationsProvider",
      "category": "Локальные компоненты",
      "keywords": [
        "контейнер уведомлений",
        "toast provider",
        "область показа тостов"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { NotificationsProvider } from '@daisforge/ui';",
      "minimalUsage": "<NotificationsProvider />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в Notification.stories.tsx",
          "type": "usage",
          "code": "<NotificationsProvider>\n        <Button\n          view=\"positive\"\n          onClick={() =>\n            addNotification(\n              {\n                id: 'positive-notification',\n                view: 'positive',\n                title: 'Title',\n                icon: <IconPlasma />,\n                children: (\n                  <Typography variant=\"TextS\" color={textPrimary}>\n                    Text\n                  </Typography>\n                ),\n                closeIconType: 'thin',\n                actions: (\n                  <>\n                    <Button\n                      size=\"xxs\"\n                      view=\"secondary\"\n                      style={{ marginRight: '4px' }}\n                    >\n                      Label\n                    </Button>\n                    <Button size=\"xxs\" view=\"secondary\">\n                      Label\n                    </Button>\n                  </>\n                ),\n                layout: 'horizontal',\n                width: '459px',\n              },\n              null,\n            )\n          }\n        >\n          Уведомление: positive\n        </Button>\n        <Button\n          view=\"warning\"\n          onClick={() =>\n            addNotification(\n              {\n                id: 'warning-notification',\n                view: 'warning',\n                title: 'Title',\n                icon: <IconPlasma />,\n                children: (\n                  <Typography variant=\"TextS\" color={textPrimary}>\n                    Text\n                  </Typography>\n                ),\n                closeIconType: 'thin',\n                actions: (\n                  <>\n                    <Button\n                      size=\"xxs\"\n                      view=\"secondary\"\n                      style={{ marginRight: '4px' }}\n                    >\n                      Label\n                    </Button>\n                    <Button size=\"xxs\" view=\"secondary\">\n                      Label\n                    </Button>\n                  </>\n                ),\n                layout: 'horizontal',\n                width: '459px',\n              },\n              null,\n            )\n          }\n        >\n          Уведомление: warning\n        </Button>\n        <Button\n          view=\"accent\"\n          onClick={() =>\n            addNotification(\n              {\n                id: 'info-notification',\n                view: 'info\n// … (обрезано)",
          "sourceFile": "packages/storybook/src/stories/Notification/Notification.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Позиционирование Позиционирование С помощью свойства  placement  у компонента  NotificationsProvider  можно задать позиционирование для Notification.",
          "type": "vendor",
          "code": "import { NotificationsProvider } from '@daisforge/ui';\nexport function App() {\n    return (\n        <NotificationsProvider placement=\"top-right\">\n            ...\n        </NotificationsProvider>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "NotificationsProvider NotificationsProvider",
          "type": "vendor",
          "code": "import ReactDOM from 'react-dom';\nimport { NotificationsProvider } from '@daisforge/ui';\nimport { App } from './App';\nReactDOM.render(\n    <NotificationsProvider>\n        <App />\n    </NotificationsProvider>,\n    document.getElementById('root')\n);"
        }
      ]
    },
    "NumberFormat": {
      "name": "NumberFormat",
      "group": "components",
      "folderName": "NumberFormat",
      "role": "primary",
      "description": "Поле ввода с форматированием чисел (разделители, десятичные) и кнопкой очистки",
      "props": [
        {
          "name": "suffix",
          "type": "string | undefined",
          "required": false,
          "description": "Суффикс текста в поле ввода."
        },
        {
          "name": "onClear",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "NumberFormatCompProps",
      "sourceFile": "packages/ui-kit/src/components/NumberFormat/NumberFormat.tsx",
      "type": "wrapper",
      "atomicBase": "NumberFormat",
      "formVariant": "FormNumberFormat",
      "category": "Локальные компоненты",
      "keywords": [
        "форматированное число",
        "разделители разрядов",
        "числовая маска"
      ],
      "chooseWhen": "Вне react-hook-form — форматированное числовое поле с value/onChange напрямую.",
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "allowLeadingZeros",
          "type": "boolean",
          "required": false,
          "description": "Разрешает ведущие нули (например, \"0123\").",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "allowNegative",
          "type": "boolean",
          "required": false,
          "description": "Разрешает ввод отрицательных чисел.",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "decimalScale",
          "type": "number",
          "required": false,
          "description": "Количество знаков после запятой.",
          "default": "3",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "decimalSeparator",
          "type": "string",
          "required": false,
          "description": "Разделитель десятичных знаков (например, \".\").",
          "default": ".",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "fixedDecimalScale",
          "type": "boolean",
          "required": false,
          "description": "Фиксирует количество знаков после запятой, даже если число их не содержит (добавляет нули).",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isAllowed",
          "type": "((values: NumberFormatValues) => boolean)",
          "required": false,
          "description": "Функция для валидации входного значения.\nЕсли эта функция возвращает false, метод onChange не будет вызван, и значение ввода не изменится.",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение лейбла.",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "(((event?: ChangeEvent<HTMLInputElement>, values?: NumberFormatValues) => void) & ChangeEventHandler<HTMLInputElement>) | undefined",
          "required": false,
          "description": "Callback, вызываемый при изменении значения в поле ввода.\nПринимает событие изменения (ChangeEvent) и объект NumberFormatValues:\n```\nfloatValue: number | undefined;\nformattedValue: string;\nvalue: string;\n```\nОбработчик изменения элемента формы",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optional",
          "type": "boolean",
          "required": false,
          "description": "Флаг необязательности поля",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optionalText",
          "type": "string",
          "required": false,
          "description": "Подпись для указания необязательности поля",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "requiredPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "thousandSeparator",
          "type": "string | boolean",
          "required": false,
          "description": "Разделитель тысяч.\nМожет быть строкой (например, \",\") или булевым значением.",
          "default": "' ' (пробел)",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "thousandsGroupStyle",
          "type": "\"none\" | \"thousand\" | \"lakh\" | \"wan\"",
          "required": false,
          "description": "Стиль группировки тысяч:\n- 'thousand' (123 456 789),\n- 'lakh' (индийский стиль, 12 34 56 789),\n- 'wan' (китайский стиль, 1 2345 6789),\n- 'none' (без группировки).",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"clear\" | \"default\" | \"viewMode\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chips",
          "type": "TextFieldPrimitiveValue[]",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipType",
          "type": "\"text\" | \"default\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipValidator",
          "type": "((value: string) => ChipValidatorReturn)",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "clear",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "enumerationType",
          "type": "\"plain\" | \"chip\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasDivider",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintContentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOffset",
          "type": "[number, number]",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPortal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetIcon",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintText",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintView",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintWidth",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "leftHelper",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onBlur",
          "type": "FocusEventHandler<HTMLInputElement>",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeChips",
          "type": "((value: TextFieldPrimitiveValue[]) => void)",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onFocus",
          "type": "FocusEventHandler<HTMLInputElement>",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onSearch",
          "type": "(((value: string, event?: KeyboardEvent<HTMLInputElement>) => void) & ((value: string, event?: KeyboardEvent<HTMLInputElement>) => void)) | undefined",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "rightHelper",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "default": "'xs'",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textAfter",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textBefore",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "titleCaption",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "type",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { NumberFormat } from '@daisforge/ui';",
      "minimalUsage": "<NumberFormat />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Отрицательные числа",
          "type": "vendor",
          "code": "import React from 'react';\nimport { NumberFormat } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n            <NumberFormat\n                size=\"s\"\n                defaultValue=\"-123\"\n                thousandSeparator=\" \"\n                decimalSeparator=\".\"\n                allowNegative\n            />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Ведущие нули",
          "type": "vendor",
          "code": "import React from 'react';\nimport { NumberFormat } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n            <NumberFormat\n                size=\"s\"\n                defaultValue=\"000123.456\"\n                thousandSeparator=\" \"\n                decimalSeparator=\".\"\n                allowLeadingZeros\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "NumberFormatAmount": {
      "name": "NumberFormatAmount",
      "group": "components",
      "folderName": "NumberFormatAmount",
      "role": "primary",
      "description": "Поле ввода денежной суммы с крупным стилизованным шрифтом",
      "props": [
        {
          "name": "allowLeadingZeros",
          "type": "boolean | undefined",
          "required": false,
          "description": "Разрешает ведущие нули (например, \"0123\")."
        },
        {
          "name": "allowNegative",
          "type": "boolean | undefined",
          "required": false,
          "description": "Разрешает ввод отрицательных чисел."
        },
        {
          "name": "decimalScale",
          "type": "number | undefined",
          "required": false,
          "description": "Количество знаков после запятой.",
          "default": "3"
        },
        {
          "name": "decimalSeparator",
          "type": "string | undefined",
          "required": false,
          "description": "Разделитель десятичных знаков (например, \".\").",
          "default": "."
        },
        {
          "name": "fixedDecimalScale",
          "type": "boolean | undefined",
          "required": false,
          "description": "Фиксирует количество знаков после запятой, даже если число их не содержит (добавляет нули)."
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false"
        },
        {
          "name": "isAllowed",
          "type": "((values: NumberFormatValues) => boolean) | undefined",
          "required": false,
          "description": "Функция для валидации входного значения.\nЕсли эта функция возвращает false, метод onChange не будет вызван, и значение ввода не изменится."
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean | undefined",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)"
        },
        {
          "name": "labelPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": "Расположение лейбла."
        },
        {
          "name": "onChange",
          "type": "(((event?: React.ChangeEvent<HTMLInputElement> | undefined, values?: NumberFormatValues | undefined) => void) & React.ChangeEventHandler<HTMLInputElement>) | undefined",
          "required": false,
          "description": "Callback, вызываемый при изменении значения в поле ввода.\nПринимает событие изменения (ChangeEvent) и объект NumberFormatValues:\n```\nfloatValue: number | undefined;\nformattedValue: string;\nvalue: string;\n```\nОбработчик изменения элемента формы"
        },
        {
          "name": "optional",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг необязательности поля"
        },
        {
          "name": "optionalText",
          "type": "string | undefined",
          "required": false,
          "description": "Подпись для указания необязательности поля"
        },
        {
          "name": "requiredPlacement",
          "type": "\"right\" | \"left\" | undefined",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right"
        },
        {
          "name": "suffix",
          "type": "string | undefined",
          "required": false,
          "description": "Суффикс текста в поле ввода."
        },
        {
          "name": "thousandSeparator",
          "type": "string | boolean | undefined",
          "required": false,
          "description": "Разделитель тысяч.\nМожет быть строкой (например, \",\") или булевым значением.",
          "default": "' ' (пробел)"
        },
        {
          "name": "thousandsGroupStyle",
          "type": "\"none\" | \"thousand\" | \"lakh\" | \"wan\" | undefined",
          "required": false,
          "description": "Стиль группировки тысяч:\n- 'thousand' (123 456 789),\n- 'lakh' (индийский стиль, 12 34 56 789),\n- 'wan' (китайский стиль, 1 2345 6789),\n- 'none' (без группировки)."
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"clear\" | \"viewMode\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chips",
          "type": "TextFieldPrimitiveValue[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chipType",
          "type": "\"default\" | \"text\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chipValidator",
          "type": "((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { …",
          "required": false,
          "description": ""
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"accent\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "clear",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enumerationType",
          "type": "\"plain\" | \"chip\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hasDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPortal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintView",
          "type": "\"default\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "leftHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "onChangeChips",
          "type": "((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimit…",
          "required": false,
          "description": ""
        },
        {
          "name": "onClear",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onSearch",
          "type": "(((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | (((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | (((value: string, event?: React.KeyboardEvent<HT…",
          "required": false,
          "description": ""
        },
        {
          "name": "rightHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | undefined",
          "required": false,
          "description": "",
          "default": "'xs'"
        },
        {
          "name": "textAfter",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "textBefore",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "NumberFormatAmountProps",
      "sourceFile": "packages/ui-kit/src/components/NumberFormatAmount/NumberFormatAmount.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "ввод суммы",
        "amount input",
        "денежное поле"
      ],
      "docs": "# NumberFormatAmount\n\nКомпонент NumberFormatAmount — обёртка компонента NumberFormat с жирным шрифтом (bold) и опциональной кнопкой очистки. С примерами реализации подробно можно ознакомиться ниже в stories.\n\n## Ключевые особенности\n\n- Жирная типографика: `xs` — bodySBold, `s` — bodyMBold\n- При передаче `onClear` автоматически появляется крестик очистки, если поле содержит значение\n- Если одновременно переданы `onClear` и `contentRight`, иконка contentRight отображается правее крестика\n- Доступные размеры: `s`, `xs`\n\n> Подробнее о типах и пропсах — [NumberFormatAmount API](?path=/docs/локальные-компоненты-numberformatamount-api--docs)",
      "apiDocs": "# NumberFormatAmount API\n\n## NumberFormatAmountProps\n\n```typescript\ntype NumberFormatAmountProps = Omit<NumberFormatCompProps, 'ref'>;\n```\n\nКомпонент наследует все пропсы атомарного [NumberFormat](https://plasma.sberdevices.ru/sdds-finai/components/number-format/) и добавляет `onClear?: () => void` — колбэк для кнопки очистки.",
      "curatedStories": [
        {
          "exportName": "Default",
          "displayName": "Default",
          "type": "full-code",
          "code": "import { NumberFormatAmount } from '@daisforge/ui';\n\n(args: NumberFormatAmountProps) => {\n    const [value, setValue] = useState('');\n\n    return (\n      <div style={{ padding: '20px', width: '500px' }}>\n        <NumberFormatAmount\n          {...args}\n          value={value}\n          onChange={(e) => setValue(e?.target?.value ?? '')}\n          onClear={() => setValue('')}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Sizes",
          "displayName": "Размеры",
          "type": "full-code",
          "code": "import { NumberFormatAmount } from '@daisforge/ui';\n\n(args: NumberFormatAmountProps) => {\n    const sizes = ['s', 'xs'] as const;\n    const [values, setValues] = useState<Record<string, string>>({\n      s: '123456.78',\n      xs: '123456.78',\n    });\n\n    return (\n      <div\n        style={{\n          padding: '20px',\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '500px',\n        }}\n      >\n        {sizes.map((size) => (\n          <NumberFormatAmount\n            {...args}\n            key={size}\n            size={size}\n            placeholder={`Size: ${size}`}\n            value={values[size]}\n            onChange={(e) =>\n              setValues((prev) => ({\n                ...prev,\n                [size]: e?.target?.value ?? '',\n              }))\n            }\n            onClear={() => setValues((prev) => ({ ...prev, [size]: '' }))}\n          />\n        ))}\n      </div>\n    );\n  }"
        },
        {
          "exportName": "WithClear",
          "displayName": "Различные варианты",
          "type": "full-code",
          "code": "import { NumberFormatAmount } from '@daisforge/ui';\n\n(args: NumberFormatAmountProps) => {\n    const [value1, setValue1] = useState('123456.78');\n    const [value2, setValue2] = useState('999.99');\n    const [value3, setValue3] = useState('');\n    const [value4, setValue4] = useState('500');\n\n    return (\n      <div\n        style={{\n          padding: '20px',\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '500px',\n        }}\n      >\n        <NumberFormatAmount\n          {...args}\n          placeholder=\"onClear + value → крестик\"\n          value={value1}\n          onChange={(e) => setValue1(e?.target?.value ?? '')}\n          onClear={() => setValue1('')}\n        />\n\n        <NumberFormatAmount\n          {...args}\n          placeholder=\"onClear + value + contentRight → рядом\"\n          value={value2}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e) => setValue2(e?.target?.value ?? '')}\n          onClear={() => setValue2('')}\n        />\n\n        <NumberFormatAmount\n          {...args}\n          placeholder=\"Пустое значение — крестик скрыт\"\n          value={value3}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e) => setValue3(e?.target?.value ?? '')}\n          onClear={() => setValue3('')}\n        />\n\n        <NumberFormatAmount\n          {...args}\n          placeholder=\"ReadOnly — замок\"\n          value=\"1000\"\n          readOnly\n          contentRight={<IconSb size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        <NumberFormatAmount\n          {...args}\n          placeholder=\"Disabled — замок\"\n          value=\"1000\"\n          disabled\n          contentRight={<IconSb size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        <NumberFormatAmount\n          {...args}\n          placeholder=\"Только contentRight, без onClear\"\n          value={value4}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e) => setValue4(e?.target?.value ?? '')}\n        />\n      </div>\n    );\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { NumberFormatAmount } from '@daisforge/ui';",
      "minimalUsage": "<NumberFormatAmount />",
      "examples": [
        {
          "exportName": "Default",
          "displayName": "Default",
          "type": "full-code",
          "code": "import { NumberFormatAmount } from '@daisforge/ui';\n\n(args: NumberFormatAmountProps) => {\n    const [value, setValue] = useState('');\n\n    return (\n      <div style={{ padding: '20px', width: '500px' }}>\n        <NumberFormatAmount\n          {...args}\n          value={value}\n          onChange={(e) => setValue(e?.target?.value ?? '')}\n          onClear={() => setValue('')}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Sizes",
          "displayName": "Размеры",
          "type": "full-code",
          "code": "import { NumberFormatAmount } from '@daisforge/ui';\n\n(args: NumberFormatAmountProps) => {\n    const sizes = ['s', 'xs'] as const;\n    const [values, setValues] = useState<Record<string, string>>({\n      s: '123456.78',\n      xs: '123456.78',\n    });\n\n    return (\n      <div\n        style={{\n          padding: '20px',\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '500px',\n        }}\n      >\n        {sizes.map((size) => (\n          <NumberFormatAmount\n            {...args}\n            key={size}\n            size={size}\n            placeholder={`Size: ${size}`}\n            value={values[size]}\n            onChange={(e) =>\n              setValues((prev) => ({\n                ...prev,\n                [size]: e?.target?.value ?? '',\n              }))\n            }\n            onClear={() => setValues((prev) => ({ ...prev, [size]: '' }))}\n          />\n        ))}\n      </div>\n    );\n  }"
        },
        {
          "exportName": "WithClear",
          "displayName": "Различные варианты",
          "type": "full-code",
          "code": "import { NumberFormatAmount } from '@daisforge/ui';\n\n(args: NumberFormatAmountProps) => {\n    const [value1, setValue1] = useState('123456.78');\n    const [value2, setValue2] = useState('999.99');\n    const [value3, setValue3] = useState('');\n    const [value4, setValue4] = useState('500');\n\n    return (\n      <div\n        style={{\n          padding: '20px',\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '500px',\n        }}\n      >\n        <NumberFormatAmount\n          {...args}\n          placeholder=\"onClear + value → крестик\"\n          value={value1}\n          onChange={(e) => setValue1(e?.target?.value ?? '')}\n          onClear={() => setValue1('')}\n        />\n\n        <NumberFormatAmount\n          {...args}\n          placeholder=\"onClear + value + contentRight → рядом\"\n          value={value2}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e) => setValue2(e?.target?.value ?? '')}\n          onClear={() => setValue2('')}\n        />\n\n        <NumberFormatAmount\n          {...args}\n          placeholder=\"Пустое значение — крестик скрыт\"\n          value={value3}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e) => setValue3(e?.target?.value ?? '')}\n          onClear={() => setValue3('')}\n        />\n\n        <NumberFormatAmount\n          {...args}\n          placeholder=\"ReadOnly — замок\"\n          value=\"1000\"\n          readOnly\n          contentRight={<IconSb size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        <NumberFormatAmount\n          {...args}\n          placeholder=\"Disabled — замок\"\n          value=\"1000\"\n          disabled\n          contentRight={<IconSb size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        <NumberFormatAmount\n          {...args}\n          placeholder=\"Только contentRight, без onClear\"\n          value={value4}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e) => setValue4(e?.target?.value ?? '')}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в NumberFormatAmount.tsx",
          "type": "usage",
          "code": "<NumberFormatAmount\n        size=\"s\"\n        placeholder=\"С contentRight\"\n        value={value3}\n        thousandSeparator=\" \"\n        decimalSeparator=\".\"\n        decimalScale={2}\n        contentRight={<IconSb size=\"s\" />}\n        onChange={(e) => setValue3(e?.target?.value ?? '')}\n        onClear={() => setValue3('')}\n      />",
          "sourceFile": "packages/vite-project/src/pages/NumberFormatAmount.tsx"
        }
      ]
    },
    "NumberInput": {
      "name": "NumberInput",
      "group": "components",
      "folderName": "NumberInput",
      "role": "primary",
      "description": "Числовое поле со стрелками инкремента/декремента и ограничением min/max",
      "props": [
        {
          "name": "allowLeadingZeros",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "allowNegative",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "decimalScale",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "decimalSeparator",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "defaultValue",
          "type": "string | number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "fixedDecimalScale",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isAllowed",
          "type": "((values: NumberFormatValues) => boolean) | ((values: NumberFormatValues) => boolean) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "thousandSeparator",
          "type": "string | boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "thousandsGroupStyle",
          "type": "\"none\" | \"thousand\" | \"lakh\" | \"wan\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof NumberInput>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/NumberInput/NumberInput.d.ts",
      "type": "wrapper",
      "atomicBase": "NumberInput",
      "category": "Локальные компоненты",
      "keywords": [
        "степпер",
        "increment decrement",
        "числовой степпер"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "clear",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customDecrementButton",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customIncrementButton",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "decrementIcon",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "displayWithoutValue",
          "type": "\"input\" | \"increment\" | \"decrement\"",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "incrementIcon",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "inputBackgroundType",
          "type": "\"clear\" | \"fill\"",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isLoading",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isManualInput",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "limitBehavior",
          "type": "\"hidden\" | \"disabled\"",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "loader",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "max",
          "type": "number",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "min",
          "type": "number",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "((event: SyntheticEvent<HTMLInputElement, Event> | null, value: string | number) => void)",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onDecrement",
          "type": "((value: number) => void)",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onIncrement",
          "type": "((value: number) => void)",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "precision",
          "type": "number",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "segmentation",
          "type": "\"default\" | \"segmented\" | \"solid\"",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shape",
          "type": "\"pilled\" | \"cornered\"",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\"",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "step",
          "type": "number",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textAfter",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textBefore",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"secondary\"",
          "required": false,
          "inheritedFrom": "NumberInput",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { NumberInput } from '@daisforge/ui';",
      "minimalUsage": "<NumberInput />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Состояния Состояния",
          "type": "vendor",
          "code": "import React from 'react';\nimport { NumberInput } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <NumberInput value={5} width={188} disabled />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { NumberInput } from '@daisforge/ui';\nexport function App() {\n    const [value, setValue] = useState(5);\n    return (\n        <div>\n            <NumberInput\n                value={value}\n                min={0}\n                max={10}\n                width={188}\n                onChange={(_, newValue) => setValue(newValue)}\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "Overlay": {
      "name": "Overlay",
      "group": "components",
      "folderName": "Overlay",
      "role": "primary",
      "description": "Затемняющая подложка позади Modal, Toast и других всплывающих элементов",
      "props": [
        {
          "name": "backgroundColorProperty",
          "type": "string",
          "required": true,
          "description": "Значение цвета подложки."
        },
        {
          "name": "zIndex",
          "type": "string",
          "required": true,
          "description": "Значение z-index для подложки."
        },
        {
          "name": "isClickable",
          "type": "boolean | undefined",
          "required": false,
          "description": "Является ли подложка кликабельной.",
          "default": "true"
        },
        {
          "name": "onOverlayClick",
          "type": "((event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void) | undefined",
          "required": false,
          "description": "Обработчик клика при нажатии на подложку."
        },
        {
          "name": "transparent",
          "type": "boolean | undefined",
          "required": false,
          "description": "Нужно ли сделать подложку прозрачной (при открытии нескольких всплывающих компонент)."
        },
        {
          "name": "withBlur",
          "type": "boolean | undefined",
          "required": false,
          "description": "Нужно ли применять blur для подложки."
        }
      ],
      "propsTypeName": "OverlayProps",
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Overlay/Overlay.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "затемнение фона",
        "backdrop",
        "оверлей под модалкой"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Overlay } from '@daisforge/ui';",
      "minimalUsage": "<Overlay backgroundColorProperty={'значение'} zIndex={'значение'} />",
      "examples": []
    },
    "PageTitle": {
      "name": "PageTitle",
      "group": "components",
      "folderName": "PageTitle",
      "role": "primary",
      "description": "Заголовок страницы с хлебными крошками, кнопкой назад и блоком действий справа",
      "props": [
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные стили styled-components для основного контейнера"
        },
        {
          "name": "breadcrumbs",
          "type": "(PropsType<{ view: { default: PolymorphicClassName; }; size: { l: PolymorphicClassName; m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; }> & React.HTMLAttributes<HTMLDivElement> & { view?: string | undefined; size?: string | undefined; separator?: React.ReactNode; items: BreadcrumbsItem[]; showItems?: number | undefined; } & React.RefAttributes<HTMLDivElement>) | und…",
          "required": false,
          "description": "Пропсы для Breadcrumbs компонента\nПо умолчанию size='m'"
        },
        {
          "name": "onBackClick",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Callback при клике на кнопку назад"
        },
        {
          "name": "rightSlot",
          "type": "PageTitleAdaptiveSlot",
          "required": false,
          "description": "Контент справа (прижат к правому краю и к нижней границе).\nМожно передать ReactNode или callback с размерами для адаптива."
        },
        {
          "name": "showBackButton",
          "type": "boolean | undefined",
          "required": false,
          "description": "Показывать ли кнопку со стрелкой назад слева от title"
        },
        {
          "name": "subtitle",
          "type": "string | undefined",
          "required": false,
          "description": "Подзаголовок/описание страницы (текст)"
        },
        {
          "name": "subtitleTypographyProps",
          "type": "Omit<TypographyWithAutoTooltipProps<\"BodyS\">, \"children\" | \"variant\"> | undefined",
          "required": false,
          "description": "Пропсы для  TypographyWithAutoTooltip в который обернут subtitle"
        },
        {
          "name": "titleSlot",
          "type": "PageTitleAdaptiveSlot",
          "required": false,
          "description": "Кастомный слот правее заголовка.\nМожно передать ReactNode или callback с размерами для адаптива."
        },
        {
          "name": "titleTypographyProps",
          "type": "Omit<TypographyWithAutoTooltipProps<\"H2\">, \"children\" | \"variant\"> | undefined",
          "required": false,
          "description": "Пропсы для TypographyWithAutoTooltip в который обернут title"
        },
        {
          "name": "disableMediaAdaptive",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отключает принудительный адаптив компонента на viewport <= 1280px.",
          "deprecated": true,
          "default": "false"
        }
      ],
      "propsTypeName": "PageTitleProps",
      "sourceFile": "packages/ui-kit/src/components/PageTitle/PageTitle.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "заголовок страницы",
        "breadcrumbs",
        "page header"
      ],
      "docs": "# PageTitle\n\nКомпонент заголовка страницы с опциональными breadcrumbs, кнопкой «назад», подзаголовком и блоком действий.\n\n## Ключевые особенности\n\n- Опциональные breadcrumbs с настраиваемым размером (по умолчанию `size='m'`)\n- Кнопка «назад» слева от заголовка (`showBackButton`, `onBackClick`)\n- Заголовок и подзаголовок с автоматическим тултипом при обрезке текста\n- Кастомный слот правее заголовка (`titleSlot`)\n- Правый блок действий (`rightSlot`), прижатый к правому краю\n\n## Особенности\n\n- Компонент всегда использует `TypographyWithAutoTooltip` для `title` и `subtitle`\n- Если `tooltipText` не передан, текстом тултипа используется сам `title` или `subtitle`\n- Слоты `titleSlot` и `rightSlot` принимают `ReactNode` или callback с размерами для адаптива\n- По умолчанию адаптив на viewport `<= 1280px` включен; временно отключить его можно через deprecated-проп `disableMediaAdaptive`\n- Код примеров отображается через `storySourceDoc`, вкладка `Show code` синхронизирована с реализацией\n\n## Использование адаптивных слотов\n\nЕсли слот не должен менять размеры, передавайте обычный `ReactNode`:\n\n```tsx\n<PageTitle\n  title=\"Заголовок страницы\"\n  titleSlot={\n    <Button size=\"xs\" view=\"secondary\">\n      Действие\n    </Button>\n  }\n/>\n```\n\nЕсли в слоте есть кнопки, которые должны уменьшаться на 1280px, передавайте callback и используйте `buttonSize` из аргумента:\n\n```tsx\n<PageTitle\n  title=\"Заголовок страницы\"\n  rightSlot={({ buttonSize }) => (\n    <Flow mainAxisGap={8}>\n      <Button size={buttonSize} view=\"secondary\">\n        Отмена\n      </Button>\n      <Button size={buttonSize} view=\"accent\">\n        Сохранить\n      </Button>\n    </Flow>\n  )}\n/>\n```\n\nРазмер, который приходит в callback:\n\n```\nbuttonSize\n| viewport <= 1280px | viewport > 1280px |\n| xs                 | s                 |\n```\n\n> Подробнее о типах и пропсах — [PageTitle API](?path=/docs/композиции-pagetitle-api--docs)",
      "apiDocs": "# PageTitle API\n\n## PageTitleProps\n\n```typescript\ntype PageTitleProps = {\n  /**\n   * Заголовок страницы (текст)\n   */\n  title?: string;\n  /**\n   * Пропсы для TypographyWithAutoTooltip в который обернут title\n   */\n  titleTypographyProps?: Omit<\n    TypographyWithAutoTooltipProps<'H2'>,\n    'children' | 'variant'\n  >;\n  /**\n   * Подзаголовок/описание страницы (текст)\n   */\n  subtitle?: string;\n  /**\n   * Пропсы для  TypographyWithAutoTooltip в который обернут subtitle\n   */\n  subtitleTypographyProps?: Omit<\n    TypographyWithAutoTooltipProps<'BodyS'>,\n    'children' | 'variant'\n  >;\n  /**\n   * Кастомный слот правее заголовка.\n   * Можно передать ReactNode или callback с размерами для адаптива.\n   */\n  titleSlot?: PageTitleAdaptiveSlot;\n  /**\n   * Контент справа (прижат к правому краю и к нижней границе).\n   * Можно передать ReactNode или callback с размерами для адаптива.\n   */\n  rightSlot?: PageTitleAdaptiveSlot;\n  /**\n   * Отключает принудительный адаптив компонента на viewport <= 1280px.\n   *\n   * @deprecated Используйте только в крайних случаях, когда команда временно не готова адаптировать вёрстку под 1280px.\n   *\n   * @remarks\n   * При `true` компонент использует desktop-размеры для кастомных слотов и кнопки назад даже на viewport <= 1280px.\n   * Это временный escape hatch, не основной сценарий использования.\n   *\n   * @default false\n   */\n  disableMediaAdaptive?: boolean;\n  /**\n   * Пропсы для Breadcrumbs компонента\n   * По умолчанию size='m'\n   */\n  breadcrumbs?: BreadcrumbsPropsComp;\n  /**\n   * Показывать ли кнопку со стрелкой назад слева от title\n   */\n  showBackButton?: boolean;\n  /**\n   * Callback при клике на кнопку назад\n   */\n  onBackClick?: () => void;\n  /**\n   * Кастомные стили styled-components для основного контейнера\n   */\n  $css?: string | CSSObject | FlattenSimpleInterpolation;\n  /**\n   * Дополнительный className для корневого элемента\n   */\n  className?: string;\n};\n\nexport type PageTitleIconButtonProps = ComponentProps<typeof IconButton> & {\n  iconSize?: ComponentProps<typeof IconChevronLeft>['size'];\n};\n```\n\n## PageTitleSlotSizesProps\n\n```typescript\ntype PageTitleSlotSizesProps = {\n  /**\n   * Размер кнопок в кастомных слотах\n   */\n  buttonSize: 's' | 'xs';\n};\n```\n\n## PageTitleAdaptiveSlot\n\n```typescript\ntype PageTitleAdaptiveSlot =\n  | ReactNode\n  | ((props: PageTitleSlotSizesProps) => ReactNode);\n```",
      "curatedStories": [
        {
          "exportName": "Default",
          "displayName": "PageTitle",
          "type": "full-code",
          "code": "import { PageTitle } from '@daisforge/ui';\nimport { Button, Flow, IconButton } from '@daisforge/ui';\nimport { IconPlus } from '@daisforge/ui/icons';\nimport type { PageTitleSlotSizesProps } from '@daisforge/ui';\n\n() => (\n    <PageTitle\n      breadcrumbs={{\n        items: [\n          { title: 'Главная', href: '#' },\n          { title: 'Раздел', href: '#' },\n          { title: 'Страница' },\n        ],\n      }}\n      showBackButton\n      onBackClick={() => alert('onBackClick')}\n      title=\"Заголовок страницы\"\n      subtitle=\"Описание страницы или подзаголовок\"\n      rightSlot={({ buttonSize }: PageTitleSlotSizesProps) => (\n        <Flow mainAxisGap={8}>\n          <Button size={buttonSize} view=\"secondary\">\n            Действие 1\n          </Button>\n          <Button size={buttonSize} view=\"accent\">\n            Действие 2\n          </Button>\n        </Flow>\n      )}\n    />\n  )"
        },
        {
          "exportName": "WithTitleSlot",
          "displayName": "PageTitle с кастомным слотом",
          "type": "full-code",
          "code": "import { PageTitle } from '@daisforge/ui';\nimport { Button, Flow, IconButton } from '@daisforge/ui';\nimport { IconPlus } from '@daisforge/ui/icons';\nimport type { PageTitleSlotSizesProps } from '@daisforge/ui';\n\n() => (\n    <PageTitle\n      breadcrumbs={{\n        items: [{ title: 'Главная', href: '#' }, { title: 'Раздел' }],\n      }}\n      showBackButton\n      onBackClick={() => alert('onBackClick')}\n      title=\"Заголовок страницы\"\n      subtitle=\"Описание страницы или подзаголовок\"\n      titleSlot={\n        <Button size=\"xs\" view=\"secondary\">\n          Действие\n        </Button>\n      }\n      rightSlot={({ buttonSize }: PageTitleSlotSizesProps) => (\n        <Flow mainAxisGap={8}>\n          <Button size={buttonSize} view=\"secondary\">\n            Отмена\n          </Button>\n          <Button size={buttonSize} view=\"accent\">\n            Сохранить\n          </Button>\n        </Flow>\n      )}\n    />\n  )"
        },
        {
          "exportName": "WithoutBreadcrumbs",
          "displayName": "PageTitle без breadcrumbs",
          "type": "full-code",
          "code": "import { PageTitle } from '@daisforge/ui';\nimport { Button, Flow, IconButton } from '@daisforge/ui';\nimport { IconPlus } from '@daisforge/ui/icons';\nimport type { PageTitleSlotSizesProps } from '@daisforge/ui';\n\n() => (\n    <PageTitle\n      title=\"Заголовок страницы\"\n      subtitle=\"Описание страницы или подзаголовок\"\n      rightSlot={({ buttonSize }: PageTitleSlotSizesProps) => (\n        <Flow mainAxisGap={8}>\n          <Button size={buttonSize} view=\"secondary\">\n            Действие 1\n          </Button>\n          <Button size={buttonSize} view=\"accent\">\n            Действие 2\n          </Button>\n        </Flow>\n      )}\n    />\n  )"
        },
        {
          "exportName": "LongTitle",
          "displayName": "PageTitle с длинным заголовком",
          "type": "full-code",
          "code": "import { PageTitle } from '@daisforge/ui';\nimport { Button, Flow, IconButton } from '@daisforge/ui';\nimport { IconPlus } from '@daisforge/ui/icons';\nimport type { PageTitleSlotSizesProps } from '@daisforge/ui';\n\n() => (\n    <PageTitle\n      breadcrumbs={{\n        items: [\n          { title: 'Главная', href: '#' },\n          { title: 'Раздел', href: '#' },\n          { title: 'Страница' },\n        ],\n      }}\n      title=\"Очень длинный заголовок страницы, который может не поместиться в одну строку и будет обрезан с помощью TypographyWithAutoTooltip\"\n      subtitle=\"Описание страницы или подзаголовок\"\n      titleTypographyProps={{\n        tooltipText:\n          'Очень длинный заголовок страницы, который может не поместиться в одну строку и будет обрезан с помощью TypographyWithAutoTooltip',\n        lines: 1,\n        bold: true,\n      }}\n      rightSlot={({ buttonSize }: PageTitleSlotSizesProps) => (\n        <Flow mainAxisGap={8}>\n          <Button size={buttonSize} view=\"secondary\">\n            Действие 1\n          </Button>\n          <Button size={buttonSize} view=\"accent\">\n            Действие 2\n          </Button>\n        </Flow>\n      )}\n    />\n  )"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { PageTitle } from '@daisforge/ui';",
      "minimalUsage": "<PageTitle />",
      "examples": [
        {
          "exportName": "Default",
          "displayName": "PageTitle",
          "type": "full-code",
          "code": "import { PageTitle } from '@daisforge/ui';\nimport { Button, Flow, IconButton } from '@daisforge/ui';\nimport { IconPlus } from '@daisforge/ui/icons';\nimport type { PageTitleSlotSizesProps } from '@daisforge/ui';\n\n() => (\n    <PageTitle\n      breadcrumbs={{\n        items: [\n          { title: 'Главная', href: '#' },\n          { title: 'Раздел', href: '#' },\n          { title: 'Страница' },\n        ],\n      }}\n      showBackButton\n      onBackClick={() => alert('onBackClick')}\n      title=\"Заголовок страницы\"\n      subtitle=\"Описание страницы или подзаголовок\"\n      rightSlot={({ buttonSize }: PageTitleSlotSizesProps) => (\n        <Flow mainAxisGap={8}>\n          <Button size={buttonSize} view=\"secondary\">\n            Действие 1\n          </Button>\n          <Button size={buttonSize} view=\"accent\">\n            Действие 2\n          </Button>\n        </Flow>\n      )}\n    />\n  )"
        },
        {
          "exportName": "WithTitleSlot",
          "displayName": "PageTitle с кастомным слотом",
          "type": "full-code",
          "code": "import { PageTitle } from '@daisforge/ui';\nimport { Button, Flow, IconButton } from '@daisforge/ui';\nimport { IconPlus } from '@daisforge/ui/icons';\nimport type { PageTitleSlotSizesProps } from '@daisforge/ui';\n\n() => (\n    <PageTitle\n      breadcrumbs={{\n        items: [{ title: 'Главная', href: '#' }, { title: 'Раздел' }],\n      }}\n      showBackButton\n      onBackClick={() => alert('onBackClick')}\n      title=\"Заголовок страницы\"\n      subtitle=\"Описание страницы или подзаголовок\"\n      titleSlot={\n        <Button size=\"xs\" view=\"secondary\">\n          Действие\n        </Button>\n      }\n      rightSlot={({ buttonSize }: PageTitleSlotSizesProps) => (\n        <Flow mainAxisGap={8}>\n          <Button size={buttonSize} view=\"secondary\">\n            Отмена\n          </Button>\n          <Button size={buttonSize} view=\"accent\">\n            Сохранить\n          </Button>\n        </Flow>\n      )}\n    />\n  )"
        },
        {
          "exportName": "WithoutBreadcrumbs",
          "displayName": "PageTitle без breadcrumbs",
          "type": "full-code",
          "code": "import { PageTitle } from '@daisforge/ui';\nimport { Button, Flow, IconButton } from '@daisforge/ui';\nimport { IconPlus } from '@daisforge/ui/icons';\nimport type { PageTitleSlotSizesProps } from '@daisforge/ui';\n\n() => (\n    <PageTitle\n      title=\"Заголовок страницы\"\n      subtitle=\"Описание страницы или подзаголовок\"\n      rightSlot={({ buttonSize }: PageTitleSlotSizesProps) => (\n        <Flow mainAxisGap={8}>\n          <Button size={buttonSize} view=\"secondary\">\n            Действие 1\n          </Button>\n          <Button size={buttonSize} view=\"accent\">\n            Действие 2\n          </Button>\n        </Flow>\n      )}\n    />\n  )"
        },
        {
          "exportName": "LongTitle",
          "displayName": "PageTitle с длинным заголовком",
          "type": "full-code",
          "code": "import { PageTitle } from '@daisforge/ui';\nimport { Button, Flow, IconButton } from '@daisforge/ui';\nimport { IconPlus } from '@daisforge/ui/icons';\nimport type { PageTitleSlotSizesProps } from '@daisforge/ui';\n\n() => (\n    <PageTitle\n      breadcrumbs={{\n        items: [\n          { title: 'Главная', href: '#' },\n          { title: 'Раздел', href: '#' },\n          { title: 'Страница' },\n        ],\n      }}\n      title=\"Очень длинный заголовок страницы, который может не поместиться в одну строку и будет обрезан с помощью TypographyWithAutoTooltip\"\n      subtitle=\"Описание страницы или подзаголовок\"\n      titleTypographyProps={{\n        tooltipText:\n          'Очень длинный заголовок страницы, который может не поместиться в одну строку и будет обрезан с помощью TypographyWithAutoTooltip',\n        lines: 1,\n        bold: true,\n      }}\n      rightSlot={({ buttonSize }: PageTitleSlotSizesProps) => (\n        <Flow mainAxisGap={8}>\n          <Button size={buttonSize} view=\"secondary\">\n            Действие 1\n          </Button>\n          <Button size={buttonSize} view=\"accent\">\n            Действие 2\n          </Button>\n        </Flow>\n      )}\n    />\n  )"
        }
      ]
    },
    "Pagination": {
      "name": "Pagination",
      "group": "components",
      "folderName": "Pagination",
      "role": "primary",
      "description": "Постраничная навигация по спискам и таблицам с быстрым переходом и perPage",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        }
      ],
      "propsTypeName": "PaginationProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Pagination/Pagination.d.ts",
      "type": "wrapper",
      "atomicBase": "Pagination",
      "category": "Локальные компоненты",
      "keywords": [
        "постраничная навигация",
        "page navigation",
        "разбивка на страницы",
        "пагинация"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "count",
          "type": "number",
          "required": false,
          "description": "Количество страниц",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultPerPage",
          "type": "number",
          "required": false,
          "description": "Выбранное количество результатов на странице по умолчанию",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultValue",
          "type": "number",
          "required": false,
          "description": "Выбранная страница по умолчанию",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabledPages",
          "type": "string[]",
          "required": false,
          "description": "Заблокированные страницы",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasPerPage",
          "type": "boolean",
          "required": false,
          "description": "Выбор количества результатов на странице",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasQuickJump",
          "type": "boolean",
          "required": false,
          "description": "Выбор страницы через Input",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isCommonButtonStyles",
          "type": "boolean",
          "required": false,
          "description": "Авто изменение стиля кнопок в ButtonGroup",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "leftContent",
          "type": "ReactNode",
          "required": false,
          "description": "Левый контент",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "listWidth",
          "type": "Width<string | number>",
          "required": false,
          "description": "Значение css width для выпадающего списка.",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onBlurQuickJump",
          "type": "((e: FocusEvent<HTMLInputElement, Element>) => void)",
          "required": false,
          "description": "Функция которая исполняeтся при потере фокусе на поле ввода перехода по страницам",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "((page?: number, perPage?: number) => void) | undefined",
          "required": false,
          "description": "Функция которая исполняeтся при изменении `page`, `perPage`",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onFocusQuickJump",
          "type": "((e: FocusEvent<HTMLInputElement, Element>) => void)",
          "required": false,
          "description": "Функция которая исполняeтся при фокусе на поле ввода перехода по страницам",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "perPage",
          "type": "number",
          "required": false,
          "description": "Выбранное количество результатов на странице",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "perPageList",
          "type": "number[]",
          "required": false,
          "description": "Список результатов на странице",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pilled",
          "type": "boolean",
          "required": false,
          "description": "Скругление кнопки",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placeholderQuickJump",
          "type": "string",
          "required": false,
          "description": "Placeholder TextField'a для быстрого прыжка на страницу",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "rightContent",
          "type": "ReactNode",
          "required": false,
          "description": "Правый контент",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "singleLine",
          "type": "boolean",
          "required": false,
          "description": "Перенос строки для helperText",
          "default": "false",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "description": "Размер",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "slots",
          "type": "1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15",
          "required": false,
          "description": "Количество PageButtons",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "square",
          "type": "boolean",
          "required": false,
          "description": "Равная ширина и высота кнопки",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textPerPage",
          "type": "string",
          "required": false,
          "description": "Текст для выбора кол-ва результатов на странице",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textQuickJump",
          "type": "string",
          "required": false,
          "description": "Текст для быстрого прыжка на страницу",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "type",
          "type": "\"default\" | \"compact\"",
          "required": false,
          "description": "Тип обычный или компактный",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "number",
          "required": false,
          "description": "Выбранная страница",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"secondary\"",
          "required": false,
          "description": "Вид",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "viewCurrentPage",
          "type": "\"clear\" | \"default\" | \"secondary\"",
          "required": false,
          "description": "Вид выбранной кнопки",
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "helperText",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangePageValue",
          "type": "((page?: number) => void)",
          "required": false,
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangePerPageValue",
          "type": "((perPage?: number) => void)",
          "required": false,
          "inheritedFrom": "Pagination",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Pagination } from '@daisforge/ui';",
      "minimalUsage": "<Pagination />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Pagination } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Pagination slots={9} count={2000} hasPerPage perPage={20} />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Форма кнопок",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Pagination } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', gap: '1rem', flexDirection: 'column' }}>\n            <Pagination size=\"xs\" pilled={false} slots={9} count={200} />\n            <Pagination size=\"xs\" pilled={true} slots={9} count={200} />\n        </div>\n    );\n}"
        }
      ]
    },
    "Popover": {
      "name": "Popover",
      "group": "components",
      "folderName": "Popover",
      "role": "primary",
      "description": "Всплывающая панель у элемента-триггера для доп. контента, меню или подсказок",
      "props": [
        {
          "name": "stretchHeight",
          "type": "boolean | undefined",
          "required": false,
          "description": "Растянуть Popover до границы доступной области по вертикали."
        }
      ],
      "propsTypeName": "PopoverProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Popover/Popover.d.ts",
      "type": "wrapper",
      "atomicBase": "Popover",
      "category": "Локальные компоненты",
      "keywords": [
        "контекстное меню",
        "dropdown контент",
        "всплывающая подсказка"
      ],
      "chooseWhen": "Стабильная версия на текуший момент — без ресайза и явного выбора триггера hover/click/focus. Нужен ресайз или гибкие триггеры — PopoverBeta. В новых проектах - PopoverBeta. Если не устроил Popover, то PopoverBeta",
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "animated",
          "type": "boolean",
          "required": false,
          "description": "Анимированное появление Popover",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnEsc",
          "type": "boolean",
          "required": false,
          "description": "Закрывать окно при нажатии ESC.",
          "default": "true",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean",
          "required": false,
          "description": "Закрывать окно при нажатии вне области окна. (Если trigger === 'click')",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "frame",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "В каком контейнере позиционируется(по умолчанию document), можно также указать id элемента или ref для него.",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasArrow",
          "type": "boolean",
          "required": false,
          "description": "Есть ли стрелка над элементом.",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isFocusTrapped",
          "type": "boolean",
          "required": false,
          "description": "Блокировать ли фокус на всплывающем окне.",
          "default": "true",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 0]",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onResizeEnd",
          "type": "((resizableContainer?: RefObject<Resizable>) => void)",
          "required": false,
          "description": "Обработчик остановки ресайза.",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onResizeStart",
          "type": "((resizableContainer?: RefObject<Resizable>) => void)",
          "required": false,
          "description": "Обработчик начала ресайза.",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean, event: Event | SyntheticEvent<Element, Event>) => void)",
          "required": false,
          "description": "Событие сворачивания/разворачивания всплывающего окна.",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": false,
          "description": "Всплывающее окно раскрыто или нет.",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "description": "Сторона открытия окна относительно target элемента.",
          "default": "auto",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "preventOverflow",
          "type": "boolean",
          "required": false,
          "description": "Предотвратить автоматическое изменение положения.",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "resizable",
          "type": "boolean | { disabled?: boolean; directions?: ResizeDirections; defaultSize?: { width?: number | undefined; height?: number | undefined; } | undefined; ... 6 more ...; hiddenIcons?: PlacementMixed[] | undefined; } | undefined",
          "required": false,
          "description": "Настройка resizable-режима.",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "target",
          "type": "string | number | boolean | ReactElement<any, string | JSXElementConstructor<any>> | ReactFragment | ReactPortal | ((instance: HTMLElement | null) => void) | RefObject<...> | null",
          "required": false,
          "description": "Элемент или ref на элемент, рядом с которым произойдет вызов всплывающего окна.",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "trigger",
          "type": "PopoverTrigger",
          "required": false,
          "description": "Способ открытия всплывающего окна - наведение или клик мышью.",
          "default": "click",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "usePortal",
          "type": "boolean",
          "required": false,
          "description": "Находится ли в портале.",
          "default": "false",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "string",
          "required": false,
          "description": "Значение z-index для Popover.",
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "Popover",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Popover } from '@daisforge/ui';",
      "minimalUsage": "<Popover />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "<Popover style={{ \"border-radius\": \"20px\" }}>\n    <StyledSlotContent> {/* border-radius: 20px */}\n        ...\n    </StyledSlotContent>\n</Popover>"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Resizable Resizable Чтобы иметь возможность растягивать Popover нужно настроить свойство  resizable . Формат следующий",
          "type": "vendor",
          "code": "/**\n * Настройка resizable-режима.\n */\ntype resizable = {\n    resizable?:\n    |  boolean\n    |  {\n            /**\n            * Включение/выключение ресайза.\n            * @default false\n            */\n            disabled?: boolean;\n            /**\n            * Направления для ресайза.\n            */\n            directions?: ResizeDirections;\n            /**\n            * Начальный размер окна ресайза.\n            */\n            defaultSize?: { width?: number; height?: number };\n            /**\n            * Минимальная ширина ресайза в px.\n            */\n            minWidth?: number;\n            /**\n            * Минимальная высота ресайза в px.\n            */\n            minHeight?: number;\n            /**\n            * Максимальная ширина ресайза в px.\n            */\n            maxWidth?: number;\n            /**\n            * Максимальная высота ресайза в px.\n            */\n            maxHeight?: number;\n            /**\n            * Кастомные иконки ресайза.\n            */\n            icons?: {\n                topRight?: ReactNode;\n                bottomRight?: ReactNode;\n                bottomLeft?: ReactNode;\n                topLeft?: ReactNode;\n            };\n            /**\n            * Размер иконки ресайза.\n            * @default s\n            */\n            iconSize?: 'xs' | 's' | 'm';\n            /**\n            * Скрывать ли иконку для ресайза.\n            * @default false\n            */\n            hiddenIcons?: PopupPlacementMixed[];\n        };\n}"
        }
      ]
    },
    "PopoverBeta": {
      "name": "PopoverBeta",
      "group": "components",
      "folderName": "PopoverBeta",
      "role": "primary",
      "description": "Бета-версия Popover с ресайзом, порталом и триггерами hover/click/focus",
      "props": [
        {
          "name": "target",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>>",
          "required": true,
          "description": "Целевой элемент взаимодействия с всплывающим окном."
        },
        {
          "name": "defaultOpened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Раскрыто ли всплывающее окно по умолчанию.",
          "default": "false"
        },
        {
          "name": "delayClose",
          "type": "number | undefined",
          "required": false,
          "description": "Задержка перед скрытием, мс. (При trigger === 'hover')",
          "default": "0"
        },
        {
          "name": "delayOpen",
          "type": "number | undefined",
          "required": false,
          "description": "Задержка перед раскрытием, мс. (При trigger === 'hover')",
          "default": "0"
        },
        {
          "name": "flip",
          "type": "boolean | undefined",
          "required": false,
          "description": "Коррекция placement, если всплывающее окно находится за пределами экрана.",
          "default": "false"
        },
        {
          "name": "hasTail",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включение хвостика у всплывающего окна.",
          "default": "true"
        },
        {
          "name": "offset",
          "type": "number | undefined",
          "required": false,
          "description": "Отступ всплывающего окна относительно target.",
          "default": "0"
        },
        {
          "name": "onResizeEnd",
          "type": "((resizableContainer?: React.RefObject<Resizable> | undefined) => void) | undefined",
          "required": false,
          "description": "Обработчик остановки ресайза."
        },
        {
          "name": "onResizeStart",
          "type": "((resizableContainer?: React.RefObject<Resizable> | undefined) => void) | undefined",
          "required": false,
          "description": "Обработчик начала ресайза."
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean) => void) | undefined",
          "required": false,
          "description": "Событие сворачивания/разворачивания всплывающего окна."
        },
        {
          "name": "opened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Управление скрытием/раскрытием всплывающего окна."
        },
        {
          "name": "outsideClick",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрывать окно при нажатии вне области окна. (При trigger === 'click')",
          "default": "true"
        },
        {
          "name": "placement",
          "type": "Placement | undefined",
          "required": false,
          "description": "Сторона раскрытия окна относительно target-элемента.",
          "default": "bottom"
        },
        {
          "name": "portal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "Портал для всплывающего окна.\nПринимает id контейнера или ref.\nЕсли контейнер с заданным id не найден на странице,\nто он будет автоматически создан перед </body>.",
          "default": "Без использования portal всплывающее окно рендерится перед </body>."
        },
        {
          "name": "resizable",
          "type": "boolean | { disabled?: boolean | undefined; directions?: ResizeDirections | undefined; defaultSize?: { width?: number | undefined; height?: number | undefined; } | undefined; minWidth?: number | undefined; minHeight?: number | undefined; maxWidth?: number | undefined; maxHeight?: number | undefined; icons?: { topRight?: React.ReactNode; bottomRight?: React.ReactNode; bottomLeft?: React.ReactNode; …",
          "required": false,
          "description": "Настройка resizable-режима.",
          "default": "false"
        },
        {
          "name": "shift",
          "type": "boolean | undefined",
          "required": false,
          "description": "Смещение всплывающего окна при соприкосновении с границами экрана.",
          "default": "false"
        },
        {
          "name": "size",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": "Размер компонента."
        },
        {
          "name": "trigger",
          "type": "\"hover\" | \"click\" | \"focus\" | undefined",
          "required": false,
          "description": "Способ скрытия/раскрытия всплывающего окна.",
          "default": "click"
        },
        {
          "name": "view",
          "type": "\"action\" | \"info\" | undefined",
          "required": false,
          "description": "Вид компонента."
        },
        {
          "name": "zIndex",
          "type": "number | undefined",
          "required": false,
          "description": "CSS-свойство z-index всплывающего окна.",
          "default": "1000"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"closeInner\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "PopoverBetaCompProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/dist/beta/types/Popover/Popover.d.ts",
      "type": "wrapper",
      "atomicBase": "Popover",
      "atomicSubpath": "beta",
      "category": "Локальные компоненты",
      "keywords": [
        "изменяемый размер попапа",
        "resizable popup",
        "триггер наведения"
      ],
      "chooseWhen": "Новая проработанная версия — нужен изменяемый размер попапа, явный выбор триггера (hover/click/focus) или рендер в портал — иначе берите стабильный Popover.",
      "hasCuratedMeta": true,
      "inheritedProps": [],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { PopoverBeta } from '@daisforge/ui';",
      "minimalUsage": "<PopoverBeta target={'Контент'} />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в PopoverBeta.tsx",
          "type": "usage",
          "code": "<PopoverBeta target={<Button view=\"accent\">PopoverBetaExample</Button>}>\n      <div> kek</div>\n    </PopoverBeta>",
          "sourceFile": "packages/vite-project/src/pages/PopoverBeta.tsx"
        }
      ]
    },
    "PopoverDFBody": {
      "name": "PopoverDFBody",
      "group": "components",
      "folderName": "PopoverDF",
      "role": "part",
      "description": "Область содержимого всплывающего окна PopoverDF с настройкой размеров и отступов",
      "props": [
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные стили styled-components для Box-контейнера"
        },
        {
          "name": "as",
          "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"form\" | \"pattern\" | \"slot\" | \"style\" | \"title\" | \"view\" | \"s\" | \"input\" | \"search\" | \"article\" | \"button\" | \"dialog\" | \"figure\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"switch\" | \"table\" | \"text\" | \"time\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"big\" | \"blockquote\" |…",
          "required": false,
          "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
        },
        {
          "name": "background",
          "type": "Property.Background<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "backgroundColor",
          "type": "Property.BackgroundColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "border",
          "type": "Property.Border<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderColor",
          "type": "Property.BorderColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderRadius",
          "type": "Property.BorderRadius<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
        },
        {
          "name": "borderStyle",
          "type": "Property.BorderStyle | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderWidth",
          "type": "Property.BorderWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "bottom",
          "type": "Property.Bottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "boxSizing",
          "type": "Property.BoxSizing | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
        },
        {
          "name": "cursor",
          "type": "Property.Cursor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
        },
        {
          "name": "display",
          "type": "Property.Display | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "flexDirection",
          "type": "Property.FlexDirection | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
        },
        {
          "name": "flexGrow",
          "type": "Property.FlexGrow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
        },
        {
          "name": "flexShrink",
          "type": "Property.FlexShrink | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
        },
        {
          "name": "flexWrap",
          "type": "Property.FlexWrap | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "gap",
          "type": "Property.Gap<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
        },
        {
          "name": "height",
          "type": "Property.Height<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "justifyContent",
          "type": "Property.JustifyContent | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "justifyItems",
          "type": "Property.JustifyItems | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
        },
        {
          "name": "justifySelf",
          "type": "Property.JustifySelf | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
        },
        {
          "name": "left",
          "type": "Property.Left<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "margin",
          "type": "Property.Margin<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginBottom",
          "type": "Property.MarginBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginLeft",
          "type": "Property.MarginLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginRight",
          "type": "Property.MarginRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginTop",
          "type": "Property.MarginTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "maxHeight",
          "type": "Property.MaxHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "maxWidth",
          "type": "Property.MaxWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "minHeight",
          "type": "Property.MinHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "minWidth",
          "type": "Property.MinWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "opacity",
          "type": "Property.Opacity | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
        },
        {
          "name": "overflow",
          "type": "Property.Overflow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "padding",
          "type": "Property.Padding<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingBottom",
          "type": "Property.PaddingBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingLeft",
          "type": "Property.PaddingLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingRight",
          "type": "Property.PaddingRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingTop",
          "type": "Property.PaddingTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "position",
          "type": "Property.Position | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "right",
          "type": "Property.Right<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "top",
          "type": "Property.Top<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "width",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        }
      ],
      "propsTypeName": "PopoverDFBodyProps",
      "sourceFile": "packages/ui-kit/src/components/PopoverDF/components/Body.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "тело поповера",
        "содержимое всплывающего окна",
        "popover content"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "PopoverDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "PopoverDF",
        "part": "Body"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { PopoverDFBody } from '@daisforge/ui';",
      "minimalUsage": "<PopoverDFBody />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в PopoverDF.stories.tsx",
          "type": "usage",
          "code": "<PopoverDF.Body>Контент всплывающего окна.</PopoverDF.Body>",
          "sourceFile": "packages/storybook/src/stories/PopoverDF/PopoverDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в PopoverDF.stories.tsx",
          "type": "usage",
          "code": "<PopoverDF.Body>\n        <BodySlot />\n      </PopoverDF.Body>",
          "sourceFile": "packages/storybook/src/stories/PopoverDF/PopoverDF.stories.tsx"
        }
      ]
    },
    "PopoverDFFooter": {
      "name": "PopoverDFFooter",
      "group": "components",
      "folderName": "PopoverDF",
      "role": "part",
      "description": "Нижний блок всплывающего окна PopoverDF для кнопок и действий",
      "props": [
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные стили styled-components для Box-контейнера"
        },
        {
          "name": "as",
          "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"form\" | \"pattern\" | \"slot\" | \"style\" | \"title\" | \"view\" | \"s\" | \"input\" | \"search\" | \"article\" | \"button\" | \"dialog\" | \"figure\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"switch\" | \"table\" | \"text\" | \"time\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"big\" | \"blockquote\" |…",
          "required": false,
          "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
        },
        {
          "name": "background",
          "type": "Property.Background<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "backgroundColor",
          "type": "Property.BackgroundColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "border",
          "type": "Property.Border<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderColor",
          "type": "Property.BorderColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderRadius",
          "type": "Property.BorderRadius<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
        },
        {
          "name": "borderStyle",
          "type": "Property.BorderStyle | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderWidth",
          "type": "Property.BorderWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "bottom",
          "type": "Property.Bottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "boxSizing",
          "type": "Property.BoxSizing | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
        },
        {
          "name": "cursor",
          "type": "Property.Cursor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
        },
        {
          "name": "display",
          "type": "Property.Display | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "flexDirection",
          "type": "Property.FlexDirection | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
        },
        {
          "name": "flexGrow",
          "type": "Property.FlexGrow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
        },
        {
          "name": "flexShrink",
          "type": "Property.FlexShrink | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
        },
        {
          "name": "flexWrap",
          "type": "Property.FlexWrap | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "gap",
          "type": "Property.Gap<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
        },
        {
          "name": "height",
          "type": "Property.Height<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "justifyContent",
          "type": "Property.JustifyContent | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "justifyItems",
          "type": "Property.JustifyItems | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
        },
        {
          "name": "justifySelf",
          "type": "Property.JustifySelf | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
        },
        {
          "name": "left",
          "type": "Property.Left<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "margin",
          "type": "Property.Margin<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginBottom",
          "type": "Property.MarginBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginLeft",
          "type": "Property.MarginLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginRight",
          "type": "Property.MarginRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginTop",
          "type": "Property.MarginTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "maxHeight",
          "type": "Property.MaxHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "maxWidth",
          "type": "Property.MaxWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "minHeight",
          "type": "Property.MinHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "minWidth",
          "type": "Property.MinWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "opacity",
          "type": "Property.Opacity | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
        },
        {
          "name": "overflow",
          "type": "Property.Overflow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "padding",
          "type": "Property.Padding<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingBottom",
          "type": "Property.PaddingBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingLeft",
          "type": "Property.PaddingLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingRight",
          "type": "Property.PaddingRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingTop",
          "type": "Property.PaddingTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "position",
          "type": "Property.Position | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "right",
          "type": "Property.Right<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "top",
          "type": "Property.Top<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "width",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        }
      ],
      "propsTypeName": "PopoverDFFooterProps",
      "sourceFile": "packages/ui-kit/src/components/PopoverDF/components/Footer.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "футер поповера",
        "кнопки в поповере",
        "popover footer"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "PopoverDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "PopoverDF",
        "part": "Footer"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { PopoverDFFooter } from '@daisforge/ui';",
      "minimalUsage": "<PopoverDFFooter />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в PopoverDF.stories.tsx",
          "type": "usage",
          "code": "<PopoverDF.Footer>\n        <FooterActions />\n      </PopoverDF.Footer>",
          "sourceFile": "packages/storybook/src/stories/PopoverDF/PopoverDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в PopoverDF.stories.tsx",
          "type": "usage",
          "code": "<PopoverDF.Footer>\n          <FooterActions size={size} />\n        </PopoverDF.Footer>",
          "sourceFile": "packages/storybook/src/stories/PopoverDF/PopoverDF.stories.tsx"
        }
      ]
    },
    "PopoverDFHeader": {
      "name": "PopoverDFHeader",
      "group": "components",
      "folderName": "PopoverDF",
      "role": "part",
      "description": "Шапка PopoverDF: заголовок, описание, кнопка закрытия и нижний доп. блок",
      "props": [
        {
          "name": "bottomBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": "Нижний блок header на всю ширину.\nУдобен для кастомных слотов, фильтров, тегов и другого дополнительного контента."
        },
        {
          "name": "description",
          "type": "React.ReactNode",
          "required": false,
          "description": "Текст под заголовком в верхней левой части header."
        },
        {
          "name": "onClose",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Кастомный обработчик закрытия.\nЕсли не передан, будет использован обработчик закрытия из `PopoverDF`."
        },
        {
          "name": "showCloseButton",
          "type": "boolean | undefined",
          "required": false,
          "description": "Показывать ли крестик закрытия в правой верхней части header.",
          "default": "true"
        },
        {
          "name": "title",
          "type": "React.ReactNode",
          "required": false,
          "description": "Заголовок в верхней левой части header."
        }
      ],
      "propsTypeName": "PopoverDFHeaderProps",
      "sourceFile": "packages/ui-kit/src/components/PopoverDF/components/Header.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "шапка поповера",
        "заголовок всплывающего окна",
        "popover header"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "PopoverDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "PopoverDF",
        "part": "Header"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { PopoverDFHeader } from '@daisforge/ui';",
      "minimalUsage": "<PopoverDFHeader />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в PopoverDF.stories.tsx",
          "type": "usage",
          "code": "<PopoverDF.Header\n        title=\"Title\"\n        description=\"Description\"\n        showCloseButton={showCloseButton}\n        bottomBlock={withHeaderSlot ? <HeaderSlot /> : undefined}\n      />",
          "sourceFile": "packages/storybook/src/stories/PopoverDF/PopoverDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в PopoverDF.stories.tsx",
          "type": "usage",
          "code": "<PopoverDF.Header title=\"Title\" description=\"Description\" />",
          "sourceFile": "packages/storybook/src/stories/PopoverDF/PopoverDF.stories.tsx"
        }
      ]
    },
    "PopoverDF": {
      "name": "PopoverDF",
      "group": "components",
      "folderName": "PopoverDF",
      "role": "primary",
      "description": "Popover с готовыми Header/Body/Footer и управлением состоянием открытия",
      "props": [
        {
          "name": "target",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>>",
          "required": true,
          "description": "Целевой элемент взаимодействия с всплывающим окном."
        },
        {
          "name": "size",
          "type": "PopoverDFSize | undefined",
          "required": false,
          "description": "Размер PopoverDF.\nВлияет на внутренние отступы и типографику header.",
          "default": "'m'"
        },
        {
          "name": "defaultOpened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Раскрыто ли всплывающее окно по умолчанию.",
          "default": "false"
        },
        {
          "name": "delayClose",
          "type": "number | undefined",
          "required": false,
          "description": "Задержка перед скрытием, мс. (При trigger === 'hover')",
          "default": "0"
        },
        {
          "name": "delayOpen",
          "type": "number | undefined",
          "required": false,
          "description": "Задержка перед раскрытием, мс. (При trigger === 'hover')",
          "default": "0"
        },
        {
          "name": "flip",
          "type": "boolean | undefined",
          "required": false,
          "description": "Коррекция placement, если всплывающее окно находится за пределами экрана.",
          "default": "false"
        },
        {
          "name": "hasTail",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включение хвостика у всплывающего окна.",
          "default": "true"
        },
        {
          "name": "offset",
          "type": "number | undefined",
          "required": false,
          "description": "Отступ всплывающего окна относительно target.",
          "default": "0"
        },
        {
          "name": "onResizeEnd",
          "type": "((resizableContainer?: React.RefObject<Resizable> | undefined) => void) | undefined",
          "required": false,
          "description": "Обработчик остановки ресайза."
        },
        {
          "name": "onResizeStart",
          "type": "((resizableContainer?: React.RefObject<Resizable> | undefined) => void) | undefined",
          "required": false,
          "description": "Обработчик начала ресайза."
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean) => void) | undefined",
          "required": false,
          "description": "Событие сворачивания/разворачивания всплывающего окна."
        },
        {
          "name": "opened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Управление скрытием/раскрытием всплывающего окна."
        },
        {
          "name": "outsideClick",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрывать окно при нажатии вне области окна. (При trigger === 'click')",
          "default": "true"
        },
        {
          "name": "placement",
          "type": "Placement | undefined",
          "required": false,
          "description": "Сторона раскрытия окна относительно target-элемента.",
          "default": "bottom"
        },
        {
          "name": "portal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "Портал для всплывающего окна.\nПринимает id контейнера или ref.\nЕсли контейнер с заданным id не найден на странице,\nто он будет автоматически создан перед </body>.",
          "default": "Без использования portal всплывающее окно рендерится перед </body>."
        },
        {
          "name": "resizable",
          "type": "boolean | { disabled?: boolean | undefined; directions?: ResizeDirections | undefined; defaultSize?: { width?: number | undefined; height?: number | undefined; } | undefined; minWidth?: number | undefined; minHeight?: number | undefined; maxWidth?: number | undefined; maxHeight?: number | undefined; icons?: { topRight?: React.ReactNode; bottomRight?: React.ReactNode; bottomLeft?: React.ReactNode; …",
          "required": false,
          "description": "Настройка resizable-режима.",
          "default": "false"
        },
        {
          "name": "shift",
          "type": "boolean | undefined",
          "required": false,
          "description": "Смещение всплывающего окна при соприкосновении с границами экрана.",
          "default": "false"
        },
        {
          "name": "trigger",
          "type": "\"hover\" | \"click\" | \"focus\" | undefined",
          "required": false,
          "description": "Способ скрытия/раскрытия всплывающего окна.",
          "default": "click"
        },
        {
          "name": "view",
          "type": "\"action\" | \"info\" | undefined",
          "required": false,
          "description": "Вид компонента."
        },
        {
          "name": "zIndex",
          "type": "number | undefined",
          "required": false,
          "description": "CSS-свойство z-index всплывающего окна.",
          "default": "1000"
        }
      ],
      "propsTypeName": "PopoverDFProps",
      "compoundParts": [
        {
          "name": "Header",
          "typeName": "PopoverDFHeaderProps",
          "props": [
            {
              "name": "bottomBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": "Нижний блок header на всю ширину.\nУдобен для кастомных слотов, фильтров, тегов и другого дополнительного контента."
            },
            {
              "name": "description",
              "type": "React.ReactNode",
              "required": false,
              "description": "Текст под заголовком в верхней левой части header."
            },
            {
              "name": "onClose",
              "type": "(() => void) | undefined",
              "required": false,
              "description": "Кастомный обработчик закрытия.\nЕсли не передан, будет использован обработчик закрытия из `PopoverDF`."
            },
            {
              "name": "showCloseButton",
              "type": "boolean | undefined",
              "required": false,
              "description": "Показывать ли крестик закрытия в правой верхней части header.",
              "default": "true"
            },
            {
              "name": "title",
              "type": "React.ReactNode",
              "required": false,
              "description": "Заголовок в верхней левой части header."
            }
          ]
        },
        {
          "name": "Body",
          "typeName": "PopoverDFBodyProps",
          "props": [
            {
              "name": "$css",
              "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
              "required": false,
              "description": "Кастомные стили styled-components для Box-контейнера"
            },
            {
              "name": "as",
              "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"form\" | \"pattern\" | \"slot\" | \"style\" | \"title\" | \"view\" | \"s\" | \"input\" | \"search\" | \"article\" | \"button\" | \"dialog\" | \"figure\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"switch\" | \"table\" | \"text\" | \"time\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"big\" | \"blockquote\" |…",
              "required": false,
              "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
            },
            {
              "name": "background",
              "type": "Property.Background<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "backgroundColor",
              "type": "Property.BackgroundColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "border",
              "type": "Property.Border<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderColor",
              "type": "Property.BorderColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderRadius",
              "type": "Property.BorderRadius<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
            },
            {
              "name": "borderStyle",
              "type": "Property.BorderStyle | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderWidth",
              "type": "Property.BorderWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "bottom",
              "type": "Property.Bottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "boxSizing",
              "type": "Property.BoxSizing | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
            },
            {
              "name": "cursor",
              "type": "Property.Cursor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
            },
            {
              "name": "display",
              "type": "Property.Display | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "flexDirection",
              "type": "Property.FlexDirection | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
            },
            {
              "name": "flexGrow",
              "type": "Property.FlexGrow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
            },
            {
              "name": "flexShrink",
              "type": "Property.FlexShrink | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
            },
            {
              "name": "flexWrap",
              "type": "Property.FlexWrap | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "gap",
              "type": "Property.Gap<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
            },
            {
              "name": "height",
              "type": "Property.Height<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "justifyContent",
              "type": "Property.JustifyContent | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "justifyItems",
              "type": "Property.JustifyItems | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
            },
            {
              "name": "justifySelf",
              "type": "Property.JustifySelf | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
            },
            {
              "name": "left",
              "type": "Property.Left<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "margin",
              "type": "Property.Margin<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginBottom",
              "type": "Property.MarginBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginLeft",
              "type": "Property.MarginLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginRight",
              "type": "Property.MarginRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginTop",
              "type": "Property.MarginTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "maxHeight",
              "type": "Property.MaxHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "maxWidth",
              "type": "Property.MaxWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "minHeight",
              "type": "Property.MinHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "minWidth",
              "type": "Property.MinWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "opacity",
              "type": "Property.Opacity | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
            },
            {
              "name": "overflow",
              "type": "Property.Overflow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "padding",
              "type": "Property.Padding<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingBottom",
              "type": "Property.PaddingBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingLeft",
              "type": "Property.PaddingLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingRight",
              "type": "Property.PaddingRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingTop",
              "type": "Property.PaddingTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "position",
              "type": "Property.Position | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "right",
              "type": "Property.Right<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "top",
              "type": "Property.Top<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "width",
              "type": "Property.Width<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "zIndex",
              "type": "Property.ZIndex | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            }
          ]
        },
        {
          "name": "Footer",
          "typeName": "PopoverDFFooterProps",
          "props": [
            {
              "name": "$css",
              "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
              "required": false,
              "description": "Кастомные стили styled-components для Box-контейнера"
            },
            {
              "name": "as",
              "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"form\" | \"pattern\" | \"slot\" | \"style\" | \"title\" | \"view\" | \"s\" | \"input\" | \"search\" | \"article\" | \"button\" | \"dialog\" | \"figure\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"switch\" | \"table\" | \"text\" | \"time\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"big\" | \"blockquote\" |…",
              "required": false,
              "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
            },
            {
              "name": "background",
              "type": "Property.Background<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "backgroundColor",
              "type": "Property.BackgroundColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "border",
              "type": "Property.Border<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderColor",
              "type": "Property.BorderColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderRadius",
              "type": "Property.BorderRadius<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
            },
            {
              "name": "borderStyle",
              "type": "Property.BorderStyle | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderWidth",
              "type": "Property.BorderWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "bottom",
              "type": "Property.Bottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "boxSizing",
              "type": "Property.BoxSizing | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
            },
            {
              "name": "cursor",
              "type": "Property.Cursor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
            },
            {
              "name": "display",
              "type": "Property.Display | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "flexDirection",
              "type": "Property.FlexDirection | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
            },
            {
              "name": "flexGrow",
              "type": "Property.FlexGrow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
            },
            {
              "name": "flexShrink",
              "type": "Property.FlexShrink | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
            },
            {
              "name": "flexWrap",
              "type": "Property.FlexWrap | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "gap",
              "type": "Property.Gap<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
            },
            {
              "name": "height",
              "type": "Property.Height<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "justifyContent",
              "type": "Property.JustifyContent | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "justifyItems",
              "type": "Property.JustifyItems | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
            },
            {
              "name": "justifySelf",
              "type": "Property.JustifySelf | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
            },
            {
              "name": "left",
              "type": "Property.Left<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "margin",
              "type": "Property.Margin<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginBottom",
              "type": "Property.MarginBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginLeft",
              "type": "Property.MarginLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginRight",
              "type": "Property.MarginRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginTop",
              "type": "Property.MarginTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "maxHeight",
              "type": "Property.MaxHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "maxWidth",
              "type": "Property.MaxWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "minHeight",
              "type": "Property.MinHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "minWidth",
              "type": "Property.MinWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "opacity",
              "type": "Property.Opacity | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
            },
            {
              "name": "overflow",
              "type": "Property.Overflow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "padding",
              "type": "Property.Padding<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingBottom",
              "type": "Property.PaddingBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingLeft",
              "type": "Property.PaddingLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingRight",
              "type": "Property.PaddingRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingTop",
              "type": "Property.PaddingTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "position",
              "type": "Property.Position | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "right",
              "type": "Property.Right<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "top",
              "type": "Property.Top<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "width",
              "type": "Property.Width<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "zIndex",
              "type": "Property.ZIndex | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            }
          ]
        }
      ],
      "sourceFile": "packages/ui-kit/src/components/PopoverDF/PopoverDF.tsx",
      "type": "wrapper",
      "category": "Локальные компоненты",
      "hint": "Универсальный Popover. Не путать с AiAgentPopover (для конкретной команды).",
      "keywords": [
        "составной popover",
        "попап с шапкой",
        "compound popover"
      ],
      "docs": "# PopoverDF\n\n`PopoverDF` — локальная DF-обёртка над [PopoverBeta](https://plasma.sberdevices.ru/sdds-finai/beta/popover/).\n\n## Ключевые особенности\n\n- крестик закрытия живёт в `PopoverDF.Header`\n- доступны `PopoverDF.Header`, `PopoverDF.Body`, `PopoverDF.Footer`\n- доступны размеры `size=\"m\" | \"s\"`\n- `hasTail` можно отключить через `hasTail={false}`\n- при `resizable` иконка ресайза автоматически подстраивается под `placement`\n\n## Compound-компоненты\n\n```ts\nPopoverDF.Header; // Шапка\nPopoverDF.Body; // Контент\nPopoverDF.Footer; // Футер\n```\n\n## Особенности\n\n- если нужен крестик, используйте `PopoverDF.Header`; закрытие привязано к нему\n- для кастомного блока в шапке используйте `bottomBlock`\n- если нужен только контент без шапки и футера, можно оставить только `PopoverDF.Body`\n- `resizable` можно передавать как `true` или как объект конфигурации; по умолчанию `PopoverDF` использует свою resize-иконку с учётом `iconSize`, но пользовательские `icons` переопределяют её\n- для ручной смены угла ресайза используйте нативный `resizable.directions`, например `directions: ['bottom-right']`\n- если `hiddenIcons` не передан, `PopoverDF` автоматически скрывает угловые иконки, которые не входят в `directions`; для нестандартной видимости передайте `hiddenIcons` явно\n- в режиме `resizable` стартовый размер задаётся через `resizable.defaultSize`; фиксированный `style.width` на `PopoverDF` может разъехать видимый popover и resize-контейнер\n- `target` обязателен: `PopoverDF` всегда позиционируется относительно target-элемента\n\n## Кастомный target\n\nЕсли в `target` передаётся кастомный компонент, он должен поддерживать `ref` и пробрасывать его на реальный DOM-элемент. `PopoverDF` использует этот `ref` для позиционирования. Полный рабочий пример доступен в story «Кастомный target».\n\nОписание типов и compound-пропсов — в разделе [API](?path=/docs/локальные-компоненты-popoverdf-api--docs).",
      "apiDocs": "# PopoverDF API\n\n## PopoverDFProps\n\n```typescript\ntype PopoverDFProps = Omit<\n  ComponentProps<typeof PopoverBeta>,\n  'children' | 'appearance' | 'size'\n> &\n  PopoverDFBaseProps;\n```\n\n## PopoverDFHeaderProps\n\n```typescript\ntype PopoverDFHeaderProps = Omit<BoxProps, 'children'> & {\n  /**\n   * Заголовок в верхней левой части header.\n   */\n  title?: ReactNode;\n  /**\n   * Текст под заголовком в верхней левой части header.\n   */\n  description?: ReactNode;\n  /**\n   * Нижний блок header на всю ширину.\n   * Удобен для кастомных слотов, фильтров, тегов и другого дополнительного контента.\n   */\n  bottomBlock?: ReactNode;\n  /**\n   * Показывать ли крестик закрытия в правой верхней части header.\n   * @default true\n   */\n  showCloseButton?: boolean;\n  /**\n   * Кастомный обработчик закрытия.\n   * Если не передан, будет использован обработчик закрытия из `PopoverDF`.\n   */\n  onClose?: () => void;\n};\n```\n\n## PopoverDFBodyProps\n\n```typescript\ntype PopoverDFBodyProps = BoxProps;\n```\n\n## PopoverDFFooterProps\n\n```typescript\ntype PopoverDFFooterProps = BoxProps & {\n  children?: ReactNode;\n};\n```\n\n## PopoverDFResizableConfig\n\n```typescript\ntype PopoverDFResizableConfig = Exclude<\n  ComponentProps<typeof PopoverBeta>['resizable'],\n  boolean | undefined\n>;\n```",
      "curatedStories": [
        {
          "exportName": "Simple",
          "displayName": "Simple",
          "type": "full-code",
          "code": "import { useState } from 'react';\nimport { Button, Flow, PopoverDF } from '@daisforge/ui';\n\n// Контент футера — обычные кнопки, которые вы кладёте в PopoverDF.Footer\nfunction FooterActions() {\n  return (\n    <Flow mainAxisGap={8}>\n      <Button size=\"xs\" view=\"secondary\">\n        Отмена\n      </Button>\n      <Button size=\"xs\" view=\"accent\">\n        Применить\n      </Button>\n    </Flow>\n  );\n}\nfunction Example() {\n  const [opened, setOpened] = useState(false);\n\n  return (\n    <PopoverDF\n      target={\n        <Button onClick={() => setOpened(true)}>Открыть PopoverDF</Button>\n      }\n      opened={opened}\n      onToggle={setOpened}\n      placement=\"bottom-start\"\n      offset={8}\n      size=\"m\"\n      style={{ width: '320px' }}\n    >\n      <PopoverDF.Header title=\"Title\" description=\"Description\" />\n      <PopoverDF.Body>Контент поповера</PopoverDF.Body>\n      <PopoverDF.Footer>\n        <FooterActions />\n      </PopoverDF.Footer>\n    </PopoverDF>\n  );\n}"
        },
        {
          "exportName": "Playground",
          "displayName": "Playground",
          "type": "full-code",
          "code": "import { useState } from 'react';\nimport { Button, Flow, PopoverDF } from '@daisforge/ui';\n\n// Контент футера — обычные кнопки, которые вы кладёте в PopoverDF.Footer\nfunction FooterActions() {\n  return (\n    <Flow mainAxisGap={8}>\n      <Button size=\"xs\" view=\"secondary\">\n        Отмена\n      </Button>\n      <Button size=\"xs\" view=\"accent\">\n        Применить\n      </Button>\n    </Flow>\n  );\n}\nfunction Example() {\n  const [opened, setOpened] = useState(false);\n\n  return (\n    <PopoverDF\n      target={\n        <Button onClick={() => setOpened(true)}>Открыть PopoverDF</Button>\n      }\n      opened={opened}\n      onToggle={setOpened}\n      placement=\"bottom\"\n      trigger=\"click\"\n      size=\"m\"\n      hasTail\n      offset={8}\n      resizable={{\n        defaultSize: { width: 320, height: 180 },\n        minWidth: 240,\n        minHeight: 120,\n        iconSize: 's',\n      }}\n    >\n      <PopoverDF.Header\n        title=\"Title\"\n        description=\"Description\"\n        showCloseButton\n      />\n      <PopoverDF.Body>Контент поповера</PopoverDF.Body>\n      <PopoverDF.Footer>\n        <FooterActions />\n      </PopoverDF.Footer>\n    </PopoverDF>\n  );\n}"
        },
        {
          "exportName": "CustomTarget",
          "displayName": "Кастомный target",
          "type": "full-code",
          "code": "import { forwardRef, useState } from 'react';\nimport type { ButtonHTMLAttributes, ForwardedRef } from 'react';\n\nimport { PopoverDF } from '@daisforge/ui';\n\nconst PopoverTarget = forwardRef(PopoverTargetRender);\n${getFuncAsString(\n  'packages/storybook/src/stories/PopoverDF/PopoverDF.stories.tsx',\n  'PopoverTargetRender',\n)}\n${getFuncAsString(\n  'packages/storybook/src/stories/PopoverDF/PopoverDF.stories.tsx',\n  'PopoverDFCustomTargetExample',\n)}"
        }
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "PopoverDFBody",
        "PopoverDFFooter",
        "PopoverDFHeader"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { PopoverDF } from '@daisforge/ui';",
      "minimalUsage": "<PopoverDF target={'Контент'}>\n  {/* части: PopoverDF.Header, PopoverDF.Body, PopoverDF.Footer */}\n</PopoverDF>",
      "examples": [
        {
          "exportName": "Simple",
          "displayName": "Simple",
          "type": "full-code",
          "code": "import { useState } from 'react';\nimport { Button, Flow, PopoverDF } from '@daisforge/ui';\n\n// Контент футера — обычные кнопки, которые вы кладёте в PopoverDF.Footer\nfunction FooterActions() {\n  return (\n    <Flow mainAxisGap={8}>\n      <Button size=\"xs\" view=\"secondary\">\n        Отмена\n      </Button>\n      <Button size=\"xs\" view=\"accent\">\n        Применить\n      </Button>\n    </Flow>\n  );\n}\nfunction Example() {\n  const [opened, setOpened] = useState(false);\n\n  return (\n    <PopoverDF\n      target={\n        <Button onClick={() => setOpened(true)}>Открыть PopoverDF</Button>\n      }\n      opened={opened}\n      onToggle={setOpened}\n      placement=\"bottom-start\"\n      offset={8}\n      size=\"m\"\n      style={{ width: '320px' }}\n    >\n      <PopoverDF.Header title=\"Title\" description=\"Description\" />\n      <PopoverDF.Body>Контент поповера</PopoverDF.Body>\n      <PopoverDF.Footer>\n        <FooterActions />\n      </PopoverDF.Footer>\n    </PopoverDF>\n  );\n}"
        },
        {
          "exportName": "Playground",
          "displayName": "Playground",
          "type": "full-code",
          "code": "import { useState } from 'react';\nimport { Button, Flow, PopoverDF } from '@daisforge/ui';\n\n// Контент футера — обычные кнопки, которые вы кладёте в PopoverDF.Footer\nfunction FooterActions() {\n  return (\n    <Flow mainAxisGap={8}>\n      <Button size=\"xs\" view=\"secondary\">\n        Отмена\n      </Button>\n      <Button size=\"xs\" view=\"accent\">\n        Применить\n      </Button>\n    </Flow>\n  );\n}\nfunction Example() {\n  const [opened, setOpened] = useState(false);\n\n  return (\n    <PopoverDF\n      target={\n        <Button onClick={() => setOpened(true)}>Открыть PopoverDF</Button>\n      }\n      opened={opened}\n      onToggle={setOpened}\n      placement=\"bottom\"\n      trigger=\"click\"\n      size=\"m\"\n      hasTail\n      offset={8}\n      resizable={{\n        defaultSize: { width: 320, height: 180 },\n        minWidth: 240,\n        minHeight: 120,\n        iconSize: 's',\n      }}\n    >\n      <PopoverDF.Header\n        title=\"Title\"\n        description=\"Description\"\n        showCloseButton\n      />\n      <PopoverDF.Body>Контент поповера</PopoverDF.Body>\n      <PopoverDF.Footer>\n        <FooterActions />\n      </PopoverDF.Footer>\n    </PopoverDF>\n  );\n}"
        },
        {
          "exportName": "CustomTarget",
          "displayName": "Кастомный target",
          "type": "full-code",
          "code": "import { forwardRef, useState } from 'react';\nimport type { ButtonHTMLAttributes, ForwardedRef } from 'react';\n\nimport { PopoverDF } from '@daisforge/ui';\n\nconst PopoverTarget = forwardRef(PopoverTargetRender);\n${getFuncAsString(\n  'packages/storybook/src/stories/PopoverDF/PopoverDF.stories.tsx',\n  'PopoverTargetRender',\n)}\n${getFuncAsString(\n  'packages/storybook/src/stories/PopoverDF/PopoverDF.stories.tsx',\n  'PopoverDFCustomTargetExample',\n)}"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в PopoverDF.stories.tsx",
          "type": "usage",
          "code": "<PopoverDF\n      target={<Button>Открыть PopoverDF</Button>}\n      placement={placement}\n      trigger={trigger}\n      defaultOpened={defaultOpened}\n      flip={flip}\n      shift={shift}\n      offset={offset}\n      outsideClick={outsideClick}\n      delayOpen={delayOpen}\n      delayClose={delayClose}\n      size={size}\n      hasTail={hasTail}\n      resizable={resizableConfig}\n      style={resizable ? undefined : { width: '320px' }}\n    >\n      {content}\n    </PopoverDF>",
          "sourceFile": "packages/storybook/src/stories/PopoverDF/PopoverDF.stories.tsx"
        }
      ]
    },
    "PopupProvider": {
      "name": "PopupProvider",
      "group": "components",
      "folderName": "Popup",
      "role": "primary",
      "description": "Провайдер контекста для Popup — задаёт frame позиционирования и SSR-режим",
      "props": [
        {
          "name": "providerFrame",
          "type": "string | React.RefObject<HTMLElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "UNSAFE_SSR_ENABLED",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof PopupProvider>",
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Popup/PopupContext.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "контекст попапа",
        "SSR всплывающего окна",
        "provider для окна"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { PopupProvider } from '@daisforge/ui';",
      "minimalUsage": "<PopupProvider />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в PopupDF.stories.tsx",
          "type": "usage",
          "code": "<PopupProvider>\n        <div style={playgroundStyle}>{children}</div>\n      </PopupProvider>",
          "sourceFile": "packages/storybook/src/stories/PopupDF/PopupDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в PopupDF.stories.tsx",
          "type": "usage",
          "code": "<PopupProvider>\n        <StoryFrame>\n          {(frameRef) => (\n            <>\n              <Button onClick={() => setOpened(true)}>Открыть PopupDF</Button>\n              <PopupDF\n                opened={opened}\n                onToggle={setOpened}\n                frame={frameRef}\n                size=\"m\"\n                placement=\"center\"\n                style={{ width: '396px' }}\n              >\n                <PopupDF.Header\n                  title=\"Title\"\n                  description=\"Description\"\n                  rightBlock={<RightBlockSlot />}\n                />\n                <PopupDF.Body>\n                  <BodySlot />\n                </PopupDF.Body>\n                <PopupDF.Footer>\n                  <FooterActions />\n                </PopupDF.Footer>\n              </PopupDF>\n            </>\n          )}\n        </StoryFrame>\n      </PopupProvider>",
          "sourceFile": "packages/storybook/src/stories/PopupDF/PopupDF.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Перед использованием убедитесь, что  PopupProvider  подключен.",
          "type": "vendor",
          "code": "import ReactDOM from 'react-dom';\nimport { PopupProvider } from '@daisforge/ui';\nimport { App } from './App';\nReactDOM.render(\n    <PopupProvider>\n        <App />\n    </PopupProvider>,\n    document.getElementById('root')\n);"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Провайдер контекста",
          "type": "vendor",
          "code": "import ReactDOM from 'react-dom';\nimport { PopupProvider } from '@daisforge/ui';\nimport { App } from './App';\nReactDOM.render(\n    <PopupProvider>\n        <App />\n    </PopupProvider>,\n    document.getElementById('root')\n);"
        }
      ]
    },
    "Popup": {
      "name": "Popup",
      "group": "components",
      "folderName": "Popup",
      "role": "primary",
      "description": "Базовое всплывающее окно с оверлеем, перетаскиванием и изменением размера",
      "props": [],
      "propsTypeName": "PopupProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Popup/Popup.d.ts",
      "type": "wrapper",
      "atomicBase": "Popup",
      "category": "Локальные компоненты",
      "keywords": [
        "модальное окно",
        "draggable окно",
        "окно с оверлеем"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "draggable",
          "type": "boolean",
          "required": false,
          "description": "Настройка draggable-режима.",
          "inheritedFrom": "Popup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "frame",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "В каком контейнере позиционируется (по умолчанию document), можно также указать id элемента или ref для него.",
          "inheritedFrom": "Popup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number] | [string, string]",
          "required": false,
          "description": "Смещение относительно текущей позиции.\n(x, y) - [number, number], [string, string].\nПри передаче number расчёт в rem.",
          "inheritedFrom": "Popup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": false,
          "description": "Отображение Popup.",
          "inheritedFrom": "Popup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "overlay",
          "type": "ReactNode",
          "required": false,
          "description": "Соседний элемент для окна в портале.",
          "inheritedFrom": "Popup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "PopupPlacement",
          "required": false,
          "description": "Позиция на экране\ncenter - по умолчанию\nleft, right, top, bottom и их комбинации",
          "inheritedFrom": "Popup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "popupInfo",
          "type": "PopupInfo",
          "required": false,
          "description": "Дополнительная информация для программного взаимодействия с окном через контекст.",
          "inheritedFrom": "Popup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "positionFixed",
          "type": "boolean",
          "required": false,
          "description": "Если `frame` отличается от `document` применяет `position='fixed'`",
          "default": "false",
          "inheritedFrom": "Popup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "resizable",
          "type": "boolean | { disabled?: boolean; directions?: ResizeDirections; defaultSize?: { width?: number | undefined; height?: number | undefined; } | undefined; ... 8 more ...; onResizeEnd?: ((resizableContainer?: RefObject<...> | undefined) => void) | undefined; } | undefined",
          "required": false,
          "description": "Настройка resizable-режима.",
          "inheritedFrom": "Popup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withAnimation",
          "type": "boolean",
          "required": false,
          "description": "Использовать ли анимацию.",
          "inheritedFrom": "Popup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "string",
          "required": false,
          "description": "Значение z-index для Popup.",
          "inheritedFrom": "Popup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "children",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Popup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Popup",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Popup } from '@daisforge/ui';",
      "minimalUsage": "<Popup />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Провайдер контекста",
          "type": "vendor",
          "code": "import ReactDOM from 'react-dom';\nimport { PopupProvider } from '@daisforge/ui';\nimport { App } from './App';\nReactDOM.render(\n    <PopupProvider>\n        <App />\n    </PopupProvider>,\n    document.getElementById('root')\n);"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Подключение анимации",
          "type": "vendor",
          "code": "const StyledPopupTransition = styled(Popup)`\n    && > .${PopupClasses.root} {\n        opacity: 1;\n        transition: opacity 0.5s 0.1s;\n    }\n    &&.${PopupClasses.endTransition} > .${PopupClasses.root} {\n        opacity: 0;\n        transition: opacity 0.5s 0.1s;\n    }\n`;"
        }
      ]
    },
    "PopupDFBody": {
      "name": "PopupDFBody",
      "group": "components",
      "folderName": "PopupDF",
      "role": "part",
      "description": "Область содержимого всплывающего окна PopupDF с настройкой размеров и отступов",
      "props": [
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные стили styled-components для Box-контейнера"
        },
        {
          "name": "as",
          "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"center\" | \"s\" | \"article\" | \"button\" | \"dialog\" | \"figure\" | \"form\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"search\" | \"switch\" | \"table\" | \"text\" | \"time\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"big\" | \"blockquote\" | \"body\" | \"br\" | \"canvas\" | \"caption\" | \"cite\" | …",
          "required": false,
          "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
        },
        {
          "name": "background",
          "type": "Property.Background<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "backgroundColor",
          "type": "Property.BackgroundColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "border",
          "type": "Property.Border<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderColor",
          "type": "Property.BorderColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderRadius",
          "type": "Property.BorderRadius<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
        },
        {
          "name": "borderStyle",
          "type": "Property.BorderStyle | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderWidth",
          "type": "Property.BorderWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "bottom",
          "type": "Property.Bottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "boxSizing",
          "type": "Property.BoxSizing | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
        },
        {
          "name": "cursor",
          "type": "Property.Cursor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
        },
        {
          "name": "display",
          "type": "Property.Display | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "flexDirection",
          "type": "Property.FlexDirection | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
        },
        {
          "name": "flexGrow",
          "type": "Property.FlexGrow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
        },
        {
          "name": "flexShrink",
          "type": "Property.FlexShrink | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
        },
        {
          "name": "flexWrap",
          "type": "Property.FlexWrap | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "gap",
          "type": "Property.Gap<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
        },
        {
          "name": "height",
          "type": "Property.Height<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "justifyContent",
          "type": "Property.JustifyContent | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "justifyItems",
          "type": "Property.JustifyItems | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
        },
        {
          "name": "justifySelf",
          "type": "Property.JustifySelf | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
        },
        {
          "name": "left",
          "type": "Property.Left<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "margin",
          "type": "Property.Margin<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginBottom",
          "type": "Property.MarginBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginLeft",
          "type": "Property.MarginLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginRight",
          "type": "Property.MarginRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginTop",
          "type": "Property.MarginTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "maxHeight",
          "type": "Property.MaxHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "maxWidth",
          "type": "Property.MaxWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "minHeight",
          "type": "Property.MinHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "minWidth",
          "type": "Property.MinWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "opacity",
          "type": "Property.Opacity | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
        },
        {
          "name": "overflow",
          "type": "Property.Overflow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "padding",
          "type": "Property.Padding<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingBottom",
          "type": "Property.PaddingBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingLeft",
          "type": "Property.PaddingLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingRight",
          "type": "Property.PaddingRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingTop",
          "type": "Property.PaddingTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "position",
          "type": "Property.Position | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "right",
          "type": "Property.Right<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "top",
          "type": "Property.Top<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "width",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        }
      ],
      "propsTypeName": "PopupDFBodyProps",
      "sourceFile": "packages/ui-kit/src/components/PopupDF/components/Body.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "тело попапа",
        "содержимое всплывающего окна",
        "popup content"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "PopupDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "PopupDF",
        "part": "Body"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { PopupDFBody } from '@daisforge/ui';",
      "minimalUsage": "<PopupDFBody />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в PopupDF.stories.tsx",
          "type": "usage",
          "code": "<PopupDF.Body>\n                <BodySlot />\n              </PopupDF.Body>",
          "sourceFile": "packages/storybook/src/stories/PopupDF/PopupDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в PopupDF.stories.tsx",
          "type": "usage",
          "code": "<PopupDF.Body>\n                  <BodySlot />\n                </PopupDF.Body>",
          "sourceFile": "packages/storybook/src/stories/PopupDF/PopupDF.stories.tsx"
        }
      ]
    },
    "PopupDFFooter": {
      "name": "PopupDFFooter",
      "group": "components",
      "folderName": "PopupDF",
      "role": "part",
      "description": "Нижний блок всплывающего окна PopupDF для кнопок и действий",
      "props": [
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные стили styled-components для Box-контейнера"
        },
        {
          "name": "as",
          "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"center\" | \"s\" | \"article\" | \"button\" | \"dialog\" | \"figure\" | \"form\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"search\" | \"switch\" | \"table\" | \"text\" | \"time\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"big\" | \"blockquote\" | \"body\" | \"br\" | \"canvas\" | \"caption\" | \"cite\" | …",
          "required": false,
          "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
        },
        {
          "name": "background",
          "type": "Property.Background<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "backgroundColor",
          "type": "Property.BackgroundColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "border",
          "type": "Property.Border<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderColor",
          "type": "Property.BorderColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderRadius",
          "type": "Property.BorderRadius<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
        },
        {
          "name": "borderStyle",
          "type": "Property.BorderStyle | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderWidth",
          "type": "Property.BorderWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "bottom",
          "type": "Property.Bottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "boxSizing",
          "type": "Property.BoxSizing | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
        },
        {
          "name": "cursor",
          "type": "Property.Cursor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
        },
        {
          "name": "display",
          "type": "Property.Display | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "flexDirection",
          "type": "Property.FlexDirection | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
        },
        {
          "name": "flexGrow",
          "type": "Property.FlexGrow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
        },
        {
          "name": "flexShrink",
          "type": "Property.FlexShrink | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
        },
        {
          "name": "flexWrap",
          "type": "Property.FlexWrap | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "gap",
          "type": "Property.Gap<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
        },
        {
          "name": "height",
          "type": "Property.Height<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "justifyContent",
          "type": "Property.JustifyContent | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "justifyItems",
          "type": "Property.JustifyItems | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
        },
        {
          "name": "justifySelf",
          "type": "Property.JustifySelf | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
        },
        {
          "name": "left",
          "type": "Property.Left<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "margin",
          "type": "Property.Margin<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginBottom",
          "type": "Property.MarginBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginLeft",
          "type": "Property.MarginLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginRight",
          "type": "Property.MarginRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginTop",
          "type": "Property.MarginTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "maxHeight",
          "type": "Property.MaxHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "maxWidth",
          "type": "Property.MaxWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "minHeight",
          "type": "Property.MinHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "minWidth",
          "type": "Property.MinWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "opacity",
          "type": "Property.Opacity | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
        },
        {
          "name": "overflow",
          "type": "Property.Overflow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "padding",
          "type": "Property.Padding<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingBottom",
          "type": "Property.PaddingBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingLeft",
          "type": "Property.PaddingLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingRight",
          "type": "Property.PaddingRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingTop",
          "type": "Property.PaddingTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "position",
          "type": "Property.Position | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "right",
          "type": "Property.Right<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "top",
          "type": "Property.Top<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "width",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        }
      ],
      "propsTypeName": "PopupDFFooterProps",
      "sourceFile": "packages/ui-kit/src/components/PopupDF/components/Footer.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "футер попапа",
        "кнопки в попапе",
        "popup footer"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "PopupDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "PopupDF",
        "part": "Footer"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { PopupDFFooter } from '@daisforge/ui';",
      "minimalUsage": "<PopupDFFooter />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в PopupDF.stories.tsx",
          "type": "usage",
          "code": "<PopupDF.Footer>\n                  <FooterActions />\n                </PopupDF.Footer>",
          "sourceFile": "packages/storybook/src/stories/PopupDF/PopupDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в PopupDF.stories.tsx",
          "type": "usage",
          "code": "<PopupDF.Footer>\n                <FooterActions size=\"l\" />\n              </PopupDF.Footer>",
          "sourceFile": "packages/storybook/src/stories/PopupDF/PopupDF.stories.tsx"
        }
      ]
    },
    "PopupDFHeader": {
      "name": "PopupDFHeader",
      "group": "components",
      "folderName": "PopupDF",
      "role": "part",
      "description": "Шапка PopupDF: заголовок, описание, кнопка назад, доп. блок и кнопка закрытия",
      "props": [
        {
          "name": "description",
          "type": "React.ReactNode",
          "required": false,
          "description": "Текст под заголовком в верхней левой части header."
        },
        {
          "name": "onBackButtonClick",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Callback при клике на кнопку со стрелкой назад слева от заголовка."
        },
        {
          "name": "onClose",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Кастомный обработчик закрытия.\nЕсли не передан, будет использован обработчик закрытия из `PopupDF`."
        },
        {
          "name": "rightBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": "Кастомный слот в правой части header, слева от крестика закрытия.\nПрижимается к крестику; если контент широкий — «давит» на title/description\n(уходят в многоточие с тултипом). Максимальная высота — как у крестика\n(32px при `size='l'` и `size='m'`, 24px при `size='s'`), ширина не\nограничена."
        },
        {
          "name": "showCloseButton",
          "type": "boolean | undefined",
          "required": false,
          "description": "Показывать ли крестик закрытия в правой верхней части header.",
          "default": "true"
        },
        {
          "name": "subHeader",
          "type": "React.ReactNode",
          "required": false,
          "description": "Кастомный контент, относящийся по смыслу к header."
        },
        {
          "name": "title",
          "type": "React.ReactNode",
          "required": false,
          "description": "Заголовок в верхней левой части header."
        }
      ],
      "propsTypeName": "PopupDFHeaderProps",
      "sourceFile": "packages/ui-kit/src/components/PopupDF/components/Header.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "шапка попапа",
        "заголовок с кнопкой назад",
        "popup header"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "PopupDF",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "PopupDF",
        "part": "Header"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { PopupDFHeader } from '@daisforge/ui';",
      "minimalUsage": "<PopupDFHeader />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в PopupDF.stories.tsx",
          "type": "usage",
          "code": "<PopupDF.Header\n              title=\"Title\"\n              description=\"Description\"\n              subHeader={withSubHeader ? <HeaderSlot /> : undefined}\n              rightBlock={\n                withRightBlock ? <RightBlockSlot size={size} /> : undefined\n              }\n              showCloseButton={showCloseButton}\n              onBackButtonClick={showBackButton ? () => {} : undefined}\n            />",
          "sourceFile": "packages/storybook/src/stories/PopupDF/PopupDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в PopupDF.stories.tsx",
          "type": "usage",
          "code": "<PopupDF.Header\n                title=\"Заголовок PopupDF размера L\"\n                description=\"Body S. Двигай за шапку, тяни за угол, разворачивай кнопкой.\"\n                subHeader={\n                  <div style={sizeLSubHeaderStyle}>\n                    <IconInfoCircleOutline size=\"xs\" />\n                    <span>Кастомный слот</span>\n                  </div>\n                }\n                rightBlock={\n                  <IconButton\n                    size=\"xs\"\n                    view=\"secondary\"\n                    pin=\"circle-circle\"\n                    title={fullscreen ? 'Свернуть' : 'Развернуть'}\n                    onClick={() => (fullscreen ? collapse() : expand())}\n                  >\n                    <IconFullS size=\"xs\" />\n                  </IconButton>\n                }\n              />",
          "sourceFile": "packages/storybook/src/stories/PopupDF/PopupDF.stories.tsx"
        }
      ]
    },
    "PopupDF": {
      "name": "PopupDF",
      "group": "components",
      "folderName": "PopupDF",
      "role": "primary",
      "description": "Popup с готовыми Header/Body/Footer, управлением открытием и ресайзом",
      "props": [
        {
          "name": "defaultOpened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Начальное состояние открытия в uncontrolled-режиме.",
          "default": "false"
        },
        {
          "name": "onToggle",
          "type": "((opened: boolean) => void) | undefined",
          "required": false,
          "description": "Коллбэк смены состояния открытия."
        },
        {
          "name": "size",
          "type": "PopupDFSize | undefined",
          "required": false,
          "description": "Размер PopupDF.\nВлияет на внутренние отступы и типографику header.",
          "default": "'m'"
        },
        {
          "name": "draggable",
          "type": "boolean | undefined",
          "required": false,
          "description": "Настройка draggable-режима."
        },
        {
          "name": "frame",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "В каком контейнере позиционируется (по умолчанию document), можно также указать id элемента или ref для него."
        },
        {
          "name": "offset",
          "type": "[number, number] | [string, string] | undefined",
          "required": false,
          "description": "Смещение относительно текущей позиции.\n(x, y) - [number, number], [string, string].\nПри передаче number расчёт в rem."
        },
        {
          "name": "opened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отображение Popup."
        },
        {
          "name": "overlay",
          "type": "React.ReactNode",
          "required": false,
          "description": "Соседний элемент для окна в портале."
        },
        {
          "name": "placement",
          "type": "PopupPlacement | undefined",
          "required": false,
          "description": "Позиция на экране\ncenter - по умолчанию\nleft, right, top, bottom и их комбинации"
        },
        {
          "name": "popupInfo",
          "type": "PopupInfo | undefined",
          "required": false,
          "description": "Дополнительная информация для программного взаимодействия с окном через контекст."
        },
        {
          "name": "positionFixed",
          "type": "boolean | undefined",
          "required": false,
          "description": "Если `frame` отличается от `document` применяет `position='fixed'`",
          "default": "false"
        },
        {
          "name": "resizable",
          "type": "boolean | { disabled?: boolean | undefined; directions?: ResizeDirections | undefined; defaultSize?: { width?: number | undefined; height?: number | undefined; } | undefined; minWidth?: number | undefined; minHeight?: number | undefined; maxWidth?: number | undefined; maxHeight?: number | undefined; icons?: { topRight?: React.ReactNode; bottomRight?: React.ReactNode; bottomLeft?: React.ReactNode; …",
          "required": false,
          "description": "Настройка resizable-режима."
        },
        {
          "name": "withAnimation",
          "type": "boolean | undefined",
          "required": false,
          "description": "Использовать ли анимацию."
        },
        {
          "name": "zIndex",
          "type": "string | undefined",
          "required": false,
          "description": "Значение z-index для Popup."
        }
      ],
      "propsTypeName": "PopupDFProps",
      "compoundParts": [
        {
          "name": "Header",
          "typeName": "PopupDFHeaderProps",
          "props": [
            {
              "name": "description",
              "type": "React.ReactNode",
              "required": false,
              "description": "Текст под заголовком в верхней левой части header."
            },
            {
              "name": "onBackButtonClick",
              "type": "(() => void) | undefined",
              "required": false,
              "description": "Callback при клике на кнопку со стрелкой назад слева от заголовка."
            },
            {
              "name": "onClose",
              "type": "(() => void) | undefined",
              "required": false,
              "description": "Кастомный обработчик закрытия.\nЕсли не передан, будет использован обработчик закрытия из `PopupDF`."
            },
            {
              "name": "rightBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": "Кастомный слот в правой части header, слева от крестика закрытия.\nПрижимается к крестику; если контент широкий — «давит» на title/description\n(уходят в многоточие с тултипом). Максимальная высота — как у крестика\n(32px при `size='l'` и `size='m'`, 24px при `size='s'`), ширина не\nограничена."
            },
            {
              "name": "showCloseButton",
              "type": "boolean | undefined",
              "required": false,
              "description": "Показывать ли крестик закрытия в правой верхней части header.",
              "default": "true"
            },
            {
              "name": "subHeader",
              "type": "React.ReactNode",
              "required": false,
              "description": "Кастомный контент, относящийся по смыслу к header."
            },
            {
              "name": "title",
              "type": "React.ReactNode",
              "required": false,
              "description": "Заголовок в верхней левой части header."
            }
          ]
        },
        {
          "name": "Body",
          "typeName": "PopupDFBodyProps",
          "props": [
            {
              "name": "$css",
              "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
              "required": false,
              "description": "Кастомные стили styled-components для Box-контейнера"
            },
            {
              "name": "as",
              "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"center\" | \"s\" | \"article\" | \"button\" | \"dialog\" | \"figure\" | \"form\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"search\" | \"switch\" | \"table\" | \"text\" | \"time\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"big\" | \"blockquote\" | \"body\" | \"br\" | \"canvas\" | \"caption\" | \"cite\" | …",
              "required": false,
              "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
            },
            {
              "name": "background",
              "type": "Property.Background<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "backgroundColor",
              "type": "Property.BackgroundColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "border",
              "type": "Property.Border<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderColor",
              "type": "Property.BorderColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderRadius",
              "type": "Property.BorderRadius<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
            },
            {
              "name": "borderStyle",
              "type": "Property.BorderStyle | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderWidth",
              "type": "Property.BorderWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "bottom",
              "type": "Property.Bottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "boxSizing",
              "type": "Property.BoxSizing | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
            },
            {
              "name": "cursor",
              "type": "Property.Cursor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
            },
            {
              "name": "display",
              "type": "Property.Display | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "flexDirection",
              "type": "Property.FlexDirection | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
            },
            {
              "name": "flexGrow",
              "type": "Property.FlexGrow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
            },
            {
              "name": "flexShrink",
              "type": "Property.FlexShrink | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
            },
            {
              "name": "flexWrap",
              "type": "Property.FlexWrap | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "gap",
              "type": "Property.Gap<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
            },
            {
              "name": "height",
              "type": "Property.Height<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "justifyContent",
              "type": "Property.JustifyContent | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "justifyItems",
              "type": "Property.JustifyItems | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
            },
            {
              "name": "justifySelf",
              "type": "Property.JustifySelf | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
            },
            {
              "name": "left",
              "type": "Property.Left<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "margin",
              "type": "Property.Margin<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginBottom",
              "type": "Property.MarginBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginLeft",
              "type": "Property.MarginLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginRight",
              "type": "Property.MarginRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginTop",
              "type": "Property.MarginTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "maxHeight",
              "type": "Property.MaxHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "maxWidth",
              "type": "Property.MaxWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "minHeight",
              "type": "Property.MinHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "minWidth",
              "type": "Property.MinWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "opacity",
              "type": "Property.Opacity | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
            },
            {
              "name": "overflow",
              "type": "Property.Overflow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "padding",
              "type": "Property.Padding<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingBottom",
              "type": "Property.PaddingBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingLeft",
              "type": "Property.PaddingLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingRight",
              "type": "Property.PaddingRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingTop",
              "type": "Property.PaddingTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "position",
              "type": "Property.Position | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "right",
              "type": "Property.Right<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "top",
              "type": "Property.Top<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "width",
              "type": "Property.Width<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "zIndex",
              "type": "Property.ZIndex | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            }
          ]
        },
        {
          "name": "Footer",
          "typeName": "PopupDFFooterProps",
          "props": [
            {
              "name": "$css",
              "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
              "required": false,
              "description": "Кастомные стили styled-components для Box-контейнера"
            },
            {
              "name": "as",
              "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"center\" | \"s\" | \"article\" | \"button\" | \"dialog\" | \"figure\" | \"form\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"search\" | \"switch\" | \"table\" | \"text\" | \"time\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"big\" | \"blockquote\" | \"body\" | \"br\" | \"canvas\" | \"caption\" | \"cite\" | …",
              "required": false,
              "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
            },
            {
              "name": "background",
              "type": "Property.Background<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "backgroundColor",
              "type": "Property.BackgroundColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "border",
              "type": "Property.Border<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderColor",
              "type": "Property.BorderColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderRadius",
              "type": "Property.BorderRadius<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
            },
            {
              "name": "borderStyle",
              "type": "Property.BorderStyle | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderWidth",
              "type": "Property.BorderWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "bottom",
              "type": "Property.Bottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "boxSizing",
              "type": "Property.BoxSizing | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
            },
            {
              "name": "cursor",
              "type": "Property.Cursor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
            },
            {
              "name": "display",
              "type": "Property.Display | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "flexDirection",
              "type": "Property.FlexDirection | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
            },
            {
              "name": "flexGrow",
              "type": "Property.FlexGrow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
            },
            {
              "name": "flexShrink",
              "type": "Property.FlexShrink | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
            },
            {
              "name": "flexWrap",
              "type": "Property.FlexWrap | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "gap",
              "type": "Property.Gap<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
            },
            {
              "name": "height",
              "type": "Property.Height<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "justifyContent",
              "type": "Property.JustifyContent | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "justifyItems",
              "type": "Property.JustifyItems | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
            },
            {
              "name": "justifySelf",
              "type": "Property.JustifySelf | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
            },
            {
              "name": "left",
              "type": "Property.Left<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "margin",
              "type": "Property.Margin<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginBottom",
              "type": "Property.MarginBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginLeft",
              "type": "Property.MarginLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginRight",
              "type": "Property.MarginRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginTop",
              "type": "Property.MarginTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "maxHeight",
              "type": "Property.MaxHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "maxWidth",
              "type": "Property.MaxWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "minHeight",
              "type": "Property.MinHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "minWidth",
              "type": "Property.MinWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "opacity",
              "type": "Property.Opacity | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
            },
            {
              "name": "overflow",
              "type": "Property.Overflow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "padding",
              "type": "Property.Padding<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingBottom",
              "type": "Property.PaddingBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingLeft",
              "type": "Property.PaddingLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingRight",
              "type": "Property.PaddingRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingTop",
              "type": "Property.PaddingTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "position",
              "type": "Property.Position | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "right",
              "type": "Property.Right<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "top",
              "type": "Property.Top<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "width",
              "type": "Property.Width<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "zIndex",
              "type": "Property.ZIndex | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            }
          ]
        }
      ],
      "sourceFile": "packages/ui-kit/src/components/PopupDF/PopupDF.tsx",
      "type": "wrapper",
      "category": "Локальные компоненты",
      "keywords": [
        "составной popup",
        "модальное окно с шапкой",
        "compound popup"
      ],
      "docs": "# PopupDF\n\n`PopupDF` — локальная DF-обёртка над [Popup](https://plasma.sberdevices.ru/sdds-finai/components/popup/).\n\n## Ключевые особенности\n\n- крестик закрытия живёт в `PopupDF.Header`\n- доступны `PopupDF.Header`, `PopupDF.Body`, `PopupDF.Footer`\n- доступны размеры `size=\"m\" | \"s\"`\n- `title` и `description` ограничены двумя строками\n- в `Header` доступна кнопка назад через `onBackButtonClick`\n- иконка ресайза использует DF-иконку по умолчанию, учитывает `resizable.iconSize` и может быть переопределена через `resizable.icons`\n\n## Compound-компоненты\n\n```ts\nPopupDF.Header; // Шапка\nPopupDF.Body; // Контент\nPopupDF.Footer; // Футер\n```\n\n## Особенности\n\n- `Header` и `Footer` остаются опциональными и подключаются через композицию\n- `subHeader` подходит для кастомного контента, смыслово связанного с шапкой\n- если контента много, скролл должен жить внутри `PopupDF.Body`\n- по умолчанию угол иконки ресайза вычисляется из `placement` так, чтобы ресайз тянул popup внутрь доступной области\n- для ручной смены угла ресайза используйте нативный `resizable.directions`, например `directions: ['top-left']`\n- если `hiddenIcons` не передан, `PopupDF` автоматически скрывает угловые иконки, которые не входят в `directions`; для нестандартной видимости передайте `hiddenIcons` явно\n- если пользовательские `icons` не переданы, `PopupDF` заполняет угловые иконки своей `IconResizeCorneredFill`; `iconSize` влияет на DF-иконку по умолчанию\n\nОписание типов и compound-пропсов — в разделе [API](?path=/docs/локальные-компоненты-popupdf-api--docs).",
      "apiDocs": "# PopupDF API\n\n## PopupDFProps\n\n```typescript\ntype PopupDFProps = Omit<\n  ComponentProps<typeof Popup>,\n  'children' | 'isOpen'\n> & {\n  /**\n   * Содержимое popup.\n   * Обычно используется композиция из `PopupDF.Header`, `PopupDF.Body` и `PopupDF.Footer`.\n   */\n  children?: ReactNode;\n  /**\n   * Начальное состояние открытия в uncontrolled-режиме.\n   * @default false\n   */\n  defaultOpened?: boolean;\n  /**\n   * Коллбэк смены состояния открытия.\n   */\n  onToggle?: (opened: boolean) => void;\n  /**\n   * Размер PopupDF.\n   * Влияет на внутренние отступы и типографику header.\n   * @default 'm'\n   */\n  size?: PopupDFSize;\n};\n```\n\n> `PopupDF` наследует базовые пропсы `Popup` из `sdds-finai`, но добавляет compound-структуру,\n`size`, `defaultOpened`, `onToggle` и DF-иконки для базовой настройки `resizable`.\n\n## PopupDFSize\n\n```typescript\ntype PopupDFSize = 's' | 'm' | 'l';\n```\n\n> Размер попапа. Влияет на типографику шапки и внутренние отступы: `l` — крупный\nзаголовок (H4) с описанием (BodyS), `m` — средний, `s` — компактный.\n\n## PopupDFHeaderProps\n\n```typescript\ntype PopupDFHeaderProps = Omit<BoxProps, 'children'> & {\n  /**\n   * Заголовок в верхней левой части header.\n   */\n  title?: ReactNode;\n  /**\n   * Текст под заголовком в верхней левой части header.\n   */\n  description?: ReactNode;\n  /**\n   * Кастомный контент, относящийся по смыслу к header.\n   */\n  subHeader?: ReactNode;\n  /**\n   * Кастомный слот в правой части header, слева от крестика закрытия.\n   * Прижимается к крестику; если контент широкий — «давит» на title/description\n   * (уходят в многоточие с тултипом). Максимальная высота — как у крестика\n   * (32px при `size='l'` и `size='m'`, 24px при `size='s'`), ширина не\n   * ограничена.\n   */\n  rightBlock?: ReactNode;\n  /**\n   * Показывать ли крестик закрытия в правой верхней части header.\n   * @default true\n   */\n  showCloseButton?: boolean;\n  /**\n   * Callback при клике на кнопку со стрелкой назад слева от заголовка.\n   */\n  onBackButtonClick?: () => void;\n  /**\n   * Кастомный обработчик закрытия.\n   * Если не передан, будет использован обработчик закрытия из `PopupDF`.\n   */\n  onClose?: () => void;\n};\n```\n\n## PopupDFBodyProps\n\n```typescript\ntype PopupDFBodyProps = BoxProps;\n```\n\n## PopupDFFooterProps\n\n```typescript\ntype PopupDFFooterProps = BoxProps & {\n  children?: ReactNode;\n};\n```\n\n## PopupDFResizableConfig\n\n```typescript\ntype PopupDFResizableConfig = Exclude<\n  ComponentProps<typeof Popup>['resizable'],\n  boolean | undefined\n>;\n```",
      "curatedStories": [
        {
          "exportName": "Simple",
          "displayName": "Simple",
          "type": "full-code",
          "code": "import { useState } from 'react';\nimport {\n  Button,\n  Flow,\n  LinkButton,\n  PopupDF,\n  PopupProvider,\n  SSRProvider,\n} from '@daisforge/ui';\n\n// Контент футера — обычные кнопки, которые вы кладёте в PopupDF.Footer\nfunction FooterActions() {\n  return (\n    <Flow mainAxisGap={8}>\n      <LinkButton href=\"/\" size=\"xs\">\n        LinkButton\n      </LinkButton>\n      <Button size=\"xs\" view=\"secondary\">\n        Отмена\n      </Button>\n      <Button size=\"xs\" view=\"accent\">\n        Применить\n      </Button>\n    </Flow>\n  );\n}\nfunction Example() {\n  const [opened, setOpened] = useState(false);\n\n  // SSRProvider и PopupProvider обычно уже подключены на уровне приложения\n  return (\n    <SSRProvider>\n      <PopupProvider>\n        <Button onClick={() => setOpened(true)}>Открыть PopupDF</Button>\n        <PopupDF\n          opened={opened}\n          onToggle={setOpened}\n          size=\"m\"\n          placement=\"center\"\n          style={{ width: '396px' }}\n        >\n          <PopupDF.Header\n            title=\"Title\"\n            description=\"Description\"\n            rightBlock={\n              <div style={{ display: 'flex', alignItems: 'center' }}>\n                {/* кастомный контент слева от крестика, ширина не ограничена */}\n              </div>\n            }\n          />\n          <PopupDF.Body>Контент попапа</PopupDF.Body>\n          <PopupDF.Footer>\n            <FooterActions />\n          </PopupDF.Footer>\n        </PopupDF>\n      </PopupProvider>\n    </SSRProvider>\n  );\n}"
        },
        {
          "exportName": "Playground",
          "displayName": "Playground",
          "type": "full-code",
          "code": "import { useState } from 'react';\nimport {\n  Button,\n  Flow,\n  LinkButton,\n  PopupDF,\n  PopupProvider,\n  SSRProvider,\n} from '@daisforge/ui';\n\n// Контент футера — обычные кнопки, которые вы кладёте в PopupDF.Footer\nfunction FooterActions() {\n  return (\n    <Flow mainAxisGap={8}>\n      <LinkButton href=\"/\" size=\"xs\">\n        LinkButton\n      </LinkButton>\n      <Button size=\"xs\" view=\"secondary\">\n        Отмена\n      </Button>\n      <Button size=\"xs\" view=\"accent\">\n        Применить\n      </Button>\n    </Flow>\n  );\n}\nfunction Example() {\n  const [opened, setOpened] = useState(true);\n\n  return (\n    <SSRProvider>\n      <PopupProvider>\n        <Button onClick={() => setOpened(true)}>Открыть PopupDF</Button>\n        <PopupDF\n          opened={opened}\n          onToggle={setOpened}\n          size=\"m\"\n          placement=\"center\"\n          offset={[0, 0]}\n          draggable\n          resizable={{ minWidth: 240, minHeight: 120, iconSize: 's' }}\n          style={{ width: '396px' }}\n        >\n          <PopupDF.Header\n            title=\"Title\"\n            description=\"Description\"\n            rightBlock={\n              <div style={{ display: 'flex', alignItems: 'center' }}>\n                {/* кастомный контент слева от крестика, ширина не ограничена */}\n              </div>\n            }\n            showCloseButton\n          />\n          <PopupDF.Body>Контент попапа</PopupDF.Body>\n          <PopupDF.Footer>\n            <FooterActions />\n          </PopupDF.Footer>\n        </PopupDF>\n      </PopupProvider>\n    </SSRProvider>\n  );\n}"
        },
        {
          "exportName": "SizeL",
          "displayName": "Size L",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport {\n  Button,\n  IconButton,\n  LinkButton,\n  PopupDF,\n  PopupProvider,\n  SSRProvider,\n} from '@daisforge/ui';\nimport { IconFullscreenOff, IconFullscreenOn } from '@daisforge/ui/icons';\n\n// Разворот на весь экран собираем сами из пропсов PopupDF:\n// сначала выключаем resizable и draggable, чтобы попап вернулся к обычному\n// размеру, затем следующим тиком плавно растим его до краёв frame.\nfunction Example() {\n  const frameRef = useRef(null);\n  const [opened, setOpened] = useState(true);\n  const [fullscreen, setFullscreen] = useState(false);\n  const [interactive, setInteractive] = useState(true);\n\n  const expand = () => {\n    setInteractive(false);\n    window.setTimeout(() => setFullscreen(true), 30);\n  };\n\n  const collapse = () => {\n    setFullscreen(false);\n    window.setTimeout(() => setInteractive(true), 320);\n  };\n\n  const IconFullS = fullscreen ? IconFullscreenOff : IconFullscreenOn;\n\n  const sizeStyle = {\n    width: fullscreen ? 'calc(100% - 48px)' : '600px',\n    height: fullscreen ? 'calc(100% - 48px)' : '600px',\n    maxWidth: '100%',\n    maxHeight: '100%',\n    transition: 'width 280ms ease, height 280ms ease',\n    // grid тянет карточку на всю заданную высоту, иначе внешний узел Popup\n    // сжимается по контенту и height не применяется (600 даёт только ширину).\n    display: 'grid',\n    gridTemplateRows: '1fr',\n    gridTemplateColumns: '1fr',\n  };\n\n  return (\n    <SSRProvider>\n      <PopupProvider>\n        {/* frame — контейнер, внутри которого живёт и разворачивается попап */}\n        <div ref={frameRef} style={{ position: 'relative', minHeight: 720 }}>\n          <PopupDF\n            opened={opened}\n            onToggle={setOpened}\n            frame={frameRef}\n            size=\"l\"\n            placement=\"center\"\n            draggable={interactive}\n            resizable={\n              interactive\n                ? {\n                    // стартовый размер контейнера при включённом resizable\n                    defaultSize: { width: 600, height: 600 },\n                    minWidth: 320,\n                    minHeight: 220,\n                    iconSize: 's',\n                  }\n                : false\n            }\n            style={sizeStyle}\n          >\n            <PopupDF.Header\n              title=\"Заголовок PopupDF размера L\"\n              description=\"Body S. Двигай за шапку, тяни за угол, разворачивай кнопкой.\"\n              subHeader={\n                <div style={{ height: 40, display: 'flex', alignItems: 'center' }}>\n                  Кастомный слот\n                </div>\n              }\n              rightBlock={\n                <IconButton\n                  size=\"xs\"\n                  view=\"secondary\"\n                  pin=\"circle-circle\"\n                  title={fullscreen ? 'Свернуть' : 'Развернуть'}\n                  onClick={() => (fullscreen ? collapse() : expand())}\n                >\n                  <IconFullS size=\"xs\" />\n                </IconButton>\n              }\n            />\n            {/* высота 100%, чтобы контент тела рос при ресайзе попапа */}\n            <PopupDF.Body>\n              <div style={{ height: '100%' }}>Контент попапа</div>\n            </PopupDF.Body>\n            <PopupDF.Footer>\n              {/* LinkButton отделён от группы кнопок отступом 16px (L) */}\n              <div\n                style={{\n                  display: 'flex',\n                  justifyContent: 'flex-end',\n                  alignItems: 'center',\n                  gap: 16,\n                }}\n              >\n                <LinkButton href=\"/\" size=\"s\">\n                  LinkButton\n                </LinkButton>\n                <div style={{ display: 'flex', gap: 4 }}>\n                  <Button size=\"s\" view=\"secondary\">\n                    Отмена\n                  </Button>\n                  <Button size=\"s\" view=\"accent\">\n                    Применить\n                  </Button>\n                </div>\n              </div>\n            </PopupDF.Footer>\n          </PopupDF>\n        </div>\n      </PopupProvider>\n    </SSRProvider>\n  );\n}"
        }
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "PopupDFBody",
        "PopupDFFooter",
        "PopupDFHeader"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { PopupDF } from '@daisforge/ui';",
      "minimalUsage": "<PopupDF>\n  {/* части: PopupDF.Header, PopupDF.Body, PopupDF.Footer */}\n</PopupDF>",
      "examples": [
        {
          "exportName": "Simple",
          "displayName": "Simple",
          "type": "full-code",
          "code": "import { useState } from 'react';\nimport {\n  Button,\n  Flow,\n  LinkButton,\n  PopupDF,\n  PopupProvider,\n  SSRProvider,\n} from '@daisforge/ui';\n\n// Контент футера — обычные кнопки, которые вы кладёте в PopupDF.Footer\nfunction FooterActions() {\n  return (\n    <Flow mainAxisGap={8}>\n      <LinkButton href=\"/\" size=\"xs\">\n        LinkButton\n      </LinkButton>\n      <Button size=\"xs\" view=\"secondary\">\n        Отмена\n      </Button>\n      <Button size=\"xs\" view=\"accent\">\n        Применить\n      </Button>\n    </Flow>\n  );\n}\nfunction Example() {\n  const [opened, setOpened] = useState(false);\n\n  // SSRProvider и PopupProvider обычно уже подключены на уровне приложения\n  return (\n    <SSRProvider>\n      <PopupProvider>\n        <Button onClick={() => setOpened(true)}>Открыть PopupDF</Button>\n        <PopupDF\n          opened={opened}\n          onToggle={setOpened}\n          size=\"m\"\n          placement=\"center\"\n          style={{ width: '396px' }}\n        >\n          <PopupDF.Header\n            title=\"Title\"\n            description=\"Description\"\n            rightBlock={\n              <div style={{ display: 'flex', alignItems: 'center' }}>\n                {/* кастомный контент слева от крестика, ширина не ограничена */}\n              </div>\n            }\n          />\n          <PopupDF.Body>Контент попапа</PopupDF.Body>\n          <PopupDF.Footer>\n            <FooterActions />\n          </PopupDF.Footer>\n        </PopupDF>\n      </PopupProvider>\n    </SSRProvider>\n  );\n}"
        },
        {
          "exportName": "Playground",
          "displayName": "Playground",
          "type": "full-code",
          "code": "import { useState } from 'react';\nimport {\n  Button,\n  Flow,\n  LinkButton,\n  PopupDF,\n  PopupProvider,\n  SSRProvider,\n} from '@daisforge/ui';\n\n// Контент футера — обычные кнопки, которые вы кладёте в PopupDF.Footer\nfunction FooterActions() {\n  return (\n    <Flow mainAxisGap={8}>\n      <LinkButton href=\"/\" size=\"xs\">\n        LinkButton\n      </LinkButton>\n      <Button size=\"xs\" view=\"secondary\">\n        Отмена\n      </Button>\n      <Button size=\"xs\" view=\"accent\">\n        Применить\n      </Button>\n    </Flow>\n  );\n}\nfunction Example() {\n  const [opened, setOpened] = useState(true);\n\n  return (\n    <SSRProvider>\n      <PopupProvider>\n        <Button onClick={() => setOpened(true)}>Открыть PopupDF</Button>\n        <PopupDF\n          opened={opened}\n          onToggle={setOpened}\n          size=\"m\"\n          placement=\"center\"\n          offset={[0, 0]}\n          draggable\n          resizable={{ minWidth: 240, minHeight: 120, iconSize: 's' }}\n          style={{ width: '396px' }}\n        >\n          <PopupDF.Header\n            title=\"Title\"\n            description=\"Description\"\n            rightBlock={\n              <div style={{ display: 'flex', alignItems: 'center' }}>\n                {/* кастомный контент слева от крестика, ширина не ограничена */}\n              </div>\n            }\n            showCloseButton\n          />\n          <PopupDF.Body>Контент попапа</PopupDF.Body>\n          <PopupDF.Footer>\n            <FooterActions />\n          </PopupDF.Footer>\n        </PopupDF>\n      </PopupProvider>\n    </SSRProvider>\n  );\n}"
        },
        {
          "exportName": "SizeL",
          "displayName": "Size L",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport {\n  Button,\n  IconButton,\n  LinkButton,\n  PopupDF,\n  PopupProvider,\n  SSRProvider,\n} from '@daisforge/ui';\nimport { IconFullscreenOff, IconFullscreenOn } from '@daisforge/ui/icons';\n\n// Разворот на весь экран собираем сами из пропсов PopupDF:\n// сначала выключаем resizable и draggable, чтобы попап вернулся к обычному\n// размеру, затем следующим тиком плавно растим его до краёв frame.\nfunction Example() {\n  const frameRef = useRef(null);\n  const [opened, setOpened] = useState(true);\n  const [fullscreen, setFullscreen] = useState(false);\n  const [interactive, setInteractive] = useState(true);\n\n  const expand = () => {\n    setInteractive(false);\n    window.setTimeout(() => setFullscreen(true), 30);\n  };\n\n  const collapse = () => {\n    setFullscreen(false);\n    window.setTimeout(() => setInteractive(true), 320);\n  };\n\n  const IconFullS = fullscreen ? IconFullscreenOff : IconFullscreenOn;\n\n  const sizeStyle = {\n    width: fullscreen ? 'calc(100% - 48px)' : '600px',\n    height: fullscreen ? 'calc(100% - 48px)' : '600px',\n    maxWidth: '100%',\n    maxHeight: '100%',\n    transition: 'width 280ms ease, height 280ms ease',\n    // grid тянет карточку на всю заданную высоту, иначе внешний узел Popup\n    // сжимается по контенту и height не применяется (600 даёт только ширину).\n    display: 'grid',\n    gridTemplateRows: '1fr',\n    gridTemplateColumns: '1fr',\n  };\n\n  return (\n    <SSRProvider>\n      <PopupProvider>\n        {/* frame — контейнер, внутри которого живёт и разворачивается попап */}\n        <div ref={frameRef} style={{ position: 'relative', minHeight: 720 }}>\n          <PopupDF\n            opened={opened}\n            onToggle={setOpened}\n            frame={frameRef}\n            size=\"l\"\n            placement=\"center\"\n            draggable={interactive}\n            resizable={\n              interactive\n                ? {\n                    // стартовый размер контейнера при включённом resizable\n                    defaultSize: { width: 600, height: 600 },\n                    minWidth: 320,\n                    minHeight: 220,\n                    iconSize: 's',\n                  }\n                : false\n            }\n            style={sizeStyle}\n          >\n            <PopupDF.Header\n              title=\"Заголовок PopupDF размера L\"\n              description=\"Body S. Двигай за шапку, тяни за угол, разворачивай кнопкой.\"\n              subHeader={\n                <div style={{ height: 40, display: 'flex', alignItems: 'center' }}>\n                  Кастомный слот\n                </div>\n              }\n              rightBlock={\n                <IconButton\n                  size=\"xs\"\n                  view=\"secondary\"\n                  pin=\"circle-circle\"\n                  title={fullscreen ? 'Свернуть' : 'Развернуть'}\n                  onClick={() => (fullscreen ? collapse() : expand())}\n                >\n                  <IconFullS size=\"xs\" />\n                </IconButton>\n              }\n            />\n            {/* высота 100%, чтобы контент тела рос при ресайзе попапа */}\n            <PopupDF.Body>\n              <div style={{ height: '100%' }}>Контент попапа</div>\n            </PopupDF.Body>\n            <PopupDF.Footer>\n              {/* LinkButton отделён от группы кнопок отступом 16px (L) */}\n              <div\n                style={{\n                  display: 'flex',\n                  justifyContent: 'flex-end',\n                  alignItems: 'center',\n                  gap: 16,\n                }}\n              >\n                <LinkButton href=\"/\" size=\"s\">\n                  LinkButton\n                </LinkButton>\n                <div style={{ display: 'flex', gap: 4 }}>\n                  <Button size=\"s\" view=\"secondary\">\n                    Отмена\n                  </Button>\n                  <Button size=\"s\" view=\"accent\">\n                    Применить\n                  </Button>\n                </div>\n              </div>\n            </PopupDF.Footer>\n          </PopupDF>\n        </div>\n      </PopupProvider>\n    </SSRProvider>\n  );\n}"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в PopupDF.stories.tsx",
          "type": "usage",
          "code": "<PopupDF\n            opened={opened}\n            onToggle={setOpened}\n            frame={frameRef}\n            placement={placement}\n            offset={[offsetX, offsetY]}\n            size={size}\n            draggable={draggable}\n            resizable={resizableConfig}\n            style={{ width: '396px' }}\n          >\n            <PopupDF.Header\n              title=\"Title\"\n              description=\"Description\"\n              subHeader={withSubHeader ? <HeaderSlot /> : undefined}\n              rightBlock={\n                withRightBlock ? <RightBlockSlot size={size} /> : undefined\n              }\n              showCloseButton={showCloseButton}\n              onBackButtonClick={showBackButton ? () => {} : undefined}\n            />\n            {withBody && (\n              <PopupDF.Body>\n                <BodySlot />\n              </PopupDF.Body>\n            )}\n            {withFooter && (\n              <PopupDF.Footer>\n                <FooterActions size={size} />\n              </PopupDF.Footer>\n            )}\n          </PopupDF>",
          "sourceFile": "packages/storybook/src/stories/PopupDF/PopupDF.stories.tsx"
        }
      ]
    },
    "Portal": {
      "name": "Portal",
      "group": "components",
      "folderName": "Portal",
      "role": "primary",
      "description": "Рендерит контент в другой DOM-узел через createPortal (для Popup, Popover)",
      "props": [
        {
          "name": "container",
          "type": "HTMLElement | (() => HTMLElement) | undefined",
          "required": false,
          "description": "Элемент, в который добавится содержимое портала."
        }
      ],
      "propsTypeName": "PortalProps",
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Portal/Portal.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "портал DOM",
        "createPortal",
        "рендер вне дерева"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Portal } from '@daisforge/ui';",
      "minimalUsage": "<Portal />",
      "examples": []
    },
    "Price": {
      "name": "Price",
      "group": "components",
      "folderName": "Price",
      "role": "primary",
      "description": "Форматированное отображение суммы с валютой, локалью и периодичностью",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        }
      ],
      "propsTypeName": "ComponentProps<typeof Price>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Price/Price.d.ts",
      "type": "wrapper",
      "atomicBase": "Price",
      "category": "Локальные компоненты",
      "keywords": [
        "денежная сумма",
        "currency display",
        "форматирование цены"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "children",
          "type": "number",
          "required": true,
          "description": "Значение для control.",
          "inheritedFrom": "Price",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "currency",
          "type": "string",
          "required": false,
          "description": "Валюта.\nПринимает ISO 4217 код валюты.",
          "default": "`rub`",
          "inheritedFrom": "Price",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "locale",
          "type": "string",
          "required": false,
          "description": "Локаль.",
          "default": "`ru`",
          "inheritedFrom": "Price",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "minimumFractionDigits",
          "type": "number",
          "required": false,
          "description": "Минимальное количество цифр после десятичного разделителя.",
          "default": "0",
          "inheritedFrom": "Price",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "periodicity",
          "type": "ReactNode",
          "required": false,
          "description": "Указывает регулярность платежа, идет после цены.\nНапример - 990Р / день.",
          "inheritedFrom": "Price",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stroke",
          "type": "boolean",
          "required": false,
          "description": "Перечеркнутый текст (старая цена, например).",
          "default": "false",
          "inheritedFrom": "Price",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stroked",
          "type": "boolean",
          "required": false,
          "description": "Перечеркнутый текст (старая цена, например).",
          "default": "false",
          "inheritedFrom": "Price",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "undefined",
          "required": false,
          "inheritedFrom": "Price",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Price } from '@daisforge/ui';",
      "minimalUsage": "<Price children={0} />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Example 1",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Price } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column' }}>\n            <Price currency=\"rub\" minimumFractionDigits={3}>12345.67</Price>\n            <Price locale=\"en\" currency=\"rub\" minimumFractionDigits={3} stroked>12345.67</Price>\n        </div>\n    );\n}"
        }
      ]
    },
    "Progress": {
      "name": "Progress",
      "group": "components",
      "folderName": "Progress",
      "role": "primary",
      "description": "Линейный индикатор прогресса выполнения задачи или загрузки данных",
      "props": [],
      "propsTypeName": "ProgressProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Progress/Progress.d.ts",
      "type": "wrapper",
      "atomicBase": "Progress",
      "category": "Локальные компоненты",
      "keywords": [
        "индикатор загрузки",
        "progress bar",
        "шкала выполнения"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "value",
          "type": "number",
          "required": true,
          "description": "Значение прогресса в процентах.",
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "caption",
          "type": "string",
          "required": false,
          "description": "Подпись под прогрессом.",
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasValue",
          "type": "boolean",
          "required": false,
          "description": "Отображать числовое значение прогресса.",
          "default": "'true'",
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelIcon",
          "type": "ReactNode",
          "required": false,
          "description": "Иконка рядом с текстом метки.",
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "\"none\" | \"top\" | \"left\"",
          "required": false,
          "description": "Задает выравнивание метки относительно трека.",
          "default": "'top'",
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelTextPlacement",
          "type": "\"none\" | \"right\" | \"left\"",
          "required": false,
          "description": "Задает положение текста метки относительно labelIcon.",
          "default": "'right'",
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "progressSize",
          "type": "undefined",
          "required": false,
          "description": "Высота линии прогресса в пикселях.",
          "default": "'4'",
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\"",
          "required": false,
          "description": "Размер прогресса.",
          "default": "'m'",
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "status",
          "type": "Status",
          "required": false,
          "description": "Статус прогресса.",
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "valueAlign",
          "type": "\"center\" | \"end\" | \"start\"",
          "required": false,
          "description": "Выравнивание числового значения по горизонтали.\nПрименяется только когда  valuePlacement равен 'top' и нет метки.",
          "default": "'start'",
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "valuePlacement",
          "type": "\"none\" | \"top\" | \"right\"",
          "required": false,
          "description": "Задает выравнивание числового значения относительно трека.\nКогда передана метка, значение определяется автоматически из labelPlacement.",
          "default": "'right'",
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"primary\" | \"info\" | \"success\" | \"error\"",
          "required": false,
          "description": "Вид прогресса.",
          "default": "'default'",
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "displayValue",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "Progress",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Progress } from '@daisforge/ui';",
      "minimalUsage": "<Progress value={0} />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Подпись Подпись Дополнительная подпись под треком задаётся свойством  caption .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Progress } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'block' }}>\n            <Progress value={75} label=\"Загрузка файла\" caption=\"Осталось 2 минуты\" hasValue />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Числовое значение",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Progress } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>\n            <Progress value={60} valuePlacement=\"top\" hasValue />\n            <Progress value={60} valuePlacement=\"right\" hasValue />\n            <Progress value={60} valuePlacement=\"none\" hasValue />\n        </div>\n    );\n}"
        }
      ]
    },
    "ProgressBarCircular": {
      "name": "ProgressBarCircular",
      "group": "components",
      "folderName": "Progress",
      "role": "primary",
      "description": "Круговой индикатор прогресса выполнения задачи или загрузки данных",
      "props": [],
      "propsTypeName": "ComponentProps<typeof ProgressBarCircular>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/ProgressBarCircular/ProgressBarCircular.d.ts",
      "type": "wrapper",
      "atomicBase": "ProgressBarCircular",
      "category": "Локальные компоненты",
      "keywords": [
        "круговой индикатор",
        "circular progress",
        "спиннер прогресса"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "hasTrack",
          "type": "boolean",
          "required": false,
          "description": "Наличие трека",
          "inheritedFrom": "ProgressBarCircular",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maxValue",
          "type": "number",
          "required": false,
          "description": "Максимальное значение прогресса",
          "default": "100",
          "inheritedFrom": "ProgressBarCircular",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "reverse",
          "type": "boolean",
          "required": false,
          "description": "Обратное направление дуги (уменьшение по часовой стрелке)",
          "inheritedFrom": "ProgressBarCircular",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"xxl\" | \"s\" | \"l\" | \"m\" | \"xs\" | \"xxs\" | \"xl\"",
          "required": false,
          "description": "Размер компонента",
          "default": "m",
          "inheritedFrom": "ProgressBarCircular",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "strokeSize",
          "type": "number",
          "required": false,
          "description": "Толщина обводки компонента",
          "inheritedFrom": "ProgressBarCircular",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "number",
          "required": false,
          "description": "Текущее значение прогресса (от 0 до maxValue)",
          "inheritedFrom": "ProgressBarCircular",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"info\"",
          "required": false,
          "description": "Вид компонента",
          "default": "default",
          "inheritedFrom": "ProgressBarCircular",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ProgressBarCircular } from '@daisforge/ui';",
      "minimalUsage": "<ProgressBarCircular />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Трек Трек С помощью свойства  hasTrack  можно управлять отображением фоновой дуги",
          "type": "vendor",
          "code": "import React from 'react';\nimport { ProgressBarCircular } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>\n            <ProgressBarCircular value={50} hasTrack={false} />\n            <ProgressBarCircular value={50} />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React from 'react';\nimport { ProgressBarCircular } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>\n            <ProgressBarCircular value={25} />\n            <ProgressBarCircular value={50}>50%</ProgressBarCircular>\n            <ProgressBarCircular value={75} />\n        </div>\n    );\n}"
        }
      ]
    },
    "Radiobox": {
      "name": "Radiobox",
      "group": "components",
      "folderName": "Radiobox",
      "role": "primary",
      "description": "Радиокнопка для выбора одного варианта из группы взаимоисключающих опций",
      "props": [
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": "Компонента находиться в фокусе"
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "RadioboxProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Radiobox/Radiobox.d.ts",
      "type": "wrapper",
      "atomicBase": "Radiobox",
      "formVariant": "FormRadiobox",
      "category": "Локальные компоненты",
      "keywords": [
        "переключатель выбора",
        "radio button",
        "выбор одного варианта"
      ],
      "chooseWhen": "Одиночная радиокнопка вне react-hook-form — обычно используется внутри RadioGroup, а не сама по себе.",
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "checkIcon",
          "type": "ReactNode",
          "required": false,
          "description": "Кастомная иконка галочки.",
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "description",
          "type": "ReactNode",
          "required": false,
          "description": "Описание элемента",
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "indeterminateIcon",
          "type": "ReactNode",
          "required": false,
          "description": "Кастомная иконка indeterminate-состояния.",
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу",
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "ChangeEventHandler<HTMLInputElement>",
          "required": false,
          "description": "Обработчик изменения элемента формы",
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "singleLine",
          "type": "boolean",
          "required": false,
          "description": "Title и description в одну строку или с переносом строк",
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\"",
          "required": false,
          "description": "Размер компонента",
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"tertiary\" | \"paragraph\"",
          "required": false,
          "description": "Вид компонента",
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "checked",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultChecked",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maxLength",
          "type": "number",
          "required": false,
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "minLength",
          "type": "number",
          "required": false,
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "name",
          "type": "string",
          "required": false,
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onBlur",
          "type": "FocusEventHandler<HTMLInputElement>",
          "required": false,
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onFocus",
          "type": "FocusEventHandler<HTMLInputElement>",
          "required": false,
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placeholder",
          "type": "string",
          "required": false,
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "required",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "type",
          "type": "string",
          "required": false,
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | number | readonly string[]",
          "required": false,
          "inheritedFrom": "Radiobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Radiobox } from '@daisforge/ui';",
      "minimalUsage": "<Radiobox />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Компонент  Radiobox  может содержать лейбл и описание. По умолчанию, контент внутри лейбла и описания многострочный. Для того чтобы стал однострочным, необходимо использовать свойство  singleLine (по умолчанию  false ).",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Radiobox } from '@daisforge/ui';\nexport function App() {\n    return (\n        <Radiobox label=\"Радиокнопка\" description=\"Описание\" defaultChecked />\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "RadioGroup RadioGroup Компоненты  Radiobox  следует объединять в  RadioGroup",
          "type": "vendor",
          "code": "<RadioGroup aria-labelledby=\"radiogroup-title-id\">\n    <H3 id=\"radiogroup-title-id\">Заголовок</H3>\n    <Radiobox name=\"radio-1\" label=\"Радиокнопка 1\" description=\"Описание 1\" defaultChecked />\n    <Radiobox name=\"radio-1\" label=\"Радиокнопка 2\" description=\"Описание 2\" />\n</RadioGroup>"
        }
      ]
    },
    "RadioGroup": {
      "name": "RadioGroup",
      "group": "components",
      "folderName": "Radiobox",
      "role": "primary",
      "description": "Группировка Radiobox с общим управлением выбранным значением",
      "props": [],
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Radiobox/RadioGroup.d.ts",
      "type": "standalone",
      "formVariant": "FormRadioGroup",
      "category": "Локальные компоненты",
      "keywords": [
        "группа переключателей",
        "radio group",
        "набор радиокнопок"
      ],
      "chooseWhen": "Вне react-hook-form — группа радиокнопок с value/onChange напрямую.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { RadioGroup } from '@daisforge/ui';",
      "minimalUsage": "<RadioGroup />",
      "examples": []
    },
    "Range": {
      "name": "Range",
      "group": "components",
      "folderName": "Range",
      "role": "primary",
      "description": "Поле ввода диапазона значений «от—до» с двумя связанными текстовыми полями",
      "props": [
        {
          "name": "appearance",
          "type": "\"default\" | \"clear\" | \"viewMode\" | undefined",
          "required": false,
          "description": "Стиль для UI конфигурации\nВлияет на выбор предустановленого набора токенов",
          "default": "default"
        },
        {
          "name": "firstTextfieldInputWrapperRef",
          "type": "React.Ref<HTMLDivElement> | undefined",
          "required": false,
          "description": "Ссылка на обертку первого поля ввода"
        },
        {
          "name": "hasClearDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отображение разделителя для `appearance='clear'`"
        },
        {
          "name": "inputWrapperRef",
          "type": "React.Ref<HTMLDivElement> | undefined",
          "required": false,
          "description": "Ссылка на обертку полей ввода"
        },
        {
          "name": "secondTextfieldInputWrapperRef",
          "type": "React.Ref<HTMLDivElement> | undefined",
          "required": false,
          "description": "Ссылка на обертку второго поля ввода"
        }
      ],
      "propsTypeName": "RangeProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Range/Range.d.ts",
      "type": "wrapper",
      "atomicBase": "Range",
      "category": "Локальные компоненты",
      "keywords": [
        "диапазон значений",
        "range input",
        "интервал от и до"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента справа",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "firstPlaceholder",
          "type": "string",
          "required": false,
          "description": "Значение первого поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "firstTextfieldContentLeft",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента слева для первого поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "firstTextfieldContentRight",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента справа для второго поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "firstTextfieldTextAfter",
          "type": "string",
          "required": false,
          "description": "Слот для вспомогательного текста справа для первого поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "firstValue",
          "type": "TextfieldPrimitiveValue",
          "required": false,
          "description": "Значение первого поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "firstValueEdited",
          "type": "boolean",
          "required": false,
          "description": "Отредактированное значение первого поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "firstValueError",
          "type": "boolean",
          "required": false,
          "description": "Некорректное значение первого поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "firstValueSuccess",
          "type": "boolean",
          "required": false,
          "description": "Корректное значение первого поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintContentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`.",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean",
          "required": false,
          "description": "Видимость стрелки (хвоста).",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOffset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "description": "Направление раскрытия тултипа.",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "description": "Размер тултипа",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetIcon",
          "type": "ReactNode",
          "required": false,
          "description": "Иконка, рядом с которым произойдет вызов всплывающего окна.\nЕсли свойство не задано, применится иконка по умолчанию.",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение иконки подсказки, когда отсутствует label\nили же он имеет labelPlacement='inner'.",
          "default": "`outer`",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintText",
          "type": "string",
          "required": false,
          "description": "Текст тултипа",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\"",
          "required": false,
          "description": "Способ открытия тултипа - наведение или клик мышью",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintView",
          "type": "\"default\"",
          "required": false,
          "description": "Вид тултипа",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintWidth",
          "type": "string",
          "required": false,
          "description": "Ширина окна (в rem).",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "leftHelper",
          "type": "string",
          "required": false,
          "description": "Вспомогательный текст снизу слева для поля ввода.",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onBlurFirstTextfield",
          "type": "((event: FocusEvent<HTMLInputElement, Element>) => void)",
          "required": false,
          "description": "Коллбэк, вызываемый при потере фокуса первым полем ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onBlurSecondTextfield",
          "type": "((event: FocusEvent<HTMLInputElement, Element>) => void)",
          "required": false,
          "description": "Коллбэк, вызываемый при потере фокуса вторым полем ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeFirstValue",
          "type": "BaseCallbackChangeInstance",
          "required": false,
          "description": "Коллбэк, вызываемый при изменении первого поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeSecondValue",
          "type": "BaseCallbackChangeInstance",
          "required": false,
          "description": "Коллбэк, вызываемый при изменении второго поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onFocusFirstTextfield",
          "type": "((event: FocusEvent<HTMLInputElement, Element>) => void)",
          "required": false,
          "description": "Коллбэк, вызываемый при фокусе на первое поле ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onFocusSecondTextfield",
          "type": "((event: FocusEvent<HTMLInputElement, Element>) => void)",
          "required": false,
          "description": "Коллбэк, вызываемый при фокусе на второе поле ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onSearchFirstValue",
          "type": "BaseCallbackKeyboardInstance",
          "required": false,
          "description": "Коллбэк, вызываемый при нажатии `Enter` в первом поле ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onSearchSecondValue",
          "type": "BaseCallbackKeyboardInstance",
          "required": false,
          "description": "Коллбэк, вызываемый при нажатии `Enter` во втором поле ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "requiredIndicatorPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "secondPlaceholder",
          "type": "string",
          "required": false,
          "description": "Значение второго поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "secondTextfieldContentLeft",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента слева для первого поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "secondTextfieldContentRight",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента справа для второго поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "secondTextfieldTextAfter",
          "type": "string",
          "required": false,
          "description": "Слот для вспомогательного текста справа для второго поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "secondValue",
          "type": "TextfieldPrimitiveValue",
          "required": false,
          "description": "Значение второго поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "secondValueEdited",
          "type": "boolean",
          "required": false,
          "description": "Отредактированное значение второго поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "secondValueError",
          "type": "boolean",
          "required": false,
          "description": "Некорректное значение второго поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "secondValueSuccess",
          "type": "boolean",
          "required": false,
          "description": "Корректное значение второго поля ввода",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "description": "Размер компонента",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "titleCaption",
          "type": "ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу справа",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "description": "Вариант отображения",
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "autoComplete",
          "type": "string",
          "required": false,
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dividerIcon",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dividerVariant",
          "type": "\"none\" | \"dash\" | \"icon\"",
          "required": false,
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "firstTextfieldTextBefore",
          "type": "string",
          "required": false,
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "required",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "secondTextfieldTextBefore",
          "type": "string",
          "required": false,
          "inheritedFrom": "Range",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Range } from '@daisforge/ui';",
      "minimalUsage": "<Range />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Варианты разделителя",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Range } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Range\n                label=\"Диапазон\"\n                leftHelper=\"Разделитель тире\"\n                firstPlaceholder=\"От\"\n                secondPlaceholder=\"До\"\n                dividerVariant=\"dash\"\n            />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Range } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Range\n                label=\"Диапазон значений\"\n                leftHelper=\"Введите два значения\"\n                firstPlaceholder=\"От\"\n                secondPlaceholder=\"До\"\n                dividerVariant=\"dash\"\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "Rating": {
      "name": "Rating",
      "group": "components",
      "folderName": "Rating",
      "role": "primary",
      "description": "Виджет оценки звёздами или иконками с настраиваемой точностью деления",
      "props": [],
      "propsTypeName": "ComponentProps<typeof Rating>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Rating/Rating.d.ts",
      "type": "wrapper",
      "atomicBase": "Rating",
      "category": "Локальные компоненты",
      "keywords": [
        "рейтинг звёзды",
        "star rating",
        "оценка пользователем"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "decimalSeparator",
          "type": "string",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasIcons",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasValue",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "helperText",
          "type": "string",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "helperTextStretching",
          "type": "\"filled\" | \"fixed\"",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "iconQuantity",
          "type": "1 | 5 | 10",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "iconSlot",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "iconSlotHalf",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "iconSlotOutline",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "precision",
          "type": "number",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"s\" | \"l\" | \"m\" | \"xs\" | \"xxs\" | \"displayL\" | \"displayM\" | \"displayS\"",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "number | null",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "valuePlacement",
          "type": "\"before\" | \"after\"",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\"",
          "required": false,
          "inheritedFrom": "Rating",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Rating } from '@daisforge/ui';",
      "minimalUsage": "<Rating />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Rating } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Rating\n                view=\"default\"\n                size=\"l\"\n                value={3.8}\n                helperText=\"Helper text\"\n            />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Вид Rating",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Rating } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: \"flex\", flexDirection: \"column\", gap: \"2rem\" }}>\n            <Rating\n                view=\"default\"\n                size=\"l\"\n                value={3.8}\n                helperText=\"Helper text\"\n            />\n            <Rating\n                view=\"accent\"\n                size=\"l\"\n                value={3.8}\n                helperText=\"Helper text\"\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "SSRProvider": {
      "name": "SSRProvider",
      "group": "components",
      "folderName": "SSRProvider",
      "role": "primary",
      "description": "Оборачивает приложение для SSR и корректной озвучки Checkbox/Radiobox скринридерами.",
      "props": [],
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/SSRProvider/SSRProvider.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "server-side rendering",
        "accessibility",
        "скринридер"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { SSRProvider } from '@daisforge/ui';",
      "minimalUsage": "<SSRProvider />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в PopupDF.stories.tsx",
          "type": "usage",
          "code": "<SSRProvider>\n      <PopupProvider>\n        <div style={playgroundStyle}>{children}</div>\n      </PopupProvider>\n    </SSRProvider>",
          "sourceFile": "packages/storybook/src/stories/PopupDF/PopupDF.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в PopupDF.stories.tsx",
          "type": "usage",
          "code": "<SSRProvider>\n      <PopupProvider>\n        <StoryFrame>\n          {(frameRef) => (\n            <>\n              <Button onClick={() => setOpened(true)}>Открыть PopupDF</Button>\n              <PopupDF\n                opened={opened}\n                onToggle={setOpened}\n                frame={frameRef}\n                size=\"m\"\n                placement=\"center\"\n                style={{ width: '396px' }}\n              >\n                <PopupDF.Header\n                  title=\"Title\"\n                  description=\"Description\"\n                  rightBlock={<RightBlockSlot />}\n                />\n                <PopupDF.Body>\n                  <BodySlot />\n                </PopupDF.Body>\n                <PopupDF.Footer>\n                  <FooterActions />\n                </PopupDF.Footer>\n              </PopupDF>\n            </>\n          )}\n        </StoryFrame>\n      </PopupProvider>\n    </SSRProvider>",
          "sourceFile": "packages/storybook/src/stories/PopupDF/PopupDF.stories.tsx"
        }
      ]
    },
    "SegmentGroup": {
      "name": "SegmentGroup",
      "group": "components",
      "folderName": "Segment",
      "role": "primary",
      "description": "Контейнер сегментированного переключателя (segmented control) из кнопок-вкладок",
      "props": [],
      "propsTypeName": "SegmentGroupProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Segment/Segment.d.ts",
      "type": "wrapper",
      "atomicBase": "SegmentGroup",
      "formVariant": "FormSegmentGroup",
      "category": "Локальные компоненты",
      "keywords": [
        "сегментированный контрол",
        "segmented control",
        "переключатель вкладок"
      ],
      "chooseWhen": "Вне react-hook-form — сегментированный переключатель с value/onChange напрямую.",
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "clip",
          "type": "boolean",
          "required": false,
          "description": "При ограничении ширины разрешает скролл и отображает дополнительные элементы со стрелками",
          "default": "true",
          "inheritedFrom": "SegmentGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "filledBackground",
          "type": "boolean",
          "required": false,
          "description": "Группа сегментов c фоном, используйте свойство hasBackground",
          "inheritedFrom": "SegmentGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasBackground",
          "type": "boolean",
          "required": false,
          "description": "Группа сегментов c фоном",
          "inheritedFrom": "SegmentGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasDivider",
          "type": "boolean",
          "required": false,
          "description": "Отображать разделители между элементами сегмента",
          "inheritedFrom": "SegmentGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "orientation",
          "type": "\"vertical\"",
          "required": false,
          "description": "Ориентация группы сегментов",
          "inheritedFrom": "SegmentGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pilled",
          "type": "boolean",
          "required": false,
          "description": "Группа сегментов c округлым border-radius",
          "inheritedFrom": "SegmentGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "selectionMode",
          "type": "\"multiple\" | \"single\"",
          "required": false,
          "description": "Сегмент множественного или одиночного выбора",
          "inheritedFrom": "SegmentGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "description": "Размер группы сегментов",
          "inheritedFrom": "SegmentGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "description": "Группа сегментов растянута на доступную область, только в горизонтальном режиме",
          "inheritedFrom": "SegmentGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"filled\"",
          "required": false,
          "description": "Вид группы сегментов",
          "inheritedFrom": "SegmentGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "SegmentGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { SegmentGroup } from '@daisforge/ui';",
      "minimalUsage": "<SegmentGroup />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в LeftPanel.stories.tsx",
          "type": "usage",
          "code": "<SegmentGroup\n                        style={{ marginBottom: s.x8 }}\n                        hasBackground\n                        size={buttonSize}\n                        stretch\n                      >\n                        {items.map((_, i) => (\n                          <SegmentItem\n                            view=\"secondary\"\n                            // eslint-disable-next-line react/no-array-index-key\n                            key={`item:${i}`}\n                            value={`item_${i}`}\n                            label={`Label ${i + 1}`}\n                            size={buttonSize}\n                          />\n                        ))}\n                      </SegmentGroup>",
          "sourceFile": "packages/storybook/src/stories/LeftPanel/LeftPanel.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FiltersActions.stories.tsx",
          "type": "usage",
          "code": "<SegmentGroup\n              hasBackground\n              size=\"xs\"\n              style={{ marginRight: '8px' }}\n            >\n              {Array(3)\n                .fill(0)\n                .map((_, i) => (\n                  <FiltersActions.SegmentItem\n                    key={`item:${i}`}\n                    value={`item_${i}`}\n                    label={`Сегмент${i + 1}`}\n                  />\n                ))}\n            </SegmentGroup>",
          "sourceFile": "packages/storybook/src/stories/FiltersActions/FiltersActions.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Управление внешним видом",
          "type": "vendor",
          "code": "import React from 'react';\nimport { SegmentGroup, SegmentItem, SegmentProvider, useSegment } from '@daisforge/ui';\nexport function App() {\n    const items = Array(4).fill(0);\n    const SegmentTemplate = () => {\n        const {selectedSegmentItems} = useSegment();\n        return (\n            <>\n                <div>Выбранный элемент: {selectedSegmentItems.join(', ')}</div>\n                <br />\n                <SegmentGroup orientation=\"vertical\" hasBackground clip={false}>\n                    {items.map((_, i) => (\n                        <SegmentItem\n                            label={`Label ${i}`}\n                            value={`label_${i}`}\n                            key={`label_${i}`}\n                            view='secondary'\n                        />\n                    ))}\n                </SegmentGroup>\n            </>\n        )\n    }\n    return (\n        <div style={{ display: \"block\" }} >\n            <SegmentProvider defaultSelected={['label_1']}>\n                <SegmentTemplate/>\n            </SegmentProvider>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React from 'react';\nimport { SegmentGroup, SegmentItem, SegmentProvider, useSegment } from '@daisforge/ui';\nexport function App() {\n    const items = Array(4).fill(0);\n    const SegmentTemplate = () => {\n        const {selectedSegmentItems} = useSegment();\n        return (\n            <>\n                <div>Выбранный элемент: {selectedSegmentItems.join(', ')}</div>\n                <br />\n                <SegmentGroup hasBackground pilled clip={false}>\n                    {items.map((_, i) => (\n                        <SegmentItem\n                            label={`Label ${i}`}\n                            value={`label_${i}`}\n                            key={`label_${i}`}\n                            view='default'\n                            pilled\n                        />\n                    ))}\n                </SegmentGroup>\n            </>\n        )\n    }\n    return (\n        <div style={{ display: \"block\" }} >\n            <SegmentProvider defaultSelected={['label_1']}>\n                <SegmentTemplate/>\n            </SegmentProvider>\n        </div>\n    );\n}"
        }
      ]
    },
    "SegmentIconItem": {
      "name": "SegmentIconItem",
      "group": "components",
      "folderName": "Segment",
      "role": "primary",
      "description": "Элемент сегментированного контрола SegmentGroup с иконкой без текста",
      "props": [
        {
          "name": "value",
          "type": "string | (readonly string[] & string)",
          "required": true,
          "description": ""
        },
        {
          "name": "customHandleSelect",
          "type": "((e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "icon",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "pilled",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"xs\" | \"s\" | \"m\" | \"l\" | \"xl\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"none\" | \"secondary\" | \"default\" | \"accent\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"submit\" | \"reset\" | \"button\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof SegmentIconItem>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Segment/Segment.d.ts",
      "type": "wrapper",
      "atomicBase": "SegmentIconItem",
      "category": "Локальные компоненты",
      "keywords": [
        "сегмент с иконкой",
        "icon segment",
        "кнопка переключателя"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { SegmentIconItem } from '@daisforge/ui';",
      "minimalUsage": "<SegmentIconItem value={{}} />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Сегменты только с иконкой",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconPlasma } from '@salutejs/plasma-icons'\nimport { SegmentGroup, SegmentIconItem, SegmentProvider, useSegment } from '@daisforge/ui';\nexport function App() {\n    const items = Array(4).fill(0);\n    const SegmentTemplate = () => {\n        const {selectedSegmentItems} = useSegment();\n        return (\n            <>\n                <div>Выбранный элемент: {selectedSegmentItems.join(', ')}</div>\n                <br />\n                <SegmentGroup hasBackground pilled clip={false}>\n                    {items.map((_, i) => (\n                        <SegmentIconItem\n                            icon={<IconPlasma color=\"inherit\" size=\"xs\" />}\n                            value={`label_${i}`}\n                            key={`label_${i}`}\n                            view='default'\n                        />\n                    ))}\n                </SegmentGroup>\n            </>\n        )\n    }\n    return (\n        <div style={{ display: \"block\" }} >\n            <SegmentProvider defaultSelected={['label_1']}>\n                <SegmentTemplate/>\n            </SegmentProvider>\n        </div>\n    );\n}"
        }
      ]
    },
    "SegmentItem": {
      "name": "SegmentItem",
      "group": "components",
      "folderName": "Segment",
      "role": "primary",
      "description": "Элемент сегментированного контрола SegmentGroup с текстовой меткой",
      "props": [
        {
          "name": "value",
          "type": "string | (readonly string[] & string)",
          "required": true,
          "description": "Значение сегмента"
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для контента слева."
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для контента справа."
        },
        {
          "name": "customHandleSelect",
          "type": "((e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void) | undefined",
          "required": false,
          "description": "Коллбек для обработки выбора сегмента"
        },
        {
          "name": "label",
          "type": "React.ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу"
        },
        {
          "name": "maxItemWidth",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "Обрезает контент по максимальной ширине и добавляет ...",
          "default": "'auto'"
        },
        {
          "name": "pilled",
          "type": "boolean | undefined",
          "required": false,
          "description": "Сегмент c округлым border-radius"
        },
        {
          "name": "size",
          "type": "string | undefined",
          "required": false,
          "description": "Размер сегмента"
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": "Вид сегмента",
          "default": "'default'"
        },
        {
          "name": "type",
          "type": "\"submit\" | \"reset\" | \"button\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "SegmentItemProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Segment/Segment.d.ts",
      "type": "wrapper",
      "atomicBase": "SegmentItem",
      "category": "Локальные компоненты",
      "keywords": [
        "сегмент с текстом",
        "segment tab",
        "вкладка-кнопка"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { SegmentItem } from '@daisforge/ui';",
      "minimalUsage": "<SegmentItem value={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в WidgetL.tsx",
          "type": "usage",
          "code": "<SegmentItem\n                      // eslint-disable-next-line react/no-array-index-key\n                      key={`item:${i}`}\n                      value={`item_${i}`}\n                      label={`Label${i + 1}`}\n                      size=\"xs\"\n                      view=\"secondary\"\n                    />",
          "sourceFile": "packages/storybook/src/stories/AnalyticalWidget/components/WidgetL.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в LeftPanelBlock.tsx",
          "type": "usage",
          "code": "<SegmentItem\n                        view=\"secondary\"\n                        // eslint-disable-next-line react/no-array-index-key\n                        key={`item:${i}`}\n                        value={`item_${i}`}\n                        label={`Label ${i + 1}`}\n                        size=\"s\"\n                      />",
          "sourceFile": "packages/storybook/src/stories/BlockTitle/components/LeftPanelBlock.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Управление внешним видом",
          "type": "vendor",
          "code": "import React from 'react';\nimport { SegmentGroup, SegmentItem, SegmentProvider, useSegment } from '@daisforge/ui';\nexport function App() {\n    const items = Array(4).fill(0);\n    const SegmentTemplate = () => {\n        const {selectedSegmentItems} = useSegment();\n        return (\n            <>\n                <div>Выбранный элемент: {selectedSegmentItems.join(', ')}</div>\n                <br />\n                <SegmentGroup orientation=\"vertical\" hasBackground clip={false}>\n                    {items.map((_, i) => (\n                        <SegmentItem\n                            label={`Label ${i}`}\n                            value={`label_${i}`}\n                            key={`label_${i}`}\n                            view='secondary'\n                        />\n                    ))}\n                </SegmentGroup>\n            </>\n        )\n    }\n    return (\n        <div style={{ display: \"block\" }} >\n            <SegmentProvider defaultSelected={['label_1']}>\n                <SegmentTemplate/>\n            </SegmentProvider>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React from 'react';\nimport { SegmentGroup, SegmentItem, SegmentProvider, useSegment } from '@daisforge/ui';\nexport function App() {\n    const items = Array(4).fill(0);\n    const SegmentTemplate = () => {\n        const {selectedSegmentItems} = useSegment();\n        return (\n            <>\n                <div>Выбранный элемент: {selectedSegmentItems.join(', ')}</div>\n                <br />\n                <SegmentGroup hasBackground pilled clip={false}>\n                    {items.map((_, i) => (\n                        <SegmentItem\n                            label={`Label ${i}`}\n                            value={`label_${i}`}\n                            key={`label_${i}`}\n                            view='default'\n                            pilled\n                        />\n                    ))}\n                </SegmentGroup>\n            </>\n        )\n    }\n    return (\n        <div style={{ display: \"block\" }} >\n            <SegmentProvider defaultSelected={['label_1']}>\n                <SegmentTemplate/>\n            </SegmentProvider>\n        </div>\n    );\n}"
        }
      ]
    },
    "SegmentProvider": {
      "name": "SegmentProvider",
      "group": "components",
      "folderName": "Segment",
      "role": "primary",
      "description": "Провайдер состояния выбора для группы элементов SegmentGroup/SegmentItem",
      "props": [
        {
          "name": "defaultSelected",
          "type": "string[] | undefined",
          "required": false,
          "description": "Выбранные по умолчанию сегменты.\nПередается массив value сегментов, выбранных по умолчанию"
        },
        {
          "name": "onChangeSelected",
          "type": "((selectedLabel: string) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения выюранных сегментов"
        },
        {
          "name": "selected",
          "type": "string[] | undefined",
          "required": false,
          "description": "Выбранные сегменты.\nПередается массив value сегментов"
        },
        {
          "name": "singleSelectedRequired",
          "type": "boolean | undefined",
          "required": false,
          "description": "Один сегмент должен быть обязательно выбран."
        }
      ],
      "propsTypeName": "ComponentProps<typeof SegmentProvider>",
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Segment/SegmentProvider/SegmentProvider.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "контекст сегментов",
        "controlled selection",
        "состояние выбора вкладки"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { SegmentProvider } from '@daisforge/ui';",
      "minimalUsage": "<SegmentProvider />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в LeftPanelBlock.tsx",
          "type": "usage",
          "code": "<SegmentProvider defaultSelected={['item_0']}>\n                  <SegmentGroup hasBackground size=\"xs\" stretch>\n                    {items.map((_, i) => (\n                      <SegmentItem\n                        view=\"secondary\"\n                        // eslint-disable-next-line react/no-array-index-key\n                        key={`item:${i}`}\n                        value={`item_${i}`}\n                        label={`Label ${i + 1}`}\n                        size=\"s\"\n                      />\n                    ))}\n                  </SegmentGroup>\n                </SegmentProvider>",
          "sourceFile": "packages/storybook/src/stories/BlockTitle/components/LeftPanelBlock.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в LeftPanel.stories.tsx",
          "type": "usage",
          "code": "<SegmentProvider defaultSelected={['item_0']}>\n                      <SegmentGroup\n                        style={{ marginBottom: s.x8 }}\n                        hasBackground\n                        size={buttonSize}\n                        stretch\n                      >\n                        {items.map((_, i) => (\n                          <SegmentItem\n                            view=\"secondary\"\n                            // eslint-disable-next-line react/no-array-index-key\n                            key={`item:${i}`}\n                            value={`item_${i}`}\n                            label={`Label ${i + 1}`}\n                            size={buttonSize}\n                          />\n                        ))}\n                      </SegmentGroup>\n                    </SegmentProvider>",
          "sourceFile": "packages/storybook/src/stories/LeftPanel/LeftPanel.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Управление внешним видом",
          "type": "vendor",
          "code": "import React from 'react';\nimport { SegmentGroup, SegmentItem, SegmentProvider, useSegment } from '@daisforge/ui';\nexport function App() {\n    const items = Array(4).fill(0);\n    const SegmentTemplate = () => {\n        const {selectedSegmentItems} = useSegment();\n        return (\n            <>\n                <div>Выбранный элемент: {selectedSegmentItems.join(', ')}</div>\n                <br />\n                <SegmentGroup orientation=\"vertical\" hasBackground clip={false}>\n                    {items.map((_, i) => (\n                        <SegmentItem\n                            label={`Label ${i}`}\n                            value={`label_${i}`}\n                            key={`label_${i}`}\n                            view='secondary'\n                        />\n                    ))}\n                </SegmentGroup>\n            </>\n        )\n    }\n    return (\n        <div style={{ display: \"block\" }} >\n            <SegmentProvider defaultSelected={['label_1']}>\n                <SegmentTemplate/>\n            </SegmentProvider>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React from 'react';\nimport { SegmentGroup, SegmentItem, SegmentProvider, useSegment } from '@daisforge/ui';\nexport function App() {\n    const items = Array(4).fill(0);\n    const SegmentTemplate = () => {\n        const {selectedSegmentItems} = useSegment();\n        return (\n            <>\n                <div>Выбранный элемент: {selectedSegmentItems.join(', ')}</div>\n                <br />\n                <SegmentGroup hasBackground pilled clip={false}>\n                    {items.map((_, i) => (\n                        <SegmentItem\n                            label={`Label ${i}`}\n                            value={`label_${i}`}\n                            key={`label_${i}`}\n                            view='default'\n                            pilled\n                        />\n                    ))}\n                </SegmentGroup>\n            </>\n        )\n    }\n    return (\n        <div style={{ display: \"block\" }} >\n            <SegmentProvider defaultSelected={['label_1']}>\n                <SegmentTemplate/>\n            </SegmentProvider>\n        </div>\n    );\n}"
        }
      ]
    },
    "Select": {
      "name": "Select",
      "group": "components",
      "folderName": "Select",
      "role": "primary",
      "description": "Выпадающий список для выбора одного или нескольких значений из перечня",
      "props": [
        {
          "name": "type",
          "type": "\"submit\" | \"reset\" | \"button\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof Select>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Select/Select.d.ts",
      "type": "wrapper",
      "atomicBase": "Select",
      "formVariant": "FormSelect",
      "category": "Локальные компоненты",
      "keywords": [
        "выпадающий список",
        "dropdown select",
        "выбор из списка"
      ],
      "chooseWhen": "Вне react-hook-form — самостоятельный выпадающий список с value/onChange напрямую.",
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "items",
          "type": "K[]",
          "required": true,
          "description": "Список элементов.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "afterList",
          "type": "ReactNode",
          "required": false,
          "description": "Ячейка для контента в конце выпадающего списка.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "arrowPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Сторона расположения стрелки скрытия/раскрытия.",
          "default": "left",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "beforeList",
          "type": "ReactNode",
          "required": false,
          "description": "Ячейка для контента в начале выпадающего списка.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipClickArea",
          "type": "\"full\" | \"close-icon\"",
          "required": false,
          "description": "Область, по которой происходит нажатие.",
          "default": "full",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipType",
          "type": "\"text\" | \"default\"",
          "required": false,
          "description": "Внешний вид chip.",
          "default": "default",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"accent\" | \"secondary\"",
          "required": false,
          "description": "Внешний вид чипа в варианте textfield-like multiselect.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeAfterSelect",
          "type": "boolean",
          "required": false,
          "description": "Закрывать ли выпадающий список после выбора элемента.",
          "default": "если single, то true; если multiple, то false",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента справа.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "emptyStateDescription",
          "type": "ReactNode",
          "required": false,
          "description": "Текст выпадающего списка при пустом массиве items.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "flip",
          "type": "boolean",
          "required": false,
          "description": "Коррекция placement, если выпадающий список находится за пределами экрана.",
          "default": "false",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "helperText",
          "type": "string",
          "required": false,
          "description": "Вспомогательный текст снизу слева для поля ввода.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintContentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean",
          "required": false,
          "description": "Видимость стрелки (хвоста).",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOffset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "description": "Направление раскрытия тултипа.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPortal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "Портал для окна подсказки. Принимает id контейнера или ref.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "description": "Размер тултипа",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetIcon",
          "type": "ReactNode",
          "required": false,
          "description": "Иконка, рядом с которым произойдет вызов всплывающего окна.\nЕсли свойство не задано, применится иконка по умолчанию.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение иконки подсказки, когда отсутствует label\nили же он имеет labelPlacement='inner'.",
          "default": "`outer`",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintText",
          "type": "string",
          "required": false,
          "description": "Текст тултипа",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\"",
          "required": false,
          "description": "Способ открытия тултипа - наведение или клик мышью",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintView",
          "type": "\"default\"",
          "required": false,
          "description": "Вид тултипа",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintWidth",
          "type": "string",
          "required": false,
          "description": "Ширина окна (в rem).",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isTargetAmount",
          "type": "boolean",
          "required": false,
          "description": "Если включено - будет выведено общее количество выбранных элементов вместо перечисления.",
          "default": "false",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение лейбла.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "listMaxHeight",
          "type": "Height<string | number>",
          "required": false,
          "description": "Максимальная высота выпадающего списка.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "listWidth",
          "type": "Width<string | number>",
          "required": false,
          "description": "Значение css width для выпадающего списка.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "mode",
          "type": "\"radio\" | \"default\"",
          "required": false,
          "description": "Режим работы взаимодействия с элементами.\n- default: элемент можно выбрать и можно отменить его выбор.\n- radio: если элемент выбран, то отменить его выбор нельзя. Только для single-режима.",
          "default": "default",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onScroll",
          "type": "((e: UIEvent<HTMLElement, UIEvent>) => void)",
          "required": false,
          "description": "Коллбэк, срабатывающий при скролле.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean) => void)",
          "required": false,
          "description": "Событие сворачивания/разворачивания выпадающего списка.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optional",
          "type": "boolean",
          "required": false,
          "description": "Флаг необязательности поля",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optionalText",
          "type": "string",
          "required": false,
          "description": "Подпись для указания необязательности поля",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "SelectPlacement | SelectPlacementBasic[]",
          "required": false,
          "description": "Сторона открытия дропдауна относительно target элемента.",
          "default": "bottom",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "portal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "Портал для выпадающего списка. Принимает id контейнера или ref.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderItem",
          "type": "((item: K) => ReactNode)",
          "required": false,
          "description": "Callback для кастомной настройки айтема в выпадающем списке.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderSelectionIcon",
          "type": "((selected: boolean | \"indeterminate\") => ReactNode)",
          "required": false,
          "description": "Callback для кастомной настройки иконки выбранного элемента.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderTarget",
          "type": "((value: K | null, opened?: boolean) => ReactNode) | ((value: K[], opened?: boolean) => ReactNode) | undefined",
          "required": false,
          "description": "Callback для кастомной настройки значения в селекте.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderValue",
          "type": "((item: K) => string)",
          "required": false,
          "description": "Callback для кастомной настройки значения в селекте.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "requiredPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shift",
          "type": "boolean",
          "required": false,
          "description": "Смещение выпадающего списка при соприкосновении с границами экрана.",
          "default": "false",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "singleLine",
          "type": "boolean",
          "required": false,
          "description": "Label в элементе выпадающего списка в одну строку или с переносом строк.",
          "default": "true",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "description": "Размер компонента.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "target",
          "type": "\"textfield-like\" | \"button-like\"",
          "required": false,
          "description": "Стиль селекта: button-like или textfield-like.",
          "default": "textfield-like",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "treeView",
          "type": "boolean",
          "required": false,
          "description": "Режим отображения выпадающего списка в виде дерева.",
          "default": "false",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "variant",
          "type": "\"normal\" | \"tight\"",
          "required": false,
          "description": "Вариант: обычный или сжатый",
          "default": "normal",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"secondary\" | \"black\" | \"white\" | \"edited\"",
          "required": false,
          "description": "Вид компонента.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "virtual",
          "type": "boolean",
          "required": false,
          "description": "Виртуализация в выпадающем списке.\nНе поддерживается в многоуровневых списках.",
          "default": "false",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "ZIndex",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего списка.",
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "_checkboxAppearance",
          "type": "string",
          "required": false,
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "_offset",
          "type": "[number, number]",
          "required": false,
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"viewMode\"",
          "required": false,
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultValue",
          "type": "string | string[]",
          "required": false,
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "multiselect",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "ChangeEventHandler<HTMLSelectElement> | ((value: string, item: K | null) => void) | ((value: string[], item: K | null) => void)",
          "required": false,
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placeholder",
          "type": "string",
          "required": false,
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "required",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "selectAllOptions",
          "type": "SelectAllProps",
          "required": false,
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | string[]",
          "required": false,
          "inheritedFrom": "Select",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Select } from '@daisforge/ui';",
      "minimalUsage": "<Select items={[]} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в Select.tsx",
          "type": "usage",
          "code": "<Select\n        items={items}\n        value={value}\n        onChange={setValue}\n        placeholder=\"Placeholder\"\n        label=\"Select\"\n        helperText=\"Helper text\"\n      />",
          "sourceFile": "packages/vite-project/src/pages/Select.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvas.cellsMerging.stories.tsx",
          "type": "usage",
          "code": "<Select\n            target=\"textfield-like\"\n            label=\"Режим выделения\"\n            value={selectionMode}\n            onChange={(v) => setSelectionMode(v as CellsSelectionMode)}\n            items={SELECTION_MODE_OPTIONS}\n          />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.CellsMerging/TableCanvas.cellsMerging.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Appearance Appearance appearance=\"viewMode\"  — режим просмотра.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Select } from '@daisforge/ui';\nexport function App() {\n    const items = [\n        { value: 'option_1', label: 'Опция 1' },\n        { value: 'option_2', label: 'Опция 2' },\n    ];\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '20px', maxWidth: '350px' }}>\n            <Select items={items} appearance=\"default\" label=\"Default\" placeholder=\"Placeholder\" />\n            <Select items={items} appearance=\"viewMode\" value=\"option_1\" readOnly label=\"ViewMode\" placeholder=\"Placeholder\" />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Использование Использование Обязательным параметром является только  items . Для controlled-варианта передавайте  value  и  onChange , для интеграции с формой используйте  name  и при необходимости  defaultValue . Множественный выбор включается через  multiselect . В single-режиме  value  имеет тип  string , в multiselect-режиме  string[] . В single-режиме можно использовать  mode=\"radio\" , если нужно запретить снятие выбора повторным кликом. В multiselect-режиме доступны  selectAllOptions  и  isTargetAmount . Select поддерживает два вида target-элемента",
          "type": "vendor",
          "code": "type Items = Array<{\n    /**\n     * Значение item.\n     */\n    value: string;\n    /**\n     * Метка-подпись к item.\n     */\n    label: string;\n    /**\n     * Сторона открытия вложенного списка относительно текущего элемента.\n     * @default right\n     */\n    placement?: SelectPlacement | Array<SelectPlacementBasic>;\n    /**\n     * Список дочерних items.\n     */\n    items?: Array<ItemOption>;\n    /**\n     * Item не активен.\n     */\n    disabled?: boolean;\n    /**\n     * Слот для контента слева.\n     */\n    contentLeft?: ReactNode;\n    /**\n     * Слот для контента справа.\n     */\n    contentRight?: ReactNode;\n    /**\n     * Classname для item.\n     */\n    className?: string;\n    /**\n     * Максимальная высота дочернего выпадающего списка.\n     */\n    listMaxHeight?: CSSProperties['height'];\n}>;"
        }
      ]
    },
    "Sheet": {
      "name": "Sheet",
      "group": "components",
      "folderName": "Sheet",
      "role": "primary",
      "description": "Шторка (bottom sheet), выезжающая поверх экрана снизу с шапкой и футером",
      "props": [
        {
          "name": "closeOnEsc",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрывать шторку при нажатии на ESC.",
          "default": "true"
        },
        {
          "name": "initialSnapPoint",
          "type": "string | undefined",
          "required": false,
          "description": "Начальная точка остановки.\nПо умолчанию — первая из `snapPoints`."
        },
        {
          "name": "onEscKeyDown",
          "type": "((event: KeyboardEvent) => void) | undefined",
          "required": false,
          "description": "Обработчик нажатия ESC (если не передан, используется onClose)."
        },
        {
          "name": "onOverlayClick",
          "type": "((event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void) | undefined",
          "required": false,
          "description": "Обработчик клика по оверлею (если не передан, используется onClose)."
        },
        {
          "name": "onSnapPointChange",
          "type": "((snapPoint: string) => void) | undefined",
          "required": false,
          "description": "Обработчик смены активной точки остановки."
        },
        {
          "name": "snapPoints",
          "type": "SheetSnapPoints | undefined",
          "required": false,
          "description": "Точки остановки шторки.\nCSS-размеры: '320px', '50%', '40dvh'.\nЕсли не передано или массив пуст — snap-points отключены."
        }
      ],
      "propsTypeName": "SheetProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Sheet/Sheet.d.ts",
      "type": "wrapper",
      "atomicBase": "Sheet",
      "category": "Локальные компоненты",
      "keywords": [
        "боттом шит",
        "bottom sheet",
        "выезжающая панель снизу"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "onClose",
          "type": "() => void",
          "required": true,
          "description": "Обработчик закрытия шторки. Вызывается при смахивании шторки вниз,\nпри клике по оверлею (если не передан onOverlayClick)\nи при нажатии ESC (если не передан onEscKeyDown).",
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentFooter",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента в нижней части",
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentHeader",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента в заголовке",
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "handlePlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Позиция шторки относительно подложки",
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasHandle",
          "type": "boolean",
          "required": false,
          "description": "Наличие ручки у шторки",
          "default": "true",
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasScrollEvents",
          "type": "boolean",
          "required": false,
          "description": "Наличие событий скролла",
          "default": "true",
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isFooterFixed",
          "type": "boolean",
          "required": false,
          "description": "Является ли нижняя часть фиксированной",
          "default": "false",
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isHeaderFixed",
          "type": "boolean",
          "required": false,
          "description": "Является ли заголовок фиксированным",
          "default": "false",
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": false,
          "description": "Состояние шторки, открыта или скрыта",
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "throttleMs",
          "type": "number",
          "required": false,
          "description": "Throttling внутренних обработчиков события onScroll",
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withBlur",
          "type": "boolean",
          "required": false,
          "description": "Нужно ли применять blur для подложки.",
          "default": "false",
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withOverlay",
          "type": "boolean",
          "required": false,
          "description": "Наличие оверлея шторки. Если включен, то контент под шторкой перекрывается оверлеем, при нажатии на\nкоторый шторка закрывается.",
          "default": "true",
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withTransition",
          "type": "boolean",
          "required": false,
          "description": "Наличие состояния анимации/перехода",
          "default": "true",
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "Sheet",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Sheet } from '@daisforge/ui';",
      "minimalUsage": "<Sheet onClose={() => {}} />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Подложка Подложка Наличие или отсутствие подложки задается с помощью свойства  withOverlay . В случае, когда подложка отсутствует, у пользователя появляется возможность взаимодействовать с контентом вне шторки.",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { Sheet } from '@daisforge/ui';\nimport { Button } from '@daisforge/ui';\nexport function App() {\n    const [opened, setOpened] = useState(false);\n    return (\n        <>\n            <Button onClick={() => setOpened(!opened)}>\n                {opened ? 'Закрыть' : 'Открыть'}\n            </Button>\n            <Sheet opened={opened}\n                onClose={() => setOpened(false)}\n                withOverlay={false}\n            >\n                <div style={{ 'padding-bottom': '300px' }}>body</div>\n            </Sheet>\n        </>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Использование Использование Компонент  Sheet  может содержать любой контент напрямую через  children . Также есть возможность добавить любой контент в заголовок и футер с помощью свойств  contentHeader  и  contentFooter .",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { Sheet } from '@daisforge/ui';\nimport { Button } from '@daisforge/ui';\nexport function App() {\n    const [opened, setOpened] = useState(false);\n    return (\n        <>\n            <Button onClick={() => setOpened(true)}>Открыть</Button>\n            <Sheet opened={opened}\n                onClose={() => setOpened(false)}\n                contentHeader={\n                    <div>\n                        <h4>header</h4>\n                    </div>\n                }\n                contentFooter={\n                    <div>\n                        <p>footer</p>\n                    </div>\n                }\n            >\n                <div style={{ 'padding-bottom': '300px' }}>body</div>\n            </Sheet>\n        </>\n    );\n}"
        }
      ]
    },
    "LineSkeleton": {
      "name": "LineSkeleton",
      "group": "components",
      "folderName": "Skeleton",
      "role": "primary",
      "description": "Плейсхолдер-линия для имитации загрузки текстовой строки",
      "props": [
        {
          "name": "animationDuration",
          "type": "number | undefined",
          "required": false,
          "description": "Длительность одного цикла анимации в миллисекундах"
        }
      ],
      "propsTypeName": "ComponentProps<typeof LineSkeleton>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Skeleton/Skeleton.d.ts",
      "type": "wrapper",
      "atomicBase": "LineSkeleton",
      "category": "Локальные компоненты",
      "keywords": [
        "скелетон загрузки",
        "loading placeholder",
        "заглушка строки"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "animationType",
          "type": "\"shimmer\" | \"pulse\"",
          "required": false,
          "description": "Тип анимации",
          "default": "'shimmer'",
          "inheritedFrom": "LineSkeleton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customFadeInColor",
          "type": "string",
          "required": false,
          "description": "Значение цвета фона начала анимации `pulse`",
          "inheritedFrom": "LineSkeleton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customFadeOutColor",
          "type": "string",
          "required": false,
          "description": "Значение цвета фона в конце анимации `pulse`",
          "inheritedFrom": "LineSkeleton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "customGradientColor",
          "type": "string",
          "required": false,
          "description": "Значение градиента скелетона для анимации `shimmer`",
          "inheritedFrom": "LineSkeleton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "roundness",
          "type": "0 | 4 | 8 | 12 | 14 | 16 | 18 | 20 | 24 | 28 | 32 | 250",
          "required": false,
          "description": "Скругленность",
          "inheritedFrom": "LineSkeleton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "lighter",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "LineSkeleton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"bodyM\" | \"bodyL\" | \"bodyS\" | \"bodyXS\" | \"bodyXXS\" | \"dsplL\" | \"dsplM\" | \"dsplS\" | \"textL\" | \"textM\" | \"textS\" | \"textXS\"",
          "required": false,
          "inheritedFrom": "LineSkeleton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"lighter\"",
          "required": false,
          "inheritedFrom": "LineSkeleton",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LineSkeleton } from '@daisforge/ui';",
      "minimalUsage": "<LineSkeleton />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в AnalyticalWidget.stories.tsx",
          "type": "usage",
          "code": "<LineSkeleton size=\"bodyM\" style={{ width: 180 }} />",
          "sourceFile": "packages/storybook/src/stories/AnalyticalWidget/AnalyticalWidget.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvasContextMenu.stories.tsx",
          "type": "usage",
          "code": "<LineSkeleton size=\"bodyS\" />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.ContextMenu/TableCanvasContextMenu.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React from 'react';\nimport { LineSkeleton } from '@daisforge/ui';\nexport function App() {\n    return (\n        <LineSkeleton size=\"h3\" />\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Тип анимации",
          "type": "vendor",
          "code": "import React from 'react';\nimport { LineSkeleton } from '@daisforge/ui';\nexport function App() {\n    return (\n        <LineSkeleton size=\"h3\" animationType=\"shimmer\" />\n    );\n}"
        }
      ]
    },
    "RectSkeleton": {
      "name": "RectSkeleton",
      "group": "components",
      "folderName": "Skeleton",
      "role": "primary",
      "description": "Прямоугольный плейсхолдер для блоков и изображений на время загрузки",
      "props": [
        {
          "name": "animationDuration",
          "type": "number | undefined",
          "required": false,
          "description": "Длительность одного цикла анимации в миллисекундах"
        },
        {
          "name": "animationType",
          "type": "\"shimmer\" | \"pulse\" | undefined",
          "required": false,
          "description": "Тип анимации",
          "default": "'shimmer'"
        },
        {
          "name": "customFadeInColor",
          "type": "string | undefined",
          "required": false,
          "description": "Значение цвета фона начала анимации `pulse`"
        },
        {
          "name": "customFadeOutColor",
          "type": "string | undefined",
          "required": false,
          "description": "Значение цвета фона в конце анимации `pulse`"
        },
        {
          "name": "customGradientColor",
          "type": "string | undefined",
          "required": false,
          "description": "Значение градиента скелетона для анимации `shimmer`"
        },
        {
          "name": "roundness",
          "type": "0 | 250 | 32 | 28 | 24 | 20 | 18 | 16 | 14 | 12 | 8 | 4 | undefined",
          "required": false,
          "description": "Скругленность"
        },
        {
          "name": "lighter",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof RectSkeleton>",
      "sourceFile": "node_modules/@salutejs/plasma-new-hope/types/components/Skeleton/RectSkeleton/RectSkeleton.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "скелетон блока",
        "loading placeholder",
        "заглушка изображения"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { RectSkeleton } from '@daisforge/ui';",
      "minimalUsage": "<RectSkeleton />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в TableCanvasContextMenu.stories.tsx",
          "type": "usage",
          "code": "<RectSkeleton width={16} height={16} roundness={4} />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.ContextMenu/TableCanvasContextMenu.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableTabs.stories.tsx",
          "type": "usage",
          "code": "<RectSkeleton width=\"100%\" height={600} />",
          "sourceFile": "packages/storybook/src/stories/TableTabs/TableTabs.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React from 'react';\nimport { RectSkeleton } from '@daisforge/ui';\nexport function App() {\n    return (\n        <RectSkeleton width=\"12rem\" height=\"8rem\" />\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Длительность анимации",
          "type": "vendor",
          "code": "import React from 'react';\nimport { LineSkeleton, RectSkeleton, TextSkeleton } from '@daisforge/ui';\nexport function App() {\n    return (\n        <>\n            <LineSkeleton size=\"h3\" animationDuration={1200} />\n            <RectSkeleton width=\"12rem\" height=\"8rem\" animationDuration={600} />\n            <TextSkeleton size=\"textM\" lines={4} animationDuration={0} />\n        </>\n    );\n}"
        }
      ]
    },
    "TextSkeleton": {
      "name": "TextSkeleton",
      "group": "components",
      "folderName": "Skeleton",
      "role": "primary",
      "description": "Многострочный текстовый плейсхолдер для имитации абзацев во время загрузки",
      "props": [
        {
          "name": "lines",
          "type": "number",
          "required": true,
          "description": ""
        },
        {
          "name": "animationDuration",
          "type": "number | undefined",
          "required": false,
          "description": "Длительность одного цикла анимации в миллисекундах"
        },
        {
          "name": "animationType",
          "type": "\"shimmer\" | \"pulse\" | undefined",
          "required": false,
          "description": "Тип анимации",
          "default": "'shimmer'"
        },
        {
          "name": "customFadeInColor",
          "type": "string | undefined",
          "required": false,
          "description": "Значение цвета фона начала анимации `pulse`"
        },
        {
          "name": "customFadeOutColor",
          "type": "string | undefined",
          "required": false,
          "description": "Значение цвета фона в конце анимации `pulse`"
        },
        {
          "name": "customGradientColor",
          "type": "string | undefined",
          "required": false,
          "description": "Значение градиента скелетона для анимации `shimmer`"
        },
        {
          "name": "roundness",
          "type": "0 | 250 | 32 | 28 | 24 | 20 | 18 | 16 | 14 | 12 | 8 | 4 | undefined",
          "required": false,
          "description": "Скругленность"
        },
        {
          "name": "lighter",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"bodyL\" | \"bodyM\" | \"bodyS\" | \"bodyXS\" | \"bodyXXS\" | \"dsplL\" | \"dsplM\" | \"dsplS\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"textL\" | \"textM\" | \"textS\" | \"textXS\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"lighter\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof TextSkeleton>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Skeleton/Skeleton.d.ts",
      "type": "wrapper",
      "atomicBase": "TextSkeleton",
      "category": "Локальные компоненты",
      "keywords": [
        "скелетон текста",
        "text placeholder",
        "заглушка абзаца"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { TextSkeleton } from '@daisforge/ui';",
      "minimalUsage": "<TextSkeleton lines={0} />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TextSkeleton } from '@daisforge/ui';\nexport function App() {\n    return (\n        <TextSkeleton size=\"textM\" lines={4} />\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Длительность анимации",
          "type": "vendor",
          "code": "import React from 'react';\nimport { LineSkeleton, RectSkeleton, TextSkeleton } from '@daisforge/ui';\nexport function App() {\n    return (\n        <>\n            <LineSkeleton size=\"h3\" animationDuration={1200} />\n            <RectSkeleton width=\"12rem\" height=\"8rem\" animationDuration={600} />\n            <TextSkeleton size=\"textM\" lines={4} animationDuration={0} />\n        </>\n    );\n}"
        }
      ]
    },
    "Slider": {
      "name": "Slider",
      "group": "components",
      "folderName": "Slider",
      "role": "primary",
      "description": "Ползунок для выбора числа или диапазона чисел в заданных границах (min/max).",
      "props": [],
      "propsTypeName": "SliderProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Slider/Slider.d.ts",
      "type": "wrapper",
      "atomicBase": "Slider",
      "category": "Локальные компоненты",
      "keywords": [
        "диапазон значений",
        "range slider",
        "числовой ползунок"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "max",
          "type": "number",
          "required": true,
          "description": "Максимальное значение",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "min",
          "type": "number",
          "required": true,
          "description": "Минимальное значение",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "ariaLabel",
          "type": "string | string[]",
          "required": false,
          "description": "Ярлык, определяющий назначение ползунка, например «Минимальная цена» [a11y].\nЯрлык, определяющий назначение ползунков (a11y).\nПервый элемент — левый ползунок, второй — правый",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultValue",
          "type": "number | number[]",
          "required": false,
          "description": "Изначальное знaчение\nНачальное значение (неконтролируемый режим)\nНачальное значение (неконтролируемый режим).\nНе передавайте одновременно с value",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelContentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот под контент слева от подписи (например, иконку)",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение подписи.",
          "default": "`top`",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "multipleStepSize",
          "type": "number",
          "required": false,
          "description": "Размер увеличенного шага (клавиши PageUp / PageDown).\nУказывает процентное отношение от диапазона [min, max].\nНапример, значение 10 при диапазоне 0–100 даёт шаг 10.",
          "default": "10",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "((event: FormTypeNumber) => void) | ((value: number) => void) | ((event: FormTypeString) => void) | ((value: number[]) => void)",
          "required": false,
          "description": "Вызывается при перемещении ползунка\nВызывается при перемещении ползунка.\nВ режиме формы (при наличии name) получает событие с полем target.value в формате \"min - max\"",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeCommitted",
          "type": "((value: number) => void) | ((value: number[]) => void)",
          "required": false,
          "description": "Вызывается при отпускании ползунка",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pointerSize",
          "type": "\"none\" | \"small\" | \"large\"",
          "required": false,
          "description": "Размер ползунка",
          "default": "'small'",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "rangeValuesPlacement",
          "type": "string",
          "required": false,
          "description": "Расположение значений минимума и максимума интервала.",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "showCurrentValue",
          "type": "boolean",
          "required": false,
          "description": "Отображать ли текущее значение.",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "showRangeValues",
          "type": "boolean",
          "required": false,
          "description": "Отображать ли значения минимума и максимума интервала.",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\"",
          "required": false,
          "description": "Размер контрола",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "step",
          "type": "number",
          "required": false,
          "description": "Шаг ползунка.",
          "default": "1",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "number | number[]",
          "required": false,
          "description": "Текущее знaчение\nТекущее значение (контролируемый режим).\nНе передавайте одновременно с defaultValue\nТекущее значение (контролируемый режим)",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\"",
          "required": false,
          "description": "Вид контрола",
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "currentValueVisibility",
          "type": "\"hover\" | \"always\"",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hideMaxValueDiff",
          "type": "number",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hideMinValueDiff",
          "type": "number",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelContent",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelReversed",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "name",
          "type": "string",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onBlurTextField",
          "type": "((value: number[], event: FocusEvent<HTMLInputElement, Element>) => void)",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeTextField",
          "type": "((value: number[], event: ChangeEvent<HTMLInputElement>) => void)",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onKeyDownTextField",
          "type": "((value: number[], event: KeyboardEvent<HTMLInputElement>) => void)",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\"",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pointerVisibility",
          "type": "\"hover\" | \"always\"",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "reversed",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "scaleAlign",
          "type": "\"none\" | \"top\" | \"bottom\" | \"side\"",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "scaleTicks",
          "type": "number[] | ScaleTickItem[]",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "settings",
          "type": "Partial<{ indent?: number; fontSizeMultiplier?: number; backgroundColor?: string | undefined; fillColor?: string | undefined; }> | undefined",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "showScale",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "sliderAlign",
          "type": "\"none\" | \"center\" | \"right\" | \"left\"",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "tickType",
          "type": "\"separator\" | \"bullet\"",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "type",
          "type": "\"single\" | \"double\"",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "valuePlacement",
          "type": "\"none\" | \"top\" | \"bottom\" | \"right\" | \"left\"",
          "required": false,
          "inheritedFrom": "Slider",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Slider } from '@daisforge/ui';",
      "minimalUsage": "<Slider max={0} min={0} />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в TableCanvas.bigData.stories.tsx",
          "type": "usage",
          "code": "<Slider\n                value={cols}\n                min={1}\n                max={1500}\n                onChangeCommitted={(value) => setCols(value)}\n              />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.CellsMerging/TableCanvas.bigData.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Состояния Состояния Компонент поддерживает состояние  disabled",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { Slider } from '@daisforge/ui';\nexport function App() {\n    const [value, setValue] = useState(50);\n    return (\n        <div style={{ display: 'flex', gap: '1rem', flexDirection: 'column', width: '25rem' }}>\n            <Slider min={0} max={100} value={value} label=\"Активный\" onChange={setValue} />\n            <Slider min={0} max={100} value={50} label=\"Неактивный\" disabled />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Ориентация Ориентация Слайдер поддерживает горизонтальное (по умолчанию) и вертикальное отображение через свойство  orientation",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { Slider } from '@daisforge/ui';\nexport function App() {\n    const [value, setValue] = useState(30);\n    return (\n        <div style={{ width: '25rem', display: 'flex', flexDirection: 'column' }}>\n            <Slider\n                min={0}\n                max={100}\n                value={value}\n                label=\"Громкость\"\n                orientation=\"horizontal\"\n                onChange={setValue}\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "Spinner": {
      "name": "Spinner",
      "group": "components",
      "folderName": "Spinner",
      "role": "primary",
      "description": "Анимированный индикатор загрузки контента или ожидания ответа сервера.",
      "props": [
        {
          "name": "deviceScale",
          "type": "number | undefined",
          "required": false,
          "description": "",
          "deprecated": true
        }
      ],
      "propsTypeName": "SpinnerProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Spinner/Spinner.d.ts",
      "type": "wrapper",
      "atomicBase": "Spinner",
      "category": "Локальные компоненты",
      "keywords": [
        "индикатор загрузки",
        "loading spinner",
        "прелоадер"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\" | \"xs\" | \"xxs\" | \"xl\"",
          "required": false,
          "description": "Размер спиннера",
          "inheritedFrom": "Spinner",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"info\"",
          "required": false,
          "description": "Цвет спиннера",
          "inheritedFrom": "Spinner",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "height",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "Spinner",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "width",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "Spinner",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Spinner } from '@daisforge/ui';",
      "minimalUsage": "<Spinner />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Example 1",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Spinner } from '@daisforge/ui';\nexport function App() {\n    return (\n        <Spinner size=\"l\" />\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Примеры Примеры",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Autocomplete, Cell, Spinner } from '@daisforge/ui';\nexport function App() {\n    const mockData = [\n        { label: 'Алексей Смирнов' },\n        { label: 'Екатерина Иванова' },\n        { label: 'Дмитрий Петров' },\n        { label: 'Ольга Васильева' },\n        { label: 'Сергей Сидоров' },\n        { label: 'Мария Кузнецова' },\n        { label: 'Андрей Попов' },\n        { label: 'Анна Николаева' },\n        { label: 'Иван Федоров' },\n        { label: 'Наталья Морозова' },\n        { label: 'Михаил Павлов' },\n        { label: 'Елена Романова' },\n        { label: 'Владимир Киселев' },\n        { label: 'Татьяна Захарова' },\n        { label: 'Николай Семенов' },\n        { label: 'Юлия Белова' },\n        { label: 'Александр Гусев' },\n        { label: 'Оксана Яковлева' },\n        { label: 'Игорь Егорова' },\n        { label: 'Вера Тихомирова' },\n        { label: 'Артем Григорьев' },\n        { label: 'Евгения Козлова' },\n        { label: 'Максим Лебедев' },\n        { label: 'Виктория Калашникова' },\n        { label: 'Константин Абрамов' },\n        { label: 'Светлана Новикова' },\n        { label: 'Юрий Волков' },\n        { label: 'Валентина Воробьева' },\n        { label: 'Павел Сергеев' },\n        { label: 'Людмила Виноградова' },\n        { label: 'Антон Соловьев' },\n        { label: 'Маргарита Цветкова' },\n        { label: 'Роман Трофимов' },\n        { label: 'Лариса Зайцева' },\n        { label: 'Евгений Никитин' },\n        { label: 'Галина Михайлова' },\n        { label: 'Владислав Антонов' },\n        { label: 'Дарья Филатова' },\n        { label: 'Олег Буров' },\n        { label: 'Инна Медведева' },\n        { label: 'Вячеслав Крылов' },\n        { label: 'Тамара Беляева' },\n        { label: 'Кирилл Марков' },\n        { label: 'Марина Пономарева' },\n        { label: 'Борис Захаров' },\n        { label: 'Жанна Савельева' },\n        { label: 'Федор Жуков' },\n        { label: 'Елизавета Логинова' },\n        { label: 'Виктор Рыбаков' },\n        { label: 'Лилия Макарова' },\n    ];\n    const getData = async (data, page, pageSize = 10) => {\n        return new Promise((resolve) => {\n            setTimeout(() => {\n                resolve({page, data: data.slice(page * pageSize - 1, page * pageSize - 1 + pageSize)})\n            }, 1500)\n        })\n    }\n    const [suggestions, setSuggestions] = useState({ page: 1, data: mockData.slice(0, 10) })\n    \n// … (обрезано)"
        }
      ]
    },
    "SplitView": {
      "name": "SplitView",
      "group": "components",
      "folderName": "SplitView",
      "role": "primary",
      "description": "Двухпанельный layout с изменяемой шириной боковой панели и её fullscreen-режимом.",
      "props": [
        {
          "name": "mainContent",
          "type": "React.ReactNode",
          "required": true,
          "description": "Prop для основного контента (слева)"
        },
        {
          "name": "headerHeight",
          "type": "number | undefined",
          "required": false,
          "description": "Высота шапки в пикселях. Если передан — используется как приоритет для sticky top и расчёта высоты.\nЕсли не передан — берётся из CSS-переменной --global-header-height (fallback 72px)."
        },
        {
          "name": "insidePageLayout",
          "type": "boolean | undefined",
          "required": false,
          "description": "Компенсация padding-inline от PageLayout.\nПри true контейнер SplitView получает отрицательный margin-right,\nчтобы sidebar прижимался к правому краю viewport.",
          "default": "false"
        },
        {
          "name": "sidebar",
          "type": "{ content: SplitViewAdaptiveContent; isOpened?: boolean | undefined; isFullScreened?: boolean | undefined; fullScreenedModalDFProps?: ModalDFProps | undefined; defaultWidthPercent?: number | undefined; maxWidthPercent?: number | undefined; minWidthPx?: number | undefined; paddingLeftOnClosed?: number | undefined; } | undefined",
          "required": false,
          "description": "Prop свойств sidebar-а (справа), в том числе и контента"
        },
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onResize",
          "type": "((data: SplVSizes) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "refContainer",
          "type": "React.Ref<HTMLDivElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "disableMediaAdaptive",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отключает принудительный адаптив компонента на viewport <= 1280px.",
          "deprecated": true,
          "default": "false"
        }
      ],
      "propsTypeName": "SplitViewProps",
      "sourceFile": "packages/ui-kit/src/components/SplitView/SplitView.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "split screen",
        "resizable панель",
        "мастер-детейл layout"
      ],
      "docs": "# SplitView\n\nКонтейнер с возможностью разделения основного контента и дополнительного в боковом меню.\n\n## Ключевые особенности\n\n- Resize через разделитель между контентами (зажатие и движение курсора)\n- Полноэкранный режим для sidebar\n- Скрытие sidebar полностью\n- Гибкая настройка ширины sidebar в процентах и пикселях\n- Колбек `onResize` для отслеживания размеров\n\n## CSS-переменные\n\n- `--main-width` — ширина основного блока\n- `--separator-width` — ширина разделителя\n- `--sidebar-width` — ширина sidebar\n- `--sidebar-width-in-px` — ширина sidebar в пикселях\n\n## Особенности\n\n- Объект `splitViewClassNames` доступен для импорта. Включает классы: `container`, `separator`, `separatorButton`, `mainBlock`, `sidebarBlock` и другие\n- Как контентный заполнитель для sidebar рекомендуется использовать компонент Widget с его compound-компонентами\n- При использовании внутри PageLayout установите `insidePageLayout={true}`\n- `sidebar.content` принимает `ReactNode` или callback с размерами для адаптива\n- По умолчанию адаптив на viewport `<= 1280px` включен; временно отключить его можно через deprecated-проп `disableMediaAdaptive`\n\n## Использование адаптивного sidebar.content\n\nЕсли контент sidebar не должен менять размеры, передавайте обычный `ReactNode`:\n\n```tsx\n<SplitView\n  mainContent={<Content />}\n  sidebar={{\n    isOpened: true,\n    content: <Widget />,\n  }}\n/>\n```\n\nЕсли внутри sidebar есть Avatar, который должен уменьшаться на 1280px, передавайте callback и используйте `avatarSize` из аргумента:\n\n```tsx\n<SplitView\n  mainContent={<Content />}\n  sidebar={{\n    isOpened: true,\n    content: ({ avatarSize }) => (\n      <Widget>\n        <Widget.Header\n          title=\"Заголовок\"\n          titleLeftSlot={<Avatar size={avatarSize} name=\"User\" />}\n        />\n      </Widget>\n    ),\n  }}\n/>\n```\n\nРазмер, который приходит в callback:\n\n```\navatarSize\n| viewport <= 1280px  | viewport > 1280px |\n| m                   | l                 |\n```\n\nДефолтный min-width sidebar:\n\n```\nsidebar min-width\n| viewport <= 1280px | viewport > 1280px |\n| 440px              | 600px             |\n```\n\nОписание типов — в разделе [API](/docs/композиции-splitview-api--docs).",
      "apiDocs": "# SplitView API\n\n## SplitViewProps\n\n```typescript\ntype SplitViewProps = Omit<ComponentProps<'div'>, 'ref' | 'onResize'> & {\n  /**\n   * Prop для основного контента (слева)\n   */\n  mainContent: ReactNode;\n  /**\n   * Prop свойств sidebar-а (справа), в том числе и контента\n   */\n  sidebar?: {\n    /**\n     * Prop для контента sidebar-а\n     * Можно передать ReactNode или callback с размерами для адаптива.\n     */\n    content: SplitViewAdaptiveContent;\n    /**\n     * Состояние открытости sidebar-а (sidebar может полностью закрываться)\n     * @default true\n     */\n    isOpened?: boolean;\n    /**\n     * Состояние открытости полноэкранного режима sidebar-а.\n     * Открытие sidebar-а в модальном окне на всю ширину экрана\n     * @default false\n     */\n    isFullScreened?: boolean;\n    /**\n     * Для переопределения (или добавления) свойств модального окна.\n     * Не все свойства можно переопределить.\n     */\n    fullScreenedModalDFProps?: ModalDFProps;\n    /**\n     * Число от 1 до 100. Процент от ширины родителя.\n     * Величина sidebar-а ширины по умолчанию в %-ых значениях от родителя\n     * @default 30\n     */\n    defaultWidthPercent?: number;\n    /**\n     * Число от 1 до 100. Процент от ширины родителя.\n     * @default 70\n     */\n    maxWidthPercent?: number;\n    /**\n     * Число в пикселях\n     * @default 600, на viewport <= 1280px — 440\n     */\n    minWidthPx?: number;\n    /**\n     * Отступ слева у sidebar в px, когда он будет закрыт (Указывать до 32px - не больше).\n     * Может понадобится для корректного смещения SplitView вправо.\n     * @example 32\n     *\n     * @default 0\n     */\n    paddingLeftOnClosed?: number;\n  };\n  /**\n   * Отключает принудительный адаптив компонента на viewport <= 1280px.\n   *\n   * @deprecated Используйте только в крайних случаях, когда команда временно не готова адаптировать вёрстку под 1280px.\n   *\n   * @remarks\n   * При `true` компонент использует desktop-размеры для `sidebar.content` и desktop min-width sidebar, если `sidebar.minWidthPx` не передан.\n   * Поведение сохраняется даже на viewport <= 1280px.\n   * Это временный escape hatch, не основной сценарий использования.\n   *\n   * @default false\n   */\n  disableMediaAdaptive?: boolean;\n  refContainer?: Ref<HTMLDivElement>;\n  $css?: string | CSSObject | FlattenSimpleInterpolation;\n  onResize?: (data: SplVSizes) => void;\n  /**\n   * Высота шапки в пикселях. Если передан — используется как приоритет для sticky top и расчёта высоты.\n   * Если не передан — берётся из CSS-переменной --global-header-height (fallback 72px).\n   */\n  headerHeight?: number;\n  /**\n   * Компенсация padding-inline от PageLayout.\n   * При true контейнер SplitView получает отрицательный margin-right,\n   * чтобы sidebar прижимался к правому краю viewport.\n   * @default false\n   */\n  insidePageLayout?: boolean;\n};\n\nexport type SplVSizes = {\n  /**\n   * Ширина main content в процентах\n   */\n  main: number;\n  /**\n   * Ширина main content в пикселях\n   */\n  mainPx?: number;\n  /**\n   * Ширина sidebar content в процентах\n   */\n  sidebar: number;\n  /**\n   * Ширина sidebar content в пикселях\n   */\n  sidebarPx?: number;\n};\n```\n\n## SplitViewSlotSizesProps\n\n```typescript\ntype SplitViewSlotSizesProps = {\n  /**\n   * Размер Avatar в кастомном контенте sidebar\n   */\n  avatarSize: 'l' | 'm';\n};\n```\n\n## SplitViewAdaptiveContent\n\n```typescript\ntype SplitViewAdaptiveContent =\n  | ReactNode\n  | ((props: SplitViewSlotSizesProps) => ReactNode);\n```\n\n## SplVSizes\n\n```typescript\ntype SplVSizes = {\n  /**\n   * Ширина main content в процентах\n   */\n  main: number;\n  /**\n   * Ширина main content в пикселях\n   */\n  mainPx?: number;\n  /**\n   * Ширина sidebar content в процентах\n   */\n  sidebar: number;\n  /**\n   * Ширина sidebar content в пикселях\n   */\n  sidebarPx?: number;\n};\n```\n\n## CSS-переменные\n\n- `--main-width` — ширина основного блока\n- `--separator-width` — ширина разделителя\n- `--sidebar-width` — ширина sidebar\n- `--sidebar-width-in-px` — ширина sidebar в пикселях",
      "curatedStories": [
        {
          "exportName": "SplitViewStory",
          "displayName": "SplitView",
          "type": "full-code",
          "code": "import { createRows, type Row } from './tableData';\nimport {\n  IconChevronLeft,\n  IconChevronRight,\n  Avatar,\n  SplitView,\n  backgroundPrimary,\n  Badge,\n  Button,\n  ColumnConfig,\n  Flow,\n  H2,\n  IconButton,\n  s,\n  Table,\n  Widget,\n} from '@daisforge/ui';\nimport type { SplitViewSlotSizesProps } from '@daisforge/ui';\nimport { useBreakpoint } from '@ui-kit/utils';\nimport React, { useMemo, useState } from 'react';\n\n\n${getFuncAsString(\n  'packages/storybook/src/stories/SplitView/SplitView.stories.tsx',\n  'SplitViewTableComponent',\n)}\n\n() => {\n    const [rows] = useState(createRows);\n    const [openedTask, setOpenedTask] = useState<Row | null>(null);\n    const [sidebarIsOpened, setSidebarIsOpened] = useState(false);\n    const [sidebarIsFullScreened, setSidebarIsFullScreened] = useState(false);\n    const { down } = useBreakpoint();\n    const sidebarMinWidthPx = down('xl') ? 530 : undefined;\n    const openTaskSidebar = (row: Row) => {\n      setOpenedTask(row);\n      setSidebarIsOpened(true);\n    };\n    const toggleFullScreen = () => {\n      setSidebarIsFullScreened((prev) => !prev);\n    };\n    const onSidebarEsc = () => {\n      setSidebarIsFullScreened(false);\n      setSidebarIsOpened(false);\n      setTimeout(() => {\n        setOpenedTask(null);\n      }, 300);\n    };\n\n    return (\n      <div style={{ backgroundColor: backgroundPrimary }}>\n        <StoryHeader>Header FinAI</StoryHeader>\n\n        <SplitView\n          // стилизация для примера\n          $css={{ marginInline: -16, paddingLeft: 16 }}\n          mainContent={\n            <div style={{ paddingBlock: s.x12 }}>\n              <H2 style={{ paddingBlock: s.x8 }}>Основной контент</H2>\n              <SplitViewTableComponent\n                rows={rows}\n                setOpenedTask={openTaskSidebar}\n              />\n            </div>\n          }\n          sidebar={{\n            isOpened: sidebarIsOpened,\n            isFullScreened: sidebarIsFullScreened,\n            minWidthPx: sidebarMinWidthPx,\n            // стилизация для примера\n            paddingLeftOnClosed: 16,\n            content: ({ avatarSize }: SplitViewSlotSizesProps) => (\n              <Widget\n                containerType={sidebarIsFullScreened ? 'modal' : 'splitView'}\n              >\n                <Widget.Header\n                  onClose={onSidebarEsc}\n                  fullScreened={sidebarIsFullScreened}\n                  toggleFullScreened={toggleFullScreen}\n                  title={`Обработка документов по ${openedTask?.id}`}\n                  titleLeftSlot={\n                    <Avatar size={avatarSize} name={openedTask?.task ?? ''} />\n                  }\n                  rightBlock={\n                    <>\n                      <Widget.IconButtonDots\n                        size=\"xs\"\n                        iconSize=\"xs\"\n                        iconOrientation=\"vertical\"\n                        dropdownProps={{\n                          items: [\n                            { label: 'label 1', value: '1' },\n                            { label: 'label 2', value: '2' },\n                          ],\n                        }}\n                      />\n                      <Widget.Divider />\n                      <Flow mainAxisGap={s.x2}>\n                        <IconButton view=\"secondary\" size=\"xs\">\n                          <IconChevronLeft size=\"xs\" />\n                        </IconButton>\n                        <IconButton view=\"secondary\" size=\"xs\">\n                          <IconChevronRight size=\"xs\" />\n                        </IconButton>\n                      </Flow>\n                    </>\n                  }\n                  badge={{ text: 'Бейдж' }}\n                  bottomBlock={\n                    <div style={{ display: 'flex', gap: s.x2 }}>\n                      <Badge\n                        size=\"s\"\n                        transparent\n                        view=\"accent\"\n                        text=\"В работе\"\n                      />\n                      <Badge\n                        size=\"s\"\n                        transparent\n                        view=\"negative\"\n                        text=\"2-й раз\"\n                      />\n                    </div>\n                  }\n                />\n\n                <Widget.Content>\n                  <div\n                    style={{ height: '2000px', backgroundColor: 'goldenrod' }}\n                  >\n                    <span\n                      style={{\n                        position: 'absolute',\n                        right: 0,\n                        width: '4px',\n                        backgroundColor: 'teal',\n                      }}\n                    />\n                  </div>\n                </Widget.Content>\n\n                <Widget.Footer\n                  leftBlock={\n                    <Flow mainAxisGap={s.x4}>\n                      <Button text=\"Кнопка 1\" size=\"xs\" view=\"secondary\" />\n                      <Widget.IconButtonDots size=\"xs\" />\n                    </Flow>\n                  }\n                  rightBlock={\n                    <Flow mainAxisGap={s.x4}>\n                      <Button text=\"Кнопка\" size=\"xs\" view=\"secondary\" />\n                      <Button text=\"Главная кнопка\" size=\"xs\" view=\"accent\" />\n                    </Flow>\n                  }\n                />\n              </Widget>\n            ),\n          }}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "SplitViewWithTabsStory",
          "displayName": "SplitView + Tabs Icon Vertical",
          "type": "full-code",
          "code": "import { createRows, type Row } from './tableData';\nimport {\n  IconChevronLeft,\n  IconChevronRight,\n  Avatar,\n  SplitView,\n  backgroundPrimary,\n  Badge,\n  Button,\n  ColumnConfig,\n  Divider,\n  Flow,\n  H2,\n  IconButton,\n  IconTabItem,\n  s,\n  Table,\n  Tabs,\n  Widget,\n} from '@daisforge/ui';\nimport { IconPlasma } from '@ui-kit/icons';\nimport type { SplitViewSlotSizesProps } from '@daisforge/ui';\nimport { useBreakpoint } from '@ui-kit/utils';\nimport React, { useMemo, useState } from 'react';\n\n\n${getFuncAsString(\n  'packages/storybook/src/stories/SplitView/SplitView.stories.tsx',\n  'SplitViewTableComponent',\n)}\n\n() => {\n    const [rows] = useState(createRows);\n    const [openedTask, setOpenedTask] = useState<Row | null>(null);\n    const [sidebarIsOpened, setSidebarIsOpened] = useState(false);\n    const [sidebarIsFullScreened, setSidebarIsFullScreened] = useState(false);\n    const [activeTab, setActiveTab] = useState(0);\n    const { down } = useBreakpoint();\n    const sidebarMinWidthPx = down('xl') ? 530 : undefined;\n\n    const tabItems = [0, 1, 2, 3, 4];\n\n    const openTaskSidebar = (row: Row) => {\n      setOpenedTask(row);\n      setSidebarIsOpened(true);\n    };\n    const toggleFullScreen = () => {\n      setSidebarIsFullScreened((prev) => !prev);\n    };\n    const onSidebarEsc = () => {\n      setSidebarIsFullScreened(false);\n      setSidebarIsOpened(false);\n      setTimeout(() => {\n        setOpenedTask(null);\n      }, 300);\n    };\n\n    return (\n      <div style={{ backgroundColor: backgroundPrimary }}>\n        <StoryHeader>Header FinAI</StoryHeader>\n\n        <SplitView\n          $css={{ marginInline: -16, paddingLeft: 16 }}\n          mainContent={\n            <div style={{ paddingBlock: s.x12 }}>\n              <H2 style={{ paddingBlock: s.x8 }}>Основной контент</H2>\n              <SplitViewTableComponent\n                rows={rows}\n                setOpenedTask={openTaskSidebar}\n              />\n            </div>\n          }\n          sidebar={{\n            isOpened: sidebarIsOpened,\n            isFullScreened: sidebarIsFullScreened,\n            minWidthPx: sidebarMinWidthPx,\n            paddingLeftOnClosed: 16,\n            content: ({ avatarSize }: SplitViewSlotSizesProps) => (\n              <div style={{ display: 'flex', height: '100%' }}>\n                {/* Tabs Icon Vertical S — СЛЕВА */}\n                <Tabs\n                  orientation=\"vertical\"\n                  size=\"s\"\n                  view=\"divider\"\n                  style={{ alignSelf: 'flex-start', paddingTop: s.x8 }}\n                >\n                  {tabItems.map((id, i) => (\n                    <IconTabItem\n                      key={`tab:${id}`}\n                      selected={i === activeTab}\n                      onClick={() => setActiveTab(i)}\n                      orientation=\"vertical\"\n                      view=\"divider\"\n                      size=\"s\"\n                      tabIndex={0}\n                      style={{ padding: `${s.x4} 10px ${s.x3} 10px` }}\n                    >\n                      <IconPlasma color=\"inherit\" />\n                    </IconTabItem>\n                  ))}\n                </Tabs>\n\n                {/* Divider вертикальный между табами и Widget */}\n                <Divider orientation=\"vertical\" />\n\n                {/* Основной контент Widget — СПРАВА */}\n                <Widget\n                  containerType={sidebarIsFullScreened ? 'modal' : 'splitView'}\n                  style={{ flex: 1, minWidth: 0 }}\n                >\n                  <Widget.Header\n                    onClose={onSidebarEsc}\n                    fullScreened={sidebarIsFullScreened}\n                    toggleFullScreened={toggleFullScreen}\n                    title={`Обработка документов по ${openedTask?.id}`}\n                    titleLeftSlot={\n                      <Avatar size={avatarSize} name={openedTask?.task ?? ''} />\n                    }\n                    rightBlock={\n                      <>\n                        <Widget.IconButtonDots\n                          size=\"xs\"\n                          iconSize=\"xs\"\n                          iconOrientation=\"vertical\"\n                          dropdownProps={{\n                            items: [\n                              { label: 'label 1', value: '1' },\n                              { label: 'label 2', value: '2' },\n                            ],\n                          }}\n                        />\n                        <Widget.Divider />\n                        <Flow mainAxisGap={s.x2}>\n                          <IconButton view=\"secondary\" size=\"xs\">\n                            <IconChevronLeft size=\"xs\" />\n                          </IconButton>\n                          <IconButton view=\"secondary\" size=\"xs\">\n                            <IconChevronRight size=\"xs\" />\n                          </IconButton>\n                        </Flow>\n                      </>\n                    }\n                    badge={{ text: 'Бейдж' }}\n                    bottomBlock={\n                      <div style={{ display: 'flex', gap: s.x2 }}>\n                        <Badge\n                          size=\"s\"\n                          transparent\n                          view=\"accent\"\n                          text=\"В работе\"\n                        />\n                        <Badge\n                          size=\"s\"\n                          transparent\n                          view=\"negative\"\n                          text=\"2-й раз\"\n                        />\n                      </div>\n                    }\n                  />\n\n                  <Widget.Content>\n                    <div\n                      style={{\n                        height: '2000px',\n                        backgroundColor: 'goldenrod',\n                      }}\n                    >\n                      Кастомный слот — Tab {activeTab + 1}\n                    </div>\n                  </Widget.Content>\n\n                  <Widget.Footer\n                    leftBlock={\n                      <Flow mainAxisGap={s.x4}>\n                        <Button text=\"Кнопка 1\" size=\"xs\" view=\"secondary\" />\n                        <Widget.IconButtonDots size=\"xs\" />\n                      </Flow>\n                    }\n                    rightBlock={\n                      <Flow mainAxisGap={s.x4}>\n                        <Button text=\"Кнопка\" size=\"xs\" view=\"secondary\" />\n                        <Button text=\"Главная кнопка\" size=\"xs\" view=\"accent\" />\n                      </Flow>\n                    }\n                  />\n                </Widget>\n              </div>\n            ),\n          }}\n        />\n      </div>\n    );\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { SplitView } from '@daisforge/ui';",
      "minimalUsage": "<SplitView mainContent={'Контент'} />",
      "examples": [
        {
          "exportName": "SplitViewStory",
          "displayName": "SplitView",
          "type": "full-code",
          "code": "import { createRows, type Row } from './tableData';\nimport {\n  IconChevronLeft,\n  IconChevronRight,\n  Avatar,\n  SplitView,\n  backgroundPrimary,\n  Badge,\n  Button,\n  ColumnConfig,\n  Flow,\n  H2,\n  IconButton,\n  s,\n  Table,\n  Widget,\n} from '@daisforge/ui';\nimport type { SplitViewSlotSizesProps } from '@daisforge/ui';\nimport { useBreakpoint } from '@ui-kit/utils';\nimport React, { useMemo, useState } from 'react';\n\n\n${getFuncAsString(\n  'packages/storybook/src/stories/SplitView/SplitView.stories.tsx',\n  'SplitViewTableComponent',\n)}\n\n() => {\n    const [rows] = useState(createRows);\n    const [openedTask, setOpenedTask] = useState<Row | null>(null);\n    const [sidebarIsOpened, setSidebarIsOpened] = useState(false);\n    const [sidebarIsFullScreened, setSidebarIsFullScreened] = useState(false);\n    const { down } = useBreakpoint();\n    const sidebarMinWidthPx = down('xl') ? 530 : undefined;\n    const openTaskSidebar = (row: Row) => {\n      setOpenedTask(row);\n      setSidebarIsOpened(true);\n    };\n    const toggleFullScreen = () => {\n      setSidebarIsFullScreened((prev) => !prev);\n    };\n    const onSidebarEsc = () => {\n      setSidebarIsFullScreened(false);\n      setSidebarIsOpened(false);\n      setTimeout(() => {\n        setOpenedTask(null);\n      }, 300);\n    };\n\n    return (\n      <div style={{ backgroundColor: backgroundPrimary }}>\n        <StoryHeader>Header FinAI</StoryHeader>\n\n        <SplitView\n          // стилизация для примера\n          $css={{ marginInline: -16, paddingLeft: 16 }}\n          mainContent={\n            <div style={{ paddingBlock: s.x12 }}>\n              <H2 style={{ paddingBlock: s.x8 }}>Основной контент</H2>\n              <SplitViewTableComponent\n                rows={rows}\n                setOpenedTask={openTaskSidebar}\n              />\n            </div>\n          }\n          sidebar={{\n            isOpened: sidebarIsOpened,\n            isFullScreened: sidebarIsFullScreened,\n            minWidthPx: sidebarMinWidthPx,\n            // стилизация для примера\n            paddingLeftOnClosed: 16,\n            content: ({ avatarSize }: SplitViewSlotSizesProps) => (\n              <Widget\n                containerType={sidebarIsFullScreened ? 'modal' : 'splitView'}\n              >\n                <Widget.Header\n                  onClose={onSidebarEsc}\n                  fullScreened={sidebarIsFullScreened}\n                  toggleFullScreened={toggleFullScreen}\n                  title={`Обработка документов по ${openedTask?.id}`}\n                  titleLeftSlot={\n                    <Avatar size={avatarSize} name={openedTask?.task ?? ''} />\n                  }\n                  rightBlock={\n                    <>\n                      <Widget.IconButtonDots\n                        size=\"xs\"\n                        iconSize=\"xs\"\n                        iconOrientation=\"vertical\"\n                        dropdownProps={{\n                          items: [\n                            { label: 'label 1', value: '1' },\n                            { label: 'label 2', value: '2' },\n                          ],\n                        }}\n                      />\n                      <Widget.Divider />\n                      <Flow mainAxisGap={s.x2}>\n                        <IconButton view=\"secondary\" size=\"xs\">\n                          <IconChevronLeft size=\"xs\" />\n                        </IconButton>\n                        <IconButton view=\"secondary\" size=\"xs\">\n                          <IconChevronRight size=\"xs\" />\n                        </IconButton>\n                      </Flow>\n                    </>\n                  }\n                  badge={{ text: 'Бейдж' }}\n                  bottomBlock={\n                    <div style={{ display: 'flex', gap: s.x2 }}>\n                      <Badge\n                        size=\"s\"\n                        transparent\n                        view=\"accent\"\n                        text=\"В работе\"\n                      />\n                      <Badge\n                        size=\"s\"\n                        transparent\n                        view=\"negative\"\n                        text=\"2-й раз\"\n                      />\n                    </div>\n                  }\n                />\n\n                <Widget.Content>\n                  <div\n                    style={{ height: '2000px', backgroundColor: 'goldenrod' }}\n                  >\n                    <span\n                      style={{\n                        position: 'absolute',\n                        right: 0,\n                        width: '4px',\n                        backgroundColor: 'teal',\n                      }}\n                    />\n                  </div>\n                </Widget.Content>\n\n                <Widget.Footer\n                  leftBlock={\n                    <Flow mainAxisGap={s.x4}>\n                      <Button text=\"Кнопка 1\" size=\"xs\" view=\"secondary\" />\n                      <Widget.IconButtonDots size=\"xs\" />\n                    </Flow>\n                  }\n                  rightBlock={\n                    <Flow mainAxisGap={s.x4}>\n                      <Button text=\"Кнопка\" size=\"xs\" view=\"secondary\" />\n                      <Button text=\"Главная кнопка\" size=\"xs\" view=\"accent\" />\n                    </Flow>\n                  }\n                />\n              </Widget>\n            ),\n          }}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "SplitViewWithTabsStory",
          "displayName": "SplitView + Tabs Icon Vertical",
          "type": "full-code",
          "code": "import { createRows, type Row } from './tableData';\nimport {\n  IconChevronLeft,\n  IconChevronRight,\n  Avatar,\n  SplitView,\n  backgroundPrimary,\n  Badge,\n  Button,\n  ColumnConfig,\n  Divider,\n  Flow,\n  H2,\n  IconButton,\n  IconTabItem,\n  s,\n  Table,\n  Tabs,\n  Widget,\n} from '@daisforge/ui';\nimport { IconPlasma } from '@ui-kit/icons';\nimport type { SplitViewSlotSizesProps } from '@daisforge/ui';\nimport { useBreakpoint } from '@ui-kit/utils';\nimport React, { useMemo, useState } from 'react';\n\n\n${getFuncAsString(\n  'packages/storybook/src/stories/SplitView/SplitView.stories.tsx',\n  'SplitViewTableComponent',\n)}\n\n() => {\n    const [rows] = useState(createRows);\n    const [openedTask, setOpenedTask] = useState<Row | null>(null);\n    const [sidebarIsOpened, setSidebarIsOpened] = useState(false);\n    const [sidebarIsFullScreened, setSidebarIsFullScreened] = useState(false);\n    const [activeTab, setActiveTab] = useState(0);\n    const { down } = useBreakpoint();\n    const sidebarMinWidthPx = down('xl') ? 530 : undefined;\n\n    const tabItems = [0, 1, 2, 3, 4];\n\n    const openTaskSidebar = (row: Row) => {\n      setOpenedTask(row);\n      setSidebarIsOpened(true);\n    };\n    const toggleFullScreen = () => {\n      setSidebarIsFullScreened((prev) => !prev);\n    };\n    const onSidebarEsc = () => {\n      setSidebarIsFullScreened(false);\n      setSidebarIsOpened(false);\n      setTimeout(() => {\n        setOpenedTask(null);\n      }, 300);\n    };\n\n    return (\n      <div style={{ backgroundColor: backgroundPrimary }}>\n        <StoryHeader>Header FinAI</StoryHeader>\n\n        <SplitView\n          $css={{ marginInline: -16, paddingLeft: 16 }}\n          mainContent={\n            <div style={{ paddingBlock: s.x12 }}>\n              <H2 style={{ paddingBlock: s.x8 }}>Основной контент</H2>\n              <SplitViewTableComponent\n                rows={rows}\n                setOpenedTask={openTaskSidebar}\n              />\n            </div>\n          }\n          sidebar={{\n            isOpened: sidebarIsOpened,\n            isFullScreened: sidebarIsFullScreened,\n            minWidthPx: sidebarMinWidthPx,\n            paddingLeftOnClosed: 16,\n            content: ({ avatarSize }: SplitViewSlotSizesProps) => (\n              <div style={{ display: 'flex', height: '100%' }}>\n                {/* Tabs Icon Vertical S — СЛЕВА */}\n                <Tabs\n                  orientation=\"vertical\"\n                  size=\"s\"\n                  view=\"divider\"\n                  style={{ alignSelf: 'flex-start', paddingTop: s.x8 }}\n                >\n                  {tabItems.map((id, i) => (\n                    <IconTabItem\n                      key={`tab:${id}`}\n                      selected={i === activeTab}\n                      onClick={() => setActiveTab(i)}\n                      orientation=\"vertical\"\n                      view=\"divider\"\n                      size=\"s\"\n                      tabIndex={0}\n                      style={{ padding: `${s.x4} 10px ${s.x3} 10px` }}\n                    >\n                      <IconPlasma color=\"inherit\" />\n                    </IconTabItem>\n                  ))}\n                </Tabs>\n\n                {/* Divider вертикальный между табами и Widget */}\n                <Divider orientation=\"vertical\" />\n\n                {/* Основной контент Widget — СПРАВА */}\n                <Widget\n                  containerType={sidebarIsFullScreened ? 'modal' : 'splitView'}\n                  style={{ flex: 1, minWidth: 0 }}\n                >\n                  <Widget.Header\n                    onClose={onSidebarEsc}\n                    fullScreened={sidebarIsFullScreened}\n                    toggleFullScreened={toggleFullScreen}\n                    title={`Обработка документов по ${openedTask?.id}`}\n                    titleLeftSlot={\n                      <Avatar size={avatarSize} name={openedTask?.task ?? ''} />\n                    }\n                    rightBlock={\n                      <>\n                        <Widget.IconButtonDots\n                          size=\"xs\"\n                          iconSize=\"xs\"\n                          iconOrientation=\"vertical\"\n                          dropdownProps={{\n                            items: [\n                              { label: 'label 1', value: '1' },\n                              { label: 'label 2', value: '2' },\n                            ],\n                          }}\n                        />\n                        <Widget.Divider />\n                        <Flow mainAxisGap={s.x2}>\n                          <IconButton view=\"secondary\" size=\"xs\">\n                            <IconChevronLeft size=\"xs\" />\n                          </IconButton>\n                          <IconButton view=\"secondary\" size=\"xs\">\n                            <IconChevronRight size=\"xs\" />\n                          </IconButton>\n                        </Flow>\n                      </>\n                    }\n                    badge={{ text: 'Бейдж' }}\n                    bottomBlock={\n                      <div style={{ display: 'flex', gap: s.x2 }}>\n                        <Badge\n                          size=\"s\"\n                          transparent\n                          view=\"accent\"\n                          text=\"В работе\"\n                        />\n                        <Badge\n                          size=\"s\"\n                          transparent\n                          view=\"negative\"\n                          text=\"2-й раз\"\n                        />\n                      </div>\n                    }\n                  />\n\n                  <Widget.Content>\n                    <div\n                      style={{\n                        height: '2000px',\n                        backgroundColor: 'goldenrod',\n                      }}\n                    >\n                      Кастомный слот — Tab {activeTab + 1}\n                    </div>\n                  </Widget.Content>\n\n                  <Widget.Footer\n                    leftBlock={\n                      <Flow mainAxisGap={s.x4}>\n                        <Button text=\"Кнопка 1\" size=\"xs\" view=\"secondary\" />\n                        <Widget.IconButtonDots size=\"xs\" />\n                      </Flow>\n                    }\n                    rightBlock={\n                      <Flow mainAxisGap={s.x4}>\n                        <Button text=\"Кнопка\" size=\"xs\" view=\"secondary\" />\n                        <Button text=\"Главная кнопка\" size=\"xs\" view=\"accent\" />\n                      </Flow>\n                    }\n                  />\n                </Widget>\n              </div>\n            ),\n          }}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в PageLayout.stories.tsx",
          "type": "usage",
          "code": "<SplitView\n          insidePageLayout\n          mainContent={\n            <Layout\n              variant=\"V1_1\"\n              marginTop=\"0\"\n              marginBottom=\"0\"\n              paddingTop=\"16px\"\n              headerSlot={DefaultPageHeader}\n              mainSlot={<LongContentBlocks count={25} />}\n            />\n          }\n          sidebar={{\n            content: (\n              <SidebarContent>\n                <Widget>\n                  <Widget.Header title=\"Фильтры\" />\n                  <Widget.Content>\n                    Sticky sidebar — не скроллится вместе с основным контентом\n                  </Widget.Content>\n                </Widget>\n              </SidebarContent>\n            ),\n            isOpened: sidebarOpen,\n            defaultWidthPercent: 25,\n          }}\n        />",
          "sourceFile": "packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в SplitViewAndListOfFilters.tsx",
          "type": "usage",
          "code": "<SplitView\n          headerHeight={56}\n          mainContent={\n            <div>\n              {/* Полоска фильтров - здесь может быть дёрганье при открытии sidebar */}\n              <ListOfFilters\n                opened={filterListOpened}\n                items={filterList}\n                clearAll={clearAll}\n              />\n\n              {/* Имитация основного контента */}\n              <div style={{ padding: 16 }}>\n                <h3>Основной контент (mainContent)</h3>\n                <p style={{ color: '#666' }}>\n                  Выберите фильтры кнопками сверху, затем откройте/закройте\n                  sidebar.\n                  <br />\n                  Наблюдайте за полоской чипов — при анимации sidebar она будет\n                  дёргаться.\n                </p>\n                <div\n                  style={{\n                    marginTop: 16,\n                    padding: 16,\n                    background: '#f5f5f5',\n                    borderRadius: 8,\n                    fontFamily: 'monospace',\n                    fontSize: 13,\n                  }}\n                >\n                  <div>Текущие фильтры:</div>\n                  <pre>{JSON.stringify(filters, null, 2)}</pre>\n                </div>\n              </div>\n            </div>\n          }\n          sidebar={{\n            isOpened: sidebarOpened,\n            content: (\n              <div style={{ padding: 16, height: '100%' }}>\n                <h3>Sidebar</h3>\n                <p style={{ color: '#666' }}>\n                  Контент бокового меню. Потяните разделитель для ресайза.\n                </p>\n                <button\n                  onClick={() => setSidebarOpened(false)}\n                  style={{\n                    marginTop: 12,\n                    padding: '6px 12px',\n                    border: '1px solid #ccc',\n                    borderRadius: 4,\n                    cursor: 'pointer',\n                  }}\n                >\n                  Закрыть\n                </button>\n              </div>\n            ),\n          }}\n        />",
          "sourceFile": "packages/vite-project/src/pages/SplitViewAndListOfFilters.tsx"
        }
      ]
    },
    "Steps": {
      "name": "Steps",
      "group": "components",
      "folderName": "Steps",
      "role": "primary",
      "description": "Пошаговый индикатор прогресса (степпер) для многошаговых процессов и визардов.",
      "props": [],
      "propsTypeName": "ComponentProps<typeof Steps>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Steps/Steps.d.ts",
      "type": "wrapper",
      "atomicBase": "Steps",
      "category": "Локальные компоненты",
      "keywords": [
        "степпер",
        "wizard",
        "прогресс по шагам",
        "шаги"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "contentAlign",
          "type": "StepsContentAlign",
          "required": false,
          "description": "Выравнивание контента в шагах",
          "default": "'left'",
          "inheritedFrom": "Steps",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "current",
          "type": "number",
          "required": false,
          "description": "Индекс текущего шага, для uncontrolled компонента",
          "inheritedFrom": "Steps",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasContent",
          "type": "StepsContent",
          "required": false,
          "description": "Режим отображения контента",
          "default": "'all'",
          "inheritedFrom": "Steps",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasLine",
          "type": "boolean",
          "required": false,
          "description": "Включает разделительную линию",
          "default": "true",
          "inheritedFrom": "Steps",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasLoader",
          "type": "boolean",
          "required": false,
          "description": "Отображает loader вместо индикатора активного шага.",
          "inheritedFrom": "Steps",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "items",
          "type": "StepItemProps[]",
          "required": false,
          "description": "Массив шагов",
          "default": "[]",
          "inheritedFrom": "Steps",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "itemView",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\"",
          "required": false,
          "description": "Отображение элемента шага",
          "inheritedFrom": "Steps",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "((item: StepItemProps, index: number, prevIndex?: number) => void)",
          "required": false,
          "description": "Обработчик изменения шага, делает индикаторы и заголовки шагов кликабельными",
          "inheritedFrom": "Steps",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "orientation",
          "type": "StepsOrientation",
          "required": false,
          "description": "Ориентация компонента",
          "default": "'horizontal'",
          "inheritedFrom": "Steps",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\" | \"xs\"",
          "required": false,
          "description": "Размер шага",
          "inheritedFrom": "Steps",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "status",
          "type": "StepStatus",
          "required": false,
          "description": "Статус текущего шага, имеет приоритет над item.status",
          "inheritedFrom": "Steps",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\"",
          "required": false,
          "description": "Отображение шага",
          "inheritedFrom": "Steps",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Steps } from '@daisforge/ui';",
      "minimalUsage": "<Steps />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Внешнее управление",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { Steps, Button } from '@daisforge/ui';\nexport function App() {\n    const items = [{\n        indicator: 1,\n    }, {\n        indicator: 2,\n    }, {\n        indicator: 3,\n    }];\n    const [current, setCurrent] = useState(0);\n    const onClick = () => setCurrent((prev) => prev + 1);\n    return (\n        <section>\n            <Steps items={items} current={current} />\n            <br />\n            <Button view=\"secondary\" onClick={onClick}>\n                Next\n            </Button>\n        </section>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Внешний вид",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Steps } from '@daisforge/ui';\nexport function App() {\n    const completedItems = [{\n        indicator: 1,\n        title: 'Title',\n        status: 'completed',\n    }, {\n        indicator: 2,\n        title: 'Title',\n        status: 'active',\n    }, {\n        indicator: 3,\n        title: 'Title',\n        status: 'inactive',\n    }];\n    return (\n        <div style={{ display: 'flex', gap: '2rem', flexDirection: 'column' }}>\n            <Steps view=\"default\" items={completedItems} />\n            <Steps view=\"accent\" items={completedItems} />\n        </div>\n    );\n}"
        }
      ]
    },
    "StoriesPreview": {
      "name": "StoriesPreview",
      "group": "components",
      "folderName": "Stories",
      "role": "part",
      "description": "Превью-аватар одной истории с кольцом непрочитанного и подписью, открывает просмотр",
      "props": [
        {
          "name": "slides",
          "type": "StorySlide[]",
          "required": true,
          "description": "Сегменты группы: показываются по очереди после клика на триггер."
        },
        {
          "name": "defaultDuration",
          "type": "number | undefined",
          "required": false,
          "description": "Дефолтная длительность сегментов этой группы, мс."
        },
        {
          "name": "height",
          "type": "number | undefined",
          "required": false,
          "description": "Высота прямоугольного триггера, px. По умолчанию равна `size`."
        },
        {
          "name": "image",
          "type": "string | undefined",
          "required": false,
          "description": "Картинка-превью внутри триггера. Если не задана — заливка-заглушка."
        },
        {
          "name": "renderTrigger",
          "type": "((state: StoriesTriggerState) => React.ReactNode) | undefined",
          "required": false,
          "description": "Полная замена визуала триггера. Отменяет встроенную отрисовку."
        },
        {
          "name": "shape",
          "type": "StoriesShape | undefined",
          "required": false,
          "description": "Форма триггера. По умолчанию `circle`."
        },
        {
          "name": "titleProps",
          "type": "Partial<TypographyWithAutoTooltipProps<\"BodyL\" | \"BodyM\" | \"BodyS\" | \"BodyXS\" | \"BodyXXS\" | \"DsplL\" | \"DsplM\" | \"DsplS\" | \"H1\" | \"H2\" | \"H3\" | \"H4\" | \"H5\" | \"TextL\" | \"TextM\" | \"TextS\" | \"TextXS\">> | undefined",
          "required": false,
          "description": "Пропсы подписи (TypographyWithAutoTooltip) поверх дефолтов; выравнивание — через `style.textAlign`."
        },
        {
          "name": "viewed",
          "type": "boolean | undefined",
          "required": false,
          "description": "Просмотрена ли группа. Контролируется снаружи: по колбэкам гасите обводку."
        },
        {
          "name": "width",
          "type": "number | undefined",
          "required": false,
          "description": "Ширина прямоугольного триггера, px. По умолчанию равна `size`."
        }
      ],
      "propsTypeName": "StoriesPreviewProps",
      "sourceFile": "packages/ui-kit/src/components/Stories/components/StoriesPreview/StoriesPreview.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "аватар истории",
        "preview триггер",
        "открыть сторис",
        "кольцо просмотра"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Stories",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "Stories",
        "part": "Preview"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { StoriesPreview } from '@daisforge/ui';",
      "minimalUsage": "<StoriesPreview slides={[]} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в Stories.stories.tsx",
          "type": "usage",
          "code": "<Stories.Preview\n        title=\"Слева\"\n        titleProps={{ style: { textAlign: 'left' } }}\n        image={asset('◀', '#f7971e', '#ffd200')}\n        viewed={viewed[1]}\n        slides={[{ src: asset('Слайд', '#f7971e', '#ffd200') }]}\n      />",
          "sourceFile": "packages/storybook/src/stories/Stories/Stories.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в Stories.stories.tsx",
          "type": "usage",
          "code": "<Stories.Preview\n        title=\"Справа\"\n        titleProps={{ style: { textAlign: 'right' } }}\n        image={asset('▶', '#c471ed', '#f64f59')}\n        viewed={viewed[3]}\n        slides={[{ src: asset('Слайд', '#c471ed', '#f64f59') }]}\n      />",
          "sourceFile": "packages/storybook/src/stories/Stories/Stories.stories.tsx"
        }
      ]
    },
    "Stories": {
      "name": "Stories",
      "group": "components",
      "folderName": "Stories",
      "role": "primary",
      "description": "Полноэкранные истории (как в Instagram) с превью-триггерами и автопрогрессом слайдов.",
      "props": [
        {
          "name": "activeGroupIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Controlled-индекс активной группы."
        },
        {
          "name": "activeSlideIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Controlled-индекс активного сегмента."
        },
        {
          "name": "arrows",
          "type": "StoriesArrows | undefined",
          "required": false,
          "description": "Режим видимости стрелок навигации. По умолчанию `auto` (скрыть при единственном сегменте)."
        },
        {
          "name": "defaultDuration",
          "type": "number | undefined",
          "required": false,
          "description": "Длительность сегмента по умолчанию, мс."
        },
        {
          "name": "defaultOpen",
          "type": "boolean | undefined",
          "required": false,
          "description": "Начальное открытие для uncontrolled-режима."
        },
        {
          "name": "groupTransition",
          "type": "StoriesGroupTransition | undefined",
          "required": false,
          "description": "Пресет анимации перехода между группами. По умолчанию `slide`."
        },
        {
          "name": "hideDisabledArrows",
          "type": "boolean | undefined",
          "required": false,
          "description": "Прятать стрелку, когда в её сторону листать некуда (крайний сегмент),\nвместо показа в disabled-состоянии. По умолчанию `true`."
        },
        {
          "name": "loadingDelay",
          "type": "number | undefined",
          "required": false,
          "description": "Задержка показа ассета, мс (для демо/тестов загрузки)."
        },
        {
          "name": "mode",
          "type": "StoriesMode | undefined",
          "required": false,
          "description": "Явный режим темы. По умолчанию определяется автоматически."
        },
        {
          "name": "onClose",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Вьюер закрылся (крестик / Esc / клик по оверлею / автозакрытие)."
        },
        {
          "name": "onComplete",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Досмотрены все группы (перед автозакрытием)."
        },
        {
          "name": "onError",
          "type": "((ctx: StoryErrorContext) => void) | undefined",
          "required": false,
          "description": "Ошибка загрузки ассета сегмента."
        },
        {
          "name": "onGroupChange",
          "type": "((groupIndex: number) => void) | undefined",
          "required": false,
          "description": "Сменилась активная группа."
        },
        {
          "name": "onGroupComplete",
          "type": "((groupIndex: number) => void) | undefined",
          "required": false,
          "description": "Группа полностью досмотрена — удобно гасить индикатор «просмотрено»."
        },
        {
          "name": "onOpenChange",
          "type": "((open: boolean, meta: { groupIndex: number; }) => void) | undefined",
          "required": false,
          "description": "Изменилось открытие/закрытие вьюера."
        },
        {
          "name": "onSlideChange",
          "type": "((groupIndex: number, slideIndex: number) => void) | undefined",
          "required": false,
          "description": "Сменился активный сегмент (под-стори)."
        },
        {
          "name": "overlay",
          "type": "boolean | undefined",
          "required": false,
          "description": "Показывать затемнённый оверлей. По умолчанию `true`."
        },
        {
          "name": "overlayColor",
          "type": "string | undefined",
          "required": false,
          "description": "Цвет оверлея."
        },
        {
          "name": "pauseHoldDelay",
          "type": "number | undefined",
          "required": false,
          "description": "Порог удержания указателя для паузы, мс. По умолчанию 200."
        },
        {
          "name": "preloadOnHover",
          "type": "boolean | undefined",
          "required": false,
          "description": "Предзагружать первый ассет группы при наведении на её триггер. По умолчанию `true`."
        },
        {
          "name": "renderError",
          "type": "((ctx: StoryErrorContext) => React.ReactNode) | undefined",
          "required": false,
          "description": "Свой контент при ошибке загрузки ассета (по умолчанию — встроенный EmptyState)."
        },
        {
          "name": "zIndex",
          "type": "number | undefined",
          "required": false,
          "description": "z-index оверлея."
        }
      ],
      "propsTypeName": "StoriesProps",
      "compoundParts": [
        {
          "name": "Preview",
          "typeName": "StoriesPreviewProps",
          "props": [
            {
              "name": "slides",
              "type": "StorySlide[]",
              "required": true,
              "description": "Сегменты группы: показываются по очереди после клика на триггер."
            },
            {
              "name": "defaultDuration",
              "type": "number | undefined",
              "required": false,
              "description": "Дефолтная длительность сегментов этой группы, мс."
            },
            {
              "name": "height",
              "type": "number | undefined",
              "required": false,
              "description": "Высота прямоугольного триггера, px. По умолчанию равна `size`."
            },
            {
              "name": "image",
              "type": "string | undefined",
              "required": false,
              "description": "Картинка-превью внутри триггера. Если не задана — заливка-заглушка."
            },
            {
              "name": "renderTrigger",
              "type": "((state: StoriesTriggerState) => React.ReactNode) | undefined",
              "required": false,
              "description": "Полная замена визуала триггера. Отменяет встроенную отрисовку."
            },
            {
              "name": "shape",
              "type": "StoriesShape | undefined",
              "required": false,
              "description": "Форма триггера. По умолчанию `circle`."
            },
            {
              "name": "titleProps",
              "type": "Partial<TypographyWithAutoTooltipProps<\"BodyL\" | \"BodyM\" | \"BodyS\" | \"BodyXS\" | \"BodyXXS\" | \"DsplL\" | \"DsplM\" | \"DsplS\" | \"H1\" | \"H2\" | \"H3\" | \"H4\" | \"H5\" | \"TextL\" | \"TextM\" | \"TextS\" | \"TextXS\">> | undefined",
              "required": false,
              "description": "Пропсы подписи (TypographyWithAutoTooltip) поверх дефолтов; выравнивание — через `style.textAlign`."
            },
            {
              "name": "viewed",
              "type": "boolean | undefined",
              "required": false,
              "description": "Просмотрена ли группа. Контролируется снаружи: по колбэкам гасите обводку."
            },
            {
              "name": "width",
              "type": "number | undefined",
              "required": false,
              "description": "Ширина прямоугольного триггера, px. По умолчанию равна `size`."
            }
          ]
        }
      ],
      "sourceFile": "packages/ui-kit/src/components/Stories/Stories.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "hint": "Переиспользуемый компонент сторей для разных команд. Триггеры — Stories.Preview, слайды передаются данными.",
      "keywords": [
        "instagram-истории",
        "полноэкранный слайдер",
        "автопроигрывание слайдов"
      ],
      "docs": "# Stories\n\nШаблонный движок сторей (как в Instagram): ряд триггеров-превью, по клику на который открывается полноэкранный вьюер с индикаторами прогресса, тап-навигацией, паузой и предзагрузкой ассетов. Компонент заложен под переиспользование разными командами.\n\n## Ключевые особенности\n\n- **Триггеры двух форм** — круглые и прямоугольные (`Stories.Preview`), с состоянием «просмотрено» (градиентная обводка гаснет; контролируется снаружи — например, гасится сразу при первом открытии группы по `onGroupChange`).\n- **Полноэкранный вьюер** — индикаторы прогресса сверху; тап по левой/правой части баннера, боковые стрелки и клавиши ←/→ листают сегменты внутри группы, а на границе группы — переходят к соседней.\n- **Пауза по удержанию** — на pointer-событиях (мышь + тач/тачпад), с настраиваемым порогом.\n- **Длительность на трёх уровнях** — слайд → группа → компонент; любую под-сторю можно удлинить или укоротить персонально.\n- **Асинхронная загрузка ассетов** — спиннер на время загрузки + предзагрузка первого ассета по ховеру на триггер и остальных в фоне.\n- **Ошибка загрузки** — по умолчанию `EmptyState` (размер `s`, иконка загрузки) с текстом «Не удалось загрузить» и синей ссылкой-кнопкой «Обновить»; свой контент — через `renderError`, событие — `onError`.\n- **Оверлей** — включается/выключается, настраиваются цвет и `zIndex` (можно открывать поверх `ModalDF`).\n- **Внешний API** — controlled/uncontrolled пропсы, императивный `ref` и колбэки; детали — в разделе [API](?path=/docs/локальные-компоненты-stories-api--docs).\n\n## Compound-компоненты\n\n```ts\nStories; // корень: стор, оверлей, вьюер, внешний API\nStories.Preview; // триггер (circle/rect); слайды группы передаются пропом slides\n```\n\n## Использование\n\n```tsx\n\n<Stories defaultDuration={5000} onSlideChange={(group, slide) => {}}>\n  <Stories.Preview\n    title=\"Обновления\"\n    image={coverUrl}\n    slides={[\n      {\n        src: slide1Url,\n        footer: <Button size=\"s\" stretching=\"filled\" text=\"Подробнее\" />,\n      },\n      { src: slide2Url, duration: 3000 },\n      { src: slide3Url, objectFit: 'contain' },\n    ]}\n  />\n</Stories>;\n```\n\n## Особенности\n\n- **Гибрид компаунд + данные** — триггеры пишутся как `Stories.Preview`, а сегменты передаются данными (`slides`). Это даёт свободную вёрстку триггеров и одновременно единый индекс для программного `goTo(group, slide)`.\n- **Прогресс без ре-рендеров** — заполнение индикатора тикает через `requestAnimationFrame` прямо в DOM (transform), в обход React; в стор уходят только дискретные события (смена сегмента/группы, пауза).\n- **object-fit per-слайд** — по умолчанию `cover`, переопределяется на каждом сегменте.\n- **Нижний слот `footer`** — произвольный ReactNode на каждом сегменте (кнопка / текст / что угодно); потребитель сам задаёт вид и ширину.\n- **Стрелки навигации** — листают сегменты внутри группы, а на границе группы переходят к соседней (как тап и клавиши ←/→). Видимость — проп `arrows`: `auto` (по умолчанию — скрыты, если сегмент всего один), `always` (всегда), `never` (не показывать). Недоступную по направлению стрелку по умолчанию не рендерим (на первом/последнем сегменте) — управляется пропом `hideDisabledArrows` (по умолчанию `true`; `false` возвращает прежнее disabled-состояние).\n- **Video** — заложено в модель (`slide.type`), но пока не реализовано: сейчас поддерживаются картинки и GIF.\n- **Конец сторей** — после последнего сегмента последней группы вьюер закрывается и вызывается `onComplete`.\n- **Ошибка на сегменте** — автопереход останавливается (показывается error-state). Гашение «просмотрено» по `onGroupChange` (при открытии) на это не влияет; `onGroupComplete` (полный просмотр группы) сработает только при ручном пролистывании до конца.\n- **Закрытие** — крестик, `Esc` и клик по оверлею/вне контента.\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-stories-api--docs).",
      "apiDocs": "# Stories API\n\n## StoriesProps\n\n```typescript\ninterface StoriesProps {\n  /** Триггеры-превью: список `Stories.Preview`. */\n  children: ReactNode;\n  /** Длительность сегмента по умолчанию, мс. */\n  defaultDuration?: number;\n\n  /** Controlled-открытие вьюера. */\n  open?: boolean;\n  /** Начальное открытие для uncontrolled-режима. */\n  defaultOpen?: boolean;\n  /** Controlled-индекс активной группы. */\n  activeGroupIndex?: number;\n  /** Controlled-индекс активного сегмента. */\n  activeSlideIndex?: number;\n\n  /** Изменилось открытие/закрытие вьюера. */\n  onOpenChange?: (open: boolean, meta: { groupIndex: number }) => void;\n  /** Сменилась активная группа. */\n  onGroupChange?: (groupIndex: number) => void;\n  /** Сменился активный сегмент (под-стори). */\n  onSlideChange?: (groupIndex: number, slideIndex: number) => void;\n  /** Досмотрены все группы (перед автозакрытием). */\n  onComplete?: () => void;\n  /** Группа полностью досмотрена — удобно гасить индикатор «просмотрено». */\n  onGroupComplete?: (groupIndex: number) => void;\n  /** Вьюер закрылся (крестик / Esc / клик по оверлею / автозакрытие). */\n  onClose?: () => void;\n  /** Ошибка загрузки ассета сегмента. */\n  onError?: (ctx: StoryErrorContext) => void;\n  /** Свой контент при ошибке загрузки ассета (по умолчанию — встроенный EmptyState). */\n  renderError?: (ctx: StoryErrorContext) => ReactNode;\n\n  /** Показывать затемнённый оверлей. По умолчанию `true`. */\n  overlay?: boolean;\n  /** Цвет оверлея. */\n  overlayColor?: string;\n  /** z-index оверлея. */\n  zIndex?: number;\n\n  /** Предзагружать первый ассет группы при наведении на её триггер. По умолчанию `true`. */\n  preloadOnHover?: boolean;\n  /** Задержка показа ассета, мс (для демо/тестов загрузки). */\n  loadingDelay?: number;\n  /** Порог удержания указателя для паузы, мс. По умолчанию 200. */\n  pauseHoldDelay?: number;\n  /** Пресет анимации перехода между группами. По умолчанию `slide`. */\n  groupTransition?: StoriesGroupTransition;\n  /** Режим видимости стрелок навигации. По умолчанию `auto` (скрыть при единственном сегменте). */\n  arrows?: StoriesArrows;\n  /**\n   * Прятать стрелку, когда в её сторону листать некуда (крайний сегмент),\n   * вместо показа в disabled-состоянии. По умолчанию `true`.\n   */\n  hideDisabledArrows?: boolean;\n  /** Явный режим темы. По умолчанию определяется автоматически. */\n  mode?: StoriesMode;\n\n  className?: string;\n}\n```\n\n### StoriesGroupTransition\n\n```typescript\ntype StoriesGroupTransition = 'slide' | 'fade' | 'none';\n```\n\n### StoriesArrows\n\n```typescript\ntype StoriesArrows = 'auto' | 'always' | 'never';\n```\n\n### StoriesMode\n\n```typescript\ntype StoriesMode = 'light' | 'dark';\n```\n\n## StoriesPreviewProps\n\n```typescript\ninterface StoriesPreviewProps {\n  /** Сегменты группы: показываются по очереди после клика на триггер. */\n  slides: StorySlide[];\n  /** Форма триггера. По умолчанию `circle`. */\n  shape?: StoriesShape;\n  /** Подпись под триггером (по умолчанию до 2 строк, ellipsis с авто-тултипом). */\n  title?: string;\n  /** Пропсы подписи (TypographyWithAutoTooltip) поверх дефолтов; выравнивание — через `style.textAlign`. */\n  titleProps?: StoriesTitleProps;\n  /** Картинка-превью внутри триггера. Если не задана — заливка-заглушка. */\n  image?: string;\n  /** Просмотрена ли группа. Контролируется снаружи: по колбэкам гасите обводку. */\n  viewed?: boolean;\n  /** Дефолтная длительность сегментов этой группы, мс. */\n  defaultDuration?: number;\n  /** Размер круглого триггера (сторона), px. По умолчанию 98. */\n  size?: number;\n  /** Ширина прямоугольного триггера, px. По умолчанию равна `size`. */\n  width?: number;\n  /** Высота прямоугольного триггера, px. По умолчанию равна `size`. */\n  height?: number;\n  /** Полная замена визуала триггера. Отменяет встроенную отрисовку. */\n  renderTrigger?: (state: StoriesTriggerState) => ReactNode;\n  className?: string;\n}\n```\n\n### StoriesShape\n\n```typescript\ntype StoriesShape = 'circle' | 'rect';\n```\n\n### StoriesTitleProps\n\n```typescript\ntype StoriesTitleProps = Partial<\n  TypographyWithAutoTooltipProps<TypographyVariant>\n>;\n```\n\n## StorySlide\n\n```typescript\ninterface StorySlide {\n  /** Стабильный идентификатор сегмента (ключи, внешняя адресация). */\n  id?: string;\n  /** URL ассета (картинка или GIF). */\n  src: string;\n  /** Тип ассета. По умолчанию `image` (video пока не реализован). */\n  type?: StoryAssetType;\n  /** Длительность показа сегмента, мс. Переопределяет дефолт группы и компонента. */\n  duration?: number;\n  /** Способ вписывания ассета. По умолчанию `cover`. */\n  objectFit?: StoriesObjectFit;\n  /** Слот внизу баннера (любой ReactNode). Может отличаться на каждом сегменте. */\n  footer?: ReactNode;\n}\n```\n\n### StoryAssetType\n\n```typescript\ntype StoryAssetType = 'image' | 'gif' | 'video';\n```\n\n### StoriesObjectFit\n\n```typescript\ntype StoriesObjectFit =\n  | 'cover'\n  | 'contain'\n  | 'fill'\n  | 'none'\n  | 'scale-down';\n```\n\n## StoriesTriggerState\n\n```typescript\ninterface StoriesTriggerState {\n  /** Порядковый индекс группы. */\n  index: number;\n  /** Просмотрена ли группа (значение пропа `viewed`). */\n  viewed: boolean;\n  /** Открыт ли сейчас вьюер на этой группе. */\n  isActive: boolean;\n}\n```\n\n## StoryErrorContext\n\n```typescript\ninterface StoryErrorContext {\n  groupIndex: number;\n  slideIndex: number;\n  slide: StorySlide;\n  /** Повторить загрузку ассета. */\n  retry: () => void;\n}\n```\n\n## StoriesController\n\n```typescript\ninterface StoriesController {\n  /** Открыть вьюер (опционально сразу на группе/сегменте). */\n  open: (groupIndex?: number, slideIndex?: number) => void;\n  /** Закрыть вьюер. */\n  close: () => void;\n  /** Следующий сегмент (в конце группы — следующая группа; в самом конце — закрытие). */\n  next: () => void;\n  /** Предыдущий сегмент (в начале группы — предыдущая группа). */\n  prev: () => void;\n  /** Следующая группа. */\n  nextGroup: () => void;\n  /** Предыдущая группа. */\n  prevGroup: () => void;\n  /** Перейти к конкретной группе и сегменту. */\n  goTo: (groupIndex: number, slideIndex?: number) => void;\n  /** Поставить на паузу. */\n  pause: () => void;\n  /** Снять с паузы. */\n  resume: () => void;\n}\n```\n\n## StoriesRef\n\n```typescript\ninterface StoriesRef extends StoriesController {\n  /** Текущее состояние вьюера. */\n  getState: () => StoriesState;\n}\n```\n\n## StoriesState\n\n```typescript\ninterface StoriesState {\n  /** Открыт ли вьюер. */\n  isOpen: boolean;\n  /** Индекс активной группы. */\n  groupIndex: number;\n  /** Индекс активного сегмента внутри группы. */\n  slideIndex: number;\n  /** Идёт ли проигрывание (false во время паузы). */\n  isPlaying: boolean;\n}\n```",
      "curatedStories": [
        {
          "exportName": "Circle",
          "displayName": "Круглые триггеры",
          "type": "full-code",
          "code": "import { Button, Stories } from '@daisforge/ui';\nimport { useState } from 'react';\n\n${viewedSource}\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'CircleStoriesExample',\n)}"
        },
        {
          "exportName": "Rect",
          "displayName": "Прямоугольные триггеры",
          "type": "full-code",
          "code": "import { Button, Stories } from '@daisforge/ui';\n\n${viewedSource}\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'RectStoriesExample',\n)}"
        },
        {
          "exportName": "Loading",
          "displayName": "Спиннер загрузки (эмуляция)",
          "type": "full-code",
          "code": "import { Stories } from '@daisforge/ui';\n\n${viewedSource}\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'LoadingStoriesExample',\n)}"
        },
        {
          "exportName": "ErrorState",
          "displayName": "Ошибка: дефолтный EmptyState + ретрай",
          "type": "full-code",
          "code": "import { Stories } from '@daisforge/ui';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'ErrorStateExample',\n)}"
        },
        {
          "exportName": "ErrorCustom",
          "displayName": "Ошибка: кастомный контент (renderError)",
          "type": "full-code",
          "code": "import { BodyS, Button, Stories, surfaceAccentMinor, surfaceInfo } from '@daisforge/ui';\nimport { br, s } from '@daisforge/ui/constants';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'ErrorCustomExample',\n)}"
        },
        {
          "exportName": "ImperativeControl",
          "displayName": "Внешнее управление через ref",
          "type": "full-code",
          "code": "import { Button, Stories, StoriesRef } from '@daisforge/ui';\nimport { useRef, useState } from 'react';\n\n${viewedSource}\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'ImperativeControlExample',\n)}"
        },
        {
          "exportName": "InsideModal",
          "displayName": "Триггеры внутри ModalDF",
          "type": "full-code",
          "code": "import { Button, ModalDF, Stories } from '@daisforge/ui';\nimport { useState } from 'react';\n\n${viewedSource}\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'InsideModalExample',\n)}"
        },
        {
          "exportName": "HiddenArrows",
          "displayName": "Стрелки скрыты (arrows=",
          "type": "full-code",
          "code": "import { Stories } from '@daisforge/ui';\n\n${viewedSource}\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'HiddenArrowsExample',\n)}"
        },
        {
          "exportName": "Titles",
          "displayName": "Подписи: 2 строки, ellipsis, выравнивание",
          "type": "full-code",
          "code": "import { Stories } from '@daisforge/ui';\n\n${viewedSource}\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'TitlesExample',\n)}"
        },
        {
          "exportName": "CarouselWrapped",
          "displayName": "Превью внутри Carousel (вложенность)",
          "type": "full-code",
          "code": "import { Carousel, CarouselItem, Stories } from '@daisforge/ui';\n\n${viewedSource}\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'CarouselWrappedExample',\n)}"
        }
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "StoriesPreview"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Stories } from '@daisforge/ui';",
      "minimalUsage": "<Stories>\n  {/* части: Stories.Preview */}\n</Stories>",
      "examples": [
        {
          "exportName": "Circle",
          "displayName": "Круглые триггеры",
          "type": "full-code",
          "code": "import { Button, Stories } from '@daisforge/ui';\nimport { useState } from 'react';\n\n${viewedSource}\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'CircleStoriesExample',\n)}"
        },
        {
          "exportName": "Rect",
          "displayName": "Прямоугольные триггеры",
          "type": "full-code",
          "code": "import { Button, Stories } from '@daisforge/ui';\n\n${viewedSource}\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'RectStoriesExample',\n)}"
        },
        {
          "exportName": "Loading",
          "displayName": "Спиннер загрузки (эмуляция)",
          "type": "full-code",
          "code": "import { Stories } from '@daisforge/ui';\n\n${viewedSource}\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'LoadingStoriesExample',\n)}"
        },
        {
          "exportName": "ErrorState",
          "displayName": "Ошибка: дефолтный EmptyState + ретрай",
          "type": "full-code",
          "code": "import { Stories } from '@daisforge/ui';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/Stories/Stories.stories.tsx',\n  'ErrorStateExample',\n)}"
        }
      ]
    },
    "Switch": {
      "name": "Switch",
      "group": "components",
      "folderName": "Switch",
      "role": "primary",
      "description": "Тумблер для мгновенного переключения состояния вкл/выкл в интерфейсе.",
      "props": [
        {
          "name": "description",
          "type": "string | undefined",
          "required": false,
          "description": "Дополнительное описание"
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": "Добавить рамку при фокусе"
        },
        {
          "name": "hasBackground",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отображение подложки у switch"
        },
        {
          "name": "label",
          "type": "React.ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу"
        },
        {
          "name": "labelPosition",
          "type": "\"before\" | \"after\" | undefined",
          "required": false,
          "description": "Расположение подпись"
        },
        {
          "name": "onChange",
          "type": "React.ChangeEventHandler<HTMLInputElement> | undefined",
          "required": false,
          "description": "Обработчик изменения элемента формы"
        },
        {
          "name": "singleLine",
          "type": "boolean | undefined",
          "required": false,
          "description": "Перенос строки label",
          "default": "true"
        },
        {
          "name": "size",
          "type": "\"l\" | \"m\" | \"s\" | undefined",
          "required": false,
          "description": "Размер компонента."
        },
        {
          "name": "toggleSize",
          "type": "\"l\" | \"s\" | undefined",
          "required": false,
          "description": "Размер toggle."
        },
        {
          "name": "view",
          "type": "\"default\" | undefined",
          "required": false,
          "description": "Вид компонента."
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "outlined",
          "type": "boolean | undefined",
          "required": false,
          "description": "Добавить рамку при фокусе",
          "deprecated": true
        },
        {
          "name": "pressed",
          "type": "boolean | undefined",
          "required": false,
          "description": "Нажатие на компонент",
          "deprecated": true
        }
      ],
      "propsTypeName": "SwitchProps",
      "sourceFile": "packages/ui-kit/src/components/Switch/Switch.tsx",
      "type": "wrapper",
      "formVariant": "FormSwitch",
      "category": "Локальные компоненты",
      "keywords": [
        "toggle",
        "переключатель настройки",
        "вкл выкл"
      ],
      "docs": "# Switch\n\nКомпонент Switch - обертка компонента Switch c добавлением подложки.\n\n## Ключевые особенности\n\n- При наличии `hasBackground`, `size` фиксированно будет равен `m`\n\n## Особенности\n\n- Размер `size` игнорируется и принудительно устанавливается в `m`, если передан проп `hasBackground`\n\n> Подробнее о типах и пропсах — [Switch API](?path=/docs/локальные-компоненты-switch-api--docs)",
      "apiDocs": "# Switch API\n\n## BaseSwitchProps\n\n```typescript\ntype BaseSwitchProps = ComponentProps<typeof Switch> & {\n  /**\n   * Отображение подложки у switch\n   */\n  hasBackground?: boolean;\n};\n```\n\n> Остальные пропсы наследуются от `Switch` из `@salutejs/sdds-finai`",
      "curatedStories": [
        {
          "exportName": "SwitchStory",
          "displayName": "Example",
          "type": "full-code",
          "code": "import { Switch } from '@daisforge/ui';\n\n() => (\n    <div\n      style={{\n        minHeight: '500px',\n        padding: '20px',\n        display: 'flex',\n      }}\n    >\n      <Switch label=\"Label\" hasBackground />\n    </div>\n  )"
        }
      ],
      "chooseWhen": "Вне react-hook-form — тумблер вкл/выкл с value/onChange напрямую.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Switch } from '@daisforge/ui';",
      "minimalUsage": "<Switch />",
      "examples": [
        {
          "exportName": "SwitchStory",
          "displayName": "Example",
          "type": "full-code",
          "code": "import { Switch } from '@daisforge/ui';\n\n() => (\n    <div\n      style={{\n        minHeight: '500px',\n        padding: '20px',\n        display: 'flex',\n      }}\n    >\n      <Switch label=\"Label\" hasBackground />\n    </div>\n  )"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в Table.tsx",
          "type": "usage",
          "code": "<Switch\n        style={{ width: 'fit-content' }}\n        label=\"Включить колонки Title и Priority\"\n        checked={bool}\n        onChange={() => setBool((prev) => !prev)}\n      />",
          "sourceFile": "packages/vite-project/src/pages/Table.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в Table.multipleFeatures.stories.tsx",
          "type": "usage",
          "code": "<Switch\n          style={{ width: 'fit-content' }}\n          label=\"Включить колонки Title и Priority\"\n          checked={bool}\n          onChange={() => setBool((prev) => !prev)}\n        />",
          "sourceFile": "packages/storybook/src/stories/Table/Table.multipleFeatures.stories.tsx"
        },
        {
          "exportName": "Vendor",
          "displayName": "Кастомная подсветка",
          "type": "vendor",
          "code": "import React, { useRef, useState } from 'react';\nimport { Tour, Button, TextField, Switch } from '@daisforge/ui';\nexport function App() {\n    const textFieldRef = useRef(null);\n    const switchRef = useRef(null);\n    const buttonRef = useRef(null);\n    const [open, setOpen] = useState(false);\n    const [current, setCurrent] = useState(0);\n    const [name, setName] = useState('');\n    const [checked, setChecked] = useState(false);\n    const onClose = () => { setOpen(false); setCurrent(0); };\n    const steps = [\n        { target: textFieldRef, title: 'Имя пользователя', description: 'Введите имя для профиля.' },\n        { target: '#custom-highlight-switch', title: 'Уведомления', description: 'Включите push-уведомления.', placement: 'left' },\n        { target: buttonRef, title: 'Сохранить', description: 'Примените все изменения.', placement: 'top' },\n    ];\n    const renderHighlight = ({ left, top, width, height, borderRadius }) => (\n        <div\n            style={{\n                position: 'fixed',\n                left,\n                top,\n                width,\n                height,\n                borderRadius,\n                background: 'rgba(0, 102, 255, 0.1)',\n                animation: 'tour-doc-pulse 1.4s ease-in-out infinite',\n                pointerEvents: 'none',\n            }}\n        />\n    );\n    const renderStep = (cur, length, last, step, goToStep) => (\n        <div style={{ padding: '1rem', background: 'var(--surface-solid-card)', borderRadius: '0.75rem', boxShadow: '0 4px 16px rgba(0,0,0,0.12)', maxWidth: '16rem', display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>\n            {step.title && <strong>{step.title}</strong>}\n            {step.description && <small style={{ opacity: 0.7 }}>{step.description}</small>}\n            <div style={{ display: 'flex', gap: '0.5rem', marginTop: '0.25rem' }}>\n                {cur > 0 && <Button size=\"s\" view=\"secondary\" onClick={() => goToStep(cur - 1)}>Назад</Button>}\n                {last ? <Button size=\"s\" view=\"default\" onClick={onClose}>Закрыть</Button> : <Button size=\"s\" view=\"default\" onClick={() => goToStep(cur + 1)}>Далее</Button>}\n            </div>\n        </div>\n    );\n    return (\n        <>\n            <style>{`\n                @keyframes tour-doc-pulse {\n                    0%, 100% { box-shadow: 0 0 0 2px rgba(0,102,255,0.85), 0 0 0 6px rgba(0,102,255,0.2); }\n                   \n// … (обрезано)"
        }
      ]
    },
    "TableFilterSelect": {
      "name": "TableFilterSelect",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "primary",
      "description": "",
      "props": [
        {
          "name": "onChange",
          "type": "((v: string) => void) | ((v: string[]) => void)",
          "required": true,
          "description": ""
        },
        {
          "name": "options",
          "type": "{ text: string; value: string; }[]",
          "required": true,
          "description": ""
        },
        {
          "name": "value",
          "type": "string | string[]",
          "required": true,
          "description": ""
        },
        {
          "name": "afterList",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "beforeList",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "listMaxHeight",
          "type": "string | undefined",
          "required": false,
          "description": "",
          "default": "'360px'"
        },
        {
          "name": "mode",
          "type": "\"multiple\" | \"single\" | undefined",
          "required": false,
          "description": "",
          "default": "'single'"
        },
        {
          "name": "size",
          "type": "\"big\" | \"small\" | \"medium\" | undefined",
          "required": false,
          "description": "",
          "default": "'medium'"
        },
        {
          "name": "width",
          "type": "string | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TableFilterSelectProps",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/combobox.tsx",
      "type": "composition",
      "relatedExports": [
        "SplitIconButton",
        "CellEditorCombobox",
        "CellEditorNumberFormat",
        "CellEditorTextArea",
        "TableFilterSelectListItem",
        "ContainerStyled",
        "TextCellEntry",
        "Canvas",
        "TextCellEntryType"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableFilterSelect } from '@daisforge/ui/components/TableCanvas';",
      "minimalUsage": "<TableFilterSelect onChange={() => {}} options={[]} value={[]} />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в TableCanvas.filtering.stories.tsx",
          "type": "usage",
          "code": "<TableFilterSelect\n                  mode=\"multiple\"\n                  value={draftValue}\n                  onChange={setDraftValue}\n                  options={issueTypeOptions}\n                  size={rowSize}\n                  width=\"232px\"\n                  beforeList={\n                    <TableFilterSelectListItem $size={rowSize}>\n                      Произвольный вспомогательный элемент заголовка списка с\n                      подсказкой\n                    </TableFilterSelectListItem>\n                  }\n                  afterList={\n                    <Box\n                      $css={`position: sticky; bottom: 0; background-color: white; display: grid; gap: ${\n                        rowSize === 'big' ? '4px' : '4px'\n                      }; margin-top: 4px;`}\n                    >\n                      <Divider />\n                      <Button\n                        size={rowSize === 'small' ? 'xxs' : 's'}\n                        style={{ marginLeft: 'auto ' }}\n                        view=\"accent\"\n                        onClick={apply}\n                      >\n                        Применить\n                      </Button>\n                    </Box>\n                  }\n                />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Filtering/TableCanvas.filtering.stories.tsx"
        }
      ]
    },
    "TableFilterSelectList": {
      "name": "TableFilterSelectList",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "primary",
      "description": "",
      "props": [
        {
          "name": "as",
          "type": "string | React.ComponentType<any> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof TableFilterSelectList>",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/styled.ts",
      "type": "composition",
      "relatedExports": [
        "SplitIconButton",
        "CellEditorCombobox",
        "CellEditorNumberFormat",
        "CellEditorTextArea",
        "TableFilterSelectListItem",
        "ContainerStyled",
        "TextCellEntry",
        "Canvas",
        "TextCellEntryType"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableFilterSelectList } from '@daisforge/ui/components/TableCanvas';",
      "minimalUsage": "<TableFilterSelectList />",
      "examples": []
    },
    "TableFilterSelectListItem": {
      "name": "TableFilterSelectListItem",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "internal",
      "description": "Пункт списка выпадающего фильтра колонки TableCanvas для выбора значения",
      "props": [
        {
          "name": "as",
          "type": "string | React.ComponentType<any> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof TableFilterSelectListItem>",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/styled.ts",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "пункт фильтра",
        "элемент списка",
        "выбор значения колонки"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableCanvas",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableFilterSelectListItem } from '@daisforge/ui/components/TableCanvas';",
      "minimalUsage": "<TableFilterSelectListItem />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в TableCanvas.multipleFeatures.stories.tsx",
          "type": "usage",
          "code": "<TableFilterSelectListItem\n                  $size={props.headerContextState.rowSize}\n                >\n                  custom beforeList\n                </TableFilterSelectListItem>",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.MultipleFeatures/TableCanvas.multipleFeatures.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvas.filtering.stories.tsx",
          "type": "usage",
          "code": "<TableFilterSelectListItem $size={rowSize}>\n                      Произвольный вспомогательный элемент заголовка списка с\n                      подсказкой\n                    </TableFilterSelectListItem>",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Filtering/TableCanvas.filtering.stories.tsx"
        }
      ]
    },
    "TableFilterSelectSearchTextfield": {
      "name": "TableFilterSelectSearchTextfield",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "primary",
      "description": "",
      "props": [
        {
          "name": "as",
          "type": "string | React.ComponentType<any> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof TableFilterSelectSearchTextfield>",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/styled.ts",
      "type": "composition",
      "relatedExports": [
        "SplitIconButton",
        "CellEditorCombobox",
        "CellEditorNumberFormat",
        "CellEditorTextArea",
        "TableFilterSelectListItem",
        "ContainerStyled",
        "TextCellEntry",
        "Canvas",
        "TextCellEntryType"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableFilterSelectSearchTextfield } from '@daisforge/ui/components/TableCanvas';",
      "minimalUsage": "<TableFilterSelectSearchTextfield />",
      "examples": []
    },
    "TableFilterSelectTotalListItemContainer": {
      "name": "TableFilterSelectTotalListItemContainer",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "primary",
      "description": "",
      "props": [
        {
          "name": "as",
          "type": "string | React.ComponentType<any> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof TableFilterSelectTotalListItemContainer>",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/styled.ts",
      "type": "composition",
      "relatedExports": [
        "SplitIconButton",
        "CellEditorCombobox",
        "CellEditorNumberFormat",
        "CellEditorTextArea",
        "TableFilterSelectListItem",
        "ContainerStyled",
        "TextCellEntry",
        "Canvas",
        "TextCellEntryType"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableFilterSelectTotalListItemContainer } from '@daisforge/ui/components/TableCanvas';",
      "minimalUsage": "<TableFilterSelectTotalListItemContainer />",
      "examples": []
    },
    "Table": {
      "name": "Table",
      "group": "components",
      "folderName": "Table",
      "role": "primary",
      "description": "Устаревшая HTML-таблица (react-data-grid); для новых проектов используйте TableCanvas.",
      "props": [
        {
          "name": "columnConfig",
          "type": "readonly ColumnConfig<RowType, SummaryRowType>[]",
          "required": true,
          "description": "columnConfig - Конфигурация колонок.\n\n(рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)"
        },
        {
          "name": "rows",
          "type": "RowType[]",
          "required": true,
          "description": "rows - данные для таблицы. ```RowType extends Record<string | number, any>```"
        },
        {
          "name": "bottomSummaryRows",
          "type": "SummaryRowType[] | undefined",
          "required": false,
          "description": "rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```"
        },
        {
          "name": "headerContextValue",
          "type": "HeaderContextValueType | undefined",
          "required": false,
          "description": "headerContextValue:  любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext."
        },
        {
          "name": "rowContextValue",
          "type": "RowContextValueType | undefined",
          "required": false,
          "description": "rowContextValue:  любые стейты, которые нужны в cell - кладем в rowContextValue.  И получаем доступ с помощью useRowContext."
        },
        {
          "name": "tableConfig",
          "type": "{ highlightActiveType?: HighlightActiveType | undefined; rowSize?: { showInControl: boolean; default?: \"big\" | \"small\" | \"medium\" | undefined; available?: (\"big\" | \"small\" | \"medium\")[] | undefined; onRowSizeChange?: ((size: \"big\" | \"small\" | \"medium\") => void) | undefined; domMetadata?: DomMetadata | undefined; } | undefined; rowHeight?: Maybe<number | RowHeightFunc<RowType>>; sorting?: { state: …",
          "required": false,
          "description": "tableConfig - Конфигурация фичей таблицы (их активация и отключение)",
          "default": "{}"
        },
        {
          "name": "topSummaryRows",
          "type": "SummaryRowType[] | undefined",
          "required": false,
          "description": "topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```"
        },
        {
          "name": "refTable",
          "type": "React.Ref<DataGridHandle> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "refTableContainer",
          "type": "React.Ref<HTMLDivElement> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TableProps",
      "rawType": "export type TableProps<\n  FilterStateType extends ObjectForExtending,\n  RowIdType extends string | number,\n  HeaderContextValueType extends ObjectForExtending,\n  RowContextValueType extends ObjectForExtending,\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n> = {\n  /**\n   * columnConfig - Конфигурация колонок.\n   *\n   * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n   */\n  columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n  /**\n   * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n   */\n  rows: RowType[];\n  /**\n   * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n   */\n  topSummaryRows?: SummaryRowType[];\n  /**\n   * rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n   */\n  bottomSummaryRows?: SummaryRowType[];\n  /**\n   * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n   */\n  tableConfig?: Prettify<\n    TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n  >;\n  /**\n   * headerContextValue:  любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext.\n   */\n  headerContextValue?: HeaderContextValueType;\n  /**\n   * rowContextValue:  любые стейты, которые нужны в cell - кладем в rowContextValue.  И получаем доступ с помощью useRowContext.\n   */\n  rowContextValue?: RowContextValueType;\n  refTable?: Ref<DataGridHandle>;\n  refTableContainer?: React.Ref<HTMLDivElement>;\n};",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/components/Table/Table.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "hint": "Устаревшая таблица. Если пользователь не уточняет — скорее всего ему нужна TableCanvas. Table — для legacy-проектов.",
      "keywords": [
        "табличные данные",
        "деприкейтед таблица",
        "react-data-grid"
      ],
      "docs": "# Table\n\n`Table` - legacy HTML-таблица на базе `react-data-grid` и `react-table`-подходов, которая поддерживается для существующих продуктов. Для новых таблиц по умолчанию используйте `TableCanvas`.\n\n## Ключевые особенности\n\n- Отображение строк и колонок через `rows`, `columnConfig` и `tableConfig`\n- Сортировка, фильтрация, поиск, пагинация и infinity scroll\n- Выбор строк, вложенные строки, группировка строк и группировка колонок\n- Настройка колонок, изменение ширины, кастомный render ячеек и итоговые строки\n- ControlBlock, sidebar, context menu, row instruments и состояния загрузки/пустых данных\n\n## Legacy-статус\n\n`Table` оставлен для поддержки проектов, которые уже используют HTML-таблицу. Если задача не требует совместимости с legacy API, выбирайте `TableCanvas`: он является основной таблицей библиотеки и лучше подходит для больших данных, canvas-render и новых сценариев.\n\n## Основные сущности\n\n- `TableProps` - публичные props компонента\n- `TableConfig` - конфигурация фич таблицы\n- `ColumnConfig` - конфигурация колонок, render-ов, сортировки, фильтрации и редактирования\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-api--docs).",
      "apiDocs": "# Table API\n\n## TableProps\n\n```typescript\ntype TableProps<\n  FilterStateType extends ObjectForExtending,\n  RowIdType extends string | number,\n  HeaderContextValueType extends ObjectForExtending,\n  RowContextValueType extends ObjectForExtending,\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n> = {\n  /**\n   * columnConfig - Конфигурация колонок.\n   *\n   * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n   */\n  columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n  /**\n   * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n   */\n  rows: RowType[];\n  /**\n   * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n   */\n  topSummaryRows?: SummaryRowType[];\n  /**\n   * rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n   */\n  bottomSummaryRows?: SummaryRowType[];\n  /**\n   * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n   */\n  tableConfig?: Prettify<\n    TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n  >;\n  /**\n   * headerContextValue:  любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext.\n   */\n  headerContextValue?: HeaderContextValueType;\n  /**\n   * rowContextValue:  любые стейты, которые нужны в cell - кладем в rowContextValue.  И получаем доступ с помощью useRowContext.\n   */\n  rowContextValue?: RowContextValueType;\n  refTable?: Ref<DataGridHandle>;\n  refTableContainer?: React.Ref<HTMLDivElement>;\n};\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *```jsx\n   * import { Table } from '@daisforge/ui';\n   *\n   * <Table\n   * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n   * {...rest}\n   * />\n   * ```\n   */\n  selecting?: {\n    state: [\n      ReadonlySet<RowIdType>,\n      React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n    ];\n  } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n       */\n      controlBlock?: {\n        domMetadata?: DomMetadata;\n      };\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n       */\n      sidebar?: {\n        domMetadata?: DomMetadata;\n      };\n    };\n  /**\n   * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n   *\n   * columnConfig=[{editingCell: {...}}]\n   */\n  editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n  /**\n   * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n   *\n   * columnConfig=[{subRow: {...}}]\n   */\n  subRows?: SubRows<RowType, RowIdType>;\n  rowsGrouping?: RowsGrouping<RowType>;\n\n  /**\n   * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации -  resizableColumn: true. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={resizableColumn: true}\n   *\n   * columnConfig=[{resizable: true}]\n   */\n  resizableColumn?: boolean;\n  /**\n   * style - inline-стили. Для стилей самой таблицы (без вложенности).\n   *\n   * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n   */\n  style?: Omit<\n    CSSProperties,\n    'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n  >;\n  /**\n   * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n   *\n   * Пример:\n   *\n   * ```css\n   * & > .rdg-header-row > .rdgCell {\n   * background-color: red;\n   * }\n   * ```\n   *\n   */\n  css?: string | CSSObject;\n\n  summaryRows?: SummaryRowsConfig;\n  /**\n   * controlBlock - пропс для активации, кастомизации контролблока.\n   */\n  controlBlock?: ControlBlockConfig;\n  /**\n     * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n     * Пример:\n     *\n     * ```tsx\n        tableConfig={{ containerStyle: { height: '70vh' } }}\n     * ```\n     */\n  containerStyle?: CSSProperties | undefined;\n  /**\n   * containerCss - стили для контейнера таблицы и контролблока.\n   * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n   */\n  containerCss?: string | CSSObject | undefined;\n  /**\n   * containerId - html-атрибут id контейнера таблицы.\n   */\n  containerId?: string | undefined;\n\n  /**\n   * infinityScroll - бесконечная подгрузка данных при скролле.\n   *\n   *  Условие активации - наличие самого пропса infinityScroll.\n   *\n   * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n   * (Предполагается, что если есть infinityScroll,\n   * то в таблице представлен не весь объем данных,\n   * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n   *\n   */\n  infinityScroll?: {\n    onTrigger: (rows: RowType[]) => Promise<void> | void;\n    isLoading: boolean;\n    /**\n     * @default true\n     */\n    hasMore?: boolean;\n    /**\n     * @default 100   (px)\n     */\n    scrollThreshold?: number;\n  };\n  /**\n   * @isLoading - состояние загрузки данных для таблицы.\n   */\n  isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n  /**\n   * loadingOverlay - конфигурация для отображения оверлея загрузки.\n   * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n   */\n  loadingOverlay?: {\n    /**\n     * Активен ли оверлей загрузки\n     * @default true\n     */\n    active?: boolean;\n    /**\n     * Кастомный компонент спиннера\n     * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n     */\n    spinner?: ReactNode;\n    /**\n     * Основной заголовок оверлея\n     * @default \"Загрузка таблицы\"\n     */\n    title?: string;\n    /**\n     * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n     * @default \"\"\n     */\n    subtitle?: string;\n    /**\n     * Задержка перед показом подзаголовка (мс)\n     * @default 10000 (10 секунд)\n     */\n    showSubtitleDelay?: number;\n  };\n  noRowsFallback?: boolean | { custom: ReactNode };\n  columnsControl?: ColumnsControlConfig;\n  rowDetailPanel?: RowDetailConfig<RowType>;\n  rowInstruments?: {\n    getRowDropdownConfig: RowInstrumentsType<RowType>;\n    /**\n     * @default false\n     */\n    defaultOpened?: boolean;\n    /**\n     * @default true\n     */\n    showInControl?: boolean;\n    /**\n     * Внешний стейт видимости\n     */\n    openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  };\n  fullScreenEnabled?: FullScreen;\n  keyText?: boolean | KeyTextConfig;\n  /**\n   * pagination - пропс для пагинации.\n   *\n   * Условие активации - наличие самого пропса pagination.\n   *\n   * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n   * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n   *\n   */\n  pagination?: PaginationProps;\n  /**\n   * searching - пропс для поиска по таблицу.\n   *\n   * Условие активации - наличие searching.enabled: true\n   *\n   */\n  /**\n   * Конфигурация табов в сайдбаре\n   */\n  sidebarConfig?: SidebarConfig;\n  searching?: SearchingProps;\n  /**\n   * onHeaderContextMenu - пропс для активации открытия контекстного меню.\n   *\n   */\n  onHeaderContextMenu?: HeaderContextMenuProps;\n  onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n  onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n    RowType,\n    SummaryRowType\n  >;\n} & Pick<\n  DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n  | 'summaryRowHeight'\n  | 'onFill'\n  | 'onCopy'\n  | 'onPaste'\n  | 'onCellClick'\n  | 'onCellDoubleClick'\n  | 'onCellContextMenu'\n  | 'onCellKeyDown'\n  | 'onSelectedCellChange'\n  | 'onScroll'\n  | 'onColumnResize'\n  | 'onColumnsReorder'\n  | 'enableVirtualization'\n  | 'rowClass'\n  | 'data-testid'\n  | 'headerRowHeight'\n>;\n```\n\n## ColumnConfig\n\n```typescript\ntype ColumnConfig<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n  /**\n   * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n   */\n  nameAsString?: string;\n  sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n  searching?: {\n    valueInRow: (row: Row) => string | number;\n  };\n  filtering?: {\n    keyInFilterState: string;\n    /**\n     * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n     */\n    valueInRow?: (row: Row) => string | number;\n    /**\n     * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n     */\n  } & (\n    | {\n        component: 'input';\n        filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n      }\n    | {\n        component: 'select';\n        /**\n         * Произвольное содержимое над списком опций фильтра.\n         *\n         * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n         * фильтров. Рендерится как компонент, поэтому внутри можно\n         * использовать хуки и локальное состояние.\n         *\n         * @example\n         * beforeList: ({ headerContextState }) => (\n         *   <TableFilterSelectListItem $size={headerContextState.rowSize}>\n         *     Подсказка над списком\n         *   </TableFilterSelectListItem>\n         * )\n         */\n        beforeList?: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        /**\n         * Произвольное содержимое под списком опций фильтра.\n         *\n         * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n         * фильтров. Рендерится как компонент, поэтому внутри можно\n         * использовать хуки и локальное состояние — например, чтобы держать\n         * черновик выбора и применять его по кнопке.\n         *\n         * @example\n         * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n         *   <TableFilterSelectListItem $size={headerContextState.rowSize}>\n         *     Подсказка под списком\n         *   </TableFilterSelectListItem>\n         * )\n         */\n        afterList?: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        filter:\n          | {\n              typeOfValue: 'single';\n              /**\n               * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n               */\n              filteringType?: FilterCb<'single'>;\n            }\n          | {\n              typeOfValue: 'multiple';\n              /**\n               * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n               */\n              filteringType?: FilterCb<'multiple'>;\n            };\n        selectOptions:\n          | {\n              type: 'constant';\n              options: SelectOptions[];\n            }\n          | {\n              type: 'stateInHeaderContext';\n              /**\n               * тип optionsState, который будет в HeaderContext:\n               * ```ts\n               * {\n               * value: string | number;\n               * text: string | number;\n               * }[];\n               * ```\n               */\n              optionsKeyInHeaderContext: string;\n            };\n        /**\n         * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n         * @default \"360px\"\n         */\n        listMaxHeight?: string;\n      }\n    | {\n        component: 'custom';\n        customRender: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n        compareWithClearedValue?: (\n          clearedValue: unknown,\n          currV: unknown,\n        ) => boolean;\n      }\n  );\n\n  contentFormat?: ContentFormat;\n\n  editingCell?: Editing<Row>;\n\n  subRow?: {\n    /**\n     * @default false\n     */\n    isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n    /**\n     * @default false\n     */\n    hideHeaderExpandAllArrow?: boolean;\n    /**\n     * @default false\n     */\n    parentKeyAsDefault?: boolean;\n    /**\n     * @default undefined\n     */\n    contentFormat?: ContentFormat;\n\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    renderSubRowCell?: RenderSubRowCell<any>;\n  } & (\n    | {\n        keyOfColumnInSubRow:\n          | string\n          | number\n          | ((lvl: number) => string | number);\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        editingCell: Editing<any>;\n      }\n    | {\n        editingCell?: undefined;\n        keyOfColumnInSubRow?:\n          | string\n          | number\n          | ((lvl: number) => string | number);\n      }\n  );\n  rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n  keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
      "curatedStories": [
        {
          "exportName": "Docs",
          "displayName": "API",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => <></>"
        },
        {
          "exportName": "Docs",
          "displayName": "API",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => <></>"
        },
        {
          "exportName": "Docs",
          "displayName": "API",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => <></>"
        }
      ],
      "legacy": true,
      "supersededBy": "TableCanvas",
      "chooseWhen": "Практически никогда для нового кода — только для доработки уже существующих экранов на react-data-grid, где миграция на TableCanvas не входит в задачу.",
      "hasCuratedMeta": true,
      "relatedExports": [
        "TableFilterSelectListItem",
        "ControlBlockSwitch",
        "NoRowsFallback",
        "ContainerStyled"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Table } from '@daisforge/ui';",
      "minimalUsage": "<Table columnConfig={[]} rows={[]} />",
      "examples": [
        {
          "exportName": "Docs",
          "displayName": "API",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => <></>"
        },
        {
          "exportName": "Docs",
          "displayName": "API",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => <></>"
        },
        {
          "exportName": "Docs",
          "displayName": "API",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => <></>"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в Table.multipleFeatures.stories.tsx",
          "type": "usage",
          "code": "<Table\n          tableConfig={{\n            css: `\n              & .rdg-control-block-container {\n                background-color: red;\n                min-height: 200px;\n              }\n            `,\n            loadingOverlay: {\n              active: isVisibleLoadingOverlay,\n              showSubtitleDelay: 5000,\n              subtitle:\n                'Данные обрабатываются, обычно это занимает не более 10 секунд',\n            },\n            containerStyle: { height: 700 },\n            fullScreenEnabled: {\n              showInControl: true,\n              domMetadata: {\n                className: 'someClassForFullScreenEnabled',\n                dataAttributes: {\n                  'data-test-fullscreen-enabled': 'test-fullscreen-enabled',\n                },\n              },\n            },\n            columnsControl: {\n              enable: true,\n              pinnedDefault: ['task', 'developer'],\n            },\n            rowSize: {\n              showInControl: true,\n              domMetadata: {\n                className: 'someTestClassForRowSize',\n                dataAttributes: {\n                  'data-test-row-size': 'test-row-size',\n                },\n              },\n            },\n            keyText: {\n              showInControl: true,\n              controlBlock: {\n                domMetadata: {\n                  className: 'someTestClassForKeyTextInControlBlock',\n                  dataAttributes: {\n                    'data-test-key-text-control-block':\n                      'test-key-text-control-block',\n                  },\n                },\n              },\n              sidebar: {\n                domMetadata: {\n                  className: 'someTestClassForKeyTextInSidebar',\n                  dataAttributes: {\n                    'data-test-key-text-sidebar': 'test-key-text-sidebar',\n                  },\n                },\n              },\n            },\n            summaryRows: {\n              showDefault: true,\n              showInControl: true,\n              domMetadata: {\n                className: 'someTestClassForSummaryRows',\n                dataAttributes: {\n                  'data-test-summary-rows': 'test-summary-rows',\n                },\n              },\n            },\n            searching: {\n              enabled: true,\n              searchClasses: 'someClassForSearch',\n              debounceDelay: 400,\n              domMetada\n// … (обрезано)",
          "sourceFile": "packages/storybook/src/stories/Table/Table.multipleFeatures.stories.tsx"
        }
      ]
    },
    "ControlBlockSwitch": {
      "name": "ControlBlockSwitch",
      "group": "components",
      "folderName": "Table",
      "role": "internal",
      "description": "Неактивный переключатель-индикатор состояния в управляющем блоке строки Table",
      "props": [
        {
          "name": "description",
          "type": "string | undefined",
          "required": false,
          "description": "Дополнительное описание"
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": "Добавить рамку при фокусе"
        },
        {
          "name": "hasBackground",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отображение подложки у switch"
        },
        {
          "name": "label",
          "type": "React.ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу"
        },
        {
          "name": "labelPosition",
          "type": "\"before\" | \"after\" | undefined",
          "required": false,
          "description": "Расположение подпись"
        },
        {
          "name": "onChange",
          "type": "React.ChangeEventHandler<HTMLInputElement> | undefined",
          "required": false,
          "description": "Обработчик изменения элемента формы"
        },
        {
          "name": "singleLine",
          "type": "boolean | undefined",
          "required": false,
          "description": "Перенос строки label",
          "default": "true"
        },
        {
          "name": "size",
          "type": "\"s\" | \"m\" | \"l\" | undefined",
          "required": false,
          "description": "Размер компонента."
        },
        {
          "name": "toggleSize",
          "type": "\"s\" | \"l\" | undefined",
          "required": false,
          "description": "Размер toggle."
        },
        {
          "name": "view",
          "type": "\"default\" | undefined",
          "required": false,
          "description": "Вид компонента."
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "outlined",
          "type": "boolean | undefined",
          "required": false,
          "description": "Добавить рамку при фокусе",
          "deprecated": true
        },
        {
          "name": "pressed",
          "type": "boolean | undefined",
          "required": false,
          "description": "Нажатие на компонент",
          "deprecated": true
        }
      ],
      "propsTypeName": "ControlBlockSwitchProps",
      "sourceFile": "packages/ui-kit/src/components/Table/widgets/control-block/control-block-switch.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "индикатор переключателя",
        "readonly switch",
        "статус строки"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Table",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ControlBlockSwitch } from '@daisforge/ui';",
      "minimalUsage": "<ControlBlockSwitch />",
      "examples": []
    },
    "NoRowsFallback": {
      "name": "NoRowsFallback",
      "group": "components",
      "folderName": "Table",
      "role": "internal",
      "description": "Заглушка «нет данных» с картинкой и текстом для пустой таблицы Table",
      "props": [
        {
          "name": "text",
          "type": "string | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "NoRowsFallbackProps",
      "sourceFile": "packages/ui-kit/src/components/Table/widgets/no-rows-fallback.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "пустое состояние",
        "нет данных",
        "empty state таблицы"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Table",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { NoRowsFallback } from '@daisforge/ui';",
      "minimalUsage": "<NoRowsFallback />",
      "examples": []
    },
    "ContainerStyled": {
      "name": "ContainerStyled",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "internal",
      "description": "Корневой контейнер TableCanvas: полноэкранный режим, сворачивание, скругления углов",
      "props": [
        {
          "name": "as",
          "type": "string | React.ComponentType<any> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof ContainerStyled>",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/styles/styles.ts",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "контейнер таблицы",
        "fullscreen режим",
        "сворачивание таблицы"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableCanvas",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { ContainerStyled } from '@daisforge/ui/components/TableCanvas';",
      "minimalUsage": "<ContainerStyled />",
      "examples": []
    },
    "SplitIconButton": {
      "name": "SplitIconButton",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "internal",
      "description": "Сплит-кнопка: иконка основного действия и шеврон с дропдауном для слотов TableCanvas",
      "props": [
        {
          "name": "icon",
          "type": "React.ReactNode",
          "required": true,
          "description": "Иконка основной (левой) кнопки-действия"
        },
        {
          "name": "chevronDomMetadata",
          "type": "DataAttributes | undefined",
          "required": false,
          "description": "data-атрибуты на кнопку-шеврон"
        },
        {
          "name": "chevronIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": "Полная замена иконки шеврона своим узлом. Обычно не нужна — шеврон наш\n(IconChevronDown), а размер задаётся через chevronSize. Если задан, имеет\nприоритет над chevronSize."
        },
        {
          "name": "chevronSize",
          "type": "\"s\" | \"xs\" | \"m\" | undefined",
          "required": false,
          "description": "Размер нашей иконки-шеврона. Игнорируется, если задан chevronIcon.",
          "default": "'xs'"
        },
        {
          "name": "domMetadata",
          "type": "DataAttributes | undefined",
          "required": false,
          "description": "data-атрибуты на контейнер"
        },
        {
          "name": "dropdownProps",
          "type": "TableDropdownConfigProps | undefined",
          "required": false,
          "description": "Доп. конфиг TableDropdown (placement, listWidth и т.п.)"
        },
        {
          "name": "iconDomMetadata",
          "type": "DataAttributes | undefined",
          "required": false,
          "description": "data-атрибуты на основную кнопку"
        },
        {
          "name": "iconTooltip",
          "type": "React.ReactNode",
          "required": false,
          "description": "Tooltip на левой кнопке-иконке (если задан — оборачиваем в TableTooltip)."
        },
        {
          "name": "items",
          "type": "ItemOption[] | undefined",
          "required": false,
          "description": "Пункты дропдауна. Если заданы — кнопка-шеврон открывает TableDropdown.\nЕсли не заданы — шеврон работает как обычная кнопка (onChevronClick)."
        },
        {
          "name": "onChevronClick",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Клик по шеврону в режиме без дропдауна (items не заданы)"
        },
        {
          "name": "onIconClick",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Клик по основной кнопке-иконке"
        },
        {
          "name": "onItemSelect",
          "type": "((item: ItemOption, event: React.SyntheticEvent<Element, Event>) => void) | undefined",
          "required": false,
          "description": "Выбор пункта дропдауна"
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean) => void) | undefined",
          "required": false,
          "description": "Колбэк открытия/закрытия дропдауна"
        },
        {
          "name": "size",
          "type": "\"s\" | \"m\" | \"l\" | undefined",
          "required": false,
          "description": "Размер обеих кнопок (EmbedIconButton)",
          "default": "'s'"
        }
      ],
      "propsTypeName": "SplitIconButtonProps",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/components/SplitIconButton/SplitIconButton.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "сплит-кнопка",
        "split button",
        "иконка с дропдауном"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableCanvas",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { SplitIconButton } from '@daisforge/ui/components/TableCanvas';",
      "minimalUsage": "<SplitIconButton icon={'Контент'} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в starFeature.tsx",
          "type": "usage",
          "code": "<SplitIconButton\n          icon={<IconStar size={panelStarSize} />}\n          chevronSize=\"xs\"\n          size={embedSize}\n          items={items}\n          onItemSelect={(item) => setSelected(String(item.value))}\n          onIconClick={() => alert('Star icon click')}\n          domMetadata={{ 'data-test-id': 'star-compound-with-checks' }}\n        />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.ControlBlock/_lib/starFeature.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvas.controlBlock.stories.tsx",
          "type": "usage",
          "code": "<SplitIconButton\n      icon={<IconSb size=\"s\" />}\n      size=\"m\"\n      chevronSize=\"xs\"\n      onIconClick={() => alert('Icon click')}\n      items={[\n        { value: 'copy', label: 'Копировать' },\n        { value: 'paste', label: 'Вставить' },\n      ]}\n      onItemSelect={(item) => alert(`Edit: ${item.label}`)}\n      domMetadata={{ 'data-test-id': 'edit-mode-compound-btn' }}\n    />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.ControlBlock/TableCanvas.controlBlock.stories.tsx"
        }
      ]
    },
    "CellEditorCombobox": {
      "name": "CellEditorCombobox",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "internal",
      "description": "Редактор ячейки TableCanvas на основе Combobox — выбор значения из списка",
      "props": [
        {
          "name": "autoFocusType",
          "type": "\"autoFocus\" | \"none\"",
          "required": true,
          "description": ""
        },
        {
          "name": "cellHeight",
          "type": "number",
          "required": true,
          "description": ""
        },
        {
          "name": "cellWidth",
          "type": "number",
          "required": true,
          "description": ""
        },
        {
          "name": "paddingInline",
          "type": "number",
          "required": true,
          "description": ""
        },
        {
          "name": "disableLeftOffset",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "React.HTMLInputTypeAttribute | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "CellEditorComboboxProps",
      "rawType": "export type CellEditorComboboxProps<T extends ComboboxItemOption> =\n  ComboboxCompProps<T> &\n    CustomCellStyleProps & {\n      autoFocusType: 'autoFocus' | 'none';\n      paddingInline: number;\n    };",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-edit/CellEditorCombobox.tsx",
      "type": "wrapper",
      "atomicBase": "Combobox",
      "wrapsInternal": "Combobox",
      "category": "Локальные компоненты",
      "keywords": [
        "редактирование ячейки",
        "выбор из списка",
        "inline editing"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableCanvas",
      "inheritedProps": [
        {
          "name": "items",
          "type": "T[]",
          "required": true,
          "description": "Список элементов.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "afterList",
          "type": "ReactNode",
          "required": false,
          "description": "Ячейка для контента в конце выпадающего списка.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "alwaysOpened",
          "type": "boolean",
          "required": false,
          "description": "Дропдаун открыт всегда.",
          "default": "false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "arrowPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Сторона расположения стрелки скрытия/раскрытия.",
          "default": "left",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "beforeList",
          "type": "ReactNode",
          "required": false,
          "description": "Ячейка для контента в начале выпадающего списка.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeAfterSelect",
          "type": "boolean",
          "required": false,
          "description": "Закрывать ли выпадающий список после выбора элемента.",
          "default": "если single, то true; если multiple, то false; если передан alwaysOpened, то false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента слева.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "description": "Слот для контента справа.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "emptyStateDescription",
          "type": "ReactNode",
          "required": false,
          "description": "Текст для состояния когда нет результата.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "filter",
          "type": "((item: T, textValue: string) => boolean)",
          "required": false,
          "description": "Функция фильтрации элементов.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "filterValue",
          "type": "((value: string) => boolean)",
          "required": false,
          "description": "Функция валидации вводимых значений.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "flip",
          "type": "boolean",
          "required": false,
          "description": "Коррекция placement, если выпадающий список находится за пределами экрана.",
          "default": "false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "helperText",
          "type": "string",
          "required": false,
          "description": "Вспомогательный текст снизу слева для поля ввода.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintContentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean",
          "required": false,
          "description": "Видимость стрелки (хвоста).",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOffset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "description": "Направление раскрытия тултипа.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPortal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "Портал для окна подсказки. Принимает id контейнера или ref.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetIcon",
          "type": "ReactNode",
          "required": false,
          "description": "Иконка, рядом с которым произойдет вызов всплывающего окна.\nЕсли свойство не задано, применится иконка по умолчанию.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение иконки подсказки, когда отсутствует label\nили же он имеет labelPlacement='inner'.",
          "default": "`outer`",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintText",
          "type": "string",
          "required": false,
          "description": "Текст тултипа",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\"",
          "required": false,
          "description": "Способ открытия тултипа - наведение или клик мышью",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintWidth",
          "type": "string",
          "required": false,
          "description": "Ширина окна (в rem).",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение лейбла.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "listMaxHeight",
          "type": "Height<string | number>",
          "required": false,
          "description": "Максимальная высота выпадающего списка.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "listWidth",
          "type": "Width<string | number>",
          "required": false,
          "description": "Значение css width для выпадающего списка.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "mode",
          "type": "\"radio\" | \"default\"",
          "required": false,
          "description": "Режим работы взаимодействия с элементами.\n- default: элемент можно выбрать и можно отменить его выбор.\n- radio: если элемент выбран, то отменить его выбор нельзя. Только для single-режима.",
          "default": "default",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeValue",
          "type": "((value: string) => void)",
          "required": false,
          "description": "Обработчик изменения значения в строке поиска.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onScroll",
          "type": "((e: UIEvent<HTMLElement, UIEvent>) => void)",
          "required": false,
          "description": "Коллбэк, срабатывающий при скролле.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean) => void)",
          "required": false,
          "description": "Событие сворачивания/разворачивания выпадающего списка.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optional",
          "type": "boolean",
          "required": false,
          "description": "Флаг необязательности поля",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optionalText",
          "type": "string",
          "required": false,
          "description": "Подпись для указания необязательности поля",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "Placement",
          "required": false,
          "description": "Сторона открытия дропдауна относительно target элемента.",
          "default": "bottom-start",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "portal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "description": "Портал для выпадающего списка. Принимает id контейнера или ref.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderItem",
          "type": "((item: T) => ReactNode)",
          "required": false,
          "description": "Callback для кастомной настройки элемента в выпадающем списке.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderSelectionIcon",
          "type": "((selected: boolean | \"indeterminate\") => ReactNode)",
          "required": false,
          "description": "Callback для кастомной настройки иконки выбранного элемента.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "requiredPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shift",
          "type": "boolean",
          "required": false,
          "description": "Смещение выпадающего списка при соприкосновении с границами экрана.",
          "default": "false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "singleLine",
          "type": "boolean",
          "required": false,
          "description": "Label в элементе выпадающего списка в одну строку или с переносом строк.",
          "default": "true",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textAfter",
          "type": "string",
          "required": false,
          "description": "Слот для вспомогательного текста слева.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textBefore",
          "type": "string",
          "required": false,
          "description": "Слот для вспомогательного текста справа.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "treeView",
          "type": "boolean",
          "required": false,
          "description": "Режим отображения выпадающего списка в виде дерева.",
          "default": "false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "variant",
          "type": "\"normal\" | \"tight\"",
          "required": false,
          "description": "Вариант: обычный или сжатый",
          "default": "normal",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "virtual",
          "type": "boolean",
          "required": false,
          "description": "Виртуализация в выпадающем списке.\nНе поддерживается в многоуровневых списках.",
          "default": "false",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "ZIndex",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего списка.",
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "_offset",
          "type": "[number, number]",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"viewMode\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipClickArea",
          "type": "\"full\" | \"close-icon\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"accent\" | \"secondary\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultValue",
          "type": "string | string[]",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintView",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isTargetAmount",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "multiple",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "ChangeEventHandler<HTMLSelectElement> | ((value: string, item: T | null) => void) | ((value: string[], item: T | null) => void)",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placeholder",
          "type": "string",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderValue",
          "type": "((item: T) => string)",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "required",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "selectAllOptions",
          "type": "SelectAllProps",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "targetAmount",
          "type": "number",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | string[]",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\"",
          "required": false,
          "inheritedFrom": "Combobox",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellEditorCombobox } from '@daisforge/ui/components/TableCanvas';",
      "minimalUsage": "<CellEditorCombobox autoFocusType={\"autoFocus\"} cellHeight={0} cellWidth={0} paddingInline={0} items={[]} />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Appearance Appearance appearance=\"viewMode\"  — режим просмотра.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Combobox } from '@daisforge/ui/components/TableCanvas';\nexport function App() {\n    const items = [\n        { value: 'option_1', label: 'Опция 1' },\n        { value: 'option_2', label: 'Опция 2' },\n    ];\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '20px', maxWidth: '350px', height: '200px' }}>\n            <Combobox items={items} appearance=\"default\" label=\"Default\" placeholder=\"Placeholder\" />\n            <Combobox items={items} appearance=\"viewMode\" value=\"option_1\" readOnly label=\"ViewMode\" placeholder=\"Placeholder\" />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Использование Использование Обязательным параметром является только  items . Внутри items может быть такой же вложенный массив items. Формат следующий",
          "type": "vendor",
          "code": "type Items = Array<{\n    /**\n     * Значение у item.\n     */\n    value: string;\n    /**\n     * Метка-подпись к item.\n     */\n    label: string;\n    /**\n     * Сторона открытия вложенного дропдауна относительно текущего элемента.\n     * @default bottom-start\n     */\n    placement?: Placement;\n    /**\n     * Список дочерних items.\n     */\n    items?: Array<ItemOption>;\n    /**\n     * Item не активен.\n     */\n    disabled?: boolean;\n    /**\n     * Слот для контента слева.\n     */\n    contentLeft?: ReactNode;\n    /**\n     * Слот для контента справа.\n     */\n    contentRight?: ReactNode;\n    /**\n     * Classname для item.\n     */\n    className?: string;\n    /**\n     * Максимальная высота дочернего выпадающего списка.\n     */\n    listMaxHeight?: CSSProperties['height'];\n}>;"
        }
      ]
    },
    "CellEditorNumberFormat": {
      "name": "CellEditorNumberFormat",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "internal",
      "description": "Редактор ячейки TableCanvas для чисел с маской формата и разделителями",
      "props": [
        {
          "name": "autoFocusType",
          "type": "\"autoFocus\" | \"none\" | \"autoFocusAndSelect\"",
          "required": true,
          "description": ""
        },
        {
          "name": "cellHeight",
          "type": "number",
          "required": true,
          "description": ""
        },
        {
          "name": "cellWidth",
          "type": "number",
          "required": true,
          "description": ""
        },
        {
          "name": "suffix",
          "type": "string | undefined",
          "required": false,
          "description": "Суффикс текста в поле ввода."
        },
        {
          "name": "align",
          "type": "\"center\" | \"right\" | \"left\" | undefined",
          "required": false,
          "description": "",
          "default": "'right'"
        },
        {
          "name": "disableLeftOffset",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onClear",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "CellEditorNumberFormatProps",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-edit/CellEditorNumberFormat.tsx",
      "type": "wrapper",
      "atomicBase": "NumberFormat",
      "wrapsInternal": "NumberFormat",
      "category": "Локальные компоненты",
      "keywords": [
        "ввод чисел",
        "маска формата",
        "числовой редактор"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableCanvas",
      "inheritedProps": [
        {
          "name": "allowLeadingZeros",
          "type": "boolean",
          "required": false,
          "description": "Разрешает ведущие нули (например, \"0123\").",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "allowNegative",
          "type": "boolean",
          "required": false,
          "description": "Разрешает ввод отрицательных чисел.",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "decimalScale",
          "type": "number",
          "required": false,
          "description": "Количество знаков после запятой.",
          "default": "3",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "decimalSeparator",
          "type": "string",
          "required": false,
          "description": "Разделитель десятичных знаков (например, \".\").",
          "default": ".",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "fixedDecimalScale",
          "type": "boolean",
          "required": false,
          "description": "Фиксирует количество знаков после запятой, даже если число их не содержит (добавляет нули).",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isAllowed",
          "type": "((values: NumberFormatValues) => boolean)",
          "required": false,
          "description": "Функция для валидации входного значения.\nЕсли эта функция возвращает false, метод onChange не будет вызван, и значение ввода не изменится.",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение лейбла.",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "(((event?: ChangeEvent<HTMLInputElement>, values?: NumberFormatValues) => void) & ChangeEventHandler<HTMLInputElement>) | undefined",
          "required": false,
          "description": "Callback, вызываемый при изменении значения в поле ввода.\nПринимает событие изменения (ChangeEvent) и объект NumberFormatValues:\n```\nfloatValue: number | undefined;\nformattedValue: string;\nvalue: string;\n```\nОбработчик изменения элемента формы",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optional",
          "type": "boolean",
          "required": false,
          "description": "Флаг необязательности поля",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optionalText",
          "type": "string",
          "required": false,
          "description": "Подпись для указания необязательности поля",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "requiredPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "thousandSeparator",
          "type": "string | boolean",
          "required": false,
          "description": "Разделитель тысяч.\nМожет быть строкой (например, \",\") или булевым значением.",
          "default": "' ' (пробел)",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "thousandsGroupStyle",
          "type": "\"none\" | \"thousand\" | \"lakh\" | \"wan\"",
          "required": false,
          "description": "Стиль группировки тысяч:\n- 'thousand' (123 456 789),\n- 'lakh' (индийский стиль, 12 34 56 789),\n- 'wan' (китайский стиль, 1 2345 6789),\n- 'none' (без группировки).",
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"clear\" | \"default\" | \"viewMode\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chips",
          "type": "TextFieldPrimitiveValue[]",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipType",
          "type": "\"text\" | \"default\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipValidator",
          "type": "((value: string) => ChipValidatorReturn)",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "clear",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "enumerationType",
          "type": "\"plain\" | \"chip\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasDivider",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintContentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOffset",
          "type": "[number, number]",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPortal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetIcon",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintText",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintView",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintWidth",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "leftHelper",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onBlur",
          "type": "FocusEventHandler<HTMLInputElement>",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeChips",
          "type": "((value: TextFieldPrimitiveValue[]) => void)",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onFocus",
          "type": "FocusEventHandler<HTMLInputElement>",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onSearch",
          "type": "(((value: string, event?: KeyboardEvent<HTMLInputElement>) => void) & ((value: string, event?: KeyboardEvent<HTMLInputElement>) => void)) | undefined",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "rightHelper",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textAfter",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textBefore",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "titleCaption",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "type",
          "type": "string",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\"",
          "required": false,
          "inheritedFrom": "NumberFormat",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellEditorNumberFormat } from '@daisforge/ui/components/TableCanvas';",
      "minimalUsage": "<CellEditorNumberFormat autoFocusType={\"autoFocus\"} cellHeight={0} cellWidth={0} />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в TableCanvas.editing.stories.tsx",
          "type": "usage",
          "code": "<CellEditorNumberFormat\n                  cellHeight={cellHeight}\n                  cellWidth={cellWidth}\n                  autoFocusType={\n                    initialValueAsNumber === null\n                      ? 'autoFocusAndSelect'\n                      : 'autoFocus'\n                  }\n                  value={v}\n                  onChange={handleChange}\n                />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Editing/TableCanvas.editing.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Отрицательные числа",
          "type": "vendor",
          "code": "import React from 'react';\nimport { NumberFormat } from '@daisforge/ui/components/TableCanvas';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n            <NumberFormat\n                size=\"s\"\n                defaultValue=\"-123\"\n                thousandSeparator=\" \"\n                decimalSeparator=\".\"\n                allowNegative\n            />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Ведущие нули",
          "type": "vendor",
          "code": "import React from 'react';\nimport { NumberFormat } from '@daisforge/ui/components/TableCanvas';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>\n            <NumberFormat\n                size=\"s\"\n                defaultValue=\"000123.456\"\n                thousandSeparator=\" \"\n                decimalSeparator=\".\"\n                allowLeadingZeros\n            />\n        </div>\n    );\n}"
        }
      ]
    },
    "CellEditorTextArea": {
      "name": "CellEditorTextArea",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "internal",
      "description": "Редактор ячейки TableCanvas на основе автоувеличивающегося текстового поля",
      "props": [
        {
          "name": "cellHeight",
          "type": "number",
          "required": true,
          "description": ""
        },
        {
          "name": "cellWidth",
          "type": "number",
          "required": true,
          "description": ""
        },
        {
          "name": "paddingInline",
          "type": "number",
          "required": true,
          "description": ""
        },
        {
          "name": "autoFocusType",
          "type": "\"autoFocus\" | \"none\" | \"autoFocusAndSelect\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "containerClassName",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "disableLeftOffset",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "altNewline",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "dirName",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChange",
          "type": "React.ChangeEventHandler<HTMLTextAreaElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "validatedSelection",
          "type": "SelectionRange | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "CellEditorTextAreaProps",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-edit/CellEditorTextArea.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "текстовый редактор ячейки",
        "многострочный ввод",
        "inline text edit"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableCanvas",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellEditorTextArea } from '@daisforge/ui/components/TableCanvas';",
      "minimalUsage": "<CellEditorTextArea cellHeight={0} cellWidth={0} paddingInline={0} />",
      "examples": []
    },
    "TableCanvas": {
      "name": "TableCanvas",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "primary",
      "description": "Основная канвасная таблица: сортировка, фильтры, группировка, редактирование ячеек.",
      "props": [
        {
          "name": "columnConfig",
          "type": "readonly ColumnConfig<RowType, SummaryRowType>[]",
          "required": true,
          "description": "columnConfig - Конфигурация колонок.\n\n(рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)"
        },
        {
          "name": "rows",
          "type": "RowType[]",
          "required": true,
          "description": "rows - данные для таблицы. ```RowType extends Record<string | number, any>```"
        },
        {
          "name": "bottomSummaryRows",
          "type": "SummaryRowType[] | undefined",
          "required": false,
          "description": "bottomSummaryRows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```"
        },
        {
          "name": "headerContextValue",
          "type": "HeaderContextValueType | undefined",
          "required": false,
          "description": "headerContextValue:  любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью cellInfo.ctxs из args."
        },
        {
          "name": "rowContextValue",
          "type": "RowContextValueType | undefined",
          "required": false,
          "description": "rowContextValue:  любые стейты, которые нужны в cell - кладем в rowContextValue.  И получаем доступ с помощью cellInfo.ctxs из args."
        },
        {
          "name": "tableConfig",
          "type": "{ columnsGrouping?: ColumnsGroupingConfig | undefined; highlightActiveType?: HighlightActiveType | undefined; cellsSelection?: CellsSelectionConfig | undefined; highlightActiveRow?: { state?: [number | undefined, React.Dispatch<React.SetStateAction<number | undefined>>] | undefined; onChange?: ((params: { index: number | undefined; row: RowType | undefined; }) => void) | undefined; } | undefined; …",
          "required": false,
          "description": "tableConfig - Конфигурация фичей таблицы (их активация и отключение)",
          "default": "{}"
        },
        {
          "name": "refTable",
          "type": "React.Ref<DataEditorRef> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "refTableContainer",
          "type": "React.Ref<HTMLDivElement> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TableCanvasProps",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableCanvas.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "hint": "Основная таблица. Если пользователь спрашивает про 'таблицу' — скорее всего TableCanvas. Для табличных вкладок — TableTabs.",
      "keywords": [
        "excel-like таблица",
        "canvas grid",
        "редактируемая таблица"
      ],
      "docs": "# TableCanvas\n\n### Компонент для отрисовки табличных данных\n\nЕдиный инструмент для отображения данных, имеющий набор фичей. Любой продукт сможет использовать таблицу для достижения своих целей.\n\n---\n\n#### В основе HTML-canvas\n\nВ основе `TableCanvas` используется html `canvas` для обеспечения плавной непрерывной отрисовки контента.\nВ связи с этим, необходимо учитывать особенности во время отрисовки canvas-ячеек. К canvas-ячейкам относятся ячейки шапки, основных данных, итоговых данных.\n\n---\n\n#### Миграция с Table\n\nОснова API TableCanvas унаследована от API Table для легкой миграции и переиспользования протестированных решений на основе Table.\n\n- `TableProps` и `TableProps.tableConfig` обратно совместимы на 95+% c API Table (на основе имеющихся в TableCanvas фичей)\n- `TableProps.columnConfig` - претерпел изменения в связи с особенностями рендера на `canvas`.\n\nВ `TableProps.columnConfig` обновлены свойства `renderHeaderCell, renderCell, renderSummaryCell`, теперь:\n\n- они должны быть функциями, которые возвращают Canvas-элементы (импортировать из директории TableCanvas. Примеры: Canvas.Button,Canvas.Badge и тд.).\n- в них нельзя использовать компоненты, только Canvas-элементы.\n- В них нельзя вызывать хуки, это функции рендера - не компоненты.\n- если нужны данные для ячеек, то передаем данные либо в `headerContextValue`, либо в `rowContextValue`. И получаем через `args` функции.\n\n---\n\n_\\*С более подробной документацией по фичам можно ознакомиться точечно в разделе каждой фичи (в боковом меню)_\n\n---\n\n#### Импорт\n\nТипы, хуки и компоненты, связанные с `TableCanvas`, необходимо импортировать из папки компонента:\n\n```ts\n\n```\n\nОстальные компоненты (`Badge`, `Button`, `Switch` и т.д.) импортируются как обычно — из корня пакета:\n\n```ts\n\n```\n\nИконки — из `/icons`:\n\n```ts\n\n```\n\n---\n\n### API\n\n#### TableProps\n\n<!-- CustomArgTypes: TableCanvas -> TableProps (не найден в types.string.json) -->\n\n<br />\n\n#### TableProps.tableConfig\n\n<!-- CustomArgTypes: StoryTableCanvasConfigComp -> TableConfig (не найден в types.string.json) -->\n\n<br />\n\n#### TableProps.columnConfig\n\n<!-- CustomArgTypes: StoryColumnConfigTableCanvasComp -> ColumnConfig (не найден в types.string.json) -->",
      "chooseWhen": "Таблица по умолчанию для нового кода: нужны сортировка/фильтры/группировка/массовые действия/редактирование ячеек из коробки, без ручной сборки.",
      "hasCuratedMeta": true,
      "relatedExports": [
        "SplitIconButton",
        "CellEditorCombobox",
        "CellEditorNumberFormat",
        "CellEditorTextArea",
        "TableFilterSelectListItem",
        "ContainerStyled",
        "TextCellEntry",
        "Canvas",
        "TextCellEntryType"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TableCanvas } from '@daisforge/ui';",
      "minimalUsage": "<TableCanvas columnConfig={[]} rows={[]} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в TableCanvas.multipleFeatures.stories.tsx",
          "type": "usage",
          "code": "<TableCanvas\n          tableConfig={{\n            editing: {\n              onRowsChange: setRows,\n              rowKeyGetter: (r) => `${r.id}`,\n            },\n            containerStyle: { height: '80vh' },\n            unstickyHeader,\n            fullScreenEnabled: true,\n            resizableColumn: true,\n            loadingOverlay: {\n              active: isVisibleLoadingOverlay,\n              showSubtitleDelay: 5000,\n              subtitle:\n                'Данные обрабатываются, обычно это занимает не более 10 секунд',\n            },\n            rowSize: {\n              default: 'big',\n              showInControl: true,\n            },\n            cellsSelection: { mode: selectionMode },\n            highlightActiveType,\n            searching: {\n              enabled: true,\n              debounceDelay: 400,\n            },\n            keyText: {\n              showInControl: true,\n              controlBlock: {},\n              sidebar: {},\n            },\n            summaryRows: {\n              showDefault: true,\n              showInControl: true,\n            },\n            columnsControl: {\n              enable: true,\n              hiding: true,\n              pinning: true,\n              reorderingAside: true,\n              reorderingHeader: true,\n              disableHiding: ['id'],\n              disablePinning: ['developer'],\n              columnsLabel: {\n                task: 'Задачи',\n              },\n              pinnedDefault: ['id'],\n            },\n            rowMarkers: {\n              startIndex: 1,\n            },\n            sidebarConfig: {\n              customTabs: [\n                {\n                  id: 'customInfo',\n                  label: 'Информация',\n                  icon: <IconInfo size=\"s\" />,\n                  content: <CustomInfoTab />,\n                  title: 'Информация',\n                  showInSidebar: true,\n                },\n              ],\n            },\n            controlBlock: {\n              show: controlBlock,\n              rightSideInner: [\n                {\n                  text: 'Label',\n                  contentLeft: <IconSb color=\"inherit\" />,\n                  view: 'linkAccent',\n                  'data-test-id': 'Label right 1',\n                },\n                {\n                  text: 'Скачать',\n                  contentLeft: <IconSb color=\"inherit\" />,\n                  'data-test-id': 'store2',\n          \n// … (обрезано)",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.MultipleFeatures/TableCanvas.multipleFeatures.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvas.unstickyHeader.stories.tsx",
          "type": "usage",
          "code": "<TableCanvas\n        key={headerTreeLvl}\n        tableConfig={{\n          unstickyHeader: true,\n          containerStyle: { height: '70vh' },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.UnstickyHeader/TableCanvas.unstickyHeader.stories.tsx"
        }
      ]
    },
    "TableGlideInstance": {
      "name": "TableGlideInstance",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "primary",
      "description": "Внутренний адаптер TableGlide под контексты Table/TableCanvas: колонки, меню, оверлеи.",
      "props": [
        {
          "name": "CellReadOnlyEditor",
          "type": "(props: CellReadOnlyEditorGlideInstanceProps<R, SR>) => React.ReactNode",
          "required": true,
          "description": ""
        },
        {
          "name": "columns",
          "type": "readonly ColumnGlideInstance<R, SR, CustomCtxs>[]",
          "required": true,
          "description": ""
        },
        {
          "name": "rows",
          "type": "readonly R[]",
          "required": true,
          "description": ""
        },
        {
          "name": "onCellClicked",
          "type": "(((cell: Item, event: CellClickedEventArgs) => void) & ((cell: readonly [number, number], info: TableInfoWithRow<R, SR, CustomCtxs>) => void)) | undefined",
          "required": false,
          "description": "Emitted when a cell is clicked."
        },
        {
          "name": "renderOverlayFeatures",
          "type": "(((ctx: { containerElement: HTMLDivElement; renderInContainer: (children: React.ReactNode) => React.ReactPortal | null; }) => React.ReactNode) & ((ctx: { containerElement: HTMLDivElement; renderInContainer: (children: React.ReactNode) => React.ReactPortal | null; }) => React.ReactNode)) | undefined",
          "required": false,
          "description": "Рендер overlay-фич (tooltip, contextMenu, popover) внутри wrapper-div когда DOM готов"
        },
        {
          "name": "allowedFillDirections",
          "type": "FillHandleDirection | undefined",
          "required": false,
          "description": "Controls which directions fill is allowed in."
        },
        {
          "name": "cellActivationBehavior",
          "type": "CellActivationBehavior | undefined",
          "required": false,
          "description": "Determines when a cell is considered activated and will emit the `onCellActivated` event. Generally an activated\ncell will open to edit mode."
        },
        {
          "name": "cellsSelectionMode",
          "type": "CellsSelectionMode | undefined",
          "required": false,
          "description": "Режим выделения ячеек (нативный glide selection). По умолчанию 'range-cell'."
        },
        {
          "name": "checkboxSelectedRowIndexes",
          "type": "ReadonlySet<number> | undefined",
          "required": false,
          "description": "Индексы строк, выбранных через checkbox selection."
        },
        {
          "name": "checkboxVisibleRowIndexes",
          "type": "ReadonlySet<number> | undefined",
          "required": false,
          "description": "Индексы строк, у которых ЕСТЬ (виден) чекбокс — для тёмной подсветки highlightActiveType='row'."
        },
        {
          "name": "coercePasteValue",
          "type": "((val: string, cell: GridCell) => GridCell | undefined) | undefined",
          "required": false,
          "description": "Allows coercion of pasted values."
        },
        {
          "name": "columnSelect",
          "type": "\"none\" | \"single\" | \"multi\" | undefined",
          "required": false,
          "description": "{@inheritDoc rangeSelect}"
        },
        {
          "name": "columnSelectionBlending",
          "type": "SelectionBlending | undefined",
          "required": false,
          "description": "{@inheritDoc rangeSelectionBlending}"
        },
        {
          "name": "columnSelectionMode",
          "type": "\"multi\" | \"auto\" | undefined",
          "required": false,
          "description": "Determines if column selection requires a modifier key to enable multi-selection or not. In auto mode it adapts to\ntouch or mouse environments automatically, in multi-mode it always acts as if the multi key (Ctrl) is pressed."
        },
        {
          "name": "containerClassName",
          "type": "string | undefined",
          "required": false,
          "description": "className для wrapper-div"
        },
        {
          "name": "containerRef",
          "type": "React.Ref<HTMLDivElement> | undefined",
          "required": false,
          "description": "Внешний ref на wrapper-div (для TableCanvas - refTableContainer)"
        },
        {
          "name": "containerStyle",
          "type": "React.CSSProperties | undefined",
          "required": false,
          "description": "inline-style для wrapper-div"
        },
        {
          "name": "contentStateNode",
          "type": "React.ReactNode",
          "required": false,
          "description": "DOM-узел content-state (empty/error), рендерится как прямой child контейнера."
        },
        {
          "name": "copyHeaders",
          "type": "boolean | undefined",
          "required": false,
          "description": "Add table headers to copied data."
        },
        {
          "name": "customRenderers",
          "type": "readonly CustomRenderer<any>[] | undefined",
          "required": false,
          "description": "An array of custom renderers which can be used to extend the data grid."
        },
        {
          "name": "drawHeader",
          "type": "DrawHeaderCallback | undefined",
          "required": false,
          "description": "Overrides the rendering of a header. The grid will call this for every header it needs to render. Header\nrendering is not as well optimized because they do not redraw as often, but very heavy drawing methods can\nnegatively impact horizontal scrolling performance.\n\nIt is possible to return `false` after rendering just a background and the regular foreground rendering\nwill happen."
        },
        {
          "name": "editOnType",
          "type": "boolean | undefined",
          "required": false,
          "description": "Determines if the data editor should immediately begin editing when the user types on a selected cell"
        },
        {
          "name": "editorBloom",
          "type": "readonly [number, number] | undefined",
          "required": false,
          "description": "Allows overriding the default amount of bloom (the size growth of the overlay editor)"
        },
        {
          "name": "editorOverlayPortal",
          "type": "\"inside\" | undefined",
          "required": false,
          "description": "Переносит editor overlay внутрь контейнера (вместо document.body). Для модалок с CSS transform."
        },
        {
          "name": "enableColumnSelection",
          "type": "boolean | undefined",
          "required": false,
          "description": "Выделение колонок по клику на шапку (независимо от highlightActiveType). По умолчанию true."
        },
        {
          "name": "enableLowDprHairline",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включает компенсацию тонких canvas-линий при browser zoom ниже 100% / DPR < 1."
        },
        {
          "name": "enableRowSelection",
          "type": "boolean | undefined",
          "required": false,
          "description": "Выделение строк по клику/драгу на колонке нумерации. По умолчанию true."
        },
        {
          "name": "enableSelectAll",
          "type": "boolean | undefined",
          "required": false,
          "description": "Выделение всей таблицы кликом по шапке колонки нумерации. По умолчанию true."
        },
        {
          "name": "experimental",
          "type": "{ readonly disableAccessibilityTree?: boolean | undefined; readonly disableMinimumCellWidth?: boolean | undefined; readonly paddingRight?: number | undefined; readonly paddingBottom?: number | undefined; readonly enableFirefoxRescaling?: boolean | undefined; readonly enableSafariRescaling?: boolean | undefined; readonly kineticScrollPerfHack?: boolean | undefined; readonly isSubGrid?: boolean | un…",
          "required": false,
          "description": "Experimental features"
        },
        {
          "name": "fillHandle",
          "type": "FillHandle | undefined",
          "required": false,
          "description": "Enabled/disables the fill handle."
        },
        {
          "name": "fixedShadowX",
          "type": "boolean | undefined",
          "required": false,
          "description": "Enables or disables the overlay shadow when scrolling horizontally"
        },
        {
          "name": "fixedShadowY",
          "type": "boolean | undefined",
          "required": false,
          "description": "Enables or disables the overlay shadow when scrolling vertical"
        },
        {
          "name": "freezeColumns",
          "type": "number | undefined",
          "required": false,
          "description": "The number of columns which should remain in place when scrolling horizontally. The row marker column, if\nenabled is always frozen and is not included in this count."
        },
        {
          "name": "fullScreened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг fullscreen - пересканирование DOM при переключении"
        },
        {
          "name": "getCellBorder",
          "type": "CellBorderResolver | undefined",
          "required": false,
          "description": "Настройка рамок отдельных ячеек: стороны top, right, bottom, left,\nвкл/выкл и цвет. Перекрывает `verticalBorder`, `horizontalBorder` и тему.\nЕсли не задано, линии рисуются сплошными без разбивки по ячейкам.\nrow и col приходят в пользовательских индексах, без служебных колонок."
        },
        {
          "name": "getCellsForSelection",
          "type": "true | ((selection: Rectangle, abortSignal: AbortSignal) => GetCellsThunk | CellArray) | undefined",
          "required": false,
          "description": "Used to fetch large amounts of cells at once. Used for copy/paste, if unset copy will not work.\n\n`getCellsForSelection` is called when the user copies a selection to the clipboard or the data editor needs to\ninspect data which may be outside the curently visible range. It must return a two-dimensional array (an array of\nrows, where each row is an array of cells) of the cells in the selection's rectangle. Note that the rectangle can\ninclude cells that are not currently visible.\n\nIf `true` is passed instead of a callback, the data grid will internally use the `getCellContent` callback to\nprovide a basic implementation of `getCellsForSelection`. This can make it easier to light up more data grid\nfunctionality, but may have negative side effects if your data source is not able to handle being queried for\ndata outside the normal window.\n\nIf `getCellsForSelection` returns a thunk, the data may be loaded asynchronously, however the data grid may be\nunable to properly react to column spans when performing range selections. Copying large amounts of data out of\nthe grid will depend on the performance of the thunk as well."
        },
        {
          "name": "getGroupDetails",
          "type": "GroupDetailsCallback | undefined",
          "required": false,
          "description": "Provides additional details about groups to extend group functionality."
        },
        {
          "name": "getRowThemeOverride",
          "type": "((row: number, groupRow: number, contentRow: number) => Partial<Theme> | undefined) | undefined",
          "required": false,
          "description": "Allows overriding the theme of any row"
        },
        {
          "name": "gridSelection",
          "type": "GridSelection | undefined",
          "required": false,
          "description": "The current selection of the data grid. Contains all selected cells, ranges, rows, and columns.\nUsed in conjunction with {@link onGridSelectionChange}\nmethod to implement a controlled selection."
        },
        {
          "name": "groupAlignMap",
          "type": "Map<string, SpanAlignment> | undefined",
          "required": false,
          "description": "Выравнивание текста в объединённой шапке по ключу группы (ColumnGroupConfig.key)."
        },
        {
          "name": "headerHeight",
          "type": "number | undefined",
          "required": false,
          "description": "Controls the height of the header row",
          "default": "33"
        },
        {
          "name": "headerIcons",
          "type": "SpriteMap | undefined",
          "required": false,
          "description": "Additional header icons for use by `GridColumn`.\n\nProviding custom header icons to the data grid must be done with a somewhat non-standard mechanism to allow\ntheming and scaling. The `headerIcons` property takes a dictionary which maps icon names to functions which can\ntake a foreground and background color and returns back a string representation of an svg. The svg should contain\na header similar to this `<svg width=\"20\" height=\"20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">` and\ninterpolate the fg/bg colors into the string.\n\nWe recognize this process is not fantastic from a graphics workflow standpoint, improvements are very welcome\nhere."
        },
        {
          "name": "hiddenColumnsIndicator",
          "type": "((col: number) => number | HiddenColumnsIndicatorInfo) | undefined",
          "required": false,
          "description": "Индикатор скрытых колонок: сколько колонок скрыто на левой границе колонки col.\ncol === columns.length означает «справа от последней». 0 или undefined значит,\nчто индикатора нет. Полоска одна независимо от числа скрытых. Ресайз на этой границе работает\nкак обычно, а двойной клик вместо автосайза зовёт onHiddenColumnsIndicatorClicked.\nМожно вернуть { count, groupDepth }, где groupDepth задаёт, сколько верхних\nгрупп-рядов пропустить (высота полосы под сгруппированную шапку). Просто число\nозначает полосу на всю высоту."
        },
        {
          "name": "hideGrid",
          "type": "boolean | undefined",
          "required": false,
          "description": "Не рендерить canvas-grid, оставив только overlay-content внутри wrapper."
        },
        {
          "name": "highlightActiveRow",
          "type": "number | undefined",
          "required": false,
          "description": "Controlled-значение подсвеченной строки (highlightActiveType='row')."
        },
        {
          "name": "highlightActiveRowControlled",
          "type": "boolean | undefined",
          "required": false,
          "description": "Режим подсветки строки controlled (значением владеют снаружи). Если не\nзадан — таблица крутит подсветку внутренним стейтом, но колбэк всё равно\nвызывается (подписка без владения)."
        },
        {
          "name": "highlightActiveType",
          "type": "HighlightActiveType | undefined",
          "required": false,
          "description": "Управляет canvas-подсветкой активной сущности поверх glide selection."
        },
        {
          "name": "highlightRegions",
          "type": "readonly Highlight[] | undefined",
          "required": false,
          "description": "Highlight regions provide hints to users about relations between cells and selections."
        },
        {
          "name": "horizontalBorder",
          "type": "boolean | ((row: number) => boolean) | undefined",
          "required": false,
          "description": "Управление горизонтальной линией сверху строки. Функция `(row) => boolean` — точечно\nпо строкам, boolean — сразу для всех строк тела. Не задано — линии рисуются (как раньше)."
        },
        {
          "name": "hoverEffects",
          "type": "HoverEffectsConfig | undefined",
          "required": false,
          "description": "Эффекты при наведении. `hoverEffects.row` — подсветка строки под курсором:\nрисуется через bgCell (getRowThemeOverride), т.е. лежит ПОД селектингом и\nhighlightActiveType — они рисуются поверх (highlightRegions) и визуально\nперекрывают hover. По умолчанию выключено."
        },
        {
          "name": "imageEditorOverride",
          "type": "ImageEditorType | undefined",
          "required": false,
          "description": "Used to provide an override to the default image editor for the data grid. `provideEditor` may be a better\nchoice for most people."
        },
        {
          "name": "initialSize",
          "type": "readonly [width: number, height: number] | undefined",
          "required": false,
          "description": "Provides an initial size for the grid which can prevent a flicker on load if the initial size is known prior to\nlayout."
        },
        {
          "name": "isDraggable",
          "type": "boolean | \"header\" | \"cell\" | undefined",
          "required": false,
          "description": "Determines what can be dragged using HTML drag and drop"
        },
        {
          "name": "isOutsideClick",
          "type": "((e: MouseEvent | TouchEvent) => boolean) | undefined",
          "required": false,
          "description": "Custom predicate function to decide whether the click event occurred outside the grid\nEspecially used when custom editor is opened with the portal and is outside the grid, but there is no possibility\nto add a class \"click-outside-ignore\"\nIf this function is supplied and returns false, the click event is ignored"
        },
        {
          "name": "keybindings",
          "type": "Partial<Keybinds> | undefined",
          "required": false,
          "description": "Determins which keybindings are enabled."
        },
        {
          "name": "markdownDivCreateNode",
          "type": "((content: string) => DocumentFragment) | undefined",
          "required": false,
          "description": "If specified, it will be used to render Markdown, instead of the default Markdown renderer used by the Grid.\nYou'll want to use this if you need to process your Markdown for security purposes, or if you want to use a\nrenderer with different Markdown features."
        },
        {
          "name": "maxColumnAutoWidth",
          "type": "number | undefined",
          "required": false,
          "description": "The maximum width a column can be automatically sized to."
        },
        {
          "name": "maxColumnWidth",
          "type": "number | undefined",
          "required": false,
          "description": "The maximum width a column can be resized to."
        },
        {
          "name": "minColumnWidth",
          "type": "number | undefined",
          "required": false,
          "description": "The minimum width a column can be resized to."
        },
        {
          "name": "onCellActivated",
          "type": "((cell: Item, event: CellActivatedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a cell is activated, by pressing Enter, Space or double clicking it."
        },
        {
          "name": "onCellEdited",
          "type": "((cell: Item, newValue: EditableGridCell) => void) | undefined",
          "required": false,
          "description": "Emitted whenever a cell edit is completed."
        },
        {
          "name": "onCellsEdited",
          "type": "((newValues: readonly EditListItem[]) => boolean | void) | undefined",
          "required": false,
          "description": "Emitted whenever a cell mutation is completed and provides all edits inbound as a single batch."
        },
        {
          "name": "onColumnAppended",
          "type": "(() => void | Promise<number | \"left\" | \"right\" | undefined>) | undefined",
          "required": false,
          "description": "Emitted whenever a column append operation is requested. Append location can be set in callback."
        },
        {
          "name": "onColumnMoved",
          "type": "((startIndex: number, endIndex: number) => void) | undefined",
          "required": false,
          "description": "Called when the user finishes moving a column. `startIndex` is the index of the column that was moved, and\n`endIndex` is the index at which it should end up. Note that you have to effect the move of the column, and pass\nthe reordered columns back in the `columns` property."
        },
        {
          "name": "onColumnProposeMove",
          "type": "((startIndex: number, endIndex: number) => boolean) | undefined",
          "required": false,
          "description": "Called when the user is dragging a column and proposes to move it to a new location. Return `false` to prevent"
        },
        {
          "name": "onColumnResize",
          "type": "((column: GridColumn, newSize: number, colIndex: number, newSizeWithGrow: number) => void) | undefined",
          "required": false,
          "description": "Called when the user is resizing a column. `newSize` is the new size of the column. Note that you have change\nthe size of the column in the `GridColumn` and pass it back to the grid in the `columns` property."
        },
        {
          "name": "onColumnResizeEnd",
          "type": "((column: GridColumn, newSize: number, colIndex: number, newSizeWithGrow: number) => void) | undefined",
          "required": false,
          "description": "Called when the user finishes resizing a column. `newSize` is the new size of the column."
        },
        {
          "name": "onColumnResizeStart",
          "type": "((column: GridColumn, newSize: number, colIndex: number, newSizeWithGrow: number) => void) | undefined",
          "required": false,
          "description": "Called when the user starts resizing a column. `newSize` is the new size of the column."
        },
        {
          "name": "onColumnSelectionApplied",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Вызывается после применения pendingColumnSelectionKeys (сброс pending)."
        },
        {
          "name": "onColumnSelectionChange",
          "type": "((selectedColumnKeys: string[]) => void) | undefined",
          "required": false,
          "description": "Ключи выделенных КОЛОНОК (объединение: одиночный клик/Shift/select-all +\nCtrl-мультивыбор), без сервисных колонок. Канал наверх для контрл-блока\n(например «Закрепить столбцы»). Обычное выделение ячеек сюда не попадает."
        },
        {
          "name": "onDelete",
          "type": "((selection: GridSelection) => boolean | GridSelection) | undefined",
          "required": false,
          "description": "Emitted whenever the user has requested the deletion of the selection."
        },
        {
          "name": "onDragStart",
          "type": "((args: GridDragEventArgs) => void) | undefined",
          "required": false,
          "description": "If `isDraggable` is set, the grid becomes HTML draggable, and `onDragStart` will be called when dragging starts.\nYou can use this to build a UI where the user can drag the Grid around."
        },
        {
          "name": "onDrop",
          "type": "((cell: Item, dataTransfer: DataTransfer | null) => void) | undefined",
          "required": false,
          "description": "Called when a HTML Drag and Drop event is ended on the data grid."
        },
        {
          "name": "onFillPattern",
          "type": "((event: FillPatternEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted whenever the user initiats a pattern fill using the fill handle. This event provides both\na patternSource region and a fillDestination region, and can be prevented."
        },
        {
          "name": "onFinishedEditing",
          "type": "((newValue: GridCell | undefined, movement: Item) => void) | undefined",
          "required": false,
          "description": "Emitted when editing has finished, regardless of data changing or not."
        },
        {
          "name": "onGridSelectionChange",
          "type": "((newSelection: GridSelection) => void) | undefined",
          "required": false,
          "description": "Emitted whenever the grid selection changes. Specifying\nthis function will make the grid’s selection controlled, so\nso you will need to specify {@link gridSelection} as well. See\nthe \"Controlled Selection\" example for details."
        },
        {
          "name": "onGroupHeaderClicked",
          "type": "((colIndex: number, event: GroupHeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a group header is clicked."
        },
        {
          "name": "onGroupHeaderContextMenu",
          "type": "((colIndex: number, event: GroupHeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a group header should show a context menu. Usually right click."
        },
        {
          "name": "onGroupHeaderRenamed",
          "type": "((groupName: string, newVal: string) => void) | undefined",
          "required": false,
          "description": "Emitted whe the user wishes to rename a group."
        },
        {
          "name": "onHeaderClicked",
          "type": "((colIndex: number, event: HeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a column header should show a context menu. Usually right click."
        },
        {
          "name": "onHeaderIndicatorClick",
          "type": "((col: number, screenPosition: Rectangle) => void) | undefined",
          "required": false,
          "description": "Emitted when a header indicator icon is clicked."
        },
        {
          "name": "onHeaderMenuClick",
          "type": "((col: number, screenPosition: Rectangle) => void) | undefined",
          "required": false,
          "description": "Emitted when a header menu disclosure indicator is clicked."
        },
        {
          "name": "onHiddenColumnsIndicatorClicked",
          "type": "((col: number, event: HeaderClickedEventArgs | GroupHeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Двойной клик по индикатору скрытых колонок раскрывает промежуток."
        },
        {
          "name": "onHighlightActiveRowChange",
          "type": "((row: number | undefined, rowData?: R | undefined) => void) | undefined",
          "required": false,
          "description": "Controlled-сеттер подсвеченной строки. Вторым аргументом отдаёт сам объект\nстроки (`rows[index]`) — чтобы потребитель получал узел без onCellClicked."
        },
        {
          "name": "onItemHovered",
          "type": "((args: GridMouseEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when an item is hovered."
        },
        {
          "name": "onKeyDown",
          "type": "((event: GridKeyEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when the canvas receives a key down event."
        },
        {
          "name": "onKeyUp",
          "type": "((event: GridKeyEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when the canvas receives a key up event."
        },
        {
          "name": "onMouseMove",
          "type": "((args: GridMouseEventArgs) => void) | undefined",
          "required": false,
          "description": "Fires whenever the mouse moves"
        },
        {
          "name": "onPaste",
          "type": "boolean | ((target: Item, values: readonly (readonly string[])[]) => boolean) | undefined",
          "required": false,
          "description": "Called when data is pasted into the grid. If left undefined, the `DataEditor` will operate in a\nfallback mode and attempt to paste the text buffer into the current cell assuming the current cell is not\nreadonly and can accept the data type. If `onPaste` is set to false or the function returns false, the grid will\nsimply ignore paste. If `onPaste` evaluates to true the grid will attempt to split the data by tabs and newlines\nand paste into available cells.\n\nThe grid will not attempt to add additional rows if more data is pasted then can fit. In that case it is\nadvisable to simply return false from onPaste and handle the paste manually."
        },
        {
          "name": "onRowAppended",
          "type": "(() => void | Promise<number | \"top\" | \"bottom\" | undefined>) | undefined",
          "required": false,
          "description": "Emitted whenever a row append operation is requested. Append location can be set in callback."
        },
        {
          "name": "onRowMoved",
          "type": "((startIndex: number, endIndex: number) => void) | undefined",
          "required": false,
          "description": "Called whenever a row re-order operation is completed. Setting the callback enables re-ordering by dragging the\nfirst column of a row."
        },
        {
          "name": "onSearchClose",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Emitted when the search window close event is triggered."
        },
        {
          "name": "onSearchResultsChanged",
          "type": "((results: readonly Item[], navIndex: number) => void) | undefined",
          "required": false,
          "description": "Emitted whenever the search results for the current search field changes."
        },
        {
          "name": "onSearchValueChange",
          "type": "((newVal: string) => void) | undefined",
          "required": false,
          "description": "Emitted when the search value changes."
        },
        {
          "name": "onSelectionCleared",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Emitted when the grid selection is cleared."
        },
        {
          "name": "onSelectionEmit",
          "type": "((selection: GridSelection) => void) | undefined",
          "required": false,
          "description": "Канал для copy/paste (selectionRef потребителя), отдельно от controlled gridSelection."
        },
        {
          "name": "onVisibleRegionChanged",
          "type": "((range: Rectangle, tx: number, ty: number, extras: { selected?: Item | undefined; freezeRegion?: Rectangle | undefined; freezeRegions?: readonly Rectangle[] | undefined; }) => void) | undefined",
          "required": false,
          "description": "Emitted whenever the visible cells change, usually due to scrolling."
        },
        {
          "name": "overscrollX",
          "type": "number | undefined",
          "required": false,
          "description": "The overscroll properties are used to allow the grid to scroll past the logical end of the content by a fixed\nnumber of pixels. This is useful particularly on the X axis if you allow for resizing columns as it can make\nresizing the final column significantly easier."
        },
        {
          "name": "overscrollY",
          "type": "number | undefined",
          "required": false,
          "description": "{@inheritDoc overscrollX}"
        },
        {
          "name": "pendingColumnSelectionKeys",
          "type": "string[] | null | undefined",
          "required": false,
          "description": "Follow-выделение: после реордера (закрепление колонок) заново выделить эти\nключи. Пустой массив → снять выделение. null/undefined → не трогать."
        },
        {
          "name": "portalElementRef",
          "type": "React.RefObject<HTMLElement> | undefined",
          "required": false,
          "description": "Allows overriding the default portal element."
        },
        {
          "name": "portalEventTargetRef",
          "type": "React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "Ref на контейнер таблицы — события portal hover диспатчатся на него, чтобы несколько таблиц не перехватывали чужие тултипы"
        },
        {
          "name": "preventDiagonalScrolling",
          "type": "boolean | undefined",
          "required": false,
          "description": "Set to true to prevent any diagonal scrolling."
        },
        {
          "name": "provideEditor",
          "type": "ProvideEditorCallback<GridCell> | undefined",
          "required": false,
          "description": "Callback for providing a custom editor for a cell."
        },
        {
          "name": "rangeSelect",
          "type": "\"rect\" | \"cell\" | \"none\" | \"multi-cell\" | \"multi-rect\" | undefined",
          "required": false,
          "description": "Controls if multi-selection is allowed. If disabled, shift/ctrl/command clicking will work as if no modifiers\nare pressed.\n\nWhen range select is set to cell, only one cell may be selected at a time. When set to rect one one rect at a\ntime. The multi variants allow for multiples of the rect or cell to be selected."
        },
        {
          "name": "rangeSelectionBlending",
          "type": "SelectionBlending | undefined",
          "required": false,
          "description": "Controls which types of selections can exist at the same time in the grid. If selection blending is set to\nexclusive, the grid will clear other types of selections when the exclusive selection is made. By default row,\ncolumn, and range selections are exclusive."
        },
        {
          "name": "rangeSelectionColumnSpanning",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls if range selection is allowed to span columns."
        },
        {
          "name": "resizeIndicator",
          "type": "\"header\" | \"full\" | \"none\" | undefined",
          "required": false,
          "description": "Controls the resize indicator behavior.\n\n- `full` will show the resize indicator on the full height.\n- `header` will show the resize indicator only on the header.\n- `none` will not show the resize indicator."
        },
        {
          "name": "rightElement",
          "type": "React.ReactNode",
          "required": false,
          "description": "The right element is a DOM node which can be inserted at the end of the horizontal scroll region. This can be\nused to create a right handle panel, make a big add button, or display messages."
        },
        {
          "name": "rightElementProps",
          "type": "{ readonly sticky?: boolean | undefined; readonly fill?: boolean | undefined; } | undefined",
          "required": false,
          "description": "If `rightElementProps.sticky` is set to true the right element will be visible at all times, otherwise the user\nwill need to scroll to the end to reveal it.\n\nIf `rightElementProps.fill` is set, the right elements container will fill to consume all remaining space (if\nany) at the end of the grid. This does not play nice with growing columns."
        },
        {
          "name": "rowGrouping",
          "type": "RowGroupingOptions | undefined",
          "required": false,
          "description": "Controls the grouping of rows to be drawn in the grid."
        },
        {
          "name": "rowMarkers",
          "type": "\"number\" | \"none\" | RowMarkerOptions | \"checkbox\" | \"clickable-number\" | \"checkbox-visible\" | \"both\" | undefined",
          "required": false,
          "description": "Determines if row markers should be automatically added to the grid.\nInteractive row markers allow the user to select a row.\n\n- \"clickable-number\" renders a number that can be clicked to\n select the row\n- \"both\" causes the row marker to show up as a number but\n reveal a checkbox when the marker is hovered."
        },
        {
          "name": "rowSelect",
          "type": "\"none\" | \"single\" | \"multi\" | undefined",
          "required": false,
          "description": "{@inheritDoc rangeSelect}"
        },
        {
          "name": "rowSelectionBlending",
          "type": "SelectionBlending | undefined",
          "required": false,
          "description": "{@inheritDoc rangeSelectionBlending}"
        },
        {
          "name": "rowSelectionMode",
          "type": "\"multi\" | \"auto\" | undefined",
          "required": false,
          "description": "Determines if row selection requires a modifier key to enable multi-selection or not. In auto mode it adapts to\ntouch or mouse environments automatically, in multi-mode it always acts as if the multi key (Ctrl) is pressed."
        },
        {
          "name": "scaleToRem",
          "type": "boolean | undefined",
          "required": false,
          "description": "Scales most elements in the theme to match rem scaling automatically"
        },
        {
          "name": "scrollOffsetX",
          "type": "number | undefined",
          "required": false,
          "description": "Sets the initial scroll X offset"
        },
        {
          "name": "scrollOffsetY",
          "type": "number | undefined",
          "required": false,
          "description": "Sets the initial scroll Y offset."
        },
        {
          "name": "scrollToActiveCell",
          "type": "boolean | undefined",
          "required": false,
          "description": "If set to true, the data grid will attempt to scroll to keep the selction in view"
        },
        {
          "name": "searchResults",
          "type": "readonly Item[] | undefined",
          "required": false,
          "description": "The search results to display. If not provided glide will use its own internal search provider."
        },
        {
          "name": "searchValue",
          "type": "string | undefined",
          "required": false,
          "description": "The current search value."
        },
        {
          "name": "showSearch",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls the visibility of the search overlay."
        },
        {
          "name": "smoothScrollX",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls smooth scrolling in the data grid. If smooth scrolling is not enabled the grid will always be cell\naligned."
        },
        {
          "name": "smoothScrollY",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls smooth scrolling in the data grid. If smooth scrolling is not enabled the grid will always be cell\naligned."
        },
        {
          "name": "spanAlign",
          "type": "SpanAlignment | undefined",
          "required": false,
          "description": "Выравнивание текста в объединённых ячейках шапки по умолчанию.\nМожно переопределить на колонке (`spanGroupHeaderAlign`) или на группе (`getGroupDetails().spanAlign`)."
        },
        {
          "name": "spanGroupHeader",
          "type": "boolean | undefined",
          "required": false,
          "description": "Grid-дефолт слитной шапки: включает `spanGroupHeader` у ВСЕХ листовых колонок (без\nгруппы) — не нужно ставить флаг на каждую. Точечно перекрывается на колонке\n(`spanGroupHeader: true/false`). Колонки с группой проп не трогает."
        },
        {
          "name": "spanRangeBehavior",
          "type": "\"default\" | \"allowPartial\" | undefined",
          "required": false,
          "description": "If set to `default`, `gridSelection` will be coerced to always include full spans."
        },
        {
          "name": "spanShallowGroups",
          "type": "boolean | undefined",
          "required": false,
          "description": "Объединяет (rowspan) пустые нижние ряды у «мелких» групп — тех, что заканчиваются\nвыше самого глубокого уровня групп, — в одну высокую ячейку вместо пустой полосы\nпод заголовком. Точечно на группе можно переопределить через `getGroupDetails().span`\n(поставить `false`, чтобы отключить для конкретной группы). Не задано → как раньше."
        },
        {
          "name": "trailingRowOptions",
          "type": "{ readonly tint?: boolean | undefined; readonly hint?: string | undefined; readonly sticky?: boolean | undefined; readonly addIcon?: string | undefined; readonly targetColumn?: number | GridColumn | undefined; } | undefined",
          "required": false,
          "description": "Controls the trailing row used to insert new data into the grid."
        },
        {
          "name": "trapFocus",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls if focus will trap inside the data grid when doing tab and caret navigation."
        },
        {
          "name": "unstickyHeader",
          "type": "boolean | undefined",
          "required": false,
          "description": "Откреплённая шапка — header уезжает вместе со скроллом"
        },
        {
          "name": "validateCell",
          "type": "((cell: Item, newValue: EditableGridCell, prevValue: GridCell) => boolean | ValidatedGridCell) | undefined",
          "required": false,
          "description": "Used for validating cell values during editing."
        },
        {
          "name": "verticalBorder",
          "type": "boolean | ((col: number) => boolean) | undefined",
          "required": false,
          "description": "Controls the drawing of the left hand vertical border of a column. If set to a boolean value it controls all\nborders."
        },
        {
          "name": "containerProps",
          "type": "{ className?: string | undefined; style?: React.CSSProperties | undefined; ref?: React.Ref<HTMLDivElement> | undefined; } | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentStateOverlay",
          "type": "TableContentStateOverlay | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onCellContextMenu",
          "type": "((cell: Item, event: CellClickedEventArgs, args_2: TableInfoWithRow<R, SR, CustomCtxs>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onCellContextMenuDropdown",
          "type": "CellContextMenuDropdownProps<R, SR, ObjectForExtending> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onHeaderContextMenu",
          "type": "((colIndex: number, event: HeaderClickedEventArgs, args_2: TableInfoBase<R, SR, CustomCtxs>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onHeaderContextMenuDropdown",
          "type": "HeaderContextMenuDropdownProps<R, SR, CustomCtxs> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onRowsChange",
          "type": "((rows: R[], data: RowsChangeDataGlideInstance<R, SR, CustomCtxs>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "bottomSummaryRows",
          "type": "readonly SR[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ctxs",
          "type": "ObjectForExtending | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "drawCell",
          "type": "DrawCellCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "drawFocusRing",
          "type": "boolean | \"no-editor\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "freezeTrailingRows",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "groupHeaderHeight",
          "type": "number[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "imageWindowLoader",
          "type": "ImageWindowLoader | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onColumnsReorder",
          "type": "((sourceKey: string, targetKey: string) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onDragLeave",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onDragOverCell",
          "type": "((cell: Item, dataTransfer: DataTransfer | null) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "refTable",
          "type": "React.Ref<DataEditorRef> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "renderers",
          "type": "readonly InternalCellRenderer<InnerGridCell>[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "renderGroupHeader",
          "type": "((args: { ctx: CanvasRenderingContext2D; groupName: string; level: number; span: readonly [start: number, end: number]; theme: Theme; rect: Rectangle; isSelected: boolean; isHovered: boolean; spriteManager: SpriteManager; hoverX: number | undefined; hoverY: number | undefined; }) => \"default\" | CanvasEl | { defaultWithCustomGroupName: string; }) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "resizableColumn",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rowHeight",
          "type": "number | ((row: R, currentRowSize: { rowSizeName: \"big\" | \"small\" | \"medium\"; rowSizeValue: number; }, rowIndex: number) => number) | null | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rowSize",
          "type": "\"big\" | \"small\" | \"medium\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "setScrollDir",
          "type": "((dir: readonly [xDir: 0 | 1 | -1, yDir: 0 | 1 | -1] | undefined) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rowMarkerStartIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Changes the starting index for row markers.",
          "deprecated": true
        },
        {
          "name": "rowMarkerTheme",
          "type": "Partial<Theme> | undefined",
          "required": false,
          "description": "Changes the theme of the row marker column",
          "deprecated": true
        },
        {
          "name": "rowMarkerWidth",
          "type": "number | undefined",
          "required": false,
          "description": "Sets the width of row markers in pixels, if unset row markers will automatically size.",
          "deprecated": true
        }
      ],
      "propsTypeName": "TableGlideInstanceProps",
      "rawType": "export type TableGlideInstanceProps<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<\n  TableGlideProps<R, SR>,\n  'columns' | 'onHeaderContextMenu' | 'onCellContextMenu'\n> & {\n  columns: readonly ColumnGlideInstance<R, SR, CustomCtxs>[];\n  onHeaderContextMenuDropdown?: HeaderContextMenuDropdownProps<\n    R,\n    SR,\n    CustomCtxs\n  >;\n  onCellContextMenuDropdown?: CellContextMenuDropdownProps<R, SR>;\n  containerProps?: {\n    className?: string;\n    style?: React.CSSProperties;\n    ref?: React.Ref<HTMLDivElement>;\n  };\n  contentStateOverlay?: TableContentStateOverlay;\n  renderOverlayFeatures?: (ctx: {\n    containerElement: HTMLDivElement;\n    renderInContainer: (children: React.ReactNode) => React.ReactPortal | null;\n  }) => React.ReactNode;\n  CellReadOnlyEditor: (\n    props: CellReadOnlyEditorGlideInstanceProps<R, SR>,\n  ) => ReactNode;\n  onRowsChange?: (\n    rows: R[],\n    data: RowsChangeDataGlideInstance<R, SR, CustomCtxs>,\n  ) => void;\n  onCellClicked?: (\n    cell: readonly [number, number],\n    info: TableInfoWithRow<R, SR, CustomCtxs>,\n  ) => void;\n} & TableGlideInstanceContextMenu<R, SR, CustomCtxs>;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/TableGlideInstance.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "интеграция таблицы",
        "canvas grid adapter",
        "колонки таблицы"
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "SplitIconButton",
        "CellEditorCombobox",
        "CellEditorNumberFormat",
        "CellEditorTextArea",
        "TableFilterSelectListItem",
        "ContainerStyled",
        "TextCellEntry",
        "Canvas",
        "TextCellEntryType"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableGlideInstance } from '@daisforge/ui/components/TableCanvas';",
      "minimalUsage": "<TableGlideInstance CellReadOnlyEditor={() => {}} columns={[]} rows={[]} />",
      "examples": []
    },
    "TextCellEntry": {
      "name": "TextCellEntry",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "internal",
      "description": "Базовое автоувеличивающееся текстовое поле Glide Data Grid для редактирования ячейки",
      "props": [],
      "sourceFile": "node_modules/@glideappsfinal/glide-data-grid/dist/dts/internal/growing-entry/growing-entry.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "автоувеличивающееся поле",
        "редактор текста ячейки",
        "growing entry"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableCanvas",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TextCellEntry } from '@daisforge/ui';",
      "minimalUsage": "<TextCellEntry />",
      "examples": []
    },
    "Canvas": {
      "name": "Canvas",
      "group": "components",
      "folderName": "TableGlide",
      "role": "internal",
      "description": "JSX-набор примитивов (Container, Text, Icon, Button…) для кастомного контента ячеек TableGlide",
      "props": [
        {
          "name": "offsetX",
          "type": "number | undefined",
          "required": false,
          "description": "Сдвиг тултипа по X (px) относительно центра ноды. Нужен, когда видимая\nчасть ноды смещена внутри неё (например, иконка прижата к краю кнопки).",
          "default": "0"
        },
        {
          "name": "preserveLineBreaks",
          "type": "boolean | undefined",
          "required": false,
          "description": "Сохранять переносы строк (\\n) в тексте тултипа через white-space: pre-line.",
          "default": "false"
        },
        {
          "name": "maxWidth",
          "type": "string | number | undefined",
          "required": false,
          "description": "Максимальная ширина окна (в rem)."
        },
        {
          "name": "minWidth",
          "type": "string | number | undefined",
          "required": false,
          "description": "Минимальная ширина окна (в rem)."
        },
        {
          "name": "placement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": "Направление раскрытия тултипа."
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": "Вид тултипа."
        }
      ],
      "propsTypeName": "CanvasNodeTooltipProps",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/components/index.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "кастомная ячейка",
        "canvas rendering",
        "custom cell content"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableGlide",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableGlide",
      "importStatement": "import { Canvas } from '@daisforge/ui/components/TableGlide';",
      "minimalUsage": "<Canvas />",
      "examples": []
    },
    "TextCellEntryType": {
      "name": "TextCellEntryType",
      "group": "components",
      "folderName": "TableCanvas",
      "role": "internal",
      "description": "TypeScript-тип пропсов текстового поля-редактора ячейки Glide Data Grid",
      "props": [],
      "sourceFile": "node_modules/@glideappsfinal/glide-data-grid/dist/dts/internal/growing-entry/growing-entry.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "тип пропсов",
        "typescript тип",
        "growing entry type"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableCanvas",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TextCellEntryType } from '@daisforge/ui';",
      "minimalUsage": "<TextCellEntryType />",
      "examples": []
    },
    "TableContract": {
      "name": "TableContract",
      "group": "components",
      "folderName": "TableContract",
      "role": "primary",
      "description": "Таблица с автозагрузкой данных с бэкенда, поиском, фильтрами и редактированием строк.",
      "props": [
        {
          "name": "as",
          "type": "((React.ComponentType<any> | keyof JSX.IntrinsicElements) & \"button\") | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "dropdown",
          "type": "TableDropdownProps | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isTargetAction",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"secondary\" | \"clear\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"black\" | \"white\" | \"gradient\" | \"linkDefault\" | \"linkAccent\" | \"linkSecondary\" | \"linkPositive\" | \"linkWarning\" | \"linkNegative\" | \"linkGradient\" | \"linkInfo\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "additionalContent",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentPlacing",
          "type": "\"default\" | \"relaxed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isLoading",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "loader",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "outlined",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftLeft",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftRight",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "square",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretch",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretching",
          "type": "\"auto\" | \"filled\" | \"fixed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "text",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"button\" | \"submit\" | \"reset\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "value",
          "type": "string | number | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TableContractControlBlockButtonProps",
      "sourceFile": "packages/ui-kit/src/components/TableContract/TableContract.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "серверные данные",
        "SWR таблица",
        "API-таблица"
      ],
      "docs": "# TableContract\n\nСтилизованный в рамках дизайн-системы компонент Table c возможностью конфигурации отображения полностью на бэкенде. Имеет возможность гибко настраивать отображаемый вид.\nC примерами реализации подробно можно ознакомиться ниже в stories.\n\n- Работа для бэкенд-разработчика сводится к обработке конкретного endpoint-а.\n  Ответ по запросу по данному endpoint-у должен соответствовать [JSON-схеме ответа запроса](#json-схема-ответа-запроса)\n  В зависимости от фичей, которые необходимо активировать, может понадобится обработка [query-параметров запроса](#api-query-параметров-запроса).\n\n<div style={{border: '1px solid #ededed', padding: 16}}>\n\n### Быстрые ссылки\n\n- [API ответа запроса](#api-ответа-запроса)\n- [API query-параметров запроса](#api-query-параметров-запроса)\n- [JSON-схема ответа запроса](#json-схема-ответа-запроса)\n\n---\n\n##### Реализации конкретных фичей:\n\n- [Отображение данных](#отображение-данных)\n- [Поиск](#поиск)\n- [Пагинация](#пагинация)\n- [Сортировка](#сортировка)\n- [Иерархия](#иерархия)\n- [Изменение ширины колонки](#изменение-ширины-колонки)\n- [Полноэкранный режим](#полноэкранный-режим)\n- [Итоговые строки](#итоговые-строки)\n\n##### Перечень фичей, которые в разработке:\n\n- Редактирование\n- Группировка колонок - (актуальна ли данная фича ?)\n\n</div>\n\n<br />\n<br />\n\n---\n\n<br />\n\n# Примеры реализации:\n\n## Для просмотра запросов откройте Network в инструментах разработчика. (Сочетание клавиш Fn + F12)\n\n<br />\n\n<StoryCard>\n\n## Отображение данных\n\nДля отображения данных в теле ответа достаточно заполнить `data.main` и `meta.columns`.\n\n1. Заполнить `data.main` массивом любых объектов. Каждый объект будет считаться данными для определенной строки.\n\n2. Минимальное заполнение `meta.columns` ключами:\n   <CustomArgTypes\n     hideColumnDefault\n     hideHeader\n     boxShadowNone\n     include={['key', 'name']}\n     of={StoryContractColumnConfigComp}\n   />\n\n##### Пример ответа:\n\n<Source language=\"json\" code={JSON.stringify(EXAMPLES['simple'], null, 2)} />\n\n##### Результат:\n\n    <Story  of={TableContractStories.Simple} />\n\n</StoryCard>\n\n<StoryCard style={{marginTop: 36}}>\n\n## Поиск\n\nДля активации поиска необходимо:\n\n1. В ответе запроса заполнить `data.main`,`meta.columns` и `meta.tableConfig.searching`\n\n   `meta.tableConfig.searching`:\n\n   <CustomArgTypes\n     hideColumnDefault\n     hideHeader\n     boxShadowNone\n     of={StoryContractSearchingComp}\n   />\n\n2. (Если тип фильтрации 'backend') В query-параметрах запроса обработать параметр <code>{Q_PARAMS.q}</code> и сделать фильтрацию данных (`response.data`) по данному параметру:\n\n   <CustomArgTypes\n     hideColumnDefault\n     hideColumnName\n     hideHeader\n     boxShadowNone\n     include={[Q_PARAMS.q]}\n     of={StoryContractQueryParamsComp}\n   />\n\n3. (Необязательно и если тип фильтрации 'frontend') Можно дополнительно настроить поиск в рамках каждой из колонок `meta.columns.[конкретная колонка].searching`:\n   <CustomArgTypes\n     hideColumnDefault\n     hideHeader\n     boxShadowNone\n     of={StoryContractColumnSearchingComp}\n   />\n\n#### Результат:\n\n    <Story  of={TableContractStories.Searching} />\n\n</StoryCard>\n\n<StoryCard style={{marginTop: 36}}>\n\n## Пагинация\n\nДля активации пагинации необходимо в ответе запроса заполнить `data.main`,`meta.columns` и `meta.tableConfig.pagination`.\n\n1. Заполнить конфигурацию пагинации в `meta.tableConfig.pagination`:\n\n   <CustomArgTypes\n     hideColumnDefault\n     hideColumnName\n     hideHeader\n     borderNone\n     boxShadowNone\n     include={'pagination'}\n     of={StoryContractTableConfigComp}\n   />\n\n2. В query-параметрах запроса обработать параметры:\n   <CustomArgTypes\n     hideColumnDefault\n     hideHeader\n     boxShadowNone\n     include={[Q_PARAMS.page, Q_PARAMS.size]}\n     of={StoryContractQueryParamsComp}\n   />\n\n#### Результат:\n\n    <Story  of={TableContractStories.Pagination} />\n\n</StoryCard>\n\n<StoryCard style={{marginTop: 36}}>\n\n## Сортировка\n\nДля активации сортировки необходимо:\nВ ответе запроса заполнить `data.main`,`meta.columns` и `meta.tableConfig.sorting`\n\n1. Заполнить конфигурацию сортировки в `meta.tableConfig.sorting`:\n\n   <CustomArgTypes\n     hideColumnDefault\n     hideColumnName\n     hideHeader\n     borderNone\n     boxShadowNone\n     include={'sorting'}\n     of={StoryContractTableConfigComp}\n   />\n\n2. Заполнить тип сортировка для нужных колонок в `meta.columns.[конкретная колонка].sortingType`:\n   <CustomArgTypes\n     hideColumnDefault\n     hideColumnName\n     hideHeader\n     boxShadowNone\n     of={StoryContractColumnSortingComp}\n   />\n3. В query-параметрах запроса обработать параметр <code>{Q_PARAMS.sort}</code>:\n   <CustomArgTypes\n     hideColumnDefault\n     hideColumnName\n     hideHeader\n     boxShadowNone\n     include={[Q_PARAMS.sort]}\n     of={StoryContractQueryParamsComp}\n   />\n\n#### Результат:\n\n    <Story  of={TableContractStories.Sorting} />\n\n</StoryCard>\n\n<StoryCard style={{marginTop: 24}}>\n\n## Иерархия\n\nДля активации subRows необходимо в ответе запроса заполнить `data.main`,`meta.columns` и `meta.tableConfig.subRows`\n\n1. Заполнить обязательно `meta.tableConfig.subRows`\n\n   <CustomArgTypes\n     hideColumnDefault\n     hideColumnName\n     hideHeader\n     transparent\n     borderNone\n     paddingNone\n     include={'subRows'}\n     of={StoryContractTableConfigComp}\n   />\n   <CustomArgTypes\n     hideColumnName\n     hideColumnDefault\n     hideHeader\n     boxShadowNone\n     of={StoryContractSubRowsComp}\n   />\n\n2. Заполнить обязательно `meta.columns[конкретная строка]subRow`:\n   <CustomArgTypes\n     hideColumnDefault\n     hideHeader\n     boxShadowNone\n     of={StoryContractColumnSubRowsComp}\n   />\n\n#### Результат:\n\n    <Story  of={TableContractStories.SubRows} />\n\n</StoryCard>\n\n<StoryCard style={{marginTop: 36}}>\n\n## Изменение ширины колонки\n\nВ ответе запроса необходимо заполнить `data.main`, `meta.tableConfig.resizableColumn`, `meta.columns.resizable`.\n\n1. Заполнение `meta.tableConfig.resizableColumn` значением `true`:\n   <CustomArgTypes\n     hideColumnDefault\n     hideHeader\n     boxShadowNone\n     include={['resizableColumn']}\n     of={StoryContractTableConfigComp}\n   />\n2. Минимальное заполнение `meta.columns` ключами:\n   <CustomArgTypes\n     hideColumnDefault\n     hideHeader\n     boxShadowNone\n     include={['key', 'name', 'resizable']}\n     of={StoryContractColumnConfigComp}\n   />\n\n</StoryCard>\n\n<StoryCard style={{marginTop: 36}}>\n\n## Полноэкранный режим\n\nВ ответе запроса необходимо заполнить `data.main`, `meta.tableConfig.fullScreenEnabled`, `meta.columns`.\n\nЗаполнение `meta.tableConfig.fullScreenEnabled` значением `true`:\n\n<CustomArgTypes\n  hideColumnDefault\n  hideColumnName\n  hideHeader\n  boxShadowNone\n  include={['fullScreenEnabled']}\n  of={StoryContractTableConfigComp}\n/>\n\n</StoryCard>\n\n<StoryCard style={{marginTop: 36}}>\n\n## Итоговые строки\n\nВ ответе запроса необходимо заполнить `data.main`, `data.bottomSummary`/`data.topSummary`, `meta.columns.summaryCell`.\n\n1. Заполнить `data.main` массивом любых объектов. Каждый объект будет считаться данными для определенной строки.\n2. Заполнить `data.bottomSummary`/`data.topSummary` массивом любых объектов. Каждый объект будет считаться данными для определенной итоговой строки.\n3. Заполнение `meta.columns.summaryCell`:\n   <CustomArgTypes\n     hideColumnDefault\n     hideColumnName\n     hideHeader\n     boxShadowNone\n     include={['summaryCell']}\n     of={StoryContractColumnConfigComp}\n   />\n\n</StoryCard>\n\n<br />\n<br />\n<br />\n\n---\n\n# API query-параметров запроса:\n\n<CustomArgTypes hideColumnDefault of={StoryContractQueryParamsComp} />\n\n# API ответа запроса:\n\n<div className=\"sb-container\">\n  <Accordion size=\"h2\" view=\"clear\" defaultActiveEventKey={[0, 1, 2]}>\n    {[\n      { comp: StoryContractComp, title: 'response' },\n      { comp: StoryContractTableConfigComp, title: 'meta.tableConfig' },\n      { comp: StoryContractColumnConfigComp, title: 'meta.columns' },\n    ].map(function (el, i) {\n      return (\n        <AccordionItem key={el.title} type=\"arrow\" eventKey={i} title={<h3>{el.title}</h3>}>\n          <CustomArgTypes hideColumnDefault of={el.comp} />\n        </AccordionItem>\n      );\n    })}\n\n  </Accordion>\n</div>\n\n# JSON-схема ответа запроса\n\n<CopyButton\n  text=\"Скопировать схему\"\n  copyText={JSON.stringify(ContractResponseSchema, null, 2)}\n/>\n\n<Accordion size=\"h2\" view=\"clear\">\n  <AccordionItem\n    type=\"clear\"\n    title={\n      <Button view=\"secondary\" contentLeft={<IconDocumentGlassOutline />}>\n        Ознакомиться со схемой\n      </Button>\n    }\n  >\n    <Source code={JSON.stringify(ContractResponseSchema, null, 2)} />\n  </AccordionItem>\n</Accordion>\n\n# TableContract\n\nСтилизованный в рамках дизайн-системы компонент Table c возможностью конфигурации отображения полностью на бэкенд-е.\nИмеет возможность гибко настраивать отображаемый вид.\n\n### Инструкция по использованию:\n\n1. (Если еще не сделано) Установить в проект пакет библиотеки, тему глобально по ([инструкции](http://df-storybook.sh5.dev-gen1-ds.dddddd.ru/?path=/docs/%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-%D0%B8-%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5--docs)).\n2. Создать fetcher-функцию.\n3. Разместить компонент в нужной части страницы, передать fetcher-функцию.\n\n### Пример реализации:\n\n```tsx\n\n// 1) создать fetcher-функцию\nconst fetcher: FetcherFunc = async ({ params, ...rest }) =>\n  fetch(`${STATIC_ENDPOINT}${params ? `?${params}` : ''}`, rest).then((res) =>\n    res.json(),\n  );\n\nfunction Page() {\n  return (\n    <div className=\"page-layout\">\n      <h2 className=\"page-title\">Заголовок страницы</h2>\n      {/* 2) Разместить компонент в нужной части страницы, передать\n      fetcher-функцию */}\n      <TableContract fetcher={fetcher} />\n    </div>\n  );\n}\n```\n\n### Описание типа FetcherFunc:\n\n```typescript\nexport type FetcherFunc = (p: {\n  /**\n   * params - query параметры запроса, которые будут изменяться самой таблицей\n   * в зависимости от того, какие фичи активированы.\n   */\n  params?: string;\n  /**\n   * method - метод запроса. Его тип основан на типе HTTP fetch.method.\n   * Будет использоваться преимущественно GET.\n   * @example GET | POST | PUT | PATCH | DELETE\n   */\n  method?: RequestInit['method'];\n  /**\n   * body - передаваемая полезная информация. Его тип основан на типе HTTP fetch.body.\n   */\n  body?: RequestInit['body'];\n}) => ContractResponse | Promise<ContractResponse>;\n```",
      "curatedStories": [
        {
          "exportName": "Simple",
          "displayName": "Simple",
          "type": "args-only",
          "code": "{ fetcher: createFetcher(simpleRoute.ENDPOINT) }"
        },
        {
          "exportName": "Pagination",
          "displayName": "Pagination",
          "type": "args-only",
          "code": "{ fetcher: createFetcher(paginationRoute.ENDPOINT) }"
        },
        {
          "exportName": "Searching",
          "displayName": "Searching",
          "type": "args-only",
          "code": "{ fetcher: createFetcher(searchingRoute.ENDPOINT) }"
        },
        {
          "exportName": "Sorting",
          "displayName": "Sorting",
          "type": "args-only",
          "code": "{ fetcher: createFetcher(sortingRoute.ENDPOINT) }"
        },
        {
          "exportName": "SubRows",
          "displayName": "SubRows",
          "type": "args-only",
          "code": "{ fetcher: createFetcher(subRowsRoute.ENDPOINT) }"
        },
        {
          "exportName": "Editing",
          "displayName": "Editing",
          "type": "args-only",
          "code": "{ fetcher: createFetcher(editingExampleGetRoute.ENDPOINT) }"
        },
        {
          "exportName": "AllFeats",
          "displayName": "AllFeats",
          "type": "args-only",
          "code": "{\n    fetcher: createFetcher(allFeatsExampleGetRoute.ENDPOINT),\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TableContract } from '@daisforge/ui';",
      "minimalUsage": "<TableContract />",
      "examples": [
        {
          "exportName": "Simple",
          "displayName": "Simple",
          "type": "args-only",
          "code": "{ fetcher: createFetcher(simpleRoute.ENDPOINT) }"
        },
        {
          "exportName": "Pagination",
          "displayName": "Pagination",
          "type": "args-only",
          "code": "{ fetcher: createFetcher(paginationRoute.ENDPOINT) }"
        },
        {
          "exportName": "Searching",
          "displayName": "Searching",
          "type": "args-only",
          "code": "{ fetcher: createFetcher(searchingRoute.ENDPOINT) }"
        },
        {
          "exportName": "Sorting",
          "displayName": "Sorting",
          "type": "args-only",
          "code": "{ fetcher: createFetcher(sortingRoute.ENDPOINT) }"
        }
      ]
    },
    "TableGlide": {
      "name": "TableGlide",
      "group": "components",
      "folderName": "TableGlide",
      "role": "primary",
      "description": "Кастомный canvas-грид на Glide Data Grid: выделение, контекстное меню, редактирование.",
      "props": [
        {
          "name": "columns",
          "type": "ColumnGlideLast<R, SR>[]",
          "required": true,
          "description": ""
        },
        {
          "name": "rows",
          "type": "readonly R[]",
          "required": true,
          "description": ""
        },
        {
          "name": "cellsSelectionMode",
          "type": "CellsSelectionMode | undefined",
          "required": false,
          "description": "Режим выделения ячеек (нативный glide selection). По умолчанию 'range-cell'.",
          "default": "'range-cell'"
        },
        {
          "name": "checkboxSelectedRowIndexes",
          "type": "ReadonlySet<number> | undefined",
          "required": false,
          "description": "Индексы строк, выбранных через checkbox selection."
        },
        {
          "name": "checkboxVisibleRowIndexes",
          "type": "ReadonlySet<number> | undefined",
          "required": false,
          "description": "Индексы строк, у которых ЕСТЬ (виден) чекбокс — для тёмной подсветки highlightActiveType='row'."
        },
        {
          "name": "containerClassName",
          "type": "string | undefined",
          "required": false,
          "description": "className для wrapper-div"
        },
        {
          "name": "containerRef",
          "type": "React.Ref<HTMLDivElement> | undefined",
          "required": false,
          "description": "Внешний ref на wrapper-div (для TableCanvas - refTableContainer)"
        },
        {
          "name": "containerStyle",
          "type": "React.CSSProperties | undefined",
          "required": false,
          "description": "inline-style для wrapper-div"
        },
        {
          "name": "contentStateNode",
          "type": "React.ReactNode",
          "required": false,
          "description": "DOM-узел content-state (empty/error), рендерится как прямой child контейнера."
        },
        {
          "name": "editorOverlayPortal",
          "type": "\"inside\" | undefined",
          "required": false,
          "description": "Переносит editor overlay внутрь контейнера (вместо document.body). Для модалок с CSS transform."
        },
        {
          "name": "enableColumnSelection",
          "type": "boolean | undefined",
          "required": false,
          "description": "Выделение колонок по клику на шапку (независимо от highlightActiveType). По умолчанию true.",
          "default": "true"
        },
        {
          "name": "enableLowDprHairline",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включает компенсацию тонких canvas-линий при browser zoom ниже 100% / DPR < 1."
        },
        {
          "name": "enableRowSelection",
          "type": "boolean | undefined",
          "required": false,
          "description": "Выделение строк по клику/драгу на колонке нумерации. По умолчанию true.",
          "default": "true"
        },
        {
          "name": "enableSelectAll",
          "type": "boolean | undefined",
          "required": false,
          "description": "Выделение всей таблицы кликом по шапке колонки нумерации. По умолчанию true.",
          "default": "true"
        },
        {
          "name": "fullScreened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг fullscreen - пересканирование DOM при переключении"
        },
        {
          "name": "groupAlignMap",
          "type": "Map<string, SpanAlignment> | undefined",
          "required": false,
          "description": "Выравнивание текста в объединённой шапке по ключу группы (ColumnGroupConfig.key)."
        },
        {
          "name": "hideGrid",
          "type": "boolean | undefined",
          "required": false,
          "description": "Не рендерить canvas-grid, оставив только overlay-content внутри wrapper."
        },
        {
          "name": "highlightActiveRow",
          "type": "number | undefined",
          "required": false,
          "description": "Controlled-значение подсвеченной строки (highlightActiveType='row')."
        },
        {
          "name": "highlightActiveRowControlled",
          "type": "boolean | undefined",
          "required": false,
          "description": "Режим подсветки строки controlled (значением владеют снаружи). Если не\nзадан — таблица крутит подсветку внутренним стейтом, но колбэк всё равно\nвызывается (подписка без владения)."
        },
        {
          "name": "highlightActiveType",
          "type": "HighlightActiveType | undefined",
          "required": false,
          "description": "Управляет canvas-подсветкой активной сущности поверх glide selection.",
          "default": "'disabled'"
        },
        {
          "name": "hoverEffects",
          "type": "HoverEffectsConfig | undefined",
          "required": false,
          "description": "Эффекты при наведении. `hoverEffects.row` — подсветка строки под курсором:\nрисуется через bgCell (getRowThemeOverride), т.е. лежит ПОД селектингом и\nhighlightActiveType — они рисуются поверх (highlightRegions) и визуально\nперекрывают hover. По умолчанию выключено."
        },
        {
          "name": "onColumnSelectionApplied",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Вызывается после применения pendingColumnSelectionKeys (сброс pending)."
        },
        {
          "name": "onColumnSelectionChange",
          "type": "((selectedColumnKeys: string[]) => void) | undefined",
          "required": false,
          "description": "Ключи выделенных КОЛОНОК (объединение: одиночный клик/Shift/select-all +\nCtrl-мультивыбор), без сервисных колонок. Канал наверх для контрл-блока\n(например «Закрепить столбцы»). Обычное выделение ячеек сюда не попадает."
        },
        {
          "name": "onHighlightActiveRowChange",
          "type": "((row: number | undefined, rowData?: R | undefined) => void) | undefined",
          "required": false,
          "description": "Controlled-сеттер подсвеченной строки. Вторым аргументом отдаёт сам объект\nстроки (`rows[index]`) — чтобы потребитель получал узел без onCellClicked."
        },
        {
          "name": "onSelectionEmit",
          "type": "((selection: GridSelection) => void) | undefined",
          "required": false,
          "description": "Канал для copy/paste (selectionRef потребителя), отдельно от controlled gridSelection."
        },
        {
          "name": "pendingColumnSelectionKeys",
          "type": "string[] | null | undefined",
          "required": false,
          "description": "Follow-выделение: после реордера (закрепление колонок) заново выделить эти\nключи. Пустой массив → снять выделение. null/undefined → не трогать."
        },
        {
          "name": "portalEventTargetRef",
          "type": "React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "Ref на контейнер таблицы — события portal hover диспатчатся на него, чтобы несколько таблиц не перехватывали чужие тултипы"
        },
        {
          "name": "renderOverlayFeatures",
          "type": "((ctx: { containerElement: HTMLDivElement; renderInContainer: (children: React.ReactNode) => React.ReactPortal | null; }) => React.ReactNode) | undefined",
          "required": false,
          "description": "Рендер overlay-фич (tooltip, contextMenu, popover) внутри wrapper-div когда DOM готов"
        },
        {
          "name": "unstickyHeader",
          "type": "boolean | undefined",
          "required": false,
          "description": "Откреплённая шапка — header уезжает вместе со скроллом"
        },
        {
          "name": "allowedFillDirections",
          "type": "FillHandleDirection | undefined",
          "required": false,
          "description": "Controls which directions fill is allowed in."
        },
        {
          "name": "cellActivationBehavior",
          "type": "CellActivationBehavior | undefined",
          "required": false,
          "description": "Determines when a cell is considered activated and will emit the `onCellActivated` event. Generally an activated\ncell will open to edit mode."
        },
        {
          "name": "coercePasteValue",
          "type": "((val: string, cell: GridCell) => GridCell | undefined) | undefined",
          "required": false,
          "description": "Allows coercion of pasted values."
        },
        {
          "name": "columnSelect",
          "type": "\"none\" | \"single\" | \"multi\" | undefined",
          "required": false,
          "description": "{@inheritDoc rangeSelect}"
        },
        {
          "name": "columnSelectionBlending",
          "type": "SelectionBlending | undefined",
          "required": false,
          "description": "{@inheritDoc rangeSelectionBlending}"
        },
        {
          "name": "columnSelectionMode",
          "type": "\"auto\" | \"multi\" | undefined",
          "required": false,
          "description": "Determines if column selection requires a modifier key to enable multi-selection or not. In auto mode it adapts to\ntouch or mouse environments automatically, in multi-mode it always acts as if the multi key (Ctrl) is pressed."
        },
        {
          "name": "copyHeaders",
          "type": "boolean | undefined",
          "required": false,
          "description": "Add table headers to copied data."
        },
        {
          "name": "customRenderers",
          "type": "readonly CustomRenderer<any>[] | undefined",
          "required": false,
          "description": "An array of custom renderers which can be used to extend the data grid."
        },
        {
          "name": "drawHeader",
          "type": "DrawHeaderCallback | undefined",
          "required": false,
          "description": "Overrides the rendering of a header. The grid will call this for every header it needs to render. Header\nrendering is not as well optimized because they do not redraw as often, but very heavy drawing methods can\nnegatively impact horizontal scrolling performance.\n\nIt is possible to return `false` after rendering just a background and the regular foreground rendering\nwill happen."
        },
        {
          "name": "editOnType",
          "type": "boolean | undefined",
          "required": false,
          "description": "Determines if the data editor should immediately begin editing when the user types on a selected cell"
        },
        {
          "name": "editorBloom",
          "type": "readonly [number, number] | undefined",
          "required": false,
          "description": "Allows overriding the default amount of bloom (the size growth of the overlay editor)"
        },
        {
          "name": "experimental",
          "type": "{ readonly disableAccessibilityTree?: boolean | undefined; readonly disableMinimumCellWidth?: boolean | undefined; readonly paddingRight?: number | undefined; readonly paddingBottom?: number | undefined; readonly enableFirefoxRescaling?: boolean | undefined; readonly enableSafariRescaling?: boolean | undefined; readonly kineticScrollPerfHack?: boolean | undefined; readonly isSubGrid?: boolean | un…",
          "required": false,
          "description": "Experimental features"
        },
        {
          "name": "fillHandle",
          "type": "FillHandle | undefined",
          "required": false,
          "description": "Enabled/disables the fill handle."
        },
        {
          "name": "fixedShadowX",
          "type": "boolean | undefined",
          "required": false,
          "description": "Enables or disables the overlay shadow when scrolling horizontally"
        },
        {
          "name": "fixedShadowY",
          "type": "boolean | undefined",
          "required": false,
          "description": "Enables or disables the overlay shadow when scrolling vertical"
        },
        {
          "name": "freezeColumns",
          "type": "number | undefined",
          "required": false,
          "description": "The number of columns which should remain in place when scrolling horizontally. The row marker column, if\nenabled is always frozen and is not included in this count."
        },
        {
          "name": "getCellBorder",
          "type": "CellBorderResolver | undefined",
          "required": false,
          "description": "Настройка рамок отдельных ячеек: стороны top, right, bottom, left,\nвкл/выкл и цвет. Перекрывает `verticalBorder`, `horizontalBorder` и тему.\nЕсли не задано, линии рисуются сплошными без разбивки по ячейкам.\nrow и col приходят в пользовательских индексах, без служебных колонок."
        },
        {
          "name": "getCellsForSelection",
          "type": "true | ((selection: Rectangle, abortSignal: AbortSignal) => GetCellsThunk | CellArray) | undefined",
          "required": false,
          "description": "Used to fetch large amounts of cells at once. Used for copy/paste, if unset copy will not work.\n\n`getCellsForSelection` is called when the user copies a selection to the clipboard or the data editor needs to\ninspect data which may be outside the curently visible range. It must return a two-dimensional array (an array of\nrows, where each row is an array of cells) of the cells in the selection's rectangle. Note that the rectangle can\ninclude cells that are not currently visible.\n\nIf `true` is passed instead of a callback, the data grid will internally use the `getCellContent` callback to\nprovide a basic implementation of `getCellsForSelection`. This can make it easier to light up more data grid\nfunctionality, but may have negative side effects if your data source is not able to handle being queried for\ndata outside the normal window.\n\nIf `getCellsForSelection` returns a thunk, the data may be loaded asynchronously, however the data grid may be\nunable to properly react to column spans when performing range selections. Copying large amounts of data out of\nthe grid will depend on the performance of the thunk as well."
        },
        {
          "name": "getGroupDetails",
          "type": "GroupDetailsCallback | undefined",
          "required": false,
          "description": "Provides additional details about groups to extend group functionality."
        },
        {
          "name": "getRowThemeOverride",
          "type": "((row: number, groupRow: number, contentRow: number) => Partial<Theme> | undefined) | undefined",
          "required": false,
          "description": "Allows overriding the theme of any row"
        },
        {
          "name": "gridSelection",
          "type": "GridSelection | undefined",
          "required": false,
          "description": "The current selection of the data grid. Contains all selected cells, ranges, rows, and columns.\nUsed in conjunction with {@link onGridSelectionChange}\nmethod to implement a controlled selection."
        },
        {
          "name": "headerHeight",
          "type": "number | undefined",
          "required": false,
          "description": "Controls the height of the header row"
        },
        {
          "name": "headerIcons",
          "type": "SpriteMap | undefined",
          "required": false,
          "description": "Additional header icons for use by `GridColumn`.\n\nProviding custom header icons to the data grid must be done with a somewhat non-standard mechanism to allow\ntheming and scaling. The `headerIcons` property takes a dictionary which maps icon names to functions which can\ntake a foreground and background color and returns back a string representation of an svg. The svg should contain\na header similar to this `<svg width=\"20\" height=\"20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">` and\ninterpolate the fg/bg colors into the string.\n\nWe recognize this process is not fantastic from a graphics workflow standpoint, improvements are very welcome\nhere."
        },
        {
          "name": "hiddenColumnsIndicator",
          "type": "((col: number) => number | HiddenColumnsIndicatorInfo) | undefined",
          "required": false,
          "description": "Индикатор скрытых колонок: сколько колонок скрыто на левой границе колонки col.\ncol === columns.length означает «справа от последней». 0 или undefined значит,\nчто индикатора нет. Полоска одна независимо от числа скрытых. Ресайз на этой границе работает\nкак обычно, а двойной клик вместо автосайза зовёт onHiddenColumnsIndicatorClicked.\nМожно вернуть { count, groupDepth }, где groupDepth задаёт, сколько верхних\nгрупп-рядов пропустить (высота полосы под сгруппированную шапку). Просто число\nозначает полосу на всю высоту."
        },
        {
          "name": "highlightRegions",
          "type": "readonly Highlight[] | undefined",
          "required": false,
          "description": "Highlight regions provide hints to users about relations between cells and selections."
        },
        {
          "name": "horizontalBorder",
          "type": "boolean | ((row: number) => boolean) | undefined",
          "required": false,
          "description": "Управление горизонтальной линией сверху строки. Функция `(row) => boolean` — точечно\nпо строкам, boolean — сразу для всех строк тела. Не задано — линии рисуются (как раньше)."
        },
        {
          "name": "imageEditorOverride",
          "type": "ImageEditorType | undefined",
          "required": false,
          "description": "Used to provide an override to the default image editor for the data grid. `provideEditor` may be a better\nchoice for most people."
        },
        {
          "name": "initialSize",
          "type": "readonly [width: number, height: number] | undefined",
          "required": false,
          "description": "Provides an initial size for the grid which can prevent a flicker on load if the initial size is known prior to\nlayout."
        },
        {
          "name": "isDraggable",
          "type": "boolean | \"header\" | \"cell\" | undefined",
          "required": false,
          "description": "Determines what can be dragged using HTML drag and drop"
        },
        {
          "name": "isOutsideClick",
          "type": "((e: MouseEvent | TouchEvent) => boolean) | undefined",
          "required": false,
          "description": "Custom predicate function to decide whether the click event occurred outside the grid\nEspecially used when custom editor is opened with the portal and is outside the grid, but there is no possibility\nto add a class \"click-outside-ignore\"\nIf this function is supplied and returns false, the click event is ignored"
        },
        {
          "name": "keybindings",
          "type": "Partial<Keybinds> | undefined",
          "required": false,
          "description": "Determins which keybindings are enabled."
        },
        {
          "name": "markdownDivCreateNode",
          "type": "((content: string) => DocumentFragment) | undefined",
          "required": false,
          "description": "If specified, it will be used to render Markdown, instead of the default Markdown renderer used by the Grid.\nYou'll want to use this if you need to process your Markdown for security purposes, or if you want to use a\nrenderer with different Markdown features."
        },
        {
          "name": "maxColumnAutoWidth",
          "type": "number | undefined",
          "required": false,
          "description": "The maximum width a column can be automatically sized to."
        },
        {
          "name": "maxColumnWidth",
          "type": "number | undefined",
          "required": false,
          "description": "The maximum width a column can be resized to."
        },
        {
          "name": "minColumnWidth",
          "type": "number | undefined",
          "required": false,
          "description": "The minimum width a column can be resized to.",
          "default": "56"
        },
        {
          "name": "onCellActivated",
          "type": "((cell: Item, event: CellActivatedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a cell is activated, by pressing Enter, Space or double clicking it."
        },
        {
          "name": "onCellClicked",
          "type": "((cell: Item, event: CellClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a cell is clicked."
        },
        {
          "name": "onCellContextMenu",
          "type": "((cell: Item, event: CellClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a cell should show a context menu. Usually right click."
        },
        {
          "name": "onCellEdited",
          "type": "((cell: Item, newValue: EditableGridCell) => void) | undefined",
          "required": false,
          "description": "Emitted whenever a cell edit is completed."
        },
        {
          "name": "onCellsEdited",
          "type": "((newValues: readonly EditListItem[]) => boolean | void) | undefined",
          "required": false,
          "description": "Emitted whenever a cell mutation is completed and provides all edits inbound as a single batch."
        },
        {
          "name": "onColumnAppended",
          "type": "(() => void | Promise<number | \"left\" | \"right\" | undefined>) | undefined",
          "required": false,
          "description": "Emitted whenever a column append operation is requested. Append location can be set in callback."
        },
        {
          "name": "onColumnMoved",
          "type": "((startIndex: number, endIndex: number) => void) | undefined",
          "required": false,
          "description": "Called when the user finishes moving a column. `startIndex` is the index of the column that was moved, and\n`endIndex` is the index at which it should end up. Note that you have to effect the move of the column, and pass\nthe reordered columns back in the `columns` property."
        },
        {
          "name": "onColumnProposeMove",
          "type": "((startIndex: number, endIndex: number) => boolean) | undefined",
          "required": false,
          "description": "Called when the user is dragging a column and proposes to move it to a new location. Return `false` to prevent"
        },
        {
          "name": "onColumnResize",
          "type": "((column: GridColumn, newSize: number, colIndex: number, newSizeWithGrow: number) => void) | undefined",
          "required": false,
          "description": "Called when the user is resizing a column. `newSize` is the new size of the column. Note that you have change\nthe size of the column in the `GridColumn` and pass it back to the grid in the `columns` property."
        },
        {
          "name": "onColumnResizeEnd",
          "type": "((column: GridColumn, newSize: number, colIndex: number, newSizeWithGrow: number) => void) | undefined",
          "required": false,
          "description": "Called when the user finishes resizing a column. `newSize` is the new size of the column."
        },
        {
          "name": "onColumnResizeStart",
          "type": "((column: GridColumn, newSize: number, colIndex: number, newSizeWithGrow: number) => void) | undefined",
          "required": false,
          "description": "Called when the user starts resizing a column. `newSize` is the new size of the column."
        },
        {
          "name": "onDelete",
          "type": "((selection: GridSelection) => boolean | GridSelection) | undefined",
          "required": false,
          "description": "Emitted whenever the user has requested the deletion of the selection."
        },
        {
          "name": "onDragStart",
          "type": "((args: GridDragEventArgs) => void) | undefined",
          "required": false,
          "description": "If `isDraggable` is set, the grid becomes HTML draggable, and `onDragStart` will be called when dragging starts.\nYou can use this to build a UI where the user can drag the Grid around."
        },
        {
          "name": "onDrop",
          "type": "((cell: Item, dataTransfer: DataTransfer | null) => void) | undefined",
          "required": false,
          "description": "Called when a HTML Drag and Drop event is ended on the data grid."
        },
        {
          "name": "onFillPattern",
          "type": "((event: FillPatternEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted whenever the user initiats a pattern fill using the fill handle. This event provides both\na patternSource region and a fillDestination region, and can be prevented."
        },
        {
          "name": "onFinishedEditing",
          "type": "((newValue: GridCell | undefined, movement: Item) => void) | undefined",
          "required": false,
          "description": "Emitted when editing has finished, regardless of data changing or not."
        },
        {
          "name": "onGridSelectionChange",
          "type": "((newSelection: GridSelection) => void) | undefined",
          "required": false,
          "description": "Emitted whenever the grid selection changes. Specifying\nthis function will make the grid’s selection controlled, so\nso you will need to specify {@link gridSelection} as well. See\nthe \"Controlled Selection\" example for details."
        },
        {
          "name": "onGroupHeaderClicked",
          "type": "((colIndex: number, event: GroupHeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a group header is clicked."
        },
        {
          "name": "onGroupHeaderContextMenu",
          "type": "((colIndex: number, event: GroupHeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a group header should show a context menu. Usually right click."
        },
        {
          "name": "onGroupHeaderRenamed",
          "type": "((groupName: string, newVal: string) => void) | undefined",
          "required": false,
          "description": "Emitted whe the user wishes to rename a group."
        },
        {
          "name": "onHeaderClicked",
          "type": "((colIndex: number, event: HeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a column header should show a context menu. Usually right click."
        },
        {
          "name": "onHeaderContextMenu",
          "type": "((colIndex: number, event: HeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a column header should show a context menu. Usually right click."
        },
        {
          "name": "onHeaderIndicatorClick",
          "type": "((col: number, screenPosition: Rectangle) => void) | undefined",
          "required": false,
          "description": "Emitted when a header indicator icon is clicked."
        },
        {
          "name": "onHeaderMenuClick",
          "type": "((col: number, screenPosition: Rectangle) => void) | undefined",
          "required": false,
          "description": "Emitted when a header menu disclosure indicator is clicked."
        },
        {
          "name": "onHiddenColumnsIndicatorClicked",
          "type": "((col: number, event: HeaderClickedEventArgs | GroupHeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Двойной клик по индикатору скрытых колонок раскрывает промежуток."
        },
        {
          "name": "onItemHovered",
          "type": "((args: GridMouseEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when an item is hovered."
        },
        {
          "name": "onKeyDown",
          "type": "((event: GridKeyEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when the canvas receives a key down event."
        },
        {
          "name": "onKeyUp",
          "type": "((event: GridKeyEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when the canvas receives a key up event."
        },
        {
          "name": "onMouseMove",
          "type": "((args: GridMouseEventArgs) => void) | undefined",
          "required": false,
          "description": "Fires whenever the mouse moves"
        },
        {
          "name": "onPaste",
          "type": "boolean | ((target: Item, values: readonly (readonly string[])[]) => boolean) | undefined",
          "required": false,
          "description": "Called when data is pasted into the grid. If left undefined, the `DataEditor` will operate in a\nfallback mode and attempt to paste the text buffer into the current cell assuming the current cell is not\nreadonly and can accept the data type. If `onPaste` is set to false or the function returns false, the grid will\nsimply ignore paste. If `onPaste` evaluates to true the grid will attempt to split the data by tabs and newlines\nand paste into available cells.\n\nThe grid will not attempt to add additional rows if more data is pasted then can fit. In that case it is\nadvisable to simply return false from onPaste and handle the paste manually."
        },
        {
          "name": "onRowAppended",
          "type": "(() => void | Promise<number | \"top\" | \"bottom\" | undefined>) | undefined",
          "required": false,
          "description": "Emitted whenever a row append operation is requested. Append location can be set in callback."
        },
        {
          "name": "onRowMoved",
          "type": "((startIndex: number, endIndex: number) => void) | undefined",
          "required": false,
          "description": "Called whenever a row re-order operation is completed. Setting the callback enables re-ordering by dragging the\nfirst column of a row."
        },
        {
          "name": "onSearchClose",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Emitted when the search window close event is triggered."
        },
        {
          "name": "onSearchResultsChanged",
          "type": "((results: readonly Item[], navIndex: number) => void) | undefined",
          "required": false,
          "description": "Emitted whenever the search results for the current search field changes."
        },
        {
          "name": "onSearchValueChange",
          "type": "((newVal: string) => void) | undefined",
          "required": false,
          "description": "Emitted when the search value changes."
        },
        {
          "name": "onSelectionCleared",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Emitted when the grid selection is cleared."
        },
        {
          "name": "onVisibleRegionChanged",
          "type": "((range: Rectangle, tx: number, ty: number, extras: { selected?: Item | undefined; freezeRegion?: Rectangle | undefined; freezeRegions?: readonly Rectangle[] | undefined; }) => void) | undefined",
          "required": false,
          "description": "Emitted whenever the visible cells change, usually due to scrolling."
        },
        {
          "name": "overscrollX",
          "type": "number | undefined",
          "required": false,
          "description": "The overscroll properties are used to allow the grid to scroll past the logical end of the content by a fixed\nnumber of pixels. This is useful particularly on the X axis if you allow for resizing columns as it can make\nresizing the final column significantly easier."
        },
        {
          "name": "overscrollY",
          "type": "number | undefined",
          "required": false,
          "description": "{@inheritDoc overscrollX}"
        },
        {
          "name": "portalElementRef",
          "type": "React.RefObject<HTMLElement> | undefined",
          "required": false,
          "description": "Allows overriding the default portal element."
        },
        {
          "name": "preventDiagonalScrolling",
          "type": "boolean | undefined",
          "required": false,
          "description": "Set to true to prevent any diagonal scrolling."
        },
        {
          "name": "provideEditor",
          "type": "ProvideEditorCallback<GridCell> | undefined",
          "required": false,
          "description": "Callback for providing a custom editor for a cell."
        },
        {
          "name": "rangeSelect",
          "type": "\"rect\" | \"cell\" | \"none\" | \"multi-cell\" | \"multi-rect\" | undefined",
          "required": false,
          "description": "Controls if multi-selection is allowed. If disabled, shift/ctrl/command clicking will work as if no modifiers\nare pressed.\n\nWhen range select is set to cell, only one cell may be selected at a time. When set to rect one one rect at a\ntime. The multi variants allow for multiples of the rect or cell to be selected."
        },
        {
          "name": "rangeSelectionBlending",
          "type": "SelectionBlending | undefined",
          "required": false,
          "description": "Controls which types of selections can exist at the same time in the grid. If selection blending is set to\nexclusive, the grid will clear other types of selections when the exclusive selection is made. By default row,\ncolumn, and range selections are exclusive."
        },
        {
          "name": "rangeSelectionColumnSpanning",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls if range selection is allowed to span columns."
        },
        {
          "name": "resizeIndicator",
          "type": "\"header\" | \"none\" | \"full\" | undefined",
          "required": false,
          "description": "Controls the resize indicator behavior.\n\n- `full` will show the resize indicator on the full height.\n- `header` will show the resize indicator only on the header.\n- `none` will not show the resize indicator."
        },
        {
          "name": "rightElement",
          "type": "React.ReactNode",
          "required": false,
          "description": "The right element is a DOM node which can be inserted at the end of the horizontal scroll region. This can be\nused to create a right handle panel, make a big add button, or display messages."
        },
        {
          "name": "rightElementProps",
          "type": "{ readonly sticky?: boolean | undefined; readonly fill?: boolean | undefined; } | undefined",
          "required": false,
          "description": "If `rightElementProps.sticky` is set to true the right element will be visible at all times, otherwise the user\nwill need to scroll to the end to reveal it.\n\nIf `rightElementProps.fill` is set, the right elements container will fill to consume all remaining space (if\nany) at the end of the grid. This does not play nice with growing columns."
        },
        {
          "name": "rowGrouping",
          "type": "RowGroupingOptions | undefined",
          "required": false,
          "description": "Controls the grouping of rows to be drawn in the grid."
        },
        {
          "name": "rowMarkers",
          "type": "\"number\" | \"checkbox\" | \"none\" | \"both\" | RowMarkerOptions | \"clickable-number\" | \"checkbox-visible\" | undefined",
          "required": false,
          "description": "Determines if row markers should be automatically added to the grid.\nInteractive row markers allow the user to select a row.\n\n- \"clickable-number\" renders a number that can be clicked to\n select the row\n- \"both\" causes the row marker to show up as a number but\n reveal a checkbox when the marker is hovered."
        },
        {
          "name": "rowSelect",
          "type": "\"none\" | \"single\" | \"multi\" | undefined",
          "required": false,
          "description": "{@inheritDoc rangeSelect}"
        },
        {
          "name": "rowSelectionBlending",
          "type": "SelectionBlending | undefined",
          "required": false,
          "description": "{@inheritDoc rangeSelectionBlending}"
        },
        {
          "name": "rowSelectionMode",
          "type": "\"auto\" | \"multi\" | undefined",
          "required": false,
          "description": "Determines if row selection requires a modifier key to enable multi-selection or not. In auto mode it adapts to\ntouch or mouse environments automatically, in multi-mode it always acts as if the multi key (Ctrl) is pressed."
        },
        {
          "name": "scaleToRem",
          "type": "boolean | undefined",
          "required": false,
          "description": "Scales most elements in the theme to match rem scaling automatically"
        },
        {
          "name": "scrollOffsetX",
          "type": "number | undefined",
          "required": false,
          "description": "Sets the initial scroll X offset"
        },
        {
          "name": "scrollOffsetY",
          "type": "number | undefined",
          "required": false,
          "description": "Sets the initial scroll Y offset."
        },
        {
          "name": "scrollToActiveCell",
          "type": "boolean | undefined",
          "required": false,
          "description": "If set to true, the data grid will attempt to scroll to keep the selction in view"
        },
        {
          "name": "searchResults",
          "type": "readonly Item[] | undefined",
          "required": false,
          "description": "The search results to display. If not provided glide will use its own internal search provider."
        },
        {
          "name": "searchValue",
          "type": "string | undefined",
          "required": false,
          "description": "The current search value."
        },
        {
          "name": "showSearch",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls the visibility of the search overlay."
        },
        {
          "name": "smoothScrollX",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls smooth scrolling in the data grid. If smooth scrolling is not enabled the grid will always be cell\naligned."
        },
        {
          "name": "smoothScrollY",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls smooth scrolling in the data grid. If smooth scrolling is not enabled the grid will always be cell\naligned."
        },
        {
          "name": "spanAlign",
          "type": "SpanAlignment | undefined",
          "required": false,
          "description": "Выравнивание текста в объединённых ячейках шапки по умолчанию.\nМожно переопределить на колонке (`spanGroupHeaderAlign`) или на группе (`getGroupDetails().spanAlign`)."
        },
        {
          "name": "spanGroupHeader",
          "type": "boolean | undefined",
          "required": false,
          "description": "Grid-дефолт слитной шапки: включает `spanGroupHeader` у ВСЕХ листовых колонок (без\nгруппы) — не нужно ставить флаг на каждую. Точечно перекрывается на колонке\n(`spanGroupHeader: true/false`). Колонки с группой проп не трогает."
        },
        {
          "name": "spanRangeBehavior",
          "type": "\"default\" | \"allowPartial\" | undefined",
          "required": false,
          "description": "If set to `default`, `gridSelection` will be coerced to always include full spans."
        },
        {
          "name": "spanShallowGroups",
          "type": "boolean | undefined",
          "required": false,
          "description": "Объединяет (rowspan) пустые нижние ряды у «мелких» групп — тех, что заканчиваются\nвыше самого глубокого уровня групп, — в одну высокую ячейку вместо пустой полосы\nпод заголовком. Точечно на группе можно переопределить через `getGroupDetails().span`\n(поставить `false`, чтобы отключить для конкретной группы). Не задано → как раньше."
        },
        {
          "name": "trailingRowOptions",
          "type": "{ readonly tint?: boolean | undefined; readonly hint?: string | undefined; readonly sticky?: boolean | undefined; readonly addIcon?: string | undefined; readonly targetColumn?: number | GridColumn | undefined; } | undefined",
          "required": false,
          "description": "Controls the trailing row used to insert new data into the grid."
        },
        {
          "name": "trapFocus",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls if focus will trap inside the data grid when doing tab and caret navigation."
        },
        {
          "name": "validateCell",
          "type": "((cell: Item, newValue: EditableGridCell, prevValue: GridCell) => boolean | ValidatedGridCell) | undefined",
          "required": false,
          "description": "Used for validating cell values during editing."
        },
        {
          "name": "verticalBorder",
          "type": "boolean | ((col: number) => boolean) | undefined",
          "required": false,
          "description": "Controls the drawing of the left hand vertical border of a column. If set to a boolean value it controls all\nborders."
        },
        {
          "name": "bottomSummaryRows",
          "type": "readonly SR[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ctxs",
          "type": "ObjectForExtending | undefined",
          "required": false,
          "description": "",
          "default": "CTXS_EMPTY"
        },
        {
          "name": "groupHeaderHeight",
          "type": "number[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onColumnsReorder",
          "type": "((sourceKey: string, targetKey: string) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "refTable",
          "type": "React.Ref<DataEditorRef> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "renderGroupHeader",
          "type": "((args: { ctx: CanvasRenderingContext2D; groupName: string; level: number; span: readonly [start: number, end: number]; theme: Theme; rect: Rectangle; isSelected: boolean; isHovered: boolean; spriteManager: SpriteManager; hoverX: number | undefined; hoverY: number | undefined; }) => \"default\" | CanvasEl | { defaultWithCustomGroupName: string; }) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "resizableColumn",
          "type": "boolean | undefined",
          "required": false,
          "description": "",
          "default": "true"
        },
        {
          "name": "rowHeight",
          "type": "number | ((row: R, currentRowSize: { rowSizeName: \"big\" | \"small\" | \"medium\"; rowSizeValue: number; }, rowIndex: number) => number) | null | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rowSize",
          "type": "\"big\" | \"small\" | \"medium\" | undefined",
          "required": false,
          "description": "",
          "default": "'medium'"
        },
        {
          "name": "drawCell",
          "type": "DrawCellCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "drawFocusRing",
          "type": "boolean | \"no-editor\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "freezeTrailingRows",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "imageWindowLoader",
          "type": "ImageWindowLoader | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onDragLeave",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onDragOverCell",
          "type": "((cell: Item, dataTransfer: DataTransfer | null) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "renderers",
          "type": "readonly InternalCellRenderer<InnerGridCell>[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "setScrollDir",
          "type": "((dir: readonly [xDir: 0 | 1 | -1, yDir: 0 | 1 | -1] | undefined) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rowMarkerStartIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Changes the starting index for row markers.",
          "deprecated": true
        },
        {
          "name": "rowMarkerTheme",
          "type": "Partial<Theme> | undefined",
          "required": false,
          "description": "Changes the theme of the row marker column",
          "deprecated": true
        },
        {
          "name": "rowMarkerWidth",
          "type": "number | undefined",
          "required": false,
          "description": "Sets the width of row markers in pixels, if unset row markers will automatically size.",
          "deprecated": true
        }
      ],
      "propsTypeName": "TableGlideProps",
      "rawType": "export type TableGlideProps<R extends ObjectForExtending, SR> = Omit<\n  GlideProps,\n  | keyof TableGlideCustomProps<R, SR>\n  | 'getCellContent'\n  | 'drawGroupHeader'\n  | 'ref'\n  | 'groupHeaderHeight'\n> &\n  TableGlideCustomProps<R, SR>;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/components/TableGlide/TableGlide.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "canvas-таблица",
        "glide grid",
        "низкоуровневая таблица"
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "CanvasContainer",
        "CanvasNode",
        "CanvasBadge",
        "CanvasButton",
        "CanvasEmbedIconButton",
        "CanvasIcon",
        "CanvasIconButton",
        "CanvasRect",
        "CanvasText",
        "CanvasLink",
        "Canvas",
        "RootBridge"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableGlide",
      "importStatement": "import { TableGlide } from '@daisforge/ui/components/TableGlide';",
      "minimalUsage": "<TableGlide columns={[]} rows={[]} />",
      "examples": []
    },
    "CanvasContainer": {
      "name": "CanvasContainer",
      "group": "components",
      "folderName": "TableGlide",
      "role": "internal",
      "description": "Flex-контейнер сцены canvas TableGlide: layout, отступы, фон, клики по ячейке",
      "props": [
        {
          "name": "interaction",
          "type": "CanvasInteractionOptions | undefined",
          "required": false,
          "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
        },
        {
          "name": "tooltip",
          "type": "CanvasNodeTooltipConfig | undefined",
          "required": false,
          "description": "Конфиг тултипа при hover: строка (текст) или объект с text и опциональными пропсами Tooltip"
        },
        {
          "name": "zIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
        },
        {
          "name": "backgroundColor",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "bottom",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "columnGap",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "gap",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "left",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onClick",
          "type": "((event: CanvasEvent<CanvasContainer>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onMouseDown",
          "type": "((event: CanvasEvent<CanvasContainer>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onMouseEnter",
          "type": "((event: CanvasEvent<CanvasContainer>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onMouseLeave",
          "type": "((event: CanvasEvent<CanvasContainer>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "portalHoverEnabled",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "position",
          "type": "\"relative\" | \"absolute\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "right",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rowGap",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "style",
          "type": "Partial<CanvasFlexStyle> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "top",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "alignContent",
          "type": "AlignContent | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "alignItems",
          "type": "Align | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "direction",
          "type": "Direction | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "justifyContent",
          "type": "Justify | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "padding",
          "type": "number | { top?: number | undefined; right?: number | undefined; bottom?: number | undefined; left?: number | undefined; } | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "wrap",
          "type": "\"wrap\" | \"nowrap\" | \"wrap-reverse\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "CanvasContainerProps",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/core/CanvasContainer.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "флекс-layout",
        "canvas flexbox",
        "верстка ячейки"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableGlide",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableGlide",
      "importStatement": "import { CanvasContainer } from '@daisforge/ui/components/TableGlide';",
      "minimalUsage": "<CanvasContainer />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в CanvasContainer.stories.tsx",
          "type": "usage",
          "code": "<Canvas.Container\n              direction={direction}\n              alignItems={alignItems}\n              justifyContent={justifyContent}\n              gap={gap}\n              padding={padding}\n              style={{\n                ...(width > 0 ? { width } : {}),\n                ...(height > 0 ? { height } : {}),\n              }}\n              backgroundColor={backgroundColor || 'gray'}\n            >\n              <Canvas.Badge text=\"Badge\" view=\"accent\" size=\"s\" />\n              <Canvas.Text>Text</Canvas.Text>\n              <Canvas.Button view=\"accent\" size=\"xs\">\n                Button\n              </Canvas.Button>\n            </Canvas.Container>",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasContainer/CanvasContainer.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvas.simple.stories.tsx",
          "type": "usage",
          "code": "<Canvas.Container\n              direction=\"row\"\n              alignItems=\"center\"\n              justifyContent=\"space-between\"\n              gap={8}\n              wrap=\"wrap\"\n              padding={{\n                left: theme.cellHorizontalPadding,\n                right: theme.cellHorizontalPadding,\n              }}\n              style={{ width: '100%' }}\n            >\n              <Canvas.Container direction=\"column\" gap={2}>\n                <Canvas.Text\n                  font={theme.baseFontStyle}\n                  color={theme.accentFg}\n                  style={{ flexGrow: 1 }}\n                >\n                  {row.task ?? '—'}\n                </Canvas.Text>\n                <Canvas.Text\n                  font={theme.baseFontStyle}\n                  color={theme.textHeader}\n                  style={{ flexGrow: 1 }}\n                >\n                  {row.priority ?? '—'}\n                </Canvas.Text>\n              </Canvas.Container>\n              <Canvas.Button\n                portalHoverEnabled\n                variant=\"secondary\"\n                onClick={() =>\n                  // eslint-disable-next-line no-console\n                  console.log('Подробнее по сотруднику', row.complete)\n                }\n              >\n                Подробнее\n              </Canvas.Button>\n            </Canvas.Container>",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.SimpleTable/TableCanvas.simple.stories.tsx"
        }
      ]
    },
    "CanvasNode": {
      "name": "CanvasNode",
      "group": "components",
      "folderName": "TableGlide",
      "role": "internal",
      "description": "Базовый класс узла canvas-сцены TableGlide: layout, hit-test, отрисовка, события",
      "props": [
        {
          "name": "offsetX",
          "type": "number | undefined",
          "required": false,
          "description": "Сдвиг тултипа по X (px) относительно центра ноды. Нужен, когда видимая\nчасть ноды смещена внутри неё (например, иконка прижата к краю кнопки).",
          "default": "0"
        },
        {
          "name": "preserveLineBreaks",
          "type": "boolean | undefined",
          "required": false,
          "description": "Сохранять переносы строк (\\n) в тексте тултипа через white-space: pre-line.",
          "default": "false"
        },
        {
          "name": "maxWidth",
          "type": "string | number | undefined",
          "required": false,
          "description": "Максимальная ширина окна (в rem)."
        },
        {
          "name": "minWidth",
          "type": "string | number | undefined",
          "required": false,
          "description": "Минимальная ширина окна (в rem)."
        },
        {
          "name": "placement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": "Направление раскрытия тултипа."
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": "Вид тултипа."
        }
      ],
      "propsTypeName": "CanvasNodeTooltipProps",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/core/CanvasNode.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "сцена рендеринга",
        "scene graph",
        "хит-тест"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableGlide",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableGlide",
      "importStatement": "import { CanvasNode } from '@daisforge/ui/components/TableGlide';",
      "minimalUsage": "<CanvasNode />",
      "examples": []
    },
    "CanvasBadge": {
      "name": "CanvasBadge",
      "group": "components",
      "folderName": "TableGlide",
      "role": "internal",
      "description": "Значок-бейдж (текст+иконки) для отрисовки в canvas-ячейках TableGlide",
      "props": [
        {
          "name": "text",
          "type": "string",
          "required": true,
          "description": "Badge text content"
        },
        {
          "name": "clear",
          "type": "boolean | undefined",
          "required": false,
          "description": "No background, only text"
        },
        {
          "name": "customBackgroundColor",
          "type": "string | undefined",
          "required": false,
          "description": "Кастомный цвет фона. Только конкретные значения: hex, rgb(), rgba(). CSS-переменные не поддерживаются."
        },
        {
          "name": "customColor",
          "type": "string | undefined",
          "required": false,
          "description": "Кастомный цвет текста. Только конкретные значения: hex, rgb(), rgba(). CSS-переменные не поддерживаются."
        },
        {
          "name": "interaction",
          "type": "CanvasInteractionOptions | undefined",
          "required": false,
          "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
        },
        {
          "name": "leftIcon",
          "type": "ButtonIcon",
          "required": false,
          "description": "Left icon (SVG string or image)"
        },
        {
          "name": "rightIcon",
          "type": "ButtonIcon",
          "required": false,
          "description": "Right icon (SVG string or image)"
        },
        {
          "name": "size",
          "type": "BadgeSize | undefined",
          "required": false,
          "description": "Badge size"
        },
        {
          "name": "transparent",
          "type": "boolean | undefined",
          "required": false,
          "description": "Use transparent background"
        },
        {
          "name": "view",
          "type": "BadgeView | undefined",
          "required": false,
          "description": "Badge view style"
        },
        {
          "name": "zIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
        },
        {
          "name": "bottom",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "left",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pilled",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "portalHoverEnabled",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "position",
          "type": "\"absolute\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "right",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "style",
          "type": "Partial<CanvasFlexStyle> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "tooltip",
          "type": "CanvasNodeTooltipConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "top",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "CanvasBadgeProps",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasBadge.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "метка статуса",
        "лейбл",
        "status label"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableGlide",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableGlide",
      "importStatement": "import { CanvasBadge } from '@daisforge/ui/components/TableGlide';",
      "minimalUsage": "<CanvasBadge text={'значение'} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в CanvasBadge.stories.tsx",
          "type": "usage",
          "code": "<Canvas.Badge\n                text={text}\n                view={row.view}\n                size={size}\n                transparent={transparent}\n                clear={clear}\n                pilled={pilled}\n              />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasBadge/CanvasBadge.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvas.subRows.stories.tsx",
          "type": "usage",
          "code": "<Canvas.Badge\n                      id=\"kek\"\n                      text={props.row?.tribeZone}\n                      view=\"accent\"\n                      size=\"m\"\n                    />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.SubRows/TableCanvas.subRows.stories.tsx"
        }
      ]
    },
    "CanvasButton": {
      "name": "CanvasButton",
      "group": "components",
      "folderName": "TableGlide",
      "role": "internal",
      "description": "Кнопка с текстом и иконками для canvas-ячеек TableGlide (аналог Button)",
      "props": [
        {
          "name": "children",
          "type": "string",
          "required": true,
          "description": ""
        },
        {
          "name": "interaction",
          "type": "CanvasInteractionOptions | undefined",
          "required": false,
          "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
        },
        {
          "name": "leftIcon",
          "type": "ButtonIcon",
          "required": false,
          "description": "Left icon (SVG string or image)"
        },
        {
          "name": "rightIcon",
          "type": "ButtonIcon",
          "required": false,
          "description": "Right icon (SVG string or image)"
        },
        {
          "name": "size",
          "type": "ButtonSize | undefined",
          "required": false,
          "description": "Button size"
        },
        {
          "name": "view",
          "type": "ButtonView | undefined",
          "required": false,
          "description": "Button view style based on sdds_finai__light theme"
        },
        {
          "name": "zIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
        },
        {
          "name": "bottom",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "left",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onClick",
          "type": "((event: CanvasEvent<CanvasButton>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "portalHoverEnabled",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "position",
          "type": "\"absolute\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "right",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "style",
          "type": "Partial<CanvasFlexStyle> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "tooltip",
          "type": "CanvasNodeTooltipConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "top",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "variant",
          "type": "\"secondary\" | \"primary\" | \"danger\" | undefined",
          "required": false,
          "description": "",
          "deprecated": true
        }
      ],
      "propsTypeName": "CanvasButtonProps",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasButton.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "кнопка в ячейке",
        "canvas action button",
        "интерактивная ячейка"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableGlide",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableGlide",
      "importStatement": "import { CanvasButton } from '@daisforge/ui/components/TableGlide';",
      "minimalUsage": "<CanvasButton children={'значение'} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в TableCanvasTooltip.stories.tsx",
          "type": "usage",
          "code": "<Canvas.Button\n              portalHoverEnabled\n              tooltip=\"Нажмите для перехода в карточку\"\n              variant=\"secondary\"\n              onClick={() => {}}\n            >\n              Подробнее\n            </Canvas.Button>",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в CanvasButton.stories.tsx",
          "type": "usage",
          "code": "<Canvas.Button view={row.view} size={size} disabled={disabled}>\n                {text}\n              </Canvas.Button>",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasButton/CanvasButton.stories.tsx"
        }
      ]
    },
    "CanvasEmbedIconButton": {
      "name": "CanvasEmbedIconButton",
      "group": "components",
      "folderName": "TableGlide",
      "role": "internal",
      "description": "Квадратная icon-кнопка (embed-стиль) для canvas-ячеек TableGlide с кастомными цветами",
      "props": [
        {
          "name": "icon",
          "type": "ButtonIcon",
          "required": true,
          "description": ""
        },
        {
          "name": "buttonSize",
          "type": "ButtonSize | undefined",
          "required": false,
          "description": "Button size"
        },
        {
          "name": "iconColor",
          "type": "string | undefined",
          "required": false,
          "description": "Переопределяет цвет иконки в покое (иначе — цвет из view-палитры)"
        },
        {
          "name": "iconColorHovered",
          "type": "string | undefined",
          "required": false,
          "description": "Переопределяет цвет иконки при hover (иначе — iconColor override или view)"
        },
        {
          "name": "interaction",
          "type": "CanvasInteractionOptions | undefined",
          "required": false,
          "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
        },
        {
          "name": "overrideIconSize",
          "type": "number | undefined",
          "required": false,
          "description": "Переопределяет размер иконки внутри кнопки (px), приоритет над SIZE_CONFIG"
        },
        {
          "name": "overrideSquareSize",
          "type": "number | undefined",
          "required": false,
          "description": "Переопределяет размер квадратной кнопки (px), приоритет над SIZE_CONFIG"
        },
        {
          "name": "overrideWidth",
          "type": "number | undefined",
          "required": false,
          "description": "Только EmbedIconButton: ширина кнопки в раскладке и hit-area (px),\nпо умолчанию — сторона квадрата. Иконка рисуется в квадрате от левого края."
        },
        {
          "name": "view",
          "type": "ButtonView | undefined",
          "required": false,
          "description": "Button view style based on sdds_finai__light theme"
        },
        {
          "name": "zIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
        },
        {
          "name": "bottom",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "left",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onClick",
          "type": "((event: CanvasEvent<CanvasEmbedIconButton>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "portalHoverEnabled",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "position",
          "type": "\"absolute\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "right",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "style",
          "type": "Partial<CanvasFlexStyle> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "tooltip",
          "type": "CanvasNodeTooltipConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "top",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "number | \"auto\" | undefined",
          "required": false,
          "description": "",
          "deprecated": true
        },
        {
          "name": "variant",
          "type": "\"secondary\" | \"primary\" | \"danger\" | undefined",
          "required": false,
          "description": "",
          "deprecated": true
        }
      ],
      "propsTypeName": "CanvasEmbedIconButtonProps",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasEmbedIconButton.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "встроенная кнопка",
        "icon action",
        "квадратная кнопка"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableGlide",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableGlide",
      "importStatement": "import { CanvasEmbedIconButton } from '@daisforge/ui/components/TableGlide';",
      "minimalUsage": "<CanvasEmbedIconButton icon={{}} />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в CanvasEmbedIconButton.stories.tsx",
          "type": "usage",
          "code": "<Canvas.EmbedIconButton\n              icon={<IconSearch />}\n              view={row.view}\n              buttonSize={size}\n              disabled={disabled}\n            />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasEmbedIconButton/CanvasEmbedIconButton.stories.tsx"
        }
      ]
    },
    "CanvasIcon": {
      "name": "CanvasIcon",
      "group": "components",
      "folderName": "TableGlide",
      "role": "internal",
      "description": "Отрисовка иконки заданного размера и цвета в canvas-ячейке TableGlide",
      "props": [
        {
          "name": "icon",
          "type": "ButtonIcon",
          "required": true,
          "description": ""
        },
        {
          "name": "interaction",
          "type": "CanvasInteractionOptions | undefined",
          "required": false,
          "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
        },
        {
          "name": "zIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
        },
        {
          "name": "backgroundColor",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "bottom",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "left",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onClick",
          "type": "((event: CanvasEvent<CanvasIcon>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onMouseDown",
          "type": "((event: CanvasEvent<CanvasIcon>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onMouseEnter",
          "type": "((event: CanvasEvent<CanvasIcon>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onMouseLeave",
          "type": "((event: CanvasEvent<CanvasIcon>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "portalHoverEnabled",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "position",
          "type": "\"absolute\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "right",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "style",
          "type": "Partial<CanvasFlexStyle> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "tooltip",
          "type": "CanvasNodeTooltipConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "top",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "CanvasIconProps",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasIcon.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "иконка в ячейке",
        "canvas icon",
        "пиктограмма"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableGlide",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableGlide",
      "importStatement": "import { CanvasIcon } from '@daisforge/ui/components/TableGlide';",
      "minimalUsage": "<CanvasIcon icon={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в CanvasText.stories.tsx",
          "type": "usage",
          "code": "<Canvas.Icon\n                icon={<IconSearch />}\n                size={16}\n                color={theme.tokens.textAccent}\n                style={{ flexShrink: 0 }}\n              />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasText/CanvasText.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvas.simple.stories.tsx",
          "type": "usage",
          "code": "<Canvas.Icon\n                  position=\"absolute\"\n                  top={-5}\n                  right={-5}\n                  icon={<IconBrightness0Fill color=\"#d70101\" size=\"xs\" />}\n                />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.SimpleTable/TableCanvas.simple.stories.tsx"
        }
      ]
    },
    "CanvasIconButton": {
      "name": "CanvasIconButton",
      "group": "components",
      "folderName": "TableGlide",
      "role": "internal",
      "description": "Icon-кнопка с hover/click для canvas-ячеек TableGlide (аналог IconButton)",
      "props": [
        {
          "name": "icon",
          "type": "ButtonIcon",
          "required": true,
          "description": ""
        },
        {
          "name": "buttonSize",
          "type": "ButtonSize | undefined",
          "required": false,
          "description": "Button size"
        },
        {
          "name": "interaction",
          "type": "CanvasInteractionOptions | undefined",
          "required": false,
          "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
        },
        {
          "name": "view",
          "type": "ButtonView | undefined",
          "required": false,
          "description": "Button view style based on sdds_finai__light theme"
        },
        {
          "name": "zIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
        },
        {
          "name": "bottom",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "left",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onClick",
          "type": "((event: CanvasEvent<CanvasIconButton>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "portalHoverEnabled",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "position",
          "type": "\"absolute\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "right",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "style",
          "type": "Partial<CanvasFlexStyle> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "tooltip",
          "type": "CanvasNodeTooltipConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "top",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "number | \"auto\" | undefined",
          "required": false,
          "description": "",
          "deprecated": true
        },
        {
          "name": "variant",
          "type": "\"secondary\" | \"primary\" | \"danger\" | undefined",
          "required": false,
          "description": "",
          "deprecated": true
        }
      ],
      "propsTypeName": "CanvasIconButtonProps",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasIconButton.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "кнопка-иконка",
        "icon action button"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableGlide",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableGlide",
      "importStatement": "import { CanvasIconButton } from '@daisforge/ui/components/TableGlide';",
      "minimalUsage": "<CanvasIconButton icon={{}} />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в CanvasIconButton.stories.tsx",
          "type": "usage",
          "code": "<Canvas.IconButton\n              icon={<IconSearch />}\n              view={row.view}\n              buttonSize={size}\n              disabled={disabled}\n            />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasIconButton/CanvasIconButton.stories.tsx"
        }
      ]
    },
    "CanvasRect": {
      "name": "CanvasRect",
      "group": "components",
      "folderName": "TableGlide",
      "role": "internal",
      "description": "Прямоугольник с заливкой и рамкой — примитив фона/разделителя в canvas-ячейке",
      "props": [
        {
          "name": "interaction",
          "type": "CanvasInteractionOptions | undefined",
          "required": false,
          "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
        },
        {
          "name": "zIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
        },
        {
          "name": "borderColor",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "borderWidth",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "bottom",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "left",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "portalHoverEnabled",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "position",
          "type": "\"absolute\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "right",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "style",
          "type": "Partial<CanvasFlexStyle> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "tooltip",
          "type": "CanvasNodeTooltipConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "top",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "CanvasRectProps",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasRect.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "фон ячейки",
        "разделитель",
        "прямоугольник"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableGlide",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableGlide",
      "importStatement": "import { CanvasRect } from '@daisforge/ui/components/TableGlide';",
      "minimalUsage": "<CanvasRect />",
      "examples": []
    },
    "CanvasText": {
      "name": "CanvasText",
      "group": "components",
      "folderName": "TableGlide",
      "role": "internal",
      "description": "Текстовый узел canvas TableGlide: перенос строк, ellipsis, авто-тултип при обрезке",
      "props": [
        {
          "name": "interaction",
          "type": "CanvasInteractionOptions | undefined",
          "required": false,
          "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
        },
        {
          "name": "zIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
        },
        {
          "name": "bottom",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "font",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "left",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "portalHoverEnabled",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "position",
          "type": "\"absolute\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "right",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "style",
          "type": "Partial<CanvasFlexStyle> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "tooltip",
          "type": "CanvasNodeTooltipConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "top",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoTooltip",
          "type": "CanvasTextAutoTooltip | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ellipsis",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "lineHeight",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "maxLines",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "overflow",
          "type": "CanvasTextOverflowMode | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "textOverflow",
          "type": "CanvasTextOverflow | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "wordWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "CanvasTextProps",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasText.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "перенос текста",
        "обрезка текста",
        "многострочный текст"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableGlide",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableGlide",
      "importStatement": "import { CanvasText } from '@daisforge/ui/components/TableGlide';",
      "minimalUsage": "<CanvasText />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в CanvasText.stories.tsx",
          "type": "usage",
          "code": "<Canvas.Text\n                color={color || theme.textDark}\n                font={font || theme.baseFontStyle}\n                wordWrap={wordWrap}\n                overflow={overflow}\n                textOverflow={textOverflow}\n                ellipsis={ellipsis}\n                maxLines={resolvedMaxLines}\n                lineHeight={lineHeight}\n                style={{ flexGrow: 1 }}\n                autoTooltip={{\n                  enabled: true,\n                }}\n              >\n                {row.id === 1 ? text : row.longText}\n              </Canvas.Text>",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasText/CanvasText.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvasTooltip.stories.tsx",
          "type": "usage",
          "code": "<Canvas.Text\n              overflow=\"hidden\"\n              textOverflow=\"ellipsis\"\n              autoTooltip\n              style={{ flexGrow: 1 }}\n            >\n              {`${row.task}: ${longText}`}\n            </Canvas.Text>",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx"
        }
      ]
    },
    "CanvasLink": {
      "name": "CanvasLink",
      "group": "components",
      "folderName": "TableGlide",
      "role": "internal",
      "description": "Ссылка с подчёркиванием и переходом по href внутри canvas-ячейки TableGlide",
      "props": [
        {
          "name": "interaction",
          "type": "CanvasInteractionOptions | undefined",
          "required": false,
          "description": "Декларативное описание поведения зоны внутри ячейки.\n\nСамый частый сценарий:\n`interaction={{ selection: 'keep', cellClick: 'stop', editor: 'never' }}`\n— элемент выполняет собственное действие и не должен менять selection,\nзапускать editor или вызывать внешний `onCellClicked`.\n\n`interaction={{ editor: 'open-on-click' }}` — элемент просит открыть\neditor текущей ячейки. Например стрелка select-ячейки."
        },
        {
          "name": "zIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Локальный слой внутри canvas-root; рекомендуется использовать zIndex >= 0.\nЗначение суммируется по цепочке родителей и не является DOM z-index."
        },
        {
          "name": "bottom",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "font",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "left",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onClick",
          "type": "((event: CanvasEvent<CanvasLink>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "portalHoverEnabled",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "position",
          "type": "\"absolute\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "right",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "style",
          "type": "Partial<CanvasFlexStyle> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "tooltip",
          "type": "CanvasNodeTooltipConfig | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "top",
          "type": "PositionValue | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoTooltip",
          "type": "CanvasTextAutoTooltip | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ellipsis",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "lineHeight",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "maxLines",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "overflow",
          "type": "CanvasTextOverflowMode | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "textOverflow",
          "type": "CanvasTextOverflow | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "wordWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "CanvasLinkProps",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasLink.ts",
      "type": "wrapper",
      "atomicBase": "Link",
      "wrapsInternal": "Link",
      "category": "Локальные компоненты",
      "keywords": [
        "гиперссылка",
        "переход по клику",
        "canvas hyperlink"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableGlide",
      "inheritedProps": [
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Link",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "string",
          "required": false,
          "inheritedFrom": "Link",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "underline",
          "type": "\"none\" | \"hover\" | \"always\"",
          "required": false,
          "inheritedFrom": "Link",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"tertiary\" | \"paragraph\"",
          "required": false,
          "inheritedFrom": "Link",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableGlide",
      "importStatement": "import { CanvasLink } from '@daisforge/ui/components/TableGlide';",
      "minimalUsage": "<CanvasLink />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в CanvasLink.stories.tsx",
          "type": "usage",
          "code": "<Canvas.Link\n                view={row.view}\n                href={href}\n                target=\"_blank\"\n                disabled={disabled}\n              >\n                {text}\n              </Canvas.Link>",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasLink/CanvasLink.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в CanvasText.stories.tsx",
          "type": "usage",
          "code": "<Canvas.Link>{row.shortName}</Canvas.Link>",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/CanvasElements/CanvasText/CanvasText.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TextS, Link } from '@daisforge/ui/components/TableGlide';\nexport function App() {\n    return (\n        <TextS>\n            Скачайте <Link href=\"/\" target=\"_blank\">приложение.</Link>\n        </TextS>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Подчёркивание Подчёркивание Prop  underline  управляет режимом подчёркивания ссылки",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TextS, Link } from '@daisforge/ui/components/TableGlide';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n            <TextS><Link href=\"/\" underline=\"none\">Без подчёркивания</Link></TextS>\n            <TextS><Link href=\"/\" underline=\"hover\">Подчёркивание при наведении</Link></TextS>\n            <TextS><Link href=\"/\" underline=\"always\">Всегда подчёркнута</Link></TextS>\n        </div>\n    );\n}"
        }
      ]
    },
    "RootBridge": {
      "name": "RootBridge",
      "group": "components",
      "folderName": "TableGlide",
      "role": "internal",
      "description": "Служебный мост React→registry контента ячеек для canvas-рендерера TableGlide",
      "props": [
        {
          "name": "cellId",
          "type": "string",
          "required": true,
          "description": ""
        },
        {
          "name": "nodeRegistry",
          "type": "React.MutableRefObject<Map<string, React.ReactElement<any, string | React.JSXElementConstructor<any>>>>",
          "required": true,
          "description": ""
        },
        {
          "name": "renderContent",
          "type": "() => React.ReactElement<any, string | React.JSXElementConstructor<any>>",
          "required": true,
          "description": ""
        },
        {
          "name": "onRegistryChange",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "RootBridgeProps",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/components/index.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "реестр контента ячеек",
        "cell registry",
        "рендер моста"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TableGlide",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui/components/TableGlide",
      "importStatement": "import { RootBridge } from '@daisforge/ui/components/TableGlide';",
      "minimalUsage": "<RootBridge cellId={'значение'} nodeRegistry={'Контент'} renderContent={() => {}} />",
      "examples": []
    },
    "DataEditor": {
      "name": "DataEditor",
      "group": "components",
      "folderName": "TableGlide",
      "role": "primary",
      "description": "Низкоуровневый canvas-движок Glide Data Grid — база для кастомных табличных решений.",
      "props": [
        {
          "name": "columns",
          "type": "readonly GridColumn[]",
          "required": true,
          "description": "The columns to display in the data grid."
        },
        {
          "name": "getCellContent",
          "type": "(cell: Item) => GridCell",
          "required": true,
          "description": "The primary callback for getting cell data into the data grid."
        },
        {
          "name": "allowedFillDirections",
          "type": "FillHandleDirection | undefined",
          "required": false,
          "description": "Controls which directions fill is allowed in."
        },
        {
          "name": "cellActivationBehavior",
          "type": "CellActivationBehavior | undefined",
          "required": false,
          "description": "Determines when a cell is considered activated and will emit the `onCellActivated` event. Generally an activated\ncell will open to edit mode."
        },
        {
          "name": "coercePasteValue",
          "type": "((val: string, cell: GridCell) => GridCell | undefined) | undefined",
          "required": false,
          "description": "Allows coercion of pasted values."
        },
        {
          "name": "columnSelect",
          "type": "\"none\" | \"single\" | \"multi\" | undefined",
          "required": false,
          "description": "{@inheritDoc rangeSelect}"
        },
        {
          "name": "columnSelectionBlending",
          "type": "SelectionBlending | undefined",
          "required": false,
          "description": "{@inheritDoc rangeSelectionBlending}"
        },
        {
          "name": "columnSelectionMode",
          "type": "\"multi\" | \"auto\" | undefined",
          "required": false,
          "description": "Determines if column selection requires a modifier key to enable multi-selection or not. In auto mode it adapts to\ntouch or mouse environments automatically, in multi-mode it always acts as if the multi key (Ctrl) is pressed."
        },
        {
          "name": "copyHeaders",
          "type": "boolean | undefined",
          "required": false,
          "description": "Add table headers to copied data."
        },
        {
          "name": "customRenderers",
          "type": "readonly CustomRenderer<any>[] | undefined",
          "required": false,
          "description": "An array of custom renderers which can be used to extend the data grid."
        },
        {
          "name": "drawGroupHeader",
          "type": "DrawGroupHeaderCallback | undefined",
          "required": false,
          "description": "Overrides the rendering of a group header. The grid will call this for every group header it needs to render.\nGroup header rendering is not as well optimized because they do not redraw as often, but very heavy drawing\nmethods can negatively impact horizontal scrolling performance.\n\nIt is possible to return `false` after rendering just a background and the regular foreground rendering\nwill happen."
        },
        {
          "name": "drawHeader",
          "type": "DrawHeaderCallback | undefined",
          "required": false,
          "description": "Overrides the rendering of a header. The grid will call this for every header it needs to render. Header\nrendering is not as well optimized because they do not redraw as often, but very heavy drawing methods can\nnegatively impact horizontal scrolling performance.\n\nIt is possible to return `false` after rendering just a background and the regular foreground rendering\nwill happen."
        },
        {
          "name": "editOnType",
          "type": "boolean | undefined",
          "required": false,
          "description": "Determines if the data editor should immediately begin editing when the user types on a selected cell"
        },
        {
          "name": "editorBloom",
          "type": "readonly [number, number] | undefined",
          "required": false,
          "description": "Allows overriding the default amount of bloom (the size growth of the overlay editor)"
        },
        {
          "name": "experimental",
          "type": "{ readonly disableAccessibilityTree?: boolean | undefined; readonly disableMinimumCellWidth?: boolean | undefined; readonly paddingRight?: number | undefined; readonly paddingBottom?: number | undefined; readonly enableFirefoxRescaling?: boolean | undefined; readonly enableSafariRescaling?: boolean | undefined; readonly kineticScrollPerfHack?: boolean | undefined; readonly isSubGrid?: boolean | un…",
          "required": false,
          "description": "Experimental features"
        },
        {
          "name": "fillHandle",
          "type": "FillHandle | undefined",
          "required": false,
          "description": "Enabled/disables the fill handle."
        },
        {
          "name": "fixedShadowX",
          "type": "boolean | undefined",
          "required": false,
          "description": "Enables or disables the overlay shadow when scrolling horizontally"
        },
        {
          "name": "fixedShadowY",
          "type": "boolean | undefined",
          "required": false,
          "description": "Enables or disables the overlay shadow when scrolling vertical"
        },
        {
          "name": "freezeColumns",
          "type": "number | undefined",
          "required": false,
          "description": "The number of columns which should remain in place when scrolling horizontally. The row marker column, if\nenabled is always frozen and is not included in this count."
        },
        {
          "name": "getCellBorder",
          "type": "CellBorderResolver | undefined",
          "required": false,
          "description": "Настройка рамок отдельных ячеек: стороны top, right, bottom, left,\nвкл/выкл и цвет. Перекрывает `verticalBorder`, `horizontalBorder` и тему.\nЕсли не задано, линии рисуются сплошными без разбивки по ячейкам.\nrow и col приходят в пользовательских индексах, без служебных колонок."
        },
        {
          "name": "getCellsForSelection",
          "type": "true | ((selection: Rectangle, abortSignal: AbortSignal) => GetCellsThunk | CellArray) | undefined",
          "required": false,
          "description": "Used to fetch large amounts of cells at once. Used for copy/paste, if unset copy will not work.\n\n`getCellsForSelection` is called when the user copies a selection to the clipboard or the data editor needs to\ninspect data which may be outside the curently visible range. It must return a two-dimensional array (an array of\nrows, where each row is an array of cells) of the cells in the selection's rectangle. Note that the rectangle can\ninclude cells that are not currently visible.\n\nIf `true` is passed instead of a callback, the data grid will internally use the `getCellContent` callback to\nprovide a basic implementation of `getCellsForSelection`. This can make it easier to light up more data grid\nfunctionality, but may have negative side effects if your data source is not able to handle being queried for\ndata outside the normal window.\n\nIf `getCellsForSelection` returns a thunk, the data may be loaded asynchronously, however the data grid may be\nunable to properly react to column spans when performing range selections. Copying large amounts of data out of\nthe grid will depend on the performance of the thunk as well."
        },
        {
          "name": "getGroupDetails",
          "type": "GroupDetailsCallback | undefined",
          "required": false,
          "description": "Provides additional details about groups to extend group functionality."
        },
        {
          "name": "getRowThemeOverride",
          "type": "((row: number, groupRow: number, contentRow: number) => Partial<Theme> | undefined) | undefined",
          "required": false,
          "description": "Allows overriding the theme of any row"
        },
        {
          "name": "gridSelection",
          "type": "GridSelection | undefined",
          "required": false,
          "description": "The current selection of the data grid. Contains all selected cells, ranges, rows, and columns.\nUsed in conjunction with {@link onGridSelectionChange}\nmethod to implement a controlled selection."
        },
        {
          "name": "groupHeaderHeight",
          "type": "number | number[] | undefined",
          "required": false,
          "description": "Controls the header of the group header row"
        },
        {
          "name": "headerHeight",
          "type": "number | undefined",
          "required": false,
          "description": "Controls the height of the header row"
        },
        {
          "name": "headerIcons",
          "type": "SpriteMap | undefined",
          "required": false,
          "description": "Additional header icons for use by `GridColumn`.\n\nProviding custom header icons to the data grid must be done with a somewhat non-standard mechanism to allow\ntheming and scaling. The `headerIcons` property takes a dictionary which maps icon names to functions which can\ntake a foreground and background color and returns back a string representation of an svg. The svg should contain\na header similar to this `<svg width=\"20\" height=\"20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">` and\ninterpolate the fg/bg colors into the string.\n\nWe recognize this process is not fantastic from a graphics workflow standpoint, improvements are very welcome\nhere."
        },
        {
          "name": "hiddenColumnsIndicator",
          "type": "((col: number) => number | HiddenColumnsIndicatorInfo) | undefined",
          "required": false,
          "description": "Индикатор скрытых колонок: сколько колонок скрыто на левой границе колонки col.\ncol === columns.length означает «справа от последней». 0 или undefined значит,\nчто индикатора нет. Полоска одна независимо от числа скрытых. Ресайз на этой границе работает\nкак обычно, а двойной клик вместо автосайза зовёт onHiddenColumnsIndicatorClicked.\nМожно вернуть { count, groupDepth }, где groupDepth задаёт, сколько верхних\nгрупп-рядов пропустить (высота полосы под сгруппированную шапку). Просто число\nозначает полосу на всю высоту."
        },
        {
          "name": "highlightRegions",
          "type": "readonly Highlight[] | undefined",
          "required": false,
          "description": "Highlight regions provide hints to users about relations between cells and selections."
        },
        {
          "name": "horizontalBorder",
          "type": "boolean | ((row: number) => boolean) | undefined",
          "required": false,
          "description": "Управление горизонтальной линией сверху строки. Функция `(row) => boolean` — точечно\nпо строкам, boolean — сразу для всех строк тела. Не задано — линии рисуются (как раньше)."
        },
        {
          "name": "imageEditorOverride",
          "type": "ImageEditorType | undefined",
          "required": false,
          "description": "Used to provide an override to the default image editor for the data grid. `provideEditor` may be a better\nchoice for most people."
        },
        {
          "name": "initialSize",
          "type": "readonly [width: number, height: number] | undefined",
          "required": false,
          "description": "Provides an initial size for the grid which can prevent a flicker on load if the initial size is known prior to\nlayout."
        },
        {
          "name": "isDraggable",
          "type": "boolean | \"cell\" | \"header\" | undefined",
          "required": false,
          "description": "Determines what can be dragged using HTML drag and drop"
        },
        {
          "name": "isOutsideClick",
          "type": "((e: MouseEvent | TouchEvent) => boolean) | undefined",
          "required": false,
          "description": "Custom predicate function to decide whether the click event occurred outside the grid\nEspecially used when custom editor is opened with the portal and is outside the grid, but there is no possibility\nto add a class \"click-outside-ignore\"\nIf this function is supplied and returns false, the click event is ignored"
        },
        {
          "name": "keybindings",
          "type": "Partial<Keybinds> | undefined",
          "required": false,
          "description": "Determins which keybindings are enabled."
        },
        {
          "name": "markdownDivCreateNode",
          "type": "((content: string) => DocumentFragment) | undefined",
          "required": false,
          "description": "If specified, it will be used to render Markdown, instead of the default Markdown renderer used by the Grid.\nYou'll want to use this if you need to process your Markdown for security purposes, or if you want to use a\nrenderer with different Markdown features."
        },
        {
          "name": "maxColumnAutoWidth",
          "type": "number | undefined",
          "required": false,
          "description": "The maximum width a column can be automatically sized to."
        },
        {
          "name": "maxColumnWidth",
          "type": "number | undefined",
          "required": false,
          "description": "The maximum width a column can be resized to."
        },
        {
          "name": "minColumnWidth",
          "type": "number | undefined",
          "required": false,
          "description": "The minimum width a column can be resized to."
        },
        {
          "name": "onCellActivated",
          "type": "((cell: Item, event: CellActivatedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a cell is activated, by pressing Enter, Space or double clicking it."
        },
        {
          "name": "onCellClicked",
          "type": "((cell: Item, event: CellClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a cell is clicked."
        },
        {
          "name": "onCellContextMenu",
          "type": "((cell: Item, event: CellClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a cell should show a context menu. Usually right click."
        },
        {
          "name": "onCellEdited",
          "type": "((cell: Item, newValue: EditableGridCell) => void) | undefined",
          "required": false,
          "description": "Emitted whenever a cell edit is completed."
        },
        {
          "name": "onCellsEdited",
          "type": "((newValues: readonly EditListItem[]) => boolean | void) | undefined",
          "required": false,
          "description": "Emitted whenever a cell mutation is completed and provides all edits inbound as a single batch."
        },
        {
          "name": "onColumnAppended",
          "type": "(() => void | Promise<number | \"left\" | \"right\" | undefined>) | undefined",
          "required": false,
          "description": "Emitted whenever a column append operation is requested. Append location can be set in callback."
        },
        {
          "name": "onColumnMoved",
          "type": "((startIndex: number, endIndex: number) => void) | undefined",
          "required": false,
          "description": "Called when the user finishes moving a column. `startIndex` is the index of the column that was moved, and\n`endIndex` is the index at which it should end up. Note that you have to effect the move of the column, and pass\nthe reordered columns back in the `columns` property."
        },
        {
          "name": "onColumnProposeMove",
          "type": "((startIndex: number, endIndex: number) => boolean) | undefined",
          "required": false,
          "description": "Called when the user is dragging a column and proposes to move it to a new location. Return `false` to prevent"
        },
        {
          "name": "onColumnResize",
          "type": "((column: GridColumn, newSize: number, colIndex: number, newSizeWithGrow: number) => void) | undefined",
          "required": false,
          "description": "Called when the user is resizing a column. `newSize` is the new size of the column. Note that you have change\nthe size of the column in the `GridColumn` and pass it back to the grid in the `columns` property."
        },
        {
          "name": "onColumnResizeEnd",
          "type": "((column: GridColumn, newSize: number, colIndex: number, newSizeWithGrow: number) => void) | undefined",
          "required": false,
          "description": "Called when the user finishes resizing a column. `newSize` is the new size of the column."
        },
        {
          "name": "onColumnResizeStart",
          "type": "((column: GridColumn, newSize: number, colIndex: number, newSizeWithGrow: number) => void) | undefined",
          "required": false,
          "description": "Called when the user starts resizing a column. `newSize` is the new size of the column."
        },
        {
          "name": "onDelete",
          "type": "((selection: GridSelection) => boolean | GridSelection) | undefined",
          "required": false,
          "description": "Emitted whenever the user has requested the deletion of the selection."
        },
        {
          "name": "onDragStart",
          "type": "((args: GridDragEventArgs) => void) | undefined",
          "required": false,
          "description": "If `isDraggable` is set, the grid becomes HTML draggable, and `onDragStart` will be called when dragging starts.\nYou can use this to build a UI where the user can drag the Grid around."
        },
        {
          "name": "onDrop",
          "type": "((cell: Item, dataTransfer: DataTransfer | null) => void) | undefined",
          "required": false,
          "description": "Called when a HTML Drag and Drop event is ended on the data grid."
        },
        {
          "name": "onFillPattern",
          "type": "((event: FillPatternEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted whenever the user initiats a pattern fill using the fill handle. This event provides both\na patternSource region and a fillDestination region, and can be prevented."
        },
        {
          "name": "onFinishedEditing",
          "type": "((newValue: GridCell | undefined, movement: Item) => void) | undefined",
          "required": false,
          "description": "Emitted when editing has finished, regardless of data changing or not."
        },
        {
          "name": "onGridSelectionChange",
          "type": "((newSelection: GridSelection) => void) | undefined",
          "required": false,
          "description": "Emitted whenever the grid selection changes. Specifying\nthis function will make the grid’s selection controlled, so\nso you will need to specify {@link gridSelection} as well. See\nthe \"Controlled Selection\" example for details."
        },
        {
          "name": "onGroupHeaderClicked",
          "type": "((colIndex: number, event: GroupHeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a group header is clicked."
        },
        {
          "name": "onGroupHeaderContextMenu",
          "type": "((colIndex: number, event: GroupHeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a group header should show a context menu. Usually right click."
        },
        {
          "name": "onGroupHeaderRenamed",
          "type": "((groupName: string, newVal: string) => void) | undefined",
          "required": false,
          "description": "Emitted whe the user wishes to rename a group."
        },
        {
          "name": "onHeaderClicked",
          "type": "((colIndex: number, event: HeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a column header should show a context menu. Usually right click."
        },
        {
          "name": "onHeaderContextMenu",
          "type": "((colIndex: number, event: HeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when a column header should show a context menu. Usually right click."
        },
        {
          "name": "onHeaderIndicatorClick",
          "type": "((col: number, screenPosition: Rectangle) => void) | undefined",
          "required": false,
          "description": "Emitted when a header indicator icon is clicked."
        },
        {
          "name": "onHeaderMenuClick",
          "type": "((col: number, screenPosition: Rectangle) => void) | undefined",
          "required": false,
          "description": "Emitted when a header menu disclosure indicator is clicked."
        },
        {
          "name": "onHiddenColumnsIndicatorClicked",
          "type": "((col: number, event: HeaderClickedEventArgs | GroupHeaderClickedEventArgs) => void) | undefined",
          "required": false,
          "description": "Двойной клик по индикатору скрытых колонок раскрывает промежуток."
        },
        {
          "name": "onItemHovered",
          "type": "((args: GridMouseEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when an item is hovered."
        },
        {
          "name": "onKeyDown",
          "type": "((event: GridKeyEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when the canvas receives a key down event."
        },
        {
          "name": "onKeyUp",
          "type": "((event: GridKeyEventArgs) => void) | undefined",
          "required": false,
          "description": "Emitted when the canvas receives a key up event."
        },
        {
          "name": "onMouseMove",
          "type": "((args: GridMouseEventArgs) => void) | undefined",
          "required": false,
          "description": "Fires whenever the mouse moves"
        },
        {
          "name": "onPaste",
          "type": "boolean | ((target: Item, values: readonly (readonly string[])[]) => boolean) | undefined",
          "required": false,
          "description": "Called when data is pasted into the grid. If left undefined, the `DataEditor` will operate in a\nfallback mode and attempt to paste the text buffer into the current cell assuming the current cell is not\nreadonly and can accept the data type. If `onPaste` is set to false or the function returns false, the grid will\nsimply ignore paste. If `onPaste` evaluates to true the grid will attempt to split the data by tabs and newlines\nand paste into available cells.\n\nThe grid will not attempt to add additional rows if more data is pasted then can fit. In that case it is\nadvisable to simply return false from onPaste and handle the paste manually."
        },
        {
          "name": "onRowAppended",
          "type": "(() => void | Promise<number | \"top\" | \"bottom\" | undefined>) | undefined",
          "required": false,
          "description": "Emitted whenever a row append operation is requested. Append location can be set in callback."
        },
        {
          "name": "onRowMoved",
          "type": "((startIndex: number, endIndex: number) => void) | undefined",
          "required": false,
          "description": "Called whenever a row re-order operation is completed. Setting the callback enables re-ordering by dragging the\nfirst column of a row."
        },
        {
          "name": "onSearchClose",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Emitted when the search window close event is triggered."
        },
        {
          "name": "onSearchResultsChanged",
          "type": "((results: readonly Item[], navIndex: number) => void) | undefined",
          "required": false,
          "description": "Emitted whenever the search results for the current search field changes."
        },
        {
          "name": "onSearchValueChange",
          "type": "((newVal: string) => void) | undefined",
          "required": false,
          "description": "Emitted when the search value changes."
        },
        {
          "name": "onSelectionCleared",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Emitted when the grid selection is cleared."
        },
        {
          "name": "onVisibleRegionChanged",
          "type": "((range: Rectangle, tx: number, ty: number, extras: { selected?: Item | undefined; freezeRegion?: Rectangle | undefined; freezeRegions?: readonly Rectangle[] | undefined; }) => void) | undefined",
          "required": false,
          "description": "Emitted whenever the visible cells change, usually due to scrolling."
        },
        {
          "name": "overscrollX",
          "type": "number | undefined",
          "required": false,
          "description": "The overscroll properties are used to allow the grid to scroll past the logical end of the content by a fixed\nnumber of pixels. This is useful particularly on the X axis if you allow for resizing columns as it can make\nresizing the final column significantly easier."
        },
        {
          "name": "overscrollY",
          "type": "number | undefined",
          "required": false,
          "description": "{@inheritDoc overscrollX}"
        },
        {
          "name": "portalElementRef",
          "type": "React.RefObject<HTMLElement> | undefined",
          "required": false,
          "description": "Allows overriding the default portal element."
        },
        {
          "name": "preventDiagonalScrolling",
          "type": "boolean | undefined",
          "required": false,
          "description": "Set to true to prevent any diagonal scrolling."
        },
        {
          "name": "provideEditor",
          "type": "ProvideEditorCallback<GridCell> | undefined",
          "required": false,
          "description": "Callback for providing a custom editor for a cell."
        },
        {
          "name": "rangeSelect",
          "type": "\"cell\" | \"none\" | \"rect\" | \"multi-cell\" | \"multi-rect\" | undefined",
          "required": false,
          "description": "Controls if multi-selection is allowed. If disabled, shift/ctrl/command clicking will work as if no modifiers\nare pressed.\n\nWhen range select is set to cell, only one cell may be selected at a time. When set to rect one one rect at a\ntime. The multi variants allow for multiples of the rect or cell to be selected."
        },
        {
          "name": "rangeSelectionBlending",
          "type": "SelectionBlending | undefined",
          "required": false,
          "description": "Controls which types of selections can exist at the same time in the grid. If selection blending is set to\nexclusive, the grid will clear other types of selections when the exclusive selection is made. By default row,\ncolumn, and range selections are exclusive."
        },
        {
          "name": "rangeSelectionColumnSpanning",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls if range selection is allowed to span columns."
        },
        {
          "name": "resizeIndicator",
          "type": "\"header\" | \"full\" | \"none\" | undefined",
          "required": false,
          "description": "Controls the resize indicator behavior.\n\n- `full` will show the resize indicator on the full height.\n- `header` will show the resize indicator only on the header.\n- `none` will not show the resize indicator."
        },
        {
          "name": "rightElement",
          "type": "React.ReactNode",
          "required": false,
          "description": "The right element is a DOM node which can be inserted at the end of the horizontal scroll region. This can be\nused to create a right handle panel, make a big add button, or display messages."
        },
        {
          "name": "rightElementProps",
          "type": "{ readonly sticky?: boolean | undefined; readonly fill?: boolean | undefined; } | undefined",
          "required": false,
          "description": "If `rightElementProps.sticky` is set to true the right element will be visible at all times, otherwise the user\nwill need to scroll to the end to reveal it.\n\nIf `rightElementProps.fill` is set, the right elements container will fill to consume all remaining space (if\nany) at the end of the grid. This does not play nice with growing columns."
        },
        {
          "name": "rowGrouping",
          "type": "RowGroupingOptions | undefined",
          "required": false,
          "description": "Controls the grouping of rows to be drawn in the grid."
        },
        {
          "name": "rowHeight",
          "type": "number | ((index: number) => number) | undefined",
          "required": false,
          "description": "Determins the height of each row."
        },
        {
          "name": "rowMarkers",
          "type": "\"number\" | \"none\" | RowMarkerOptions | \"checkbox\" | \"clickable-number\" | \"checkbox-visible\" | \"both\" | undefined",
          "required": false,
          "description": "Determines if row markers should be automatically added to the grid.\nInteractive row markers allow the user to select a row.\n\n- \"clickable-number\" renders a number that can be clicked to\n select the row\n- \"both\" causes the row marker to show up as a number but\n reveal a checkbox when the marker is hovered."
        },
        {
          "name": "rowSelect",
          "type": "\"none\" | \"single\" | \"multi\" | undefined",
          "required": false,
          "description": "{@inheritDoc rangeSelect}"
        },
        {
          "name": "rowSelectionBlending",
          "type": "SelectionBlending | undefined",
          "required": false,
          "description": "{@inheritDoc rangeSelectionBlending}"
        },
        {
          "name": "rowSelectionMode",
          "type": "\"multi\" | \"auto\" | undefined",
          "required": false,
          "description": "Determines if row selection requires a modifier key to enable multi-selection or not. In auto mode it adapts to\ntouch or mouse environments automatically, in multi-mode it always acts as if the multi key (Ctrl) is pressed."
        },
        {
          "name": "scaleToRem",
          "type": "boolean | undefined",
          "required": false,
          "description": "Scales most elements in the theme to match rem scaling automatically"
        },
        {
          "name": "scrollOffsetX",
          "type": "number | undefined",
          "required": false,
          "description": "Sets the initial scroll X offset"
        },
        {
          "name": "scrollOffsetY",
          "type": "number | undefined",
          "required": false,
          "description": "Sets the initial scroll Y offset."
        },
        {
          "name": "scrollToActiveCell",
          "type": "boolean | undefined",
          "required": false,
          "description": "If set to true, the data grid will attempt to scroll to keep the selction in view"
        },
        {
          "name": "searchResults",
          "type": "readonly Item[] | undefined",
          "required": false,
          "description": "The search results to display. If not provided glide will use its own internal search provider."
        },
        {
          "name": "searchValue",
          "type": "string | undefined",
          "required": false,
          "description": "The current search value."
        },
        {
          "name": "showSearch",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls the visibility of the search overlay."
        },
        {
          "name": "smoothScrollX",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls smooth scrolling in the data grid. If smooth scrolling is not enabled the grid will always be cell\naligned."
        },
        {
          "name": "smoothScrollY",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls smooth scrolling in the data grid. If smooth scrolling is not enabled the grid will always be cell\naligned."
        },
        {
          "name": "spanAlign",
          "type": "SpanAlignment | undefined",
          "required": false,
          "description": "Выравнивание текста в объединённых ячейках шапки по умолчанию.\nМожно переопределить на колонке (`spanGroupHeaderAlign`) или на группе (`getGroupDetails().spanAlign`)."
        },
        {
          "name": "spanGroupHeader",
          "type": "boolean | undefined",
          "required": false,
          "description": "Grid-дефолт слитной шапки: включает `spanGroupHeader` у ВСЕХ листовых колонок (без\nгруппы) — не нужно ставить флаг на каждую. Точечно перекрывается на колонке\n(`spanGroupHeader: true/false`). Колонки с группой проп не трогает."
        },
        {
          "name": "spanRangeBehavior",
          "type": "\"default\" | \"allowPartial\" | undefined",
          "required": false,
          "description": "If set to `default`, `gridSelection` will be coerced to always include full spans."
        },
        {
          "name": "spanShallowGroups",
          "type": "boolean | undefined",
          "required": false,
          "description": "Объединяет (rowspan) пустые нижние ряды у «мелких» групп — тех, что заканчиваются\nвыше самого глубокого уровня групп, — в одну высокую ячейку вместо пустой полосы\nпод заголовком. Точечно на группе можно переопределить через `getGroupDetails().span`\n(поставить `false`, чтобы отключить для конкретной группы). Не задано → как раньше."
        },
        {
          "name": "trailingRowOptions",
          "type": "{ readonly tint?: boolean | undefined; readonly hint?: string | undefined; readonly sticky?: boolean | undefined; readonly addIcon?: string | undefined; readonly targetColumn?: number | GridColumn | undefined; } | undefined",
          "required": false,
          "description": "Controls the trailing row used to insert new data into the grid."
        },
        {
          "name": "trapFocus",
          "type": "boolean | undefined",
          "required": false,
          "description": "Controls if focus will trap inside the data grid when doing tab and caret navigation."
        },
        {
          "name": "validateCell",
          "type": "((cell: Item, newValue: EditableGridCell, prevValue: GridCell) => boolean | ValidatedGridCell) | undefined",
          "required": false,
          "description": "Used for validating cell values during editing."
        },
        {
          "name": "verticalBorder",
          "type": "boolean | ((col: number) => boolean) | undefined",
          "required": false,
          "description": "Controls the drawing of the left hand vertical border of a column. If set to a boolean value it controls all\nborders."
        },
        {
          "name": "drawCell",
          "type": "DrawCellCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "drawFocusRing",
          "type": "boolean | \"no-editor\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "freezeTrailingRows",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "imageWindowLoader",
          "type": "ImageWindowLoader | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onDragLeave",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onDragOverCell",
          "type": "((cell: Item, dataTransfer: DataTransfer | null) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "renderers",
          "type": "readonly InternalCellRenderer<InnerGridCell>[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "setScrollDir",
          "type": "((dir: readonly [xDir: 0 | 1 | -1, yDir: 0 | 1 | -1] | undefined) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rowMarkerStartIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Changes the starting index for row markers.",
          "deprecated": true
        },
        {
          "name": "rowMarkerTheme",
          "type": "Partial<Theme> | undefined",
          "required": false,
          "description": "Changes the theme of the row marker column",
          "deprecated": true
        },
        {
          "name": "rowMarkerWidth",
          "type": "number | undefined",
          "required": false,
          "description": "Sets the width of row markers in pixels, if unset row markers will automatically size.",
          "deprecated": true
        }
      ],
      "propsTypeName": "ComponentProps<typeof DataEditor>",
      "sourceFile": "node_modules/@glideappsfinal/glide-data-grid/dist/dts/data-editor-all.d.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "glide data grid",
        "canvas-грид",
        "кастомная таблица"
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "CanvasContainer",
        "CanvasNode",
        "CanvasBadge",
        "CanvasButton",
        "CanvasEmbedIconButton",
        "CanvasIcon",
        "CanvasIconButton",
        "CanvasRect",
        "CanvasText",
        "CanvasLink",
        "Canvas",
        "RootBridge"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { DataEditor } from '@daisforge/ui';",
      "minimalUsage": "<DataEditor columns={[]} getCellContent={() => {}} />",
      "examples": []
    },
    "TableSDDS": {
      "name": "TableSDDS",
      "group": "components",
      "folderName": "TableSDDS",
      "role": "primary",
      "description": "Базовая таблица дизайн-системы: сортировка, фильтры, выбор строк без логики ui-kit.",
      "props": [],
      "propsTypeName": "TableSDDSProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Table/Table.d.ts",
      "type": "wrapper",
      "atomicBase": "Table",
      "category": "Локальные компоненты",
      "keywords": [
        "sdds таблица",
        "простая таблица",
        "атомарная таблица"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "columns",
          "type": "TableColumnData[]",
          "required": true,
          "description": "Настройка колонок",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "data",
          "type": "TableRowData[]",
          "required": true,
          "description": "Основной контент",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "borderVariant",
          "type": "\"all\" | \"header\" | \"rows\"",
          "required": false,
          "description": "Вариант отображения border",
          "default": "all",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "bottomContent",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента под таблицей.",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "classNames",
          "type": "{ root?: string; table?: string; header?: { wrapper?: string | undefined; row?: string | undefined; cell?: string | undefined; } | undefined; body?: { wrapper?: string | undefined; row?: string | undefined; cell?: string | undefined; } | undefined; } | undefined",
          "required": false,
          "description": "Возможность указать className для различных семантических узлов внутри компонента.",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "enableSelection",
          "type": "boolean",
          "required": false,
          "description": "Включение функционала выбора строк",
          "default": "false",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "filtered",
          "type": "{ id: string; value: unknown; }[]",
          "required": false,
          "description": "Состояние параметров фильтрации",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "loadingSlot",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для лоадинга под контентом.",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maxHeight",
          "type": "MaxHeight<string | number>",
          "required": false,
          "description": "Максимальная высота таблицы",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onCellUpdate",
          "type": "((rowId: string, columnId: string, value: unknown) => void)",
          "required": false,
          "description": "Обработчик обновления контента ячейки",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "((data: { selected: RowSelectionState; filtered: { id: string; value: unknown; }[]; sorted: { id: string; desc: boolean; }[] | undefined; }) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения состояния",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onScroll",
          "type": "((e: UIEvent<HTMLElement, UIEvent>) => void)",
          "required": false,
          "description": "Обработчик сколла контента.",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "selected",
          "type": "RowSelectionState",
          "required": false,
          "description": "Состояние параметров выбранных строк",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "setRowProps",
          "type": "((row: TableRowData) => HTMLAttributes<any> & ThHTMLAttributes<any>)",
          "required": false,
          "description": "Сеттер свойств для строки",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\"",
          "required": false,
          "description": "Размер таблицы",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "sorted",
          "type": "{ id: string; desc: boolean; }[]",
          "required": false,
          "description": "Состояние параметров сортировки",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stickyHeader",
          "type": "boolean",
          "required": false,
          "description": "Прилипание шапки при скролле",
          "default": "false",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "topContent",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента над таблицей.",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\"",
          "required": false,
          "description": "Внешний вид таблицы",
          "inheritedFrom": "Table",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TableSDDS } from '@daisforge/ui';",
      "minimalUsage": "<TableSDDS columns={[]} data={[]} />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Быстрый старт",
          "type": "vendor",
          "code": "export function App() {\n    const data = [\n        {\n            id: '0',\n            country: 'Канада',\n            capital: 'Оттава',\n            population: 38,\n        },\n        {\n            id: '1',\n            country: 'Бразилия',\n            capital: 'Бразилиа',\n            population: 213,\n        },\n        {\n            id: '2',\n            country: 'Германия',\n            capital: 'Берлин',\n            population: 83,\n        },\n    ];\n    const columns = [\n        {\n            id: 'country',\n            label: 'Страна',\n        },\n        {\n            id: 'capital',\n            label: 'Столица',\n        },\n        {\n            id: 'population',\n            label: 'Население, млн',\n        },\n    ];\n    return (\n        <Table data={data} columns={columns} />\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Примеры Примеры Свойство  renderCell  нужно для настройки кастомного отображения ячейки.  Это render-prop, который в параметрах принимает значение ячейки  value , объект строки, к которой принадлежит ячейка  row  и индекс этой строки  rowIndex .",
          "type": "vendor",
          "code": "export function App() {\n    const data = [\n        {\n            id: '0',\n            country: 'Канада',\n            capital: 'Оттава',\n            population: 38,\n        },\n        {\n            id: '1',\n            country: 'Бразилия',\n            capital: 'Бразилиа',\n            population: 213,\n        },\n        {\n            id: '2',\n            country: 'Германия',\n            capital: 'Берлин',\n            population: 83,\n        },\n    ];\n    const columns = [\n        {\n            id: 'country',\n            label: 'Страна',\n            renderCell: (value, { id }) => {\n                return <div style={{ background: 'lightblue' }}>{value}</div>\n            },\n        },\n        {\n            id: 'capital',\n            label: 'Столица',\n            renderCell: () => {\n                return <LineSkeleton />\n            },\n        },\n        {\n            id: 'population',\n            label: 'Население, млн',\n        },\n    ];\n    return (\n        <Table data={data} columns={columns} />\n    );\n}"
        }
      ]
    },
    "TableTabs": {
      "name": "TableTabs",
      "group": "components",
      "folderName": "TableTabs",
      "role": "primary",
      "description": "Вкладки над таблицей для переключения между разными наборами табличных данных.",
      "props": [
        {
          "name": "tabs",
          "type": "TCustomOrNotTab<T>[]",
          "required": true,
          "description": "Массив конфигураций табов"
        },
        {
          "name": "activeTabIdState",
          "type": "[T, ((newV: T) => void) | ((oldV: T) => T)] | undefined",
          "required": false,
          "description": "Контролируемое состояние активного таба [activeId, setActiveId]"
        },
        {
          "name": "collapsing",
          "type": "TableTabsCollapseConfig | undefined",
          "required": false,
          "description": "Конфигурация коллапсинга над табами.\nПри активации скругление верхних углов переходит на блок коллапсинга, у табов убирается."
        },
        {
          "name": "rightSlot",
          "type": "React.ReactNode",
          "required": false,
          "description": "Кастомный слот справа от табов (прижат к правому краю)"
        },
        {
          "name": "tabsAndPanelsContainerCss",
          "type": "string | CSSObject | undefined",
          "required": false,
          "description": "CSS для контейнера табов и панелей"
        },
        {
          "name": "tabsContainerOptions",
          "type": "TTabsContainerOptions | undefined",
          "required": false,
          "description": "Опции контейнера табов (maxWidth)"
        },
        {
          "name": "tabsProps",
          "type": "TabsProps | undefined",
          "required": false,
          "description": "Пропсы для компонента Tabs (size, view и др.)"
        }
      ],
      "propsTypeName": "TableTabsProps",
      "rawType": "export type TableTabsProps<T extends TabId = TabId> = PropsWithChildren & {\n  /** Массив конфигураций табов */\n  tabs: TCustomOrNotTab<T>[];\n  /** Контролируемое состояние активного таба [activeId, setActiveId] */\n  activeTabIdState?: [T, ((newV: T) => void) | ((oldV: T) => T)];\n  /** Пропсы для компонента Tabs (size, view и др.) */\n  tabsProps?: TTabsProps;\n  /** CSS для контейнера табов и панелей */\n  tabsAndPanelsContainerCss?: string | CSSObject;\n  /** Опции контейнера табов (maxWidth) */\n  tabsContainerOptions?: TTabsContainerOptions;\n  /** Кастомный слот справа от табов (прижат к правому краю) */\n  rightSlot?: ReactNode;\n  /**\n   * Размер табов.\n   * @default 'm'\n   */\n  size?: TableTabsSize;\n  /**\n   * Конфигурация коллапсинга над табами.\n   * При активации скругление верхних углов переходит на блок коллапсинга, у табов убирается.\n   */\n  collapsing?: TableTabsCollapseConfig;\n};",
      "isGeneric": true,
      "compoundParts": [
        {
          "name": "TabPanel",
          "typeName": "TabPanelProps",
          "rawType": "export type TabPanelProps<T extends TabId = TabId> = {\n  /** Идентификатор таба (должен совпадать с tabId в массиве tabs) */\n  tabId: T;\n  /**\n   * Размонтировать контент при переключении на другой таб\n   * @default true\n   */\n  unmountOnClose?: boolean;\n} & BoxProps;",
          "props": [
            {
              "name": "tabId",
              "type": "T",
              "required": true,
              "description": "Идентификатор таба (должен совпадать с tabId в массиве tabs)"
            },
            {
              "name": "unmountOnClose",
              "type": "boolean | undefined",
              "required": false,
              "description": "Размонтировать контент при переключении на другой таб",
              "default": "true"
            },
            {
              "name": "$css",
              "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
              "required": false,
              "description": "Кастомные стили styled-components для Box-контейнера"
            },
            {
              "name": "as",
              "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"header\" | \"rect\" | \"slot\" | \"style\" | \"title\" | \"article\" | \"button\" | \"dialog\" | \"figure\" | \"form\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"search\" | \"switch\" | \"table\" | \"text\" | \"time\" | \"view\" | \"s\" | \"h6\" | \"h5\" | \"h4\" | \"h3\" | \"h2\" | \"h1\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" …",
              "required": false,
              "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
            },
            {
              "name": "background",
              "type": "Property.Background<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "backgroundColor",
              "type": "Property.BackgroundColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "border",
              "type": "Property.Border<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderColor",
              "type": "Property.BorderColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderRadius",
              "type": "Property.BorderRadius<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
            },
            {
              "name": "borderStyle",
              "type": "Property.BorderStyle | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderWidth",
              "type": "Property.BorderWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "bottom",
              "type": "Property.Bottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "boxSizing",
              "type": "Property.BoxSizing | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
            },
            {
              "name": "cursor",
              "type": "Property.Cursor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
            },
            {
              "name": "display",
              "type": "Property.Display | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "flexDirection",
              "type": "Property.FlexDirection | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
            },
            {
              "name": "flexGrow",
              "type": "Property.FlexGrow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
            },
            {
              "name": "flexShrink",
              "type": "Property.FlexShrink | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
            },
            {
              "name": "flexWrap",
              "type": "Property.FlexWrap | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "gap",
              "type": "Property.Gap<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
            },
            {
              "name": "height",
              "type": "Property.Height<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "justifyContent",
              "type": "Property.JustifyContent | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "justifyItems",
              "type": "Property.JustifyItems | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
            },
            {
              "name": "justifySelf",
              "type": "Property.JustifySelf | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
            },
            {
              "name": "left",
              "type": "Property.Left<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "margin",
              "type": "Property.Margin<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginBottom",
              "type": "Property.MarginBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginLeft",
              "type": "Property.MarginLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginRight",
              "type": "Property.MarginRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginTop",
              "type": "Property.MarginTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "maxHeight",
              "type": "Property.MaxHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "maxWidth",
              "type": "Property.MaxWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "minHeight",
              "type": "Property.MinHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "minWidth",
              "type": "Property.MinWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "opacity",
              "type": "Property.Opacity | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
            },
            {
              "name": "overflow",
              "type": "Property.Overflow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "padding",
              "type": "Property.Padding<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingBottom",
              "type": "Property.PaddingBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingLeft",
              "type": "Property.PaddingLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingRight",
              "type": "Property.PaddingRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingTop",
              "type": "Property.PaddingTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "position",
              "type": "Property.Position | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "right",
              "type": "Property.Right<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "top",
              "type": "Property.Top<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "width",
              "type": "Property.Width<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "zIndex",
              "type": "Property.ZIndex | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            }
          ],
          "isGeneric": true
        }
      ],
      "sourceFile": "packages/ui-kit/src/components/TableTabs/TableTabs.tsx",
      "type": "standalone",
      "atomicBase": "Tabs",
      "wrapsInternal": "Tabs",
      "category": "Локальные компоненты",
      "hint": "Не путать с TableCanvas — это вкладки для переключения между таблицами.",
      "keywords": [
        "табы для таблиц",
        "переключение датасетов",
        "tabs panel"
      ],
      "docs": "# TableTabs\n\nКомпонент для организации нескольких таблиц (или произвольного контента) в табах. Работает как с `Table`, так и с `TableCanvas` — или с обоими одновременно.\n\n## Основные возможности\n\n- Единый контекст табов для `Table` и `TableCanvas`\n- Поддержка контролируемого и неконтролируемого режимов (`activeTabIdState`)\n- Кастомные табы через `custom` поле\n- `TabPanel` с возможностью unmount/hide при переключении\n- Автоматическое скрытие скругления `ControlBlock` у таблиц внутри табов\n- Опциональное ограничение ширины контейнера табов (`tabsContainerOptions.maxWidth`)\n\n## Использование\n\n```tsx\n\n```\n\nИли из корневого экспорта:\n\n```tsx\n\n```\n\n## Базовый пример\n\n```tsx\nconst [activeTabId, setActiveTabId] = useState('tab1');\n\n<TableTabs\n  activeTabIdState={[activeTabId, setActiveTabId]}\n  tabs={[\n    { tabId: 'tab1', label: 'Первый таб' },\n    { tabId: 'tab2', label: 'Второй таб' },\n  ]}\n>\n  <TableTabs.TabPanel tabId=\"tab1\">\n    <Table tableConfig={...} columnConfig={...} rows={...} />\n  </TableTabs.TabPanel>\n  <TableTabs.TabPanel tabId=\"tab2\">\n    <TableCanvas tableConfig={...} columnConfig={...} rows={...} />\n  </TableTabs.TabPanel>\n</TableTabs>\n```\n\n## Размер\n\n`size` задаёт размер табов: `m`, `s` или `xs`. На `xs` уменьшаются и сами вкладки, и кнопка сворачивания над ними. Удобно вместе с `controlBlock.size: 'xs'` у таблицы внутри.\n\n## Слот справа\n\n`rightSlot` рисует свой контент справа от ряда табов: бейдж, кнопку, статус и подобное.\n\n## Сворачивание над табами\n\n`collapsing` добавляет над табами строку с кнопкой свернуть и развернуть таблицу. У неё свой `rightSlot` под контент справа от кнопки.\n\n```tsx\n<TableTabs\n  size=\"xs\"\n  rightSlot={<Badge text=\"Online\" />}\n  collapsing={{\n    enabled: true,\n    collapseText: 'Свернуть таблицу',\n    expandText: 'Развернуть таблицу',\n    rightSlot: <Badge view=\"warning\" text=\"3 новых\" />,\n  }}\n  tabs={[\n    { tabId: 'tab1', label: 'Основная' },\n    { tabId: 'tab2', label: 'Архив' },\n  ]}\n>\n  ...\n</TableTabs>\n```\n\n## TabPanel\n\n`TableTabs.TabPanel` — дочерний компонент для содержимого каждого таба.\n\n- `tabId` — идентификатор таба (должен совпадать с `tabId` в массиве `tabs`)\n- `unmountOnClose` — если `true` (по умолчанию), контент размонтируется при переключении. Если `false` — скрывается через `display: none`",
      "apiDocs": "# TableTabs API\n\n## TableTabsProps\n\n```typescript\ntype TableTabsProps<T extends TabId = TabId> = PropsWithChildren & {\n  /** Массив конфигураций табов */\n  tabs: TCustomOrNotTab<T>[];\n  /** Контролируемое состояние активного таба [activeId, setActiveId] */\n  activeTabIdState?: [T, ((newV: T) => void) | ((oldV: T) => T)];\n  /** Пропсы для компонента Tabs (size, view и др.) */\n  tabsProps?: TTabsProps;\n  /** CSS для контейнера табов и панелей */\n  tabsAndPanelsContainerCss?: string | CSSObject;\n  /** Опции контейнера табов (maxWidth) */\n  tabsContainerOptions?: TTabsContainerOptions;\n  /** Кастомный слот справа от табов (прижат к правому краю) */\n  rightSlot?: ReactNode;\n  /**\n   * Размер табов.\n   * @default 'm'\n   */\n  size?: TableTabsSize;\n  /**\n   * Конфигурация коллапсинга над табами.\n   * При активации скругление верхних углов переходит на блок коллапсинга, у табов убирается.\n   */\n  collapsing?: TableTabsCollapseConfig;\n};\n```\n\n## TabPanelProps\n\n```typescript\ntype TabPanelProps<T extends TabId = TabId> = {\n  /** Идентификатор таба (должен совпадать с tabId в массиве tabs) */\n  tabId: T;\n  /**\n   * Размонтировать контент при переключении на другой таб\n   * @default true\n   */\n  unmountOnClose?: boolean;\n} & BoxProps;\n```\n\n## TabId\n\n```typescript\ntype TabId = string | number;\n```\n\n## TCustomOrNotTab\n\n```typescript\ntype TCustomOrNotTab<T extends TabId> = TTabItem<T> | TCustomTabItem<T>;\n```\n\n## TTabItem\n\n```typescript\ntype TTabItem<T extends TabId> = {\n  tabId: T;\n  label: ReactNode;\n} & ComponentProps<typeof TabItem>;\n```\n\n## TCustomTabItem\n\n```typescript\ntype TCustomTabItem<T extends TabId> = { tabId: T; custom: ReactNode };\n```\n\n## TTabsProps\n\n```typescript\ntype TTabsProps = ComponentProps<typeof Tabs>;\n```\n\n## TTabsContainerOptions\n\n```typescript\ntype TTabsContainerOptions = {\n  /**\n   * Максимальная ширина контейнера табов.\n   * Если установлено, контейнер будет иметь ограничение ширины и стрелки прокрутки при переполнении.\n   * Может быть числом (пиксели) или строкой (CSS значение, например '250px', '50%').\n   * Если не указано, ограничения ширины не будет.\n   */\n  maxWidth?: number | string;\n};\n```",
      "curatedStories": [
        {
          "exportName": "BasicWithTable",
          "displayName": "Table в табах",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'complete', name: '% Complete' },\n      ],\n      [],\n    );\n\n    const [activeTabId, setActiveTabId] = useState('1');\n\n    return (\n      <TableTabs\n        activeTabIdState={[activeTabId, setActiveTabId]}\n        tabs={[\n          { tabId: '1', label: 'Таб 1' },\n          { tabId: '2', label: 'Таб 2' },\n          { tabId: '3', label: 'Скелетон' },\n        ]}\n      >\n        <TableTabs.TabPanel tabId=\"1\">\n          <Table\n            tableConfig={{ containerStyle: { height: 700 } }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"2\">\n          <Table\n            tableConfig={{ containerStyle: { height: 700 } }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"3\">\n          <RectSkeleton width=\"100%\" height={600} />\n        </TableTabs.TabPanel>\n      </TableTabs>\n    );\n  }"
        },
        {
          "exportName": "BasicWithTableCanvas",
          "displayName": "TableCanvas в табах",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly CanvasColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'developer', name: 'Developer' },\n      ],\n      [],\n    );\n\n    const [activeTabId, setActiveTabId] = useState('1');\n\n    return (\n      <TableTabs\n        activeTabIdState={[activeTabId, setActiveTabId]}\n        tabs={[\n          { tabId: '1', label: 'Таб 1' },\n          { tabId: '2', label: 'Таб 2' },\n          { tabId: '3', label: 'Скелетон' },\n        ]}\n      >\n        <TableTabs.TabPanel tabId=\"1\">\n          <TableCanvas\n            tableConfig={{\n              containerStyle: { height: 700 },\n              fullScreenEnabled: true,\n            }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"2\">\n          <TableCanvas\n            tableConfig={{\n              containerStyle: { height: 700 },\n              fullScreenEnabled: true,\n            }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"3\">\n          <RectSkeleton width=\"100%\" height={600} />\n        </TableTabs.TabPanel>\n      </TableTabs>\n    );\n  }"
        },
        {
          "exportName": "FillAvailableHeightWithTableCanvas",
          "displayName": "TableCanvas без заданого статичного размера, на доступную высоту",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly CanvasColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID', width: 90 },\n        { key: 'task', name: 'Title', width: 280 },\n        { key: 'priority', name: 'Priority', width: 160 },\n        { key: 'issueType', name: 'Issue Type', width: 160 },\n        { key: 'developer', name: 'Developer' },\n      ],\n      [],\n    );\n\n    const [activeTabId, setActiveTabId] = useState('all');\n\n    return (\n      <div\n        style={{\n          height: 760,\n          padding: 24,\n          boxSizing: 'border-box',\n          display: 'flex',\n          flexDirection: 'column',\n          gap: 16,\n          minHeight: 0,\n          background: surfaceInfo,\n        }}\n      >\n        <div\n          style={{\n            flexShrink: 0,\n            display: 'flex',\n            flexDirection: 'column',\n            gap: 8,\n          }}\n        >\n          <div\n            style={{\n              fontSize: 28,\n              fontWeight: 600,\n              lineHeight: '36px',\n              color: surfaceSolidCard,\n            }}\n          >\n            Реестр документов\n          </div>\n          <div\n            style={{\n              fontSize: 14,\n              lineHeight: '20px',\n              color: surfaceSolidCard,\n            }}\n          >\n            Пример композиции, в которой TableTabs занимает доступную высоту\n            страницы, а TableCanvas и sidebar остаются внутри своей области.\n          </div>\n        </div>\n\n        <TableTabs\n          activeTabIdState={[activeTabId, setActiveTabId]}\n          tabs={[\n            { tabId: 'all', label: 'Все документы' },\n            { tabId: 'drafts', label: 'Черновики' },\n          ]}\n          tabsAndPanelsContainerCss={{\n            display: 'flex',\n            flexDirection: 'column',\n            flex: 1,\n            minHeight: 0,\n            minWidth: 0,\n            width: '100%',\n            '& .rdg__tabs-container': {\n              flexShrink: 0,\n            },\n            '& .rdg__tab-panel': {\n              display: 'flex',\n              flexDirection: 'column',\n              flex: 1,\n              minHeight: 0,\n              minWidth: 0,\n              width: '100%',\n              overflow: 'hidden',\n            },\n          }}\n        >\n          <TableTabs.TabPanel tabId=\"all\" unmountOnClose={false}>\n            <TableCanvas\n              tableConfig={{\n                containerStyle: { height: '100%' },\n                fullScreenEnabled: true,\n                columnsControl: {\n                  enable: true,\n                },\n              }}\n              columnConfig={columnConfig}\n              rows={rows}\n            />\n          </TableTabs.TabPanel>\n\n          <TableTabs.TabPanel tabId=\"drafts\" unmountOnClose={false}>\n            <TableCanvas\n              tableConfig={{\n                containerStyle: { height: '100%' },\n                fullScreenEnabled: true,\n                columnsControl: {\n                  enable: true,\n                },\n              }}\n              columnConfig={columnConfig}\n              rows={rows.slice(0, 40)}\n            />\n          </TableTabs.TabPanel>\n        </TableTabs>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "MixedTableAndCanvas",
          "displayName": "Table + TableCanvas",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'complete', name: '% Complete' },\n      ],\n      [],\n    );\n\n    const canvasColumnConfig = useMemo<readonly CanvasColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'developer', name: 'Developer' },\n      ],\n      [],\n    );\n\n    const [activeTabId, setActiveTabId] = useState('table');\n\n    return (\n      <TableTabs\n        activeTabIdState={[activeTabId, setActiveTabId]}\n        tabs={[\n          { tabId: 'table', label: 'Table (обычная)' },\n          { tabId: 'canvas', label: 'TableCanvas (канвасная)' },\n        ]}\n      >\n        <TableTabs.TabPanel tabId=\"table\">\n          <Table\n            tableConfig={{\n              containerStyle: { height: 700 },\n              fullScreenEnabled: true,\n            }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"canvas\">\n          <TableCanvas\n            tableConfig={{\n              containerStyle: { height: 700 },\n              fullScreenEnabled: true,\n            }}\n            columnConfig={canvasColumnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"canvas1\">\n          <div>test</div>\n        </TableTabs.TabPanel>\n      </TableTabs>\n    );\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "size",
          "type": "\"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"s\" | \"l\" | \"m\" | \"xs\"",
          "required": false,
          "description": "Размер табов.",
          "default": "'m'",
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "clip",
          "type": "\"scroll\" | \"showAll\"",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dividerAlign",
          "type": "\"right\" | \"left\"",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasDivider",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "index",
          "type": "number",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\"",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "outsideScroll",
          "type": "boolean | { left?: string; right?: string; } | undefined",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pilled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"filled\" | \"divider\"",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TableTabs } from '@daisforge/ui';",
      "minimalUsage": "<TableTabs tabs={[]}>\n  {/* части: TableTabs.TabPanel */}\n</TableTabs>",
      "examples": [
        {
          "exportName": "BasicWithTable",
          "displayName": "Table в табах",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'complete', name: '% Complete' },\n      ],\n      [],\n    );\n\n    const [activeTabId, setActiveTabId] = useState('1');\n\n    return (\n      <TableTabs\n        activeTabIdState={[activeTabId, setActiveTabId]}\n        tabs={[\n          { tabId: '1', label: 'Таб 1' },\n          { tabId: '2', label: 'Таб 2' },\n          { tabId: '3', label: 'Скелетон' },\n        ]}\n      >\n        <TableTabs.TabPanel tabId=\"1\">\n          <Table\n            tableConfig={{ containerStyle: { height: 700 } }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"2\">\n          <Table\n            tableConfig={{ containerStyle: { height: 700 } }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"3\">\n          <RectSkeleton width=\"100%\" height={600} />\n        </TableTabs.TabPanel>\n      </TableTabs>\n    );\n  }"
        },
        {
          "exportName": "BasicWithTableCanvas",
          "displayName": "TableCanvas в табах",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly CanvasColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'developer', name: 'Developer' },\n      ],\n      [],\n    );\n\n    const [activeTabId, setActiveTabId] = useState('1');\n\n    return (\n      <TableTabs\n        activeTabIdState={[activeTabId, setActiveTabId]}\n        tabs={[\n          { tabId: '1', label: 'Таб 1' },\n          { tabId: '2', label: 'Таб 2' },\n          { tabId: '3', label: 'Скелетон' },\n        ]}\n      >\n        <TableTabs.TabPanel tabId=\"1\">\n          <TableCanvas\n            tableConfig={{\n              containerStyle: { height: 700 },\n              fullScreenEnabled: true,\n            }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"2\">\n          <TableCanvas\n            tableConfig={{\n              containerStyle: { height: 700 },\n              fullScreenEnabled: true,\n            }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"3\">\n          <RectSkeleton width=\"100%\" height={600} />\n        </TableTabs.TabPanel>\n      </TableTabs>\n    );\n  }"
        },
        {
          "exportName": "FillAvailableHeightWithTableCanvas",
          "displayName": "TableCanvas без заданого статичного размера, на доступную высоту",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly CanvasColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID', width: 90 },\n        { key: 'task', name: 'Title', width: 280 },\n        { key: 'priority', name: 'Priority', width: 160 },\n        { key: 'issueType', name: 'Issue Type', width: 160 },\n        { key: 'developer', name: 'Developer' },\n      ],\n      [],\n    );\n\n    const [activeTabId, setActiveTabId] = useState('all');\n\n    return (\n      <div\n        style={{\n          height: 760,\n          padding: 24,\n          boxSizing: 'border-box',\n          display: 'flex',\n          flexDirection: 'column',\n          gap: 16,\n          minHeight: 0,\n          background: surfaceInfo,\n        }}\n      >\n        <div\n          style={{\n            flexShrink: 0,\n            display: 'flex',\n            flexDirection: 'column',\n            gap: 8,\n          }}\n        >\n          <div\n            style={{\n              fontSize: 28,\n              fontWeight: 600,\n              lineHeight: '36px',\n              color: surfaceSolidCard,\n            }}\n          >\n            Реестр документов\n          </div>\n          <div\n            style={{\n              fontSize: 14,\n              lineHeight: '20px',\n              color: surfaceSolidCard,\n            }}\n          >\n            Пример композиции, в которой TableTabs занимает доступную высоту\n            страницы, а TableCanvas и sidebar остаются внутри своей области.\n          </div>\n        </div>\n\n        <TableTabs\n          activeTabIdState={[activeTabId, setActiveTabId]}\n          tabs={[\n            { tabId: 'all', label: 'Все документы' },\n            { tabId: 'drafts', label: 'Черновики' },\n          ]}\n          tabsAndPanelsContainerCss={{\n            display: 'flex',\n            flexDirection: 'column',\n            flex: 1,\n            minHeight: 0,\n            minWidth: 0,\n            width: '100%',\n            '& .rdg__tabs-container': {\n              flexShrink: 0,\n            },\n            '& .rdg__tab-panel': {\n              display: 'flex',\n              flexDirection: 'column',\n              flex: 1,\n              minHeight: 0,\n              minWidth: 0,\n              width: '100%',\n              overflow: 'hidden',\n            },\n          }}\n        >\n          <TableTabs.TabPanel tabId=\"all\" unmountOnClose={false}>\n            <TableCanvas\n              tableConfig={{\n                containerStyle: { height: '100%' },\n                fullScreenEnabled: true,\n                columnsControl: {\n                  enable: true,\n                },\n              }}\n              columnConfig={columnConfig}\n              rows={rows}\n            />\n          </TableTabs.TabPanel>\n\n          <TableTabs.TabPanel tabId=\"drafts\" unmountOnClose={false}>\n            <TableCanvas\n              tableConfig={{\n                containerStyle: { height: '100%' },\n                fullScreenEnabled: true,\n                columnsControl: {\n                  enable: true,\n                },\n              }}\n              columnConfig={columnConfig}\n              rows={rows.slice(0, 40)}\n            />\n          </TableTabs.TabPanel>\n        </TableTabs>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "MixedTableAndCanvas",
          "displayName": "Table + TableCanvas",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'complete', name: '% Complete' },\n      ],\n      [],\n    );\n\n    const canvasColumnConfig = useMemo<readonly CanvasColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'developer', name: 'Developer' },\n      ],\n      [],\n    );\n\n    const [activeTabId, setActiveTabId] = useState('table');\n\n    return (\n      <TableTabs\n        activeTabIdState={[activeTabId, setActiveTabId]}\n        tabs={[\n          { tabId: 'table', label: 'Table (обычная)' },\n          { tabId: 'canvas', label: 'TableCanvas (канвасная)' },\n        ]}\n      >\n        <TableTabs.TabPanel tabId=\"table\">\n          <Table\n            tableConfig={{\n              containerStyle: { height: 700 },\n              fullScreenEnabled: true,\n            }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"canvas\">\n          <TableCanvas\n            tableConfig={{\n              containerStyle: { height: 700 },\n              fullScreenEnabled: true,\n            }}\n            columnConfig={canvasColumnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"canvas1\">\n          <div>test</div>\n        </TableTabs.TabPanel>\n      </TableTabs>\n    );\n  }"
        }
      ]
    },
    "IconTabItem": {
      "name": "IconTabItem",
      "group": "components",
      "folderName": "Tabs",
      "role": "primary",
      "description": "Элемент вкладки с иконкой без текста — для компактных панелей табов.",
      "props": [
        {
          "name": "size",
          "type": "\"xs\" | \"s\" | \"m\" | \"l\" | \"h6\" | \"h5\" | \"h4\" | \"h3\" | \"h2\" | \"h1\" | undefined",
          "required": false,
          "description": "Размер TabItem"
        },
        {
          "name": "view",
          "type": "\"default\" | \"clear\" | \"secondary\" | \"divider\" | undefined",
          "required": false,
          "description": "Вид TabItem"
        },
        {
          "name": "actionContent",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для интерактивных элементов (крестик)"
        },
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "disableScroll",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отключает скролл к TabItem при его выборе",
          "default": "false"
        },
        {
          "name": "itemIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Индекс TabItem внутри Tabs - необходим для клавиатурной навигации"
        },
        {
          "name": "onIndexChange",
          "type": "((index: number) => void) | undefined",
          "required": false,
          "description": "Callback, необходимый для клавиатурной навигации"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\" | undefined",
          "required": false,
          "description": "Расположение табов"
        },
        {
          "name": "type",
          "type": "\"button\" | \"submit\" | \"reset\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "IconTabItemProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Tabs/TabItem.d.ts",
      "type": "wrapper",
      "atomicBase": "IconTabItem",
      "category": "Локальные компоненты",
      "keywords": [
        "иконка вкладки",
        "compact tabs",
        "tab с иконкой"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { IconTabItem } from '@daisforge/ui';",
      "minimalUsage": "<IconTabItem />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в SplitView.stories.tsx",
          "type": "usage",
          "code": "<IconTabItem\n                      key={`tab:${id}`}\n                      selected={i === activeTab}\n                      onClick={() => setActiveTab(i)}\n                      orientation=\"vertical\"\n                      view=\"divider\"\n                      size=\"s\"\n                      tabIndex={0}\n                      style={{ padding: `${s.x4} 10px ${s.x3} 10px` }}\n                    >\n                      <IconPlasma color=\"inherit\" />\n                    </IconTabItem>",
          "sourceFile": "packages/storybook/src/stories/SplitView/SplitView.stories.tsx"
        },
        {
          "exportName": "Vendor",
          "displayName": "Расположение divider у вертикальных Tabs",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { Tabs, IconTabItem } from '@daisforge/ui';\nimport { IconClock } from '@salutejs/plasma-icons';\nexport function App() {\n    const items = Array(4).fill(0);\n    const [leftIndex, setLeftIndex] = useState(0);\n    const [rightIndex, setRightIndex] = useState(0);\n    return (\n        <div style={{ display: 'flex', gap: '2rem' }}>\n            <Tabs view=\"divider\" orientation=\"vertical\" dividerAlign=\"left\" size=\"xs\" style={{ width: '15rem' }}>\n                {items.map((_, i) => (\n                    <IconTabItem\n                        view=\"divider\"\n                        orientation=\"vertical\"\n                        key={`item:${i}`}\n                        size=\"xs\"\n                        selected={i === leftIndex}\n                        tabIndex={0}\n                        onClick={() => setLeftIndex(i)}\n                    >\n                        <IconClock size=\"xs\" color=\"inherit\" />\n                    </IconTabItem>\n                ))}\n            </Tabs>\n            <Tabs view=\"divider\" orientation=\"vertical\" dividerAlign=\"right\" size=\"xs\" style={{ width: '15rem' }}>\n                {items.map((_, i) => (\n                    <IconTabItem\n                        view=\"divider\"\n                        orientation=\"vertical\"\n                        key={`item:${i}`}\n                        size=\"xs\"\n                        selected={i === rightIndex}\n                        tabIndex={0}\n                        onClick={() => setRightIndex(i)}\n                    >\n                        <IconClock size=\"xs\" color=\"inherit\" />\n                    </IconTabItem>\n                ))}\n            </Tabs>\n        </div>\n    );\n}"
        }
      ]
    },
    "TabItem": {
      "name": "TabItem",
      "group": "components",
      "folderName": "Tabs",
      "role": "primary",
      "description": "Одна вкладка внутри компонента Tabs — используется только как его дочерний элемент.",
      "props": [
        {
          "name": "actionContent",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для интерактивных элементов (крестик)"
        },
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": "Контент справа"
        },
        {
          "name": "disableScroll",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отключает скролл к TabItem при его выборе",
          "default": "false"
        },
        {
          "name": "itemIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Индекс TabItem внутри Tabs - необходим для клавиатурной навигации"
        },
        {
          "name": "maxItemWidth",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "Обрезает контент по максимальной ширине и добавляет ...",
          "default": "'auto'"
        },
        {
          "name": "onIndexChange",
          "type": "((index: number) => void) | undefined",
          "required": false,
          "description": "Callback, необходимый для клавиатурной навигации"
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pilled",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"xs\" | \"s\" | \"m\" | \"l\" | \"h6\" | \"h5\" | \"h4\" | \"h3\" | \"h2\" | \"h1\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "truncate",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "value",
          "type": "string | number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"clear\" | \"secondary\" | \"divider\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"button\" | \"submit\" | \"reset\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TabItemProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Tabs/TabItem.d.ts",
      "type": "wrapper",
      "atomicBase": "TabItem",
      "category": "Локальные компоненты",
      "keywords": [
        "элемент вкладки",
        "tab item",
        "пункт табов"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { TabItem } from '@daisforge/ui';",
      "minimalUsage": "<TabItem />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в Tabs.tsx",
          "type": "usage",
          "code": "<TabItem\n            view=\"divider\"\n            // eslint-disable-next-line react/no-array-index-key\n            key={`item:${i}`}\n            size=\"m\"\n            itemIndex={i}\n            onIndexChange={(i) => setIndex(i)}\n            selected={i === index}\n            tabIndex={0}\n            onClick={() => setIndex(i)}\n          >\n            Label\n          </TabItem>",
          "sourceFile": "packages/storybook/src/stories/DrawerDF/Tabs.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в WidgetL.tsx",
          "type": "usage",
          "code": "<TabItem\n                // eslint-disable-next-line react/no-array-index-key\n                key={i}\n                view=\"divider\"\n                orientation=\"horizontal\"\n                size=\"xs\"\n                selected={i === tabIndex}\n                tabIndex={0}\n                onClick={() => setTabIndex(i)}\n              >\n                {`Tab ${i + 1}`}\n              </TabItem>",
          "sourceFile": "packages/storybook/src/stories/AnalyticalWidget/components/WidgetL.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Стандартное подключение, без клавиатурной навигации",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { Tabs, TabItem } from '@daisforge/ui';\nimport { IconClock } from '@salutejs/plasma-icons';\nexport function App() {\n    const items = Array(4).fill(0);\n    const [index, setIndex] = useState(0);\n    return (\n        <div>\n            <Tabs view=\"filled\" stretch size=\"xs\">\n                {items.map((_, i) => (\n                    <TabItem\n                        view=\"secondary\"\n                        key={`item:${i}`}\n                        size=\"xs\"\n                        selected={i === index}\n                        tabIndex={0}\n                        contentLeft={<IconClock size=\"xs\" color=\"inherit\" />}\n                        onClick={() => setIndex(i)}\n                    >\n                        {`Label${i + 1}`}\n                    </TabItem>\n                ))}\n            </Tabs>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Расположение Tabs",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { Tabs, TabItem } from '@daisforge/ui';\nimport { IconClock } from '@salutejs/plasma-icons';\nexport function App() {\n    const items = Array(8).fill(0);\n    const [index, setIndex] = useState(0);\n    return (\n        <div>\n            <Tabs view=\"divider\" orientation=\"vertical\" size=\"xs\" style={{ width: '15rem' }}>\n                {items.map((_, i) => (\n                    <TabItem\n                        view=\"divider\"\n                        orientation=\"vertical\"\n                        key={`item:${i}`}\n                        size=\"xs\"\n                        selected={i === index}\n                        tabIndex={0}\n                        contentLeft={<IconClock size=\"xs\" color=\"inherit\" />}\n                        onClick={() => setIndex(i)}\n                    >\n                        {`Label${i + 1}`}\n                    </TabItem>\n                ))}\n            </Tabs>\n        </div>\n    );\n}"
        }
      ]
    },
    "Tabs": {
      "name": "Tabs",
      "group": "components",
      "folderName": "Tabs",
      "role": "primary",
      "description": "Контейнер для сборки собственного набора вкладок из TabItem и связанных частей.",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        }
      ],
      "propsTypeName": "TabsProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Tabs/Tabs.d.ts",
      "type": "wrapper",
      "atomicBase": "Tabs",
      "category": "Локальные компоненты",
      "keywords": [
        "переключение контента",
        "tab navigation",
        "панель вкладок"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "clip",
          "type": "\"scroll\" | \"showAll\"",
          "required": false,
          "description": "Как ведет себя компонент при ограничении ширины",
          "default": "'scroll'",
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasDivider",
          "type": "boolean",
          "required": false,
          "description": "Наличие divider",
          "default": "true",
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "index",
          "type": "number",
          "required": false,
          "description": "Индекс активного элемента, необходим для клавиатурной навигации",
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\"",
          "required": false,
          "description": "Расположение табов",
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pilled",
          "type": "boolean",
          "required": false,
          "description": "Табы c округлым border-radius",
          "default": "false",
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"s\" | \"l\" | \"m\" | \"xs\"",
          "required": false,
          "description": "Размер табов",
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"filled\" | \"divider\"",
          "required": false,
          "description": "Вид табов",
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dividerAlign",
          "type": "\"right\" | \"left\"",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "outsideScroll",
          "type": "boolean | { left?: string; right?: string; } | undefined",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Tabs } from '@daisforge/ui';",
      "minimalUsage": "<Tabs />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в SplitView.stories.tsx",
          "type": "usage",
          "code": "<Tabs\n                  orientation=\"vertical\"\n                  size=\"s\"\n                  view=\"divider\"\n                  style={{ alignSelf: 'flex-start', paddingTop: s.x8 }}\n                >\n                  {tabItems.map((id, i) => (\n                    <IconTabItem\n                      key={`tab:${id}`}\n                      selected={i === activeTab}\n                      onClick={() => setActiveTab(i)}\n                      orientation=\"vertical\"\n                      view=\"divider\"\n                      size=\"s\"\n                      tabIndex={0}\n                      style={{ padding: `${s.x4} 10px ${s.x3} 10px` }}\n                    >\n                      <IconPlasma color=\"inherit\" />\n                    </IconTabItem>\n                  ))}\n                </Tabs>",
          "sourceFile": "packages/storybook/src/stories/SplitView/SplitView.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в Layout.stories.tsx",
          "type": "usage",
          "code": "<Tabs view=\"filled\" stretch size=\"xs\">\n        {items.map((_, i) => (\n          <TabItem\n            view=\"secondary\"\n            size=\"xs\"\n            selected={i === index}\n            tabIndex={0}\n            contentLeft={<IconClock size=\"xs\" color=\"inherit\" />}\n            onClick={() => setIndex(i)}\n          >\n            {`Label${i + 1}`}\n          </TabItem>\n        ))}\n      </Tabs>",
          "sourceFile": "packages/storybook/src/stories/Layout/Layout.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Стандартное подключение, без клавиатурной навигации",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { Tabs, TabItem } from '@daisforge/ui';\nimport { IconClock } from '@salutejs/plasma-icons';\nexport function App() {\n    const items = Array(4).fill(0);\n    const [index, setIndex] = useState(0);\n    return (\n        <div>\n            <Tabs view=\"filled\" stretch size=\"xs\">\n                {items.map((_, i) => (\n                    <TabItem\n                        view=\"secondary\"\n                        key={`item:${i}`}\n                        size=\"xs\"\n                        selected={i === index}\n                        tabIndex={0}\n                        contentLeft={<IconClock size=\"xs\" color=\"inherit\" />}\n                        onClick={() => setIndex(i)}\n                    >\n                        {`Label${i + 1}`}\n                    </TabItem>\n                ))}\n            </Tabs>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Расположение Tabs",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { Tabs, TabItem } from '@daisforge/ui';\nimport { IconClock } from '@salutejs/plasma-icons';\nexport function App() {\n    const items = Array(8).fill(0);\n    const [index, setIndex] = useState(0);\n    return (\n        <div>\n            <Tabs view=\"divider\" orientation=\"vertical\" size=\"xs\" style={{ width: '15rem' }}>\n                {items.map((_, i) => (\n                    <TabItem\n                        view=\"divider\"\n                        orientation=\"vertical\"\n                        key={`item:${i}`}\n                        size=\"xs\"\n                        selected={i === index}\n                        tabIndex={0}\n                        contentLeft={<IconClock size=\"xs\" color=\"inherit\" />}\n                        onClick={() => setIndex(i)}\n                    >\n                        {`Label${i + 1}`}\n                    </TabItem>\n                ))}\n            </Tabs>\n        </div>\n    );\n}"
        }
      ]
    },
    "TabsController": {
      "name": "TabsController",
      "group": "components",
      "folderName": "Tabs",
      "role": "primary",
      "description": "Готовый набор вкладок с клавиатурной навигацией (стрелки, Home/End) из списка items.",
      "props": [
        {
          "name": "index",
          "type": "number",
          "required": true,
          "description": "Индекс активного элемента, необходим для клавиатурной навигации"
        },
        {
          "name": "items",
          "type": "({ label: string; } & HorizontalTabItemProps)[]",
          "required": true,
          "description": ""
        },
        {
          "name": "onIndexChange",
          "type": "(index: number) => void",
          "required": true,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "clip",
          "type": "\"scroll\" | \"showAll\" | undefined",
          "required": false,
          "description": "Как ведет себя компонент при ограничении ширины",
          "default": "'scroll'"
        },
        {
          "name": "hasDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": "Наличие divider",
          "default": "true"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | undefined",
          "required": false,
          "description": "Расположение табов"
        },
        {
          "name": "size",
          "type": "string | undefined",
          "required": false,
          "description": "Размер табов"
        },
        {
          "name": "stretch",
          "type": "boolean | undefined",
          "required": false,
          "description": "Табы растянуты на доступную область",
          "default": "false"
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": "Вид табов"
        },
        {
          "name": "autoscroll",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "children",
          "type": "undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "outsideScroll",
          "type": "boolean | { left?: string | undefined; right?: string | undefined; } | undefined",
          "required": false,
          "description": "Уберет скругление с выбранной стороны и подвинет контейнер",
          "deprecated": true
        },
        {
          "name": "pilled",
          "type": "boolean | undefined",
          "required": false,
          "description": "Табы c округлым border-radius",
          "deprecated": true,
          "default": "false"
        }
      ],
      "propsTypeName": "TabsControllerProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Tabs/TabsController.d.ts",
      "type": "wrapper",
      "atomicBase": "TabsController",
      "category": "Локальные компоненты",
      "keywords": [
        "клавиатурная навигация",
        "готовые табы",
        "accessible tabs"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { TabsController } from '@daisforge/ui';",
      "minimalUsage": "<TabsController index={0} items={[]} onIndexChange={() => {}} />",
      "examples": []
    },
    "TextArea": {
      "name": "TextArea",
      "group": "components",
      "folderName": "TextArea",
      "role": "primary",
      "description": "Многострочное текстовое поле с кнопкой очистки содержимого.",
      "props": [
        {
          "name": "onClear",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Callback при нажатии на кнопку очистки поля ввода."
        },
        {
          "name": "onChange",
          "type": "React.ChangeEventHandler<HTMLTextAreaElement> | undefined",
          "required": false,
          "description": "Обработчик изменения элемента формы"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"viewMode\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoResize",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "clear",
          "type": "true | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "dirName",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hasDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "headerSlot",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "helperText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintOpened",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintView",
          "type": "\"default\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "labelAriaHidden",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "labelPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "leftHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "leftHelperPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "maxAuto",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "minAuto",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "optional",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "optionalText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "requiredPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "resize",
          "type": "\"none\" | \"both\" | \"horizontal\" | \"vertical\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rightHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "rightHelperPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | undefined",
          "required": false,
          "description": "",
          "default": "'s'"
        },
        {
          "name": "status",
          "type": "\"\" | \"warning\" | \"success\" | \"error\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TextAreaProps",
      "sourceFile": "packages/ui-kit/src/components/TextArea/TextArea.tsx",
      "type": "wrapper",
      "formVariant": "FormTextArea",
      "category": "Локальные компоненты",
      "keywords": [
        "многострочный ввод",
        "поле для комментария",
        "длинный текст"
      ],
      "docs": "# TextArea\n\nМногострочное текстовое поле ввода. Расширяет атомарный `TextArea` из `@salutejs/sdds-finai`, добавляя кнопку очистки.\n\n## Ключевые особенности\n\n- Размеры: `s`\n- Варианты отображения: `default`, `positive`, `warning`, `negative`\n- Размещение лейбла: `outer` (над полем) и `inner` (внутри)\n- Автоматическое изменение высоты (`autoResize`)\n- Кнопка очистки через проп `onClear`\n- Поддержка `leftHelper` для подсказок под полем\n- Состояния: `disabled`, `readOnly`, `required`, `optional`\n\nОписание типов — в разделе [API](/docs/локальные-компоненты-textarea-api--docs).",
      "apiDocs": "# TextArea API\n\nОбёртка над `TextArea` из `@salutejs/sdds-finai`. Добавляет `onClear`.\n\n## Кастомные пропсы (добавлены в обёртке)\n\n```typescript\ntype TextAreaProps = TextAreaBaseProps & {\n  /**\n   * Callback при нажатии на кнопку очистки поля ввода.\n   */\n  onClear?: () => void;\n};\n```\n\n## Пропсы из @salutejs/sdds-finai\n\nКомпонент принимает все пропсы атомарного `TextArea` из `@salutejs/sdds-finai`.\n\nПолное описание — в документации: [TextArea](https://plasma.sberdevices.ru/sdds-finai/components/textarea/)",
      "curatedStories": [
        {
          "exportName": "Default",
          "displayName": "Default",
          "type": "full-code",
          "code": "import { TextArea } from '@daisforge/ui';\n\n(args: TextAreaProps) => {\n    const [value, setValue] = useState('Значение поля');\n\n    return (\n      <div style={{ width: '400px' }}>\n        <TextArea\n          {...args}\n          value={value}\n          onChange={(e: ChangeEvent<HTMLTextAreaElement>) =>\n            setValue(e.target.value)\n          }\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Sizes",
          "displayName": "Размеры",
          "type": "full-code",
          "code": "import { TextArea } from '@daisforge/ui';\n\n(args: TextAreaProps) => {\n    const sizes = ['s'] as const;\n    const [values, setValues] = useState<Record<string, string>>({\n      l: '',\n      m: '',\n      s: '',\n      xs: '',\n    });\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '400px',\n        }}\n      >\n        {sizes.map((size) => (\n          <TextArea\n            {...args}\n            key={size}\n            size={size}\n            label={`Size: ${size}`}\n            placeholder=\"Заполните поле\"\n            value={values[size]}\n            onChange={(e: ChangeEvent<HTMLTextAreaElement>) =>\n              setValues((prev) => ({ ...prev, [size]: e.target.value }))\n            }\n          />\n        ))}\n      </div>\n    );\n  }"
        },
        {
          "exportName": "WithClear",
          "displayName": "Различные варианты",
          "type": "full-code",
          "code": "import { TextArea } from '@daisforge/ui';\n\n(args: TextAreaProps) => {\n    const [value1, setValue1] = useState('Текст для очистки');\n    const [value2, setValue2] = useState('Текст с иконкой');\n    const [value3, setValue3] = useState('');\n    const [value4, setValue4] = useState('Текст');\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '400px',\n        }}\n      >\n        <TextArea\n          {...args}\n          label=\"onClear + value → крестик\"\n          value={value1}\n          onChange={(e: ChangeEvent<HTMLTextAreaElement>) =>\n            setValue1(e.target.value)\n          }\n          onClear={() => setValue1('')}\n        />\n\n        <TextArea\n          {...args}\n          label=\"onClear + value + contentRight → рядом\"\n          value={value2}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLTextAreaElement>) =>\n            setValue2(e.target.value)\n          }\n          onClear={() => setValue2('')}\n        />\n\n        <TextArea\n          {...args}\n          label=\"Пустое значение — крестик скрыт\"\n          value={value3}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLTextAreaElement>) =>\n            setValue3(e.target.value)\n          }\n          onClear={() => setValue3('')}\n        />\n\n        <TextArea\n          {...args}\n          label=\"ReadOnly — замок вместо крестика и contentRight\"\n          value=\"Только для чтения\"\n          readOnly\n          contentRight={<IconSb size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        <TextArea\n          {...args}\n          label=\"Disabled — замок вместо крестика и contentRight\"\n          value=\"Заблокировано\"\n          disabled\n          contentRight={<IconSb size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        <TextArea\n          {...args}\n          label=\"Только contentRight, без onClear\"\n          value={value4}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLTextAreaElement>) =>\n            setValue4(e.target.value)\n          }\n        />\n      </div>\n    );\n  }"
        }
      ],
      "chooseWhen": "Вне react-hook-form — многострочное поле с value/onChange напрямую.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TextArea } from '@daisforge/ui';",
      "minimalUsage": "<TextArea />",
      "examples": [
        {
          "exportName": "Default",
          "displayName": "Default",
          "type": "full-code",
          "code": "import { TextArea } from '@daisforge/ui';\n\n(args: TextAreaProps) => {\n    const [value, setValue] = useState('Значение поля');\n\n    return (\n      <div style={{ width: '400px' }}>\n        <TextArea\n          {...args}\n          value={value}\n          onChange={(e: ChangeEvent<HTMLTextAreaElement>) =>\n            setValue(e.target.value)\n          }\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Sizes",
          "displayName": "Размеры",
          "type": "full-code",
          "code": "import { TextArea } from '@daisforge/ui';\n\n(args: TextAreaProps) => {\n    const sizes = ['s'] as const;\n    const [values, setValues] = useState<Record<string, string>>({\n      l: '',\n      m: '',\n      s: '',\n      xs: '',\n    });\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '400px',\n        }}\n      >\n        {sizes.map((size) => (\n          <TextArea\n            {...args}\n            key={size}\n            size={size}\n            label={`Size: ${size}`}\n            placeholder=\"Заполните поле\"\n            value={values[size]}\n            onChange={(e: ChangeEvent<HTMLTextAreaElement>) =>\n              setValues((prev) => ({ ...prev, [size]: e.target.value }))\n            }\n          />\n        ))}\n      </div>\n    );\n  }"
        },
        {
          "exportName": "WithClear",
          "displayName": "Различные варианты",
          "type": "full-code",
          "code": "import { TextArea } from '@daisforge/ui';\n\n(args: TextAreaProps) => {\n    const [value1, setValue1] = useState('Текст для очистки');\n    const [value2, setValue2] = useState('Текст с иконкой');\n    const [value3, setValue3] = useState('');\n    const [value4, setValue4] = useState('Текст');\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '400px',\n        }}\n      >\n        <TextArea\n          {...args}\n          label=\"onClear + value → крестик\"\n          value={value1}\n          onChange={(e: ChangeEvent<HTMLTextAreaElement>) =>\n            setValue1(e.target.value)\n          }\n          onClear={() => setValue1('')}\n        />\n\n        <TextArea\n          {...args}\n          label=\"onClear + value + contentRight → рядом\"\n          value={value2}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLTextAreaElement>) =>\n            setValue2(e.target.value)\n          }\n          onClear={() => setValue2('')}\n        />\n\n        <TextArea\n          {...args}\n          label=\"Пустое значение — крестик скрыт\"\n          value={value3}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLTextAreaElement>) =>\n            setValue3(e.target.value)\n          }\n          onClear={() => setValue3('')}\n        />\n\n        <TextArea\n          {...args}\n          label=\"ReadOnly — замок вместо крестика и contentRight\"\n          value=\"Только для чтения\"\n          readOnly\n          contentRight={<IconSb size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        <TextArea\n          {...args}\n          label=\"Disabled — замок вместо крестика и contentRight\"\n          value=\"Заблокировано\"\n          disabled\n          contentRight={<IconSb size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        <TextArea\n          {...args}\n          label=\"Только contentRight, без onClear\"\n          value={value4}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLTextAreaElement>) =>\n            setValue4(e.target.value)\n          }\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в AiChatDAIS.tsx",
          "type": "usage",
          "code": "<TextArea\n                id=\"input\"\n                autoResize\n                maxAuto={5}\n                value={inputValue}\n                placeholder={currentPlaceholder}\n                onKeyDown={handleKeyDown}\n                onChange={handleInputChange}\n              />",
          "sourceFile": "packages/storybook/src/stories/AiChatDAIS/AiChatDAIS.tsx"
        }
      ]
    },
    "TextField": {
      "name": "TextField",
      "group": "components",
      "folderName": "TextField",
      "role": "primary",
      "description": "Однострочное поле ввода текста с кнопкой очистки значения.",
      "props": [
        {
          "name": "onClear",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Callback при нажатии на кнопку очистки поля ввода.\nПри наличии value и onClear справа отображается крестик."
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TextFieldProps",
      "sourceFile": "packages/ui-kit/src/components/TextField/TextField.tsx",
      "type": "wrapper",
      "atomicBase": "TextField",
      "formVariant": "FormTextField",
      "category": "Локальные компоненты",
      "keywords": [
        "ввод текста",
        "input поле",
        "форма ввода"
      ],
      "docs": "# TextField\n\nОднострочное текстовое поле ввода. Расширяет атомарный `TextField` из `@salutejs/sdds-finai`, добавляя кнопку очистки.\n\n## Ключевые особенности\n\n- Размеры: `s`, `xs`\n- Варианты отображения: `default`, `positive`, `warning`, `negative`\n- Размещение лейбла: `outer` (над полем) и `inner` (внутри)\n- Кнопка очистки через проп `onClear`\n- Поддержка слотов `contentLeft` и `contentRight` для иконок\n- Поддержка `leftHelper` для подсказок под полем\n- Состояния: `disabled`, `readOnly`, `required`, `optional`\n\nОписание типов — в разделе [API](/docs/локальные-компоненты-textfield-api--docs).",
      "apiDocs": "# TextField API\n\nОбёртка над `TextField` из `@salutejs/sdds-finai`. Добавляет `onClear`.\n\n## Кастомные пропсы (добавлены в обёртке)\n\n```typescript\ntype TextFieldProps = TextFieldBaseProps & {\n  /**\n   * Callback при нажатии на кнопку очистки поля ввода.\n   * При наличии value и onClear справа отображается крестик.\n   */\n  onClear?: () => void;\n};\n```\n\n## Пропсы из @salutejs/sdds-finai\n\nКомпонент принимает все пропсы атомарного `TextField` из `@salutejs/sdds-finai`.\n\nПолное описание — в документации: [TextField](https://plasma.sberdevices.ru/sdds-finai/components/TextField/)",
      "curatedStories": [
        {
          "exportName": "Default",
          "displayName": "Default",
          "type": "full-code",
          "code": "import { TextField } from '@daisforge/ui';\n\n(args: TextFieldProps) => {\n    const [value, setValue] = useState('Значение поля');\n\n    return (\n      <div style={{ width: '400px' }}>\n        <TextField\n          {...args}\n          value={value}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue(e.target.value)\n          }\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Sizes",
          "displayName": "Размеры",
          "type": "full-code",
          "code": "import { TextField } from '@daisforge/ui';\n\n(args: TextFieldProps) => {\n    const sizes = ['s', 'xs'] as const;\n    const [values, setValues] = useState<Record<string, string>>({\n      l: '',\n      m: '',\n      s: '',\n      xs: '',\n    });\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '400px',\n        }}\n      >\n        {sizes.map((size) => (\n          <TextField\n            {...args}\n            key={size}\n            size={size}\n            label={`Size: ${size}`}\n            placeholder=\"Заполните поле\"\n            value={values[size]}\n            onChange={(e: ChangeEvent<HTMLInputElement>) =>\n              setValues((prev) => ({ ...prev, [size]: e.target.value }))\n            }\n          />\n        ))}\n      </div>\n    );\n  }"
        },
        {
          "exportName": "WithClear",
          "displayName": "Различные варианты",
          "type": "full-code",
          "code": "import { TextField } from '@daisforge/ui';\n\n(args: TextFieldProps) => {\n    const [value1, setValue1] = useState('Текст для очистки');\n    const [value2, setValue2] = useState('Текст с иконкой');\n    const [value3, setValue3] = useState('');\n    const [value4, setValue4] = useState('Текст');\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '400px',\n        }}\n      >\n        {/* Сценарий 3: onClear + value → только крестик */}\n        <TextField\n          {...args}\n          label=\"onClear + value → крестик\"\n          value={value1}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue1(e.target.value)\n          }\n          onClear={() => setValue1('')}\n        />\n\n        {/* Сценарий 2: onClear + value + contentRight → [крестик | иконка] рядом */}\n        <TextField\n          {...args}\n          label=\"onClear + value + contentRight → рядом\"\n          value={value2}\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue2(e.target.value)\n          }\n          onClear={() => setValue2('')}\n        />\n\n        {/* Сценарий 4: onClear без value → крестик скрыт, contentRight как есть */}\n        <TextField\n          {...args}\n          label=\"Пустое значение — крестик скрыт\"\n          value={value3}\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue3(e.target.value)\n          }\n          onClear={() => setValue3('')}\n        />\n\n        {/* Сценарий 1: readOnly → замок (заменяет всё) */}\n        <TextField\n          {...args}\n          label=\"ReadOnly — замок вместо крестика и contentRight\"\n          value=\"Только для чтения\"\n          readOnly\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        {/* Сценарий 1: disabled → замок (заменяет всё) */}\n        <TextField\n          {...args}\n          label=\"Disabled — замок вместо крестика и contentRight\"\n          value=\"Заблокировано\"\n          disabled\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        {/* Сценарий 4: только contentRight, без onClear */}\n        <TextField\n          {...args}\n          label=\"Только contentRight, без onClear\"\n          value={value4}\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue4(e.target.value)\n          }\n        />\n      </div>\n    );\n  }"
        }
      ],
      "chooseWhen": "Вне react-hook-form — однострочное поле с value/onChange напрямую.",
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "hasRequiredIndicator",
          "type": "boolean",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false",
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)",
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "description": "Расположение лейбла.",
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "ChangeEventHandler<HTMLInputElement>",
          "required": false,
          "description": "Обработчик изменения элемента формы",
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optional",
          "type": "boolean",
          "required": false,
          "description": "Флаг необязательности поля",
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "optionalText",
          "type": "string",
          "required": false,
          "description": "Подпись для указания необязательности поля",
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "requiredPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right",
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"clear\" | \"default\" | \"viewMode\"",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "checked",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chips",
          "type": "TextFieldPrimitiveValue[]",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipType",
          "type": "\"text\" | \"default\"",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipValidator",
          "type": "((value: string) => ChipValidatorReturn)",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\"",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "clear",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "enumerationType",
          "type": "\"plain\" | \"chip\"",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasDivider",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintContentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOffset",
          "type": "[number, number]",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPortal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetIcon",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintText",
          "type": "string",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\"",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintView",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintWidth",
          "type": "string",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "leftHelper",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maxLength",
          "type": "number",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "minLength",
          "type": "number",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "name",
          "type": "string",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onBlur",
          "type": "FocusEventHandler<HTMLInputElement>",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChangeChips",
          "type": "((value: TextFieldPrimitiveValue[]) => void)",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onFocus",
          "type": "FocusEventHandler<HTMLInputElement>",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onSearch",
          "type": "(((value: string, event?: KeyboardEvent<HTMLInputElement>) => void) & ((value: string, event?: KeyboardEvent<HTMLInputElement>) => void)) | undefined",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placeholder",
          "type": "string",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "readOnly",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "required",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "rightHelper",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "default": "'s'",
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textAfter",
          "type": "string",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textBefore",
          "type": "string",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "titleCaption",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "type",
          "type": "string",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | number | readonly string[]",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\"",
          "required": false,
          "inheritedFrom": "TextField",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TextField } from '@daisforge/ui';",
      "minimalUsage": "<TextField />",
      "examples": [
        {
          "exportName": "Default",
          "displayName": "Default",
          "type": "full-code",
          "code": "import { TextField } from '@daisforge/ui';\n\n(args: TextFieldProps) => {\n    const [value, setValue] = useState('Значение поля');\n\n    return (\n      <div style={{ width: '400px' }}>\n        <TextField\n          {...args}\n          value={value}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue(e.target.value)\n          }\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Sizes",
          "displayName": "Размеры",
          "type": "full-code",
          "code": "import { TextField } from '@daisforge/ui';\n\n(args: TextFieldProps) => {\n    const sizes = ['s', 'xs'] as const;\n    const [values, setValues] = useState<Record<string, string>>({\n      l: '',\n      m: '',\n      s: '',\n      xs: '',\n    });\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '400px',\n        }}\n      >\n        {sizes.map((size) => (\n          <TextField\n            {...args}\n            key={size}\n            size={size}\n            label={`Size: ${size}`}\n            placeholder=\"Заполните поле\"\n            value={values[size]}\n            onChange={(e: ChangeEvent<HTMLInputElement>) =>\n              setValues((prev) => ({ ...prev, [size]: e.target.value }))\n            }\n          />\n        ))}\n      </div>\n    );\n  }"
        },
        {
          "exportName": "WithClear",
          "displayName": "Различные варианты",
          "type": "full-code",
          "code": "import { TextField } from '@daisforge/ui';\n\n(args: TextFieldProps) => {\n    const [value1, setValue1] = useState('Текст для очистки');\n    const [value2, setValue2] = useState('Текст с иконкой');\n    const [value3, setValue3] = useState('');\n    const [value4, setValue4] = useState('Текст');\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '400px',\n        }}\n      >\n        {/* Сценарий 3: onClear + value → только крестик */}\n        <TextField\n          {...args}\n          label=\"onClear + value → крестик\"\n          value={value1}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue1(e.target.value)\n          }\n          onClear={() => setValue1('')}\n        />\n\n        {/* Сценарий 2: onClear + value + contentRight → [крестик | иконка] рядом */}\n        <TextField\n          {...args}\n          label=\"onClear + value + contentRight → рядом\"\n          value={value2}\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue2(e.target.value)\n          }\n          onClear={() => setValue2('')}\n        />\n\n        {/* Сценарий 4: onClear без value → крестик скрыт, contentRight как есть */}\n        <TextField\n          {...args}\n          label=\"Пустое значение — крестик скрыт\"\n          value={value3}\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue3(e.target.value)\n          }\n          onClear={() => setValue3('')}\n        />\n\n        {/* Сценарий 1: readOnly → замок (заменяет всё) */}\n        <TextField\n          {...args}\n          label=\"ReadOnly — замок вместо крестика и contentRight\"\n          value=\"Только для чтения\"\n          readOnly\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        {/* Сценарий 1: disabled → замок (заменяет всё) */}\n        <TextField\n          {...args}\n          label=\"Disabled — замок вместо крестика и contentRight\"\n          value=\"Заблокировано\"\n          disabled\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        {/* Сценарий 4: только contentRight, без onClear */}\n        <TextField\n          {...args}\n          label=\"Только contentRight, без onClear\"\n          value={value4}\n          contentRight={<IconCalendarOutline size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue4(e.target.value)\n          }\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в TextField.stories.tsx",
          "type": "usage",
          "code": "<TextField\n            {...args}\n            key={size}\n            size={size}\n            label={`Size: ${size}`}\n            placeholder=\"Заполните поле\"\n            value={values[size]}\n            onChange={(e: ChangeEvent<HTMLInputElement>) =>\n              setValues((prev) => ({ ...prev, [size]: e.target.value }))\n            }\n          />",
          "sourceFile": "packages/storybook/src/stories/TextField/TextField.stories.tsx"
        }
      ]
    },
    "TextFieldSearch": {
      "name": "TextFieldSearch",
      "group": "components",
      "folderName": "TextField",
      "role": "primary",
      "description": "Поле поиска на основе TextField: иконка лупы, плейсхолдер и кнопка очистки.",
      "props": [
        {
          "name": "onClear",
          "type": "((() => void) & (() => void)) | undefined",
          "required": false,
          "description": "Callback при нажатии на кнопку очистки поля ввода.\nПри наличии value и onClear справа отображается крестик.\nДействие при выполнении нажатия на кнопку очистки поля ввода"
        },
        {
          "name": "size",
          "type": "\"xs\" | \"s\" | undefined",
          "required": false,
          "description": "Размер Поля ввода",
          "default": "'s'"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean | undefined",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)"
        },
        {
          "name": "labelPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": "Расположение лейбла."
        },
        {
          "name": "onChange",
          "type": "React.ChangeEventHandler<HTMLInputElement> | undefined",
          "required": false,
          "description": "Обработчик изменения элемента формы"
        },
        {
          "name": "optional",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг необязательности поля"
        },
        {
          "name": "optionalText",
          "type": "string | undefined",
          "required": false,
          "description": "Подпись для указания необязательности поля"
        },
        {
          "name": "requiredPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"clear\" | \"viewMode\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chips",
          "type": "TextFieldPrimitiveValue[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chipType",
          "type": "\"default\" | \"text\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chipValidator",
          "type": "((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { …",
          "required": false,
          "description": ""
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"secondary\" | \"positive\" | \"warning\" | \"negative\" | \"accent\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "clear",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enumerationType",
          "type": "\"plain\" | \"chip\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hasDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPortal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintView",
          "type": "\"default\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "leftHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "onChangeChips",
          "type": "((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimit…",
          "required": false,
          "description": ""
        },
        {
          "name": "onSearch",
          "type": "(((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | (((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | (((value: string, event?: React.KeyboardEvent<HT…",
          "required": false,
          "description": ""
        },
        {
          "name": "rightHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "textAfter",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "textBefore",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "handlerClear",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Действие при выполнении нажатия на кнопку очистки поля ввода",
          "deprecated": true
        }
      ],
      "propsTypeName": "TextFieldSearchProps",
      "sourceFile": "packages/ui-kit/src/components/TextField/TextFieldSearch.tsx",
      "type": "wrapper",
      "category": "Локальные компоненты",
      "keywords": [
        "поиск по списку",
        "search input",
        "фильтр по тексту"
      ],
      "docs": "# TextFieldSearch\n\nКомпонент TextFieldSearch - обертка компонента TextField со своими готовыми стилями для поля поиска. C примерами реализации подробно можно ознакомиться ниже в stories.\n\n## Ключевые особенности\n\n- Готовые стили для поля поиска на основе TextField\n- Иконка лупы слева и крестик очистки справа\n- Доступные размеры: `s`, `xs`\n\n> Подробнее о типах и пропсах — [TextFieldSearch API](?path=/docs/локальные-компоненты-textfieldsearch-api--docs)",
      "apiDocs": "# TextFieldSearch API\n\n## TextFieldSearchProps\n\n```typescript\ntype TextFieldSearchProps = ComponentProps<typeof TextField> &\n  TextFieldSearchBaseProps;\n```\n\n## TextFieldSearchBaseProps\n\n```typescript\ntype TextFieldSearchBaseProps = {\n  /**\n   * Размер Поля ввода\n   */\n  size?: 'xs' | 's';\n  /**\n   * Действие при выполнении нажатия на кнопку очистки поля ввода\n   * @deprecated Используйте onClear\n   */\n  handlerClear?: () => void;\n  /**\n   * Действие при выполнении нажатия на кнопку очистки поля ввода\n   */\n  onClear?: () => void;\n};\n```\n\n> Остальные пропсы наследуются от `TextField`",
      "curatedStories": [
        {
          "exportName": "Default",
          "displayName": "Default",
          "type": "full-code",
          "code": "import { TextFieldSearch } from '@daisforge/ui';\n\n(args: TextFieldSearchProps) => {\n    const [value, setValue] = useState('');\n\n    return (\n      <div style={{ padding: '20px', width: '500px' }}>\n        <TextFieldSearch\n          {...args}\n          value={value}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue(e.target.value)\n          }\n          onClear={() => setValue('')}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Sizes",
          "displayName": "Размеры",
          "type": "full-code",
          "code": "import { TextFieldSearch } from '@daisforge/ui';\n\n(args: TextFieldSearchProps) => {\n    const sizes = ['s', 'xs'] as const;\n    const [values, setValues] = useState<Record<string, string>>({\n      s: '',\n      xs: '',\n    });\n\n    return (\n      <div\n        style={{\n          padding: '20px',\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '500px',\n        }}\n      >\n        {sizes.map((size) => (\n          <TextFieldSearch\n            {...args}\n            key={size}\n            size={size}\n            placeholder={`Size: ${size}`}\n            value={values[size]}\n            onChange={(e: ChangeEvent<HTMLInputElement>) =>\n              setValues((prev) => ({ ...prev, [size]: e.target.value }))\n            }\n            onClear={() => setValues((prev) => ({ ...prev, [size]: '' }))}\n          />\n        ))}\n      </div>\n    );\n  }"
        },
        {
          "exportName": "WithClear",
          "displayName": "Различные варианты",
          "type": "full-code",
          "code": "import { TextFieldSearch } from '@daisforge/ui';\n\n(args: TextFieldSearchProps) => {\n    const [value1, setValue1] = useState('Поисковый запрос');\n    const [value2, setValue2] = useState('С иконкой');\n    const [value3, setValue3] = useState('');\n    const [value4, setValue4] = useState('Текст');\n\n    return (\n      <div\n        style={{\n          padding: '20px',\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '500px',\n        }}\n      >\n        <TextFieldSearch\n          {...args}\n          placeholder=\"onClear + value → крестик\"\n          value={value1}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue1(e.target.value)\n          }\n          onClear={() => setValue1('')}\n        />\n\n        <TextFieldSearch\n          {...args}\n          placeholder=\"onClear + value + contentRight → рядом\"\n          value={value2}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue2(e.target.value)\n          }\n          onClear={() => setValue2('')}\n        />\n\n        <TextFieldSearch\n          {...args}\n          placeholder=\"Пустое значение — крестик скрыт\"\n          value={value3}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue3(e.target.value)\n          }\n          onClear={() => setValue3('')}\n        />\n\n        <TextFieldSearch\n          {...args}\n          placeholder=\"ReadOnly — замок\"\n          value=\"Только для чтения\"\n          readOnly\n          contentRight={<IconSb size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        <TextFieldSearch\n          {...args}\n          placeholder=\"Disabled — замок\"\n          value=\"Заблокировано\"\n          disabled\n          contentRight={<IconSb size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        <TextFieldSearch\n          {...args}\n          placeholder=\"Только contentRight, без onClear\"\n          value={value4}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue4(e.target.value)\n          }\n        />\n      </div>\n    );\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TextFieldSearch } from '@daisforge/ui';",
      "minimalUsage": "<TextFieldSearch />",
      "examples": [
        {
          "exportName": "Default",
          "displayName": "Default",
          "type": "full-code",
          "code": "import { TextFieldSearch } from '@daisforge/ui';\n\n(args: TextFieldSearchProps) => {\n    const [value, setValue] = useState('');\n\n    return (\n      <div style={{ padding: '20px', width: '500px' }}>\n        <TextFieldSearch\n          {...args}\n          value={value}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue(e.target.value)\n          }\n          onClear={() => setValue('')}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Sizes",
          "displayName": "Размеры",
          "type": "full-code",
          "code": "import { TextFieldSearch } from '@daisforge/ui';\n\n(args: TextFieldSearchProps) => {\n    const sizes = ['s', 'xs'] as const;\n    const [values, setValues] = useState<Record<string, string>>({\n      s: '',\n      xs: '',\n    });\n\n    return (\n      <div\n        style={{\n          padding: '20px',\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '500px',\n        }}\n      >\n        {sizes.map((size) => (\n          <TextFieldSearch\n            {...args}\n            key={size}\n            size={size}\n            placeholder={`Size: ${size}`}\n            value={values[size]}\n            onChange={(e: ChangeEvent<HTMLInputElement>) =>\n              setValues((prev) => ({ ...prev, [size]: e.target.value }))\n            }\n            onClear={() => setValues((prev) => ({ ...prev, [size]: '' }))}\n          />\n        ))}\n      </div>\n    );\n  }"
        },
        {
          "exportName": "WithClear",
          "displayName": "Различные варианты",
          "type": "full-code",
          "code": "import { TextFieldSearch } from '@daisforge/ui';\n\n(args: TextFieldSearchProps) => {\n    const [value1, setValue1] = useState('Поисковый запрос');\n    const [value2, setValue2] = useState('С иконкой');\n    const [value3, setValue3] = useState('');\n    const [value4, setValue4] = useState('Текст');\n\n    return (\n      <div\n        style={{\n          padding: '20px',\n          display: 'flex',\n          flexDirection: 'column',\n          gap: '1rem',\n          width: '500px',\n        }}\n      >\n        <TextFieldSearch\n          {...args}\n          placeholder=\"onClear + value → крестик\"\n          value={value1}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue1(e.target.value)\n          }\n          onClear={() => setValue1('')}\n        />\n\n        <TextFieldSearch\n          {...args}\n          placeholder=\"onClear + value + contentRight → рядом\"\n          value={value2}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue2(e.target.value)\n          }\n          onClear={() => setValue2('')}\n        />\n\n        <TextFieldSearch\n          {...args}\n          placeholder=\"Пустое значение — крестик скрыт\"\n          value={value3}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue3(e.target.value)\n          }\n          onClear={() => setValue3('')}\n        />\n\n        <TextFieldSearch\n          {...args}\n          placeholder=\"ReadOnly — замок\"\n          value=\"Только для чтения\"\n          readOnly\n          contentRight={<IconSb size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        <TextFieldSearch\n          {...args}\n          placeholder=\"Disabled — замок\"\n          value=\"Заблокировано\"\n          disabled\n          contentRight={<IconSb size=\"s\" />}\n          onClear={() => {}}\n        />\n\n        <TextFieldSearch\n          {...args}\n          placeholder=\"Только contentRight, без onClear\"\n          value={value4}\n          contentRight={<IconSb size=\"s\" />}\n          onChange={(e: ChangeEvent<HTMLInputElement>) =>\n            setValue4(e.target.value)\n          }\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в TextFieldSearch.stories.tsx",
          "type": "usage",
          "code": "<TextFieldSearch\n            {...args}\n            key={size}\n            size={size}\n            placeholder={`Size: ${size}`}\n            value={values[size]}\n            onChange={(e: ChangeEvent<HTMLInputElement>) =>\n              setValues((prev) => ({ ...prev, [size]: e.target.value }))\n            }\n            onClear={() => setValues((prev) => ({ ...prev, [size]: '' }))}\n          />",
          "sourceFile": "packages/storybook/src/stories/TextFieldSearch/TextFieldSearch.stories.tsx"
        }
      ]
    },
    "TextFieldGroup": {
      "name": "TextFieldGroup",
      "group": "components",
      "folderName": "TextFieldGroup",
      "role": "primary",
      "description": "Группировка нескольких TextField в единый визуальный блок (например, код и телефон).",
      "props": [],
      "propsTypeName": "ComponentProps<typeof TextFieldGroup>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/TextFieldGroup/TextFieldGroup.d.ts",
      "type": "wrapper",
      "atomicBase": "TextFieldGroup",
      "category": "Локальные компоненты",
      "keywords": [
        "группа полей ввода",
        "составное поле",
        "input group"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "gap",
          "type": "\"none\" | \"dense\" | \"wide\"",
          "required": false,
          "inheritedFrom": "TextFieldGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isCommonTextFieldStyles",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TextFieldGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\"",
          "required": false,
          "inheritedFrom": "TextFieldGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shape",
          "type": "\"default\" | \"segmented\"",
          "required": false,
          "inheritedFrom": "TextFieldGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "inheritedFrom": "TextFieldGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretching",
          "type": "\"auto\" | \"filled\"",
          "required": false,
          "inheritedFrom": "TextFieldGroup",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TextFieldGroup } from '@daisforge/ui';",
      "minimalUsage": "<TextFieldGroup />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Компонент  TextFieldGroup  - это обертка для TextField. Принимает в себя группу TextField.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TextFieldGroup, TextField } from '@daisforge/ui';\nexport function App() {\n    return (\n        <TextFieldGroup>\n            {Array(5)\n                .fill(true)\n                .map((_, i) => (\n                    <TextField placeholder={`input #${i}`} />\n                ))}\n        </TextFieldGroup>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Размер Размер Размер TextFieldGroup задается с помощью свойства  size .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TextFieldGroup, TextField } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <TextFieldGroup size=\"s\" view=\"secondary\">\n                {Array(5)\n                    .fill(true)\n                    .map((_, i) => (\n                        <TextField placeholder={`input #${i}`} />\n                    ))}\n            </TextFieldGroup>\n            <TextFieldGroup isCommonTextFieldStyles={false}>\n                <TextField placeholder=\"Размер s\" size=\"s\" />\n                <TextField placeholder=\"Размер xs\" size=\"xs\" />\n            </TextFieldGroup>\n        </div>\n    );\n}"
        }
      ]
    },
    "TimePicker": {
      "name": "TimePicker",
      "group": "components",
      "folderName": "TimePicker",
      "role": "primary",
      "description": "Поле ввода времени с масками часов/минут/секунд и ограничением диапазона.",
      "props": [
        {
          "name": "hasTimeFormat",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TimePickerProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/TimePicker/TimePicker.d.ts",
      "type": "wrapper",
      "atomicBase": "TimePicker",
      "category": "Локальные компоненты",
      "keywords": [
        "выбор времени",
        "ввод часов и минут",
        "time input"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "closeOnEsc",
          "type": "boolean",
          "required": false,
          "description": "Закрывать при нажатии Escape",
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean",
          "required": false,
          "description": "Закрывать при клике вне области",
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disableFlip",
          "type": "boolean",
          "required": false,
          "description": "Отключить автоматическое переворачивание дропдауна при нехватке места",
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "frame",
          "type": "string | RefObject<HTMLElement>",
          "required": false,
          "description": "Контейнер для позиционирования",
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)",
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "labelPlacement",
          "type": "string",
          "required": false,
          "description": "Расположение лейбла.",
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ поповера относительно поля ввода",
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean, event?: Event | SyntheticEvent<Element, Event>) => void)",
          "required": false,
          "description": "Обработчик изменения видимости",
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": false,
          "description": "Видимость поповера",
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "Placement",
          "required": false,
          "description": "Сторона открытия TimePicker относительно поля ввода.",
          "default": "bottom",
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "usePortal",
          "type": "boolean",
          "required": false,
          "description": "Использовать портал для рендера",
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "ZIndex",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего списка времени",
          "default": "1000",
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"clear\" | \"default\" | \"viewMode\"",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "autoComplete",
          "type": "string",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "columnsQuantity",
          "type": "2 | 3",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactElement<any, string | JSXElementConstructor<any>>",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultValue",
          "type": "Date",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dropdownAlign",
          "type": "\"right\" | \"left\"",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dropdownHeight",
          "type": "Height<string | number>",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dropdownWidth",
          "type": "Width<string | number>",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasClearDivider",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintContentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintOffset",
          "type": "[number, number]",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintPortal",
          "type": "string | RefObject<HTMLElement | null>",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\"",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetIcon",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"outer\" | \"inner\"",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintText",
          "type": "string",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\"",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintView",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hintWidth",
          "type": "string",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "label",
          "type": "string",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "leftHelper",
          "type": "string",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "max",
          "type": "string | Date",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "min",
          "type": "string | Date",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "multiplicityMinutes",
          "type": "TimePickerMultiplicity",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "multiplicitySeconds",
          "type": "TimePickerMultiplicity",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "(((event: ChangeEvent<HTMLInputElement> | TimePickerChangeEvent | null, formattedValues: TimePickerChangeEvent) => void) & FormEventHandler<...>)",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placeholder",
          "type": "string",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "readonly",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "required",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "requiredPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretched",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textAfter",
          "type": "string",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textBefore",
          "type": "string",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "valueEdited",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "valueError",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "valueSuccess",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "inheritedFrom": "TimePicker",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TimePicker } from '@daisforge/ui';",
      "minimalUsage": "<TimePicker />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Ограничение допустимого времени",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TimePicker } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{height: '500px'}}>\n            <TimePicker\n                columnsQuantity={3}\n                value=\"15:00:00\"\n                min=\"12:00:00\"\n                max=\"20:00:00\"\n                placeholder=\"00:00:00\"\n            />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Управление форматом времени (с секундами или без)",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TimePicker } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: \"flex\", flexDirection: \"column\", gap: \"32px\", height: '500px'}}>\n            <TimePicker size=\"s\" columnsQuantity={2} placeholder=\"ЧЧ:мм\" />\n            <TimePicker size=\"s\" columnsQuantity={3} placeholder=\"ЧЧ:мм:сс\" />\n        </div>\n    );\n}"
        }
      ]
    },
    "Toast": {
      "name": "Toast",
      "group": "components",
      "folderName": "Toast",
      "role": "primary",
      "description": "Всплывающее короткое уведомление с текстом и кнопкой закрытия.",
      "props": [
        {
          "name": "role",
          "type": "\"alert\" | \"log\" | \"status\" | undefined",
          "required": false,
          "description": "WAI-ARIA роль"
        }
      ],
      "propsTypeName": "ToastProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Toast/Toast.d.ts",
      "type": "wrapper",
      "atomicBase": "Toast",
      "category": "Локальные компоненты",
      "keywords": [
        "snackbar",
        "всплывающее уведомление",
        "временное сообщение"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "closeIconType",
          "type": "\"default\"",
          "required": false,
          "description": "Вид закрывающей иконки в Notification.",
          "inheritedFrom": "Toast",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`",
          "inheritedFrom": "Toast",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasClose",
          "type": "boolean",
          "required": false,
          "description": "Отображать ли иконку закрытия",
          "inheritedFrom": "Toast",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onCloseButtonClick",
          "type": "(() => void)",
          "required": false,
          "description": "Callback при нажатии на кнопку закрытия.",
          "inheritedFrom": "Toast",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pilled",
          "type": "boolean",
          "required": false,
          "description": "Блок подсказки c округлым border-radius",
          "inheritedFrom": "Toast",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"m\"",
          "required": false,
          "description": "Размер блока подсказки",
          "inheritedFrom": "Toast",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "string",
          "required": false,
          "description": "Текстовая надпись",
          "inheritedFrom": "Toast",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "textColor",
          "type": "string",
          "required": false,
          "description": "Цвет текста (по умолчанию берётся цвет из view)",
          "inheritedFrom": "Toast",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"negative\" | \"dark\" | \"light\" | \"info\"",
          "required": false,
          "description": "Вид блока подсказки",
          "inheritedFrom": "Toast",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "width",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "Toast",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Toast } from '@daisforge/ui';",
      "minimalUsage": "<Toast />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Система подсказок",
          "type": "vendor",
          "code": "import React from 'react';\nimport { ToastProvider } from '@daisforge/ui';\nexport const App = () => (\n    <ToastProvider>\n        <div className=\"App\">Hello, world!</div>\n    </ToastProvider>\n);"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Вид иконки",
          "type": "vendor",
          "code": "import React from 'react'\nimport { IconBell } from '@salutejs/plasma-icons';\nimport { useToast, ToastProvider, Button } from '@daisforge/ui'\nexport function App() {\n    const Icon = () => <IconBell color=\"inherit\" size=\"xs\" />;\n    const ToastExample = () => {\n        const { showToast } = useToast()\n        const onShow = () => {}\n        const onHide = () => {}\n        const toastData = {\n            contentLeft: <Icon />,\n            text: 'Подсказка c иконкой',\n            position: 'bottom',\n            role: 'status',\n            hasClose: true,\n            fade: false,\n            size: 'm',\n            view: 'positive',\n            timeout: 3000,\n            onShow,\n            onHide\n        }\n        return <Button onClick={() => showToast(toastData)} text=\"Вызвать подсказку\" />\n    }\n    return (\n        <ToastProvider>\n            <ToastExample />\n        </ToastProvider>\n    )\n}"
        }
      ]
    },
    "ToastProvider": {
      "name": "ToastProvider",
      "group": "components",
      "folderName": "Toast",
      "role": "primary",
      "description": "Провайдер контекста для показа Toast-уведомлений в любом месте приложения.",
      "props": [
        {
          "name": "defaultToastArgs",
          "type": "Partial<ShowToastArgs> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof ToastProvider>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Toast/Toast.d.ts",
      "type": "wrapper",
      "atomicBase": "ToastProvider",
      "category": "Локальные компоненты",
      "keywords": [
        "контекст уведомлений",
        "toast context",
        "провайдер снэкбаров"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { ToastProvider } from '@daisforge/ui';",
      "minimalUsage": "<ToastProvider />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Система подсказок",
          "type": "vendor",
          "code": "import React from 'react';\nimport { ToastProvider } from '@daisforge/ui';\nexport const App = () => (\n    <ToastProvider>\n        <div className=\"App\">Hello, world!</div>\n    </ToastProvider>\n);"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Вид иконки",
          "type": "vendor",
          "code": "import React from 'react'\nimport { IconBell } from '@salutejs/plasma-icons';\nimport { useToast, ToastProvider, Button } from '@daisforge/ui'\nexport function App() {\n    const Icon = () => <IconBell color=\"inherit\" size=\"xs\" />;\n    const ToastExample = () => {\n        const { showToast } = useToast()\n        const onShow = () => {}\n        const onHide = () => {}\n        const toastData = {\n            contentLeft: <Icon />,\n            text: 'Подсказка c иконкой',\n            position: 'bottom',\n            role: 'status',\n            hasClose: true,\n            fade: false,\n            size: 'm',\n            view: 'positive',\n            timeout: 3000,\n            onShow,\n            onHide\n        }\n        return <Button onClick={() => showToast(toastData)} text=\"Вызвать подсказку\" />\n    }\n    return (\n        <ToastProvider>\n            <ToastExample />\n        </ToastProvider>\n    )\n}"
        }
      ]
    },
    "Toolbar": {
      "name": "Toolbar",
      "group": "components",
      "folderName": "Toolbar",
      "role": "primary",
      "description": "Панель инструментов с набором действий, горизонтальная или вертикальная.",
      "props": [],
      "propsTypeName": "ToolbarProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Toolbar/Toolbar.d.ts",
      "type": "wrapper",
      "atomicBase": "Toolbar",
      "category": "Локальные компоненты",
      "keywords": [
        "панель действий",
        "action bar",
        "группа кнопок"
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "ToolbarDivider"
      ],
      "inheritedProps": [
        {
          "name": "hasShadow",
          "type": "boolean",
          "required": false,
          "description": "Включить/выключить тень.",
          "default": "true",
          "inheritedFrom": "Toolbar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\"",
          "required": false,
          "description": "Позиция тулбара.",
          "default": "'vertical'",
          "inheritedFrom": "Toolbar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\"",
          "required": false,
          "description": "Размер тулбара.\nШирина когда orientation равен vertical или высота когда orientation равен horizontal.",
          "default": "'m'",
          "inheritedFrom": "Toolbar",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "description": "Вид тулбара.",
          "inheritedFrom": "Toolbar",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Toolbar } from '@daisforge/ui';",
      "minimalUsage": "<Toolbar />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Компонент  Toolbar  должен содержать контент передаваемый в  children .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Toolbar, Button, ToolbarDivider } from '@daisforge/ui';\nimport { IconEdit } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <Toolbar>\n            <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n            <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n            <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n            <ToolbarDivider />\n            <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n            <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n        </Toolbar>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Размер Toolbar",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Toolbar, Button, ToolbarDivider } from '@daisforge/ui';\nimport { IconEdit } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <Toolbar size=\"s\">\n                <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n                <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n                <ToolbarDivider />\n                <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n                <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n            </Toolbar>\n            <Toolbar size=\"xs\">\n                <Button square size=\"xs\" view=\"clear\" contentLeft={<IconEdit />} />\n                <Button square size=\"xs\" view=\"clear\" contentLeft={<IconEdit />} />\n                <ToolbarDivider />\n                <Button square size=\"xs\" view=\"clear\" contentLeft={<IconEdit />} />\n                <Button square size=\"xs\" view=\"clear\" contentLeft={<IconEdit />} />\n            </Toolbar>\n        </div>\n    );\n}"
        }
      ]
    },
    "ToolbarDivider": {
      "name": "ToolbarDivider",
      "group": "components",
      "folderName": "Toolbar",
      "role": "part",
      "description": "Вертикальный или горизонтальный разделитель между группами кнопок внутри Toolbar",
      "props": [
        {
          "name": "length",
          "type": "string | number | undefined",
          "required": false,
          "description": "Размер разделителя",
          "default": "'100%'"
        },
        {
          "name": "orientation",
          "type": "string | undefined",
          "required": false,
          "description": "Направление разделителя",
          "default": "'horizontal'"
        },
        {
          "name": "size",
          "type": "string | undefined",
          "required": false,
          "description": "Размер разделителя",
          "default": "'m'"
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": "Вид разделителя",
          "default": "'default'"
        }
      ],
      "propsTypeName": "ComponentProps<typeof ToolbarDivider>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Toolbar/Toolbar.d.ts",
      "type": "wrapper",
      "atomicBase": "ToolbarDivider",
      "category": "Локальные компоненты",
      "keywords": [
        "разделитель тулбара",
        "группировка кнопок",
        "vertical divider"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Toolbar",
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { ToolbarDivider } from '@daisforge/ui';",
      "minimalUsage": "<ToolbarDivider />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Компонент  Toolbar  должен содержать контент передаваемый в  children .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Toolbar, Button, ToolbarDivider } from '@daisforge/ui';\nimport { IconEdit } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <Toolbar>\n            <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n            <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n            <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n            <ToolbarDivider />\n            <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n            <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n        </Toolbar>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Размер Toolbar",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Toolbar, Button, ToolbarDivider } from '@daisforge/ui';\nimport { IconEdit } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <Toolbar size=\"s\">\n                <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n                <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n                <ToolbarDivider />\n                <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n                <Button square size=\"s\" view=\"clear\" contentLeft={<IconEdit />} />\n            </Toolbar>\n            <Toolbar size=\"xs\">\n                <Button square size=\"xs\" view=\"clear\" contentLeft={<IconEdit />} />\n                <Button square size=\"xs\" view=\"clear\" contentLeft={<IconEdit />} />\n                <ToolbarDivider />\n                <Button square size=\"xs\" view=\"clear\" contentLeft={<IconEdit />} />\n                <Button square size=\"xs\" view=\"clear\" contentLeft={<IconEdit />} />\n            </Toolbar>\n        </div>\n    );\n}"
        }
      ]
    },
    "TooltipList": {
      "name": "TooltipList",
      "group": "components",
      "folderName": "Tooltip",
      "role": "primary",
      "description": "Тултип-подсказка со списком значений — для фильтров, тегов, мультивыбора.",
      "props": [
        {
          "name": "items",
          "type": "string[]",
          "required": true,
          "description": ""
        },
        {
          "name": "fullWidth",
          "type": "boolean | undefined",
          "required": false,
          "description": "Растягивает внутренние обёртки Tooltip (popover-target, popover-wrapper) на 100% ширины родителя.\nИспользуйте при размещении TooltipList внутри Popover-контента (например, FiltersActions.FiltersButtonWithPopover),\nчтобы дочерний элемент (Combobox и т.д.) занимал всю доступную ширину."
        },
        {
          "name": "groupLabel",
          "type": "string | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TooltipListProps",
      "sourceFile": "packages/ui-kit/src/components/Tooltip/TooltipList.tsx",
      "type": "wrapper",
      "atomicBase": "Tooltip",
      "category": "Локальные компоненты",
      "keywords": [
        "список значений",
        "фильтры",
        "теги",
        "multiselect"
      ],
      "docs": "# TooltipList\n\nКомпонент `TooltipList` является оберткой над [SDDS Tooltip](https://plasma.sberdevices.ru/sdds-finai/components/Tooltip/).\nИдеальное сочетание для работы с множественным выбором элементов.\n\n## Ключевые особенности\n\n- Обертка над SDDS Tooltip для отображения списка выбранных значений\n- Удобная комбинация с Combobox для множественного выбора\n- Подходит для фильтров, тегов и множественного выбора\n\n## Особенности\n\n- Комбинация `TooltipList` и `Combobox` особенно полезна когда нужно показать выбранные значения при наведении, поле ввода имеет ограниченную ширину или выбранных элементов может быть много\n- **Фильтры** — показать примененные фильтры\n- **Теги** — отображение выбранных тегов\n- **Множественный выбор** — видеть выбранные элементы без расширения интерфейса\n\n### Пример с Combobox\n\n<Canvas of={TooltipListStories.WithCombobox} />\n\n> Подробнее о типах и пропсах — [TooltipList API](?path=/docs/локальные-компоненты-tooltiplist-api--docs)",
      "apiDocs": "# TooltipList API\n\n## TooltipListProps\n\n```typescript\ntype TooltipListProps = Omit<TooltipProps, 'text' | 'children'> & {\n  groupLabel?: string;\n  items: string[];\n  children: React.ReactNode;\n  /**\n   * Растягивает внутренние обёртки Tooltip (popover-target, popover-wrapper) на 100% ширины родителя.\n   * Используйте при размещении TooltipList внутри Popover-контента (например, FiltersActions.FiltersButtonWithPopover),\n   * чтобы дочерний элемент (Combobox и т.д.) занимал всю доступную ширину.\n   */\n  fullWidth?: boolean;\n};\n```\n\n> Остальные пропсы наследуются от `TooltipProps` (кроме `text`, `children`)",
      "curatedStories": [
        {
          "exportName": "WithCombobox",
          "displayName": "WithCombobox",
          "type": "full-code",
          "code": "() => {\n    const mockOptions = [\n      { label: 'Блок 1', value: '1' },\n      { label: 'Блок 2', value: '2' },\n      { label: 'Блок 3', value: '3' },\n      { label: 'Блок 4', value: '4' },\n      { label: 'Блок 5', value: '5' },\n    ];\n\n    const [selectedValues, setSelectedValues] = useState<string[]>([]);\n\n    const selectedLabels = selectedValues\n      .map((value) => mockOptions.find((opt) => opt.value === value)?.label)\n      .filter((label): label is string => Boolean(label));\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: 24,\n          maxWidth: 300,\n        }}\n      >\n        <Typography variant=\"BodyM\" bold>\n          Пример с выпадающим списком\n        </Typography>\n\n        <TooltipList\n          groupLabel=\"Выбранные блоки\"\n          items={selectedLabels}\n          trigger={selectedValues.length > 0 ? 'hover' : 'none'}\n        >\n          <Combobox\n            size=\"s\"\n            multiple\n            value={selectedValues}\n            onChange={setSelectedValues}\n            items={mockOptions}\n            placeholder=\"Выберите блоки\"\n            style={{ width: '100%' }}\n          />\n        </TooltipList>\n\n        <Typography variant=\"BodyM\" bold>\n          Как это работает\n        </Typography>\n        <ul\n          style={{\n            marginTop: 0,\n          }}\n        >\n          <li>\n            <Typography variant=\"BodyS\">\n              Выберите несколько элементов в Combobox\n            </Typography>\n          </li>\n          <li>\n            <Typography variant=\"BodyS\">\n              Наведите на поле ввода - увидите Tooltip с выбранными значениями\n            </Typography>\n          </li>\n          <li>\n            <Typography variant=\"BodyS\">\n              Если ничего не выбрано - Tooltip не показывается\n            </Typography>\n          </li>\n        </ul>\n      </div>\n    );\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "animated",
          "type": "boolean",
          "required": false,
          "description": "Анимированное появление/сокрытие.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "arrow",
          "type": "boolean",
          "required": false,
          "description": "Видимость стрелки (хвоста).",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "frame",
          "type": "string | RefObject<HTMLElement>",
          "required": false,
          "description": "В каком контейнере позиционируется(по умолчанию document), можно также указать id элемента или ref для него.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasArrow",
          "type": "boolean",
          "required": false,
          "description": "Видимость стрелки (хвоста).",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hoverTimeout",
          "type": "number",
          "required": false,
          "description": "Время автоматического скрытия тултипа по ховеру в ms",
          "default": "300",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "required": false,
          "description": "Видимость тултипа.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isVisible",
          "type": "boolean",
          "required": false,
          "description": "Видимость тултипа.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maxWidth",
          "type": "string | number",
          "required": false,
          "description": "Максимальная ширина окна (в rem).",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "minWidth",
          "type": "string | number",
          "required": false,
          "description": "Минимальная ширина окна (в rem).",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "mouseEnterDelay",
          "type": "number",
          "required": false,
          "description": "Задержка открытия тултипа в ms.",
          "default": "0",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "mouseLeaveDelay",
          "type": "number",
          "required": false,
          "description": "Задержка скрытия тултипа в ms.",
          "default": "300",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onDismiss",
          "type": "(() => void)",
          "required": false,
          "description": "Событие закрытия тултипа по кнопке Esc.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": false,
          "description": "Видимость тултипа.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "description": "Направление раскрытия тултипа.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "string",
          "required": false,
          "description": "Размер тултипа.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "target",
          "type": "string | number | boolean | ReactElement<any, string | JSXElementConstructor<any>> | ReactFragment | ReactPortal | ((instance: HTMLElement | null) => void) | RefObject<...> | null",
          "required": false,
          "description": "Элемент, рядом с которым произойдет вызов всплывающего окна.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "trigger",
          "type": "\"none\" | \"hover\" | \"click\"",
          "required": false,
          "description": "Действие по target для отображения тултипа",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "usePortal",
          "type": "boolean",
          "required": false,
          "description": "Находится ли в портале.",
          "default": "true",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "string",
          "required": false,
          "description": "Вид тултипа.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "string",
          "required": false,
          "description": "Значение z-index для Tooltip.",
          "default": "9200",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "children",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TooltipList } from '@daisforge/ui';",
      "minimalUsage": "<TooltipList items={[]} />",
      "examples": [
        {
          "exportName": "WithCombobox",
          "displayName": "WithCombobox",
          "type": "full-code",
          "code": "() => {\n    const mockOptions = [\n      { label: 'Блок 1', value: '1' },\n      { label: 'Блок 2', value: '2' },\n      { label: 'Блок 3', value: '3' },\n      { label: 'Блок 4', value: '4' },\n      { label: 'Блок 5', value: '5' },\n    ];\n\n    const [selectedValues, setSelectedValues] = useState<string[]>([]);\n\n    const selectedLabels = selectedValues\n      .map((value) => mockOptions.find((opt) => opt.value === value)?.label)\n      .filter((label): label is string => Boolean(label));\n\n    return (\n      <div\n        style={{\n          display: 'flex',\n          flexDirection: 'column',\n          gap: 24,\n          maxWidth: 300,\n        }}\n      >\n        <Typography variant=\"BodyM\" bold>\n          Пример с выпадающим списком\n        </Typography>\n\n        <TooltipList\n          groupLabel=\"Выбранные блоки\"\n          items={selectedLabels}\n          trigger={selectedValues.length > 0 ? 'hover' : 'none'}\n        >\n          <Combobox\n            size=\"s\"\n            multiple\n            value={selectedValues}\n            onChange={setSelectedValues}\n            items={mockOptions}\n            placeholder=\"Выберите блоки\"\n            style={{ width: '100%' }}\n          />\n        </TooltipList>\n\n        <Typography variant=\"BodyM\" bold>\n          Как это работает\n        </Typography>\n        <ul\n          style={{\n            marginTop: 0,\n          }}\n        >\n          <li>\n            <Typography variant=\"BodyS\">\n              Выберите несколько элементов в Combobox\n            </Typography>\n          </li>\n          <li>\n            <Typography variant=\"BodyS\">\n              Наведите на поле ввода - увидите Tooltip с выбранными значениями\n            </Typography>\n          </li>\n          <li>\n            <Typography variant=\"BodyS\">\n              Если ничего не выбрано - Tooltip не показывается\n            </Typography>\n          </li>\n        </ul>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Usage",
          "displayName": "Использование в TooltipList.stories.tsx",
          "type": "usage",
          "code": "<TooltipList\n          groupLabel=\"Выбранные блоки\"\n          items={selectedLabels}\n          trigger={selectedValues.length > 0 ? 'hover' : 'none'}\n        >\n          <Combobox\n            size=\"s\"\n            multiple\n            value={selectedValues}\n            onChange={setSelectedValues}\n            items={mockOptions}\n            placeholder=\"Выберите блоки\"\n            style={{ width: '100%' }}\n          />\n        </TooltipList>",
          "sourceFile": "packages/storybook/src/stories/TooltipList/TooltipList.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Отображение при взаимодействии с target",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Tooltip, Button } from '@daisforge/ui';\nexport function App() {\n    return (\n        <>\n            <Tooltip target={(<Button>trigger: hover</Button>)} text=\"По ховеру\" placement=\"right\" hasArrow trigger=\"hover\" hoverTimeout={500} />\n            <br />\n            <Tooltip target={(<Button>trigger: click</Button>)} text=\"По клику\" placement=\"right\" hasArrow trigger=\"click\" closeOnEsc closeOnOverlayClick />\n        </>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Базовое применение",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Tooltip, Button } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{display: 'grid', gridTemplateColumns: 'repeat(3, max-content)', gridGap: '1rem 3.5rem', padding: '3.5rem'}}>\n            <Tooltip\n                target={<Tooltip target={<Button>Btn</Button>} placement=\"left\" opened text=\"left\" />}\n                placement=\"top-start\"\n                opened\n                text=\"top-start\"\n                view=\"default\"\n            />\n            <Tooltip target={<Button>Btn</Button>} placement=\"top\" opened text=\"top\" />\n            <Tooltip\n                target={<Tooltip target={<Button>Btn</Button>} placement=\"right\" opened text=\"right\" />}\n                placement=\"top-end\"\n                opened\n                text=\"top-end\"\n            />\n            <Tooltip target={<Button>Btn</Button>} placement=\"bottom-start\" opened text=\"bottom-start\" />\n            <Tooltip target={<Button>Btn</Button>} placement=\"bottom\" opened text=\"bottom\" />\n            <Tooltip target={<Button>Btn</Button>} placement=\"bottom-end\" opened text=\"bottom-end\" />\n        </div>\n    );\n}"
        }
      ]
    },
    "Tooltip": {
      "name": "Tooltip",
      "group": "components",
      "folderName": "Tooltip",
      "role": "primary",
      "description": "Всплывающая подсказка у элемента при наведении или фокусе.",
      "props": [],
      "propsTypeName": "TooltipProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Tooltip/Tooltip.d.ts",
      "type": "wrapper",
      "atomicBase": "Tooltip",
      "category": "Локальные компоненты",
      "keywords": [
        "подсказка",
        "hint",
        "hover",
        "тултип"
      ],
      "chooseWhen": "Стабильная версия на текущий момент — показ по наведению/фокусу. Нужен явный выбор триггера, включая клик — TooltipBeta. Новый проект - TooltipBeta.",
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "text",
          "type": "ReactNode",
          "required": true,
          "description": "Текст тултипа.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "animated",
          "type": "boolean",
          "required": false,
          "description": "Анимированное появление/сокрытие.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "arrow",
          "type": "boolean",
          "required": false,
          "description": "Видимость стрелки (хвоста).",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "frame",
          "type": "string | RefObject<HTMLElement>",
          "required": false,
          "description": "В каком контейнере позиционируется(по умолчанию document), можно также указать id элемента или ref для него.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasArrow",
          "type": "boolean",
          "required": false,
          "description": "Видимость стрелки (хвоста).",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hoverTimeout",
          "type": "number",
          "required": false,
          "description": "Время автоматического скрытия тултипа по ховеру в ms",
          "default": "300",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isOpen",
          "type": "boolean",
          "required": false,
          "description": "Видимость тултипа.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isVisible",
          "type": "boolean",
          "required": false,
          "description": "Видимость тултипа.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "maxWidth",
          "type": "string | number",
          "required": false,
          "description": "Максимальная ширина окна (в rem).",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "minWidth",
          "type": "string | number",
          "required": false,
          "description": "Минимальная ширина окна (в rem).",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "mouseEnterDelay",
          "type": "number",
          "required": false,
          "description": "Задержка открытия тултипа в ms.",
          "default": "0",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "mouseLeaveDelay",
          "type": "number",
          "required": false,
          "description": "Задержка скрытия тултипа в ms.",
          "default": "300",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onDismiss",
          "type": "(() => void)",
          "required": false,
          "description": "Событие закрытия тултипа по кнопке Esc.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": false,
          "description": "Видимость тултипа.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "placement",
          "type": "Placement | ComputedPlacement[]",
          "required": false,
          "description": "Направление раскрытия тултипа.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "string",
          "required": false,
          "description": "Размер тултипа.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "target",
          "type": "string | number | boolean | ReactElement<any, string | JSXElementConstructor<any>> | ReactFragment | ReactPortal | ((instance: HTMLElement | null) => void) | RefObject<...> | null",
          "required": false,
          "description": "Элемент, рядом с которым произойдет вызов всплывающего окна.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "trigger",
          "type": "\"none\" | \"hover\" | \"click\"",
          "required": false,
          "description": "Действие по target для отображения тултипа",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "usePortal",
          "type": "boolean",
          "required": false,
          "description": "Находится ли в портале.",
          "default": "true",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "string",
          "required": false,
          "description": "Вид тултипа.",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "string",
          "required": false,
          "description": "Значение z-index для Tooltip.",
          "default": "9200",
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "children",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Tooltip",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Tooltip } from '@daisforge/ui';",
      "minimalUsage": "<Tooltip text={'Контент'} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в Table.tsx",
          "type": "usage",
          "code": "<Tooltip\n                    text=\"Кастомная фича обновить\"\n                    trigger=\"hover\"\n                    mouseEnterDelay={750}\n                    usePortal\n                    animated\n                    target={\n                      <EmbedIconButton\n                        size=\"m\"\n                        onClick={() => {\n                          // eslint-disable-next-line no-alert\n                          alert(\n                            'Click on customFeatureRefresh in ControlBlock',\n                          );\n                        }}\n                      >\n                        <IconRefresh size=\"s\" />\n                      </EmbedIconButton>\n                    }\n                  />",
          "sourceFile": "packages/vite-project/src/pages/Table.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в Table.multipleFeatures.stories.tsx",
          "type": "usage",
          "code": "<Tooltip\n                        text=\"Кастомная фича обновить\"\n                        trigger=\"hover\"\n                        mouseEnterDelay={750}\n                        usePortal\n                        animated\n                        target={\n                          <EmbedIconButton\n                            size=\"m\"\n                            onClick={() => {\n                              // eslint-disable-next-line no-alert\n                              alert(\n                                'Click on customFeatureRefresh in ControlBlock',\n                              );\n                            }}\n                            style={{\n                              width: '40px',\n                              height: '40px',\n                              display: 'flex',\n                              alignItems: 'center',\n                              justifyContent: 'center',\n                            }}\n                          >\n                            <IconRefresh size=\"s\" />\n                          </EmbedIconButton>\n                        }\n                      />",
          "sourceFile": "packages/storybook/src/stories/Table/Table.multipleFeatures.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Отображение при взаимодействии с target",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Tooltip, Button } from '@daisforge/ui';\nexport function App() {\n    return (\n        <>\n            <Tooltip target={(<Button>trigger: hover</Button>)} text=\"По ховеру\" placement=\"right\" hasArrow trigger=\"hover\" hoverTimeout={500} />\n            <br />\n            <Tooltip target={(<Button>trigger: click</Button>)} text=\"По клику\" placement=\"right\" hasArrow trigger=\"click\" closeOnEsc closeOnOverlayClick />\n        </>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Базовое применение",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Tooltip, Button } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{display: 'grid', gridTemplateColumns: 'repeat(3, max-content)', gridGap: '1rem 3.5rem', padding: '3.5rem'}}>\n            <Tooltip\n                target={<Tooltip target={<Button>Btn</Button>} placement=\"left\" opened text=\"left\" />}\n                placement=\"top-start\"\n                opened\n                text=\"top-start\"\n                view=\"default\"\n            />\n            <Tooltip target={<Button>Btn</Button>} placement=\"top\" opened text=\"top\" />\n            <Tooltip\n                target={<Tooltip target={<Button>Btn</Button>} placement=\"right\" opened text=\"right\" />}\n                placement=\"top-end\"\n                opened\n                text=\"top-end\"\n            />\n            <Tooltip target={<Button>Btn</Button>} placement=\"bottom-start\" opened text=\"bottom-start\" />\n            <Tooltip target={<Button>Btn</Button>} placement=\"bottom\" opened text=\"bottom\" />\n            <Tooltip target={<Button>Btn</Button>} placement=\"bottom-end\" opened text=\"bottom-end\" />\n        </div>\n    );\n}"
        }
      ]
    },
    "TooltipBeta": {
      "name": "TooltipBeta",
      "group": "components",
      "folderName": "TooltipBeta",
      "role": "primary",
      "description": "Лёгкая всплывающая подсказка (beta) с триггерами клик / hover / фокус.",
      "props": [
        {
          "name": "children",
          "type": "string",
          "required": true,
          "description": "Контент всплывающего окна."
        },
        {
          "name": "target",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>>",
          "required": true,
          "description": "Целевой элемент взаимодействия с всплывающим окном."
        },
        {
          "name": "delayClose",
          "type": "number | undefined",
          "required": false,
          "description": "Задержка перед скрытием, мс. (При trigger === 'hover')",
          "default": "0"
        },
        {
          "name": "delayOpen",
          "type": "number | undefined",
          "required": false,
          "description": "Задержка перед раскрытием, мс. (При trigger === 'hover')",
          "default": "0"
        },
        {
          "name": "flip",
          "type": "boolean | undefined",
          "required": false,
          "description": "Коррекция placement, если всплывающее окно находится за пределами экрана.",
          "default": "false"
        },
        {
          "name": "hasTail",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включение хвостика у всплывающего окна.",
          "default": "true"
        },
        {
          "name": "iconSlot",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для иконки слева."
        },
        {
          "name": "offset",
          "type": "number | undefined",
          "required": false,
          "description": "Отступ всплывающего окна относительно target.",
          "default": "0"
        },
        {
          "name": "placement",
          "type": "Placement | undefined",
          "required": false,
          "description": "Сторона раскрытия окна относительно target-элемента.",
          "default": "bottom"
        },
        {
          "name": "portal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "Портал для всплывающего окна.\nПринимает id контейнера или ref.\nЕсли контейнер с заданным id не найден на странице,\nто он будет автоматически создан перед </body>.",
          "default": "Без использования portal всплывающее окно рендерится перед </body>."
        },
        {
          "name": "shift",
          "type": "boolean | undefined",
          "required": false,
          "description": "Смещение всплывающего окна при соприкосновении с границами экрана.",
          "default": "false"
        },
        {
          "name": "size",
          "type": "\"m\" | \"s\" | undefined",
          "required": false,
          "description": "Размер компонента."
        },
        {
          "name": "trigger",
          "type": "\"click\" | \"hover\" | \"focus\" | undefined",
          "required": false,
          "description": "Способ скрытия/раскрытия всплывающего окна.",
          "default": "click"
        },
        {
          "name": "view",
          "type": "\"default\" | undefined",
          "required": false,
          "description": "Вид компонента."
        },
        {
          "name": "zIndex",
          "type": "number | undefined",
          "required": false,
          "description": "CSS-свойство z-index всплывающего окна.",
          "default": "1000"
        }
      ],
      "propsTypeName": "TooltipBetaCompProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/dist/beta/types/Tooltip/Tooltip.d.ts",
      "type": "wrapper",
      "atomicBase": "Tooltip",
      "atomicSubpath": "beta",
      "category": "Локальные компоненты",
      "keywords": [
        "подсказка",
        "beta-компонент",
        "hover click focus",
        "тултип"
      ],
      "chooseWhen": "Новая версия с лучшей логикой работы слоев. Точно в новых проектах использовать его. Или в старых проектах, если не устроил обычный Tooltip. И точно если Нужен явный выбор триггера (клик/hover/фокус)",
      "hasCuratedMeta": true,
      "inheritedProps": [],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TooltipBeta } from '@daisforge/ui';",
      "minimalUsage": "<TooltipBeta children={'значение'} target={'Контент'} />",
      "examples": []
    },
    "Tour": {
      "name": "Tour",
      "group": "components",
      "folderName": "Tour",
      "role": "primary",
      "description": "Пошаговый онбординг-тур с подсветкой целевых элементов интерфейса.",
      "props": [],
      "propsTypeName": "TourProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Tour/Tour.d.ts",
      "type": "wrapper",
      "atomicBase": "Tour",
      "category": "Локальные компоненты",
      "keywords": [
        "онбординг",
        "walkthrough",
        "подсветка элемента"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "renderStep",
          "type": "(current: number, length: number, last: boolean, step: TourStep, goToStep: (index: number) => void) => ReactNode",
          "required": true,
          "description": "Callback для отображения карточки. Требуется вернуть ReactNode.\nПятый аргумент `goToStep` позволяет перейти к произвольному шагу",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "steps",
          "type": "TourStep[]",
          "required": true,
          "description": "Список шагов.",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "current",
          "type": "number",
          "required": false,
          "description": "Индекс активного шага",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultCurrent",
          "type": "number",
          "required": false,
          "description": "Активный шаг по-умолчанию",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultOpen",
          "type": "boolean",
          "required": false,
          "description": "Флаг открытия тура по-умолчанию",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasTail",
          "type": "boolean",
          "required": false,
          "description": "Включение стрелки у карточки тура",
          "default": "false",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "highlightBorderRadius",
          "type": "BorderRadius<string | number>",
          "required": false,
          "description": "Скругление для высветленного блока",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "highlightOffset",
          "type": "number",
          "required": false,
          "description": "Отступ высветленного блока",
          "default": "`4`",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "offset",
          "type": "[number, number]",
          "required": false,
          "description": "Отступ карточки относительно целевого элемента",
          "default": "`[12, 12]`",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onChange",
          "type": "((current: number) => void)",
          "required": false,
          "description": "Callback при смене шага",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onClose",
          "type": "(() => void)",
          "required": false,
          "description": "Callback при закрытии тура",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "overlayColor",
          "type": "Color",
          "required": false,
          "description": "Цвет фона у тура",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderHighlight",
          "type": "((props: TourHighlightProps) => ReactNode)",
          "required": false,
          "description": "Кастомный рендер подсветки целевого элемента.\nЕсли не передан — используется дефолтный Highlight (box-shadow spotlight).",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\"",
          "required": false,
          "description": "Размер тура",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "tailColor",
          "type": "Color",
          "required": false,
          "description": "Цвет стрелки",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "tailHeight",
          "type": "number",
          "required": false,
          "description": "Высота стрелки",
          "default": "8",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "tailWidth",
          "type": "number",
          "required": false,
          "description": "Ширина стрелки",
          "default": "20",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "description": "Вид тура",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "withOverlay",
          "type": "boolean",
          "required": false,
          "description": "Наличие overlay у тура",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "zIndex",
          "type": "ZIndex",
          "required": false,
          "description": "Значение z-index",
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "open",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Tour",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Tour } from '@daisforge/ui';",
      "minimalUsage": "<Tour renderStep={() => {}} steps={[]} />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Позиционирование карточки",
          "type": "vendor",
          "code": "import React, { useRef, useState } from 'react';\nimport { Tour, Button } from '@daisforge/ui';\nexport function App() {\n    const ref1 = useRef(null);\n    const [open, setOpen] = useState(false);\n    const onClose = () => setOpen(false);\n    const steps = [{ target: ref1, title: 'Отступ 32px', description: 'offset={[32, 12]} — увеличен основной отступ.' }];\n    const renderStep = (cur, length, last, step) => (\n        <div style={{ padding: '1rem', background: 'var(--surface-solid-card)', borderRadius: '0.75rem', boxShadow: '0 4px 16px rgba(0,0,0,0.12)', maxWidth: '16rem', display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>\n            {step.title && <strong>{step.title}</strong>}\n            {step.description && <small style={{ opacity: 0.7 }}>{step.description}</small>}\n            <Button size=\"s\" view=\"default\" onClick={onClose} style={{ marginTop: '0.25rem' }}>Закрыть</Button>\n        </div>\n    );\n    return (\n        <div style={{ padding: '2rem', display: 'flex', flexDirection: 'column', gap: '4rem' }}>\n            <Button ref={ref1} view=\"secondary\" style={{ alignSelf: 'flex-start' }}>Целевой элемент</Button>\n            <Button view=\"default\" onClick={() => setOpen(true)}>Запустить тур</Button>\n            <Tour open={open} current={0} onClose={onClose} steps={steps} highlightBorderRadius=\"1rem\" renderStep={renderStep} offset={[32, 12]} />\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "target target Свойство  target  принимает три формата",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { Tour, Button } from '@daisforge/ui';\nexport function App() {\n    const [open, setOpen] = useState(false);\n    const [current, setCurrent] = useState(0);\n    const onClose = () => { setOpen(false); setCurrent(0); };\n    const steps = [\n        { target: '#tour-doc-btn-1', title: 'Кнопка 1', description: 'Найдена по CSS-селектору #tour-doc-btn-1.' },\n        { target: '#tour-doc-btn-2', title: 'Кнопка 2', description: 'Найдена по CSS-селектору #tour-doc-btn-2.', placement: 'top' },\n    ];\n    const renderStep = (cur, length, last, step, goToStep) => (\n        <div style={{ padding: '1rem', background: 'var(--surface-solid-card)', borderRadius: '0.75rem', boxShadow: '0 4px 16px rgba(0,0,0,0.12)', maxWidth: '16rem', display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>\n            {step.title && <strong>{step.title}</strong>}\n            {step.description && <small style={{ opacity: 0.7 }}>{step.description}</small>}\n            <div style={{ display: 'flex', gap: '0.5rem', marginTop: '0.25rem' }}>\n                {cur > 0 && <Button size=\"s\" view=\"secondary\" onClick={() => goToStep(cur - 1)}>Назад</Button>}\n                {last ? <Button size=\"s\" view=\"default\" onClick={onClose}>Закрыть</Button> : <Button size=\"s\" view=\"default\" onClick={() => goToStep(cur + 1)}>Далее</Button>}\n            </div>\n        </div>\n    );\n    return (\n        <div style={{ padding: '2rem', display: 'flex', flexDirection: 'column', gap: '4rem' }}>\n            <div style={{ display: 'flex', justifyContent: 'space-between' }}>\n                <Button id=\"tour-doc-btn-1\" view=\"secondary\">Кнопка 1</Button>\n                <Button id=\"tour-doc-btn-2\" view=\"secondary\">Кнопка 2</Button>\n            </div>\n            <Button view=\"default\" onClick={() => setOpen(true)}>Запустить тур</Button>\n            <Tour open={open} current={current} onChange={setCurrent} onClose={onClose} steps={steps} renderStep={renderStep} highlightBorderRadius=\"1rem\" />\n        </div>\n    );\n}"
        }
      ]
    },
    "TourWidgetBullet": {
      "name": "TourWidgetBullet",
      "group": "components",
      "folderName": "TourWidget",
      "role": "part",
      "description": "Одна точка-индикатор шага степпера TourWidget, подсвечивается при активном шаге",
      "props": [
        {
          "name": "active",
          "type": "boolean | undefined",
          "required": false,
          "description": "Ручное переопределение активного состояния."
        },
        {
          "name": "index",
          "type": "number | undefined",
          "required": false,
          "description": "Индекс буллета. Сравнивается с `TourWidget.activeStepIndex`."
        },
        {
          "name": "$css",
          "type": "TourWidgetCss | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TourWidgetBulletProps",
      "sourceFile": "packages/ui-kit/src/components/TourWidget/components/TourWidgetBullet.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "точка степпера",
        "step indicator",
        "активный шаг"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TourWidget",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "TourWidget",
        "part": "Bullet"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { TourWidgetBullet } from '@daisforge/ui';",
      "minimalUsage": "<TourWidgetBullet />",
      "examples": []
    },
    "TourWidgetBullets": {
      "name": "TourWidgetBullets",
      "group": "components",
      "folderName": "TourWidget",
      "role": "part",
      "description": "Ряд точек-пагинации шагов TourWidget с прокруткой окна вокруг активного шага",
      "props": [
        {
          "name": "count",
          "type": "number",
          "required": true,
          "description": ""
        },
        {
          "name": "$css",
          "type": "TourWidgetCss | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TourWidgetBulletsProps",
      "sourceFile": "packages/ui-kit/src/components/TourWidget/components/TourWidgetBullets.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "пагинация шагов",
        "carousel dots",
        "прогресс тура"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TourWidget",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "TourWidget",
        "part": "Bullets"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { TourWidgetBullets } from '@daisforge/ui';",
      "minimalUsage": "<TourWidgetBullets count={0} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в TourWidget.examples.tsx",
          "type": "usage",
          "code": "<TourWidget.Bullets\n              count={tourStepsCount}\n              $css={{ marginInline: 'auto' }}\n            />",
          "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TourWidget.examples.tsx",
          "type": "usage",
          "code": "<TourWidget.Bullets count={tourStepsCount} />",
          "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
        }
      ]
    },
    "TourWidgetContent": {
      "name": "TourWidgetContent",
      "group": "components",
      "folderName": "TourWidget",
      "role": "part",
      "description": "Слот основного контента карточки-подсказки TourWidget (текст, медиа)",
      "props": [
        {
          "name": "$css",
          "type": "TourWidgetCss | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TourWidgetContentProps",
      "sourceFile": "packages/ui-kit/src/components/TourWidget/components/TourWidgetContent.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "контент подсказки",
        "слот описания",
        "onboarding content"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TourWidget",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "TourWidget",
        "part": "Content"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { TourWidgetContent } from '@daisforge/ui';",
      "minimalUsage": "<TourWidgetContent />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в TourWidget.examples.tsx",
          "type": "usage",
          "code": "<TourWidget.Content>\n          <MediaPlaceholder width={266} height={266} />\n        </TourWidget.Content>",
          "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TourWidget.examples.tsx",
          "type": "usage",
          "code": "<TourWidget.Content>\n          <MediaPlaceholder width={240} height={240} />\n        </TourWidget.Content>",
          "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
        }
      ]
    },
    "TourWidgetFooter": {
      "name": "TourWidgetFooter",
      "group": "components",
      "folderName": "TourWidget",
      "role": "part",
      "description": "Слот футера карточки TourWidget, обычно с кнопками навигации по туру",
      "props": [
        {
          "name": "$css",
          "type": "TourWidgetCss | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TourWidgetFooterProps",
      "sourceFile": "packages/ui-kit/src/components/TourWidget/components/TourWidgetFooter.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "кнопки навигации",
        "footer тура",
        "onboarding actions"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TourWidget",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "TourWidget",
        "part": "Footer"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { TourWidgetFooter } from '@daisforge/ui';",
      "minimalUsage": "<TourWidgetFooter />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в TourWidget.examples.tsx",
          "type": "usage",
          "code": "<TourWidget.Footer>\n          <Box\n            $css={{\n              display: 'flex',\n              flexDirection: 'column',\n            }}\n          >\n            <TourWidget.Bullets\n              count={tourStepsCount}\n              $css={{ marginInline: 'auto' }}\n            />\n            <Box\n              $css={{\n                display: 'flex',\n                flexDirection: 'row',\n                gap: '4px',\n                marginTop: '20px',\n              }}\n            >\n              <Button\n                size=\"s\"\n                stretching=\"filled\"\n                view=\"secondary\"\n                onClick={() =>\n                  setActiveStepIndex((current) =>\n                    clampStep(current - 1, tourStepsCount),\n                  )\n                }\n              >\n                Назад\n              </Button>\n              <Button\n                stretching=\"filled\"\n                size=\"s\"\n                view=\"white\"\n                onClick={() =>\n                  setActiveStepIndex((current) =>\n                    clampStep(current + 1, tourStepsCount),\n                  )\n                }\n              >\n                Далее\n              </Button>\n            </Box>\n            <LinkButton\n              size=\"s\"\n              view=\"default\"\n              onClick={() => setActiveStepIndex(0)}\n            >\n              Пропустить всё\n            </LinkButton>\n          </Box>\n        </TourWidget.Footer>",
          "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TourWidget.examples.tsx",
          "type": "usage",
          "code": "<TourWidget.Footer>\n          <Box\n            $css={{\n              display: 'flex',\n              alignItems: 'center',\n              justifyContent: 'space-between',\n              gap: '32px',\n              width: '100%',\n            }}\n          >\n            <Box\n              $css={{\n                display: 'flex',\n                alignItems: 'center',\n                gap: '32px',\n                minWidth: 0,\n              }}\n            >\n              <LinkButton\n                size=\"s\"\n                view=\"default\"\n                onClick={() => setActiveStepIndex(0)}\n              >\n                Пропустить всё\n              </LinkButton>\n              <TourWidget.Bullets count={tourStepsCount} />\n            </Box>\n            <Box\n              $css={{\n                display: 'flex',\n                alignItems: 'center',\n                gap: '4px',\n              }}\n            >\n              <Button\n                size=\"s\"\n                view=\"secondary\"\n                onClick={() =>\n                  setActiveStepIndex((current) =>\n                    clampStep(current - 1, tourStepsCount),\n                  )\n                }\n              >\n                Назад\n              </Button>\n              <Button\n                size=\"s\"\n                view=\"white\"\n                onClick={() =>\n                  setActiveStepIndex((current) =>\n                    clampStep(current + 1, tourStepsCount),\n                  )\n                }\n              >\n                Далее\n              </Button>\n            </Box>\n          </Box>\n        </TourWidget.Footer>",
          "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
        }
      ]
    },
    "TourWidgetHeader": {
      "name": "TourWidgetHeader",
      "group": "components",
      "folderName": "TourWidget",
      "role": "part",
      "description": "Заголовок и описание карточки-подсказки TourWidget",
      "props": [
        {
          "name": "$css",
          "type": "TourWidgetCss | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "description",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "title",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TourWidgetHeaderProps",
      "sourceFile": "packages/ui-kit/src/components/TourWidget/components/TourWidgetHeader.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "заголовок подсказки",
        "onboarding title",
        "описание шага"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "TourWidget",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "TourWidget",
        "part": "Header"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { TourWidgetHeader } from '@daisforge/ui';",
      "minimalUsage": "<TourWidgetHeader />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в TourWidget.examples.tsx",
          "type": "usage",
          "code": "<TourWidget.Header title=\"Title\" description=\"Description\" />",
          "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TourWidget.examples.tsx",
          "type": "usage",
          "code": "<TourWidget.Header\n          title={'Знакомьтесь:\\nновые возможности'}\n          description={\n            'Режимы просмотра\\nОбщий реестр — все пилоты со статусом «В реестре»\\n• Мои пилоты — только ваши проекты, включая черновики'\n          }\n        />",
          "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
        }
      ]
    },
    "TourWidget": {
      "name": "TourWidget",
      "group": "components",
      "folderName": "TourWidget",
      "role": "primary",
      "description": "Карточка шага тура: шапка, контент, буллеты — без логики сценария.",
      "props": [
        {
          "name": "activeStepIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Активный шаг тура. Нумерация с нуля."
        },
        {
          "name": "$css",
          "type": "TourWidgetCss | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "orientation",
          "type": "TourWidgetOrientation | undefined",
          "required": false,
          "description": "",
          "default": "'vertical'"
        }
      ],
      "propsTypeName": "TourWidgetProps",
      "compoundParts": [
        {
          "name": "Header",
          "typeName": "TourWidgetHeaderProps",
          "props": [
            {
              "name": "$css",
              "type": "TourWidgetCss | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "description",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "title",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Content",
          "typeName": "TourWidgetContentProps",
          "props": [
            {
              "name": "$css",
              "type": "TourWidgetCss | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Footer",
          "typeName": "TourWidgetFooterProps",
          "props": [
            {
              "name": "$css",
              "type": "TourWidgetCss | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Bullet",
          "typeName": "TourWidgetBulletProps",
          "props": [
            {
              "name": "active",
              "type": "boolean | undefined",
              "required": false,
              "description": "Ручное переопределение активного состояния."
            },
            {
              "name": "index",
              "type": "number | undefined",
              "required": false,
              "description": "Индекс буллета. Сравнивается с `TourWidget.activeStepIndex`."
            },
            {
              "name": "$css",
              "type": "TourWidgetCss | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Bullets",
          "typeName": "TourWidgetBulletsProps",
          "props": [
            {
              "name": "count",
              "type": "number",
              "required": true,
              "description": ""
            },
            {
              "name": "$css",
              "type": "TourWidgetCss | undefined",
              "required": false,
              "description": ""
            }
          ]
        }
      ],
      "sourceFile": "packages/ui-kit/src/components/TourWidget/TourWidget.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "карточка тура",
        "онбординг",
        "степ-виджет"
      ],
      "docs": "# TourWidget\n\n`TourWidget` — локальная compound-обертка для карточки тура. Компонент отвечает за внешний вид, раскладку, фон, буллеты и пульсацию через mixin, но не управляет сценарием тура, переходами между шагами и позиционированием относительно target-элемента.\n\n## Ключевые особенности\n\n- Две ориентации: `vertical` и `horizontal`.\n- Compound API: `TourWidget.Header`, `TourWidget.Content`, `TourWidget.Footer`, `TourWidget.Bullets`, `TourWidget.Bullet`.\n- Заголовок и описание сохраняют переводы строк `\\n` (`white-space: pre-line`); повторяющиеся пробелы схлопываются, автоматический перенос по ширине сохраняется.\n- Активный шаг передается в `TourWidget` через `activeStepIndex`, а `Bullet` читает его автоматически.\n- `Content` не фиксирует размер вложенного элемента и дает ему занять `100%`.\n- `$css` есть у корневого компонента и compound-частей для локального переопределения стилей.\n- Пульсация вынесена в `tourPulseMixin` и применяется отдельно к target-элементу.\n\n## Использование\n\n```tsx\n\n```\n\nБазовая схема работы:\n\n```tsx\nconst [activeStepIndex, setActiveStepIndex] = useState(0);\n\n<ViewContainer view=\"onDark\">\n  <TourWidget\n    activeStepIndex={activeStepIndex}\n    $css={{ width: '286px', height: '480px' }}\n  >\n    <TourWidget.Content>\n      <Box as=\"img\" src={imageSrc} alt=\"\" $css={{ width: '100%' }} />\n    </TourWidget.Content>\n    <TourWidget.Header title=\"Title\" description=\"Description\" />\n    <TourWidget.Footer>\n      <TourWidget.Bullets count={steps.length} />\n      <Button onClick={() => setActiveStepIndex((step) => step + 1)}>\n        Далее\n      </Button>\n    </TourWidget.Footer>\n  </TourWidget>\n</ViewContainer>;\n```\n\n## Compound-компоненты\n\n- `TourWidget.Header` — выводит `title`, `description` и дополнительные `children`.\n- `TourWidget.Content` — область под изображение, видео, иллюстрацию или любой ReactNode.\n- `TourWidget.Footer` — произвольная зона для кнопок, ссылки пропуска и буллетов.\n- `TourWidget.Bullets` — контейнер, который рисует массив буллетов по `count`; если буллетов больше семи, отображает окно максимум на 7 точек, прокручивает его по `activeStepIndex`, а крайние видимые точки уменьшаются до `6px`, когда за ними есть скрытые шаги.\n- `TourWidget.Bullet` — низкоуровневый визуальный индикатор шага. Активность считается как `active ?? index === activeStepIndex`.\n\n## Правильная композиция\n\n`TourWidget.Header`, `TourWidget.Content` и `TourWidget.Footer` нужно вкладывать напрямую в `TourWidget`. Компонент использует эти части как слоты: так он понимает, есть ли в туре медиа-зона, и выбирает корректную раскладку для `horizontal` и `vertical`.\n\nПравильно:\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n  <TourWidget.Content>\n    <Box as=\"img\" src={imageSrc} alt=\"\" $css={{ width: '100%' }} />\n  </TourWidget.Content>\n  <TourWidget.Header title=\"Title\" description=\"Description\" />\n  <TourWidget.Footer>\n    <TourWidget.Bullets count={steps.length} />\n  </TourWidget.Footer>\n</TourWidget>\n```\n\nЕсли нужен свой wrapper для картинки, кнопок или текста, размещайте его внутри соответствующего slot-компонента.\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n  <TourWidget.Content>\n    <MyImageWrapper>\n      <Box as=\"img\" src={imageSrc} alt=\"\" />\n    </MyImageWrapper>\n  </TourWidget.Content>\n  <TourWidget.Header>\n    <MyHeaderContent />\n  </TourWidget.Header>\n  <TourWidget.Footer>\n    <MyFooterContent />\n  </TourWidget.Footer>\n</TourWidget>\n```\n\nНе оборачивайте сам `TourWidget.Content` во внешний компонент. В таком случае `TourWidget` не сможет определить медиа-зону как свой прямой slot и горизонтальная раскладка будет работать как вариант без `Content`.\n\n```tsx\n<TourWidget orientation=\"horizontal\">\n  <MyContentWrapper>\n    <TourWidget.Content>\n      <Box as=\"img\" src={imageSrc} alt=\"\" />\n    </TourWidget.Content>\n  </MyContentWrapper>\n  <TourWidget.Header title=\"Title\" />\n  <TourWidget.Footer />\n</TourWidget>\n```\n\n## Активный шаг\n\n`activeStepIndex` хранится на корневом `TourWidget`. Внутри компонент создает локальный context, поэтому не нужно импортировать `Provider` или прокидывать `active` в каждый буллет.\n\n```tsx\n<TourWidget activeStepIndex={5}>\n  <TourWidget.Footer>\n    <TourWidget.Bullets count={10} />\n  </TourWidget.Footer>\n</TourWidget>\n```\n\nДля переключения шагов используйте свои кнопки или другой внешний контрол. `TourWidget.Bullets` не кликабельный и только отображает `activeStepIndex`.\n\n```tsx\n<TourWidget activeStepIndex={activeStepIndex}>\n  <TourWidget.Footer>\n    <TourWidget.Bullets count={10} />\n    <Button onClick={() => setActiveStepIndex((step) => step + 1)}>\n      Далее\n    </Button>\n  </TourWidget.Footer>\n</TourWidget>\n```\n\nЕсли нужна полностью ручная раскладка или состояние отдельной точки, используйте низкоуровневый `TourWidget.Bullet` и передайте `active`.\n\n## Content\n\n`TourWidget.Content` не задает жесткий размер медиа. Размер определяет вложенная нода или стиль самого `Content`.\n\n```tsx\n<TourWidget.Content>\n  <Box\n    as=\"img\"\n    src={imageSrc}\n    alt=\"\"\n    $css={{ width: '270px', height: '270px' }}\n  />\n</TourWidget.Content>\n```\n\n## Пульсация\n\nПульсация не встроена в `TourWidget`, потому что target-элемент и позиционирование тура контролируются снаружи. Для target используется `tourPulseMixin`.\n\n```tsx\n\nconst Target = styled(Box)`\n  position: relative;\n\n  &::after {\n    content: '';\n    position: absolute;\n    ${tourPulseMixin()}\n  }\n`;\n```\n\nПо умолчанию `tourPulseMixin` сам задает `inset: -4px` и `border-radius: 16px` и не добавляет заливку на target.\n\n## Темная тема\n\n`TourWidget` всегда используется на темной поверхности. Если внутри футера есть SDDS-кнопки или ссылки, оборачивайте композицию в `ViewContainer view=\"onDark\"`, чтобы вложенные controls взяли on-dark токены без ручных переопределений цвета.\n\n```tsx\n<ViewContainer view=\"onDark\">\n  <TourWidget activeStepIndex={activeStepIndex}>\n    <TourWidget.Footer>\n      <Button view=\"secondary\">Назад</Button>\n      <Button view=\"white\">Далее</Button>\n    </TourWidget.Footer>\n  </TourWidget>\n</ViewContainer>\n```\n\n## CSS-переменные\n\nКорневой `$css` можно использовать для точечной настройки внешнего вида.\n\n```tsx\n<TourWidget\n  $css={{\n    '--tour-widget-min-width': '0',\n    '--tour-widget-border-radius': '16px',\n    '--tour-widget-gradient-frame-height': '34%',\n    '--tour-widget-gradient-frame-fade': '56%',\n  }}\n/>\n```\n\n## Особенности\n\n- `TourWidget` не содержит positioner и не добавляет зависимость на `floating-ui`.\n- Компонент не хранит шаги и не переключает их сам, только отображает `activeStepIndex`.\n- `TourWidget.Bullet` — это span-индикатор, а не интерактивная кнопка.\n- `TourWidget.Bullets` — это div-viewport со сдвигающимся треком точек; при `count > 7` видны максимум семь буллетов.\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tourwidget-api--docs).",
      "apiDocs": "# TourWidget API\n\n## TourWidgetOrientation\n\n```typescript\ntype TourWidgetOrientation = 'vertical' | 'horizontal';\n```\n\n## TourWidgetCss\n\n```typescript\ntype TourWidgetCss = string | CSSObject | FlattenSimpleInterpolation;\n```\n\n## TourWidgetProps\n\n```typescript\ntype TourWidgetProps = ComponentPropsWithoutRef<'div'> & {\n  /**\n   * @default 'vertical'\n   */\n  orientation?: TourWidgetOrientation;\n  /**\n   * Активный шаг тура. Нумерация с нуля.\n   */\n  activeStepIndex?: number;\n  $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Header\n\n```typescript\ntype TourWidgetHeaderProps = Omit<\n  ComponentPropsWithoutRef<'div'>,\n  'title'\n> & {\n  title?: ReactNode;\n  description?: ReactNode;\n  $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Content\n\n```typescript\ntype TourWidgetContentProps = ComponentPropsWithoutRef<'div'> & {\n  children?: ReactNode;\n  $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Footer\n\n```typescript\ntype TourWidgetFooterProps = ComponentPropsWithoutRef<'div'> & {\n  children?: ReactNode;\n  $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Bullets\n\n```typescript\ntype TourWidgetBulletsProps = Omit<\n  ComponentPropsWithoutRef<'div'>,\n  'children' | 'onClick'\n> & {\n  count: number;\n  $css?: TourWidgetCss;\n};\n```\n\n## TourWidget.Bullet\n\n```typescript\ntype TourWidgetBulletProps = Omit<\n  ComponentPropsWithoutRef<'span'>,\n  'onClick'\n> & {\n  /**\n   * Индекс буллета. Сравнивается с `TourWidget.activeStepIndex`.\n   */\n  index?: number;\n  /**\n   * Ручное переопределение активного состояния.\n   */\n  active?: boolean;\n  $css?: TourWidgetCss;\n};\n```",
      "curatedStories": [
        {
          "exportName": "Vertical",
          "displayName": "Вертикальный тур",
          "type": "full-code",
          "code": "function VerticalExample() {\n  const tourStepsCount = 14;\n  const [activeStepIndex, setActiveStepIndex] = useState(0);\n\n  return (\n    <TourView>\n      <TourWidget\n        activeStepIndex={activeStepIndex}\n        $css={{ width: '286px', height: '480px' }}\n      >\n        <TourWidget.Content>\n          <MediaPlaceholder width={266} height={266} />\n        </TourWidget.Content>\n        <TourWidget.Header title=\"Title\" />\n        <TourWidget.Footer>\n          <Box\n            $css={{\n              display: 'flex',\n              flexDirection: 'column',\n            }}\n          >\n            <TourWidget.Bullets\n              count={tourStepsCount}\n              $css={{ marginInline: 'auto' }}\n            />\n            <Box\n              $css={{\n                display: 'flex',\n                flexDirection: 'row',\n                gap: '4px',\n                marginTop: '20px',\n              }}\n            >\n              <Button\n                size=\"s\"\n                stretching=\"filled\"\n                view=\"secondary\"\n                onClick={() =>\n                  setActiveStepIndex((current) =>\n                    clampStep(current - 1, tourStepsCount),\n                  )\n                }\n              >\n                Назад\n              </Button>\n              <Button\n                stretching=\"filled\"\n                size=\"s\"\n                view=\"white\"\n                onClick={() =>\n                  setActiveStepIndex((current) =>\n                    clampStep(current + 1, tourStepsCount),\n                  )\n                }\n              >\n                Далее\n              </Button>\n            </Box>\n            <LinkButton\n              size=\"s\"\n              view=\"default\"\n              onClick={() => setActiveStepIndex(0)}\n            >\n              Пропустить всё\n            </LinkButton>\n          </Box>\n        </TourWidget.Footer>\n      </TourWidget>\n    </TourView>\n  );\n};"
        },
        {
          "exportName": "Horizontal",
          "displayName": "Горизонтальный тур",
          "type": "full-code",
          "code": "function HorizontalExample() {\n  const tourStepsCount = 14;\n  const [activeStepIndex, setActiveStepIndex] = useState(5);\n\n  return (\n    <TourView>\n      <TourWidget\n        orientation=\"horizontal\"\n        activeStepIndex={activeStepIndex}\n        $css={{ width: '720px', height: '260px' }}\n      >\n        <TourWidget.Content>\n          <MediaPlaceholder width={240} height={240} />\n        </TourWidget.Content>\n        <TourWidget.Header title=\"Title\" description=\"Description\" />\n        <TourWidget.Footer>\n          <Box\n            $css={{\n              display: 'flex',\n              alignItems: 'center',\n              justifyContent: 'space-between',\n              gap: '32px',\n              width: '100%',\n            }}\n          >\n            <Box\n              $css={{\n                display: 'flex',\n                alignItems: 'center',\n                gap: '32px',\n                minWidth: 0,\n              }}\n            >\n              <LinkButton\n                size=\"s\"\n                view=\"default\"\n                onClick={() => setActiveStepIndex(0)}\n              >\n                Пропустить всё\n              </LinkButton>\n              <TourWidget.Bullets count={tourStepsCount} />\n            </Box>\n            <Box\n              $css={{\n                display: 'flex',\n                alignItems: 'center',\n                gap: '4px',\n              }}\n            >\n              <Button\n                size=\"s\"\n                view=\"secondary\"\n                onClick={() =>\n                  setActiveStepIndex((current) =>\n                    clampStep(current - 1, tourStepsCount),\n                  )\n                }\n              >\n                Назад\n              </Button>\n              <Button\n                size=\"s\"\n                view=\"white\"\n                onClick={() =>\n                  setActiveStepIndex((current) =>\n                    clampStep(current + 1, tourStepsCount),\n                  )\n                }\n              >\n                Далее\n              </Button>\n            </Box>\n          </Box>\n        </TourWidget.Footer>\n      </TourWidget>\n    </TourView>\n  );\n};"
        },
        {
          "exportName": "LineBreaks",
          "displayName": "Переносы строк",
          "type": "full-code",
          "code": "function LineBreaksExample() {\n  return (\n    <TourView>\n      <TourWidget $css={{ width: '320px', paddingBottom: '24px' }}>\n        <TourWidget.Header\n          title={'Знакомьтесь:\\nновые возможности'}\n          description={\n            'Режимы просмотра\\nОбщий реестр — все пилоты со статусом «В реестре»\\n• Мои пилоты — только ваши проекты, включая черновики'\n          }\n        />\n      </TourWidget>\n    </TourView>\n  );\n};"
        },
        {
          "exportName": "TourWithPulse",
          "displayName": "Тур рядом с пульсацией",
          "type": "full-code",
          "code": "function TourWithPulseExample() {\n  const tourStepsCount = 14;\n  const [activeStepIndex, setActiveStepIndex] = useState(2);\n\n  return (\n    <TourView>\n      <Box\n        $css={{\n          display: 'grid',\n          gridTemplateColumns: '220px minmax(0, max-content)',\n          gap: '14px',\n          alignItems: 'center',\n        }}\n      >\n        <Box\n          $css={{\n            display: 'flex',\n            alignItems: 'center',\n            justifyContent: 'center',\n            minHeight: '300px',\n          }}\n        >\n          <PulseTarget />\n        </Box>\n        <TourWidget\n          orientation=\"horizontal\"\n          activeStepIndex={activeStepIndex}\n          $css={{ width: '720px', height: '264px' }}\n        >\n          <TourWidget.Content>\n            <MediaPlaceholder width={240} height={240} />\n          </TourWidget.Content>\n          <TourWidget.Header title=\"Title\" description=\"Description\" />\n          <TourWidget.Footer>\n            <Box\n              $css={{\n                display: 'flex',\n                alignItems: 'center',\n                justifyContent: 'space-between',\n                gap: '32px',\n                width: '100%',\n              }}\n            >\n              <Box\n                $css={{\n                  display: 'flex',\n                  alignItems: 'center',\n                  gap: '32px',\n                  minWidth: 0,\n                }}\n              >\n                <LinkButton\n                  size=\"s\"\n                  view=\"default\"\n                  onClick={() => setActiveStepIndex(0)}\n                >\n                  Пропустить всё\n                </LinkButton>\n                <TourWidget.Bullets count={tourStepsCount} />\n              </Box>\n              <Box\n                $css={{\n                  display: 'flex',\n                  alignItems: 'center',\n                  gap: '4px',\n                }}\n              >\n                <Button\n                  size=\"s\"\n                  view=\"secondary\"\n                  onClick={() =>\n                    setActiveStepIndex((current) =>\n                      clampStep(current - 1, tourStepsCount),\n                    )\n                  }\n                >\n                  Назад\n                </Button>\n                <Button\n                  size=\"s\"\n                  view=\"white\"\n                  onClick={() =>\n                    setActiveStepIndex((current) =>\n                      clampStep(current + 1, tourStepsCount),\n                    )\n                  }\n                >\n                  Далее\n                </Button>\n              </Box>\n            </Box>\n          </TourWidget.Footer>\n        </TourWidget>\n      </Box>\n    </TourView>\n  );\n};"
        },
        {
          "exportName": "Pulse",
          "displayName": "Пульсация",
          "type": "full-code",
          "code": "function PulseExample() {\n  return (\n    <TourView>\n      <Box\n        $css={{\n          display: 'flex',\n          alignItems: 'center',\n          justifyContent: 'center',\n          minHeight: '300px',\n        }}\n      >\n        <PulseTarget />\n      </Box>\n    </TourView>\n  );\n};"
        },
        {
          "exportName": "TourWithoutContent",
          "displayName": "Тур без контента",
          "type": "full-code",
          "code": "function TourWithoutContentExample() {\n  const tourStepsCount = 14;\n  const [activeStepIndex, setActiveStepIndex] = useState(2);\n\n  return (\n    <TourView>\n      <Box\n        $css={{\n          display: 'grid',\n          gridTemplateColumns: '220px minmax(0, max-content)',\n          gap: '14px',\n          alignItems: 'center',\n        }}\n      >\n        <Box\n          $css={{\n            display: 'flex',\n            alignItems: 'center',\n            justifyContent: 'center',\n            minHeight: '300px',\n          }}\n        >\n          <PulseTarget />\n        </Box>\n        <TourWidget\n          orientation=\"horizontal\"\n          activeStepIndex={activeStepIndex}\n          $css={{ width: '480px' }}\n        >\n          <TourWidget.Header title=\"Title\" description=\"Description\" />\n          <TourWidget.Footer>\n            <Box\n              $css={{\n                display: 'flex',\n                alignItems: 'center',\n                justifyContent: 'space-between',\n                gap: '32px',\n                width: '100%',\n              }}\n            >\n              <Box\n                $css={{\n                  display: 'flex',\n                  alignItems: 'center',\n                  gap: '32px',\n                  minWidth: 0,\n                }}\n              >\n                <LinkButton\n                  size=\"s\"\n                  view=\"default\"\n                  onClick={() => setActiveStepIndex(0)}\n                >\n                  Пропустить всё\n                </LinkButton>\n              </Box>\n              <Box\n                $css={{\n                  display: 'flex',\n                  alignItems: 'center',\n                  gap: '4px',\n                }}\n              >\n                <Button\n                  size=\"s\"\n                  view=\"secondary\"\n                  onClick={() =>\n                    setActiveStepIndex((current) =>\n                      clampStep(current - 1, tourStepsCount),\n                    )\n                  }\n                >\n                  Назад\n                </Button>\n                <Button\n                  size=\"s\"\n                  view=\"white\"\n                  onClick={() =>\n                    setActiveStepIndex((current) =>\n                      clampStep(current + 1, tourStepsCount),\n                    )\n                  }\n                >\n                  Далее\n                </Button>\n              </Box>\n            </Box>\n          </TourWidget.Footer>\n        </TourWidget>\n      </Box>\n    </TourView>\n  );\n};"
        }
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "TourWidgetBullet",
        "TourWidgetBullets",
        "TourWidgetContent",
        "TourWidgetFooter",
        "TourWidgetHeader"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TourWidget } from '@daisforge/ui';",
      "minimalUsage": "<TourWidget>\n  {/* части: TourWidget.Header, TourWidget.Content, TourWidget.Footer, TourWidget.Bullet, TourWidget.Bullets */}\n</TourWidget>",
      "examples": [
        {
          "exportName": "Vertical",
          "displayName": "Вертикальный тур",
          "type": "full-code",
          "code": "function VerticalExample() {\n  const tourStepsCount = 14;\n  const [activeStepIndex, setActiveStepIndex] = useState(0);\n\n  return (\n    <TourView>\n      <TourWidget\n        activeStepIndex={activeStepIndex}\n        $css={{ width: '286px', height: '480px' }}\n      >\n        <TourWidget.Content>\n          <MediaPlaceholder width={266} height={266} />\n        </TourWidget.Content>\n        <TourWidget.Header title=\"Title\" />\n        <TourWidget.Footer>\n          <Box\n            $css={{\n              display: 'flex',\n              flexDirection: 'column',\n            }}\n          >\n            <TourWidget.Bullets\n              count={tourStepsCount}\n              $css={{ marginInline: 'auto' }}\n            />\n            <Box\n              $css={{\n                display: 'flex',\n                flexDirection: 'row',\n                gap: '4px',\n                marginTop: '20px',\n              }}\n            >\n              <Button\n                size=\"s\"\n                stretching=\"filled\"\n                view=\"secondary\"\n                onClick={() =>\n                  setActiveStepIndex((current) =>\n                    clampStep(current - 1, tourStepsCount),\n                  )\n                }\n              >\n                Назад\n              </Button>\n              <Button\n                stretching=\"filled\"\n                size=\"s\"\n                view=\"white\"\n                onClick={() =>\n                  setActiveStepIndex((current) =>\n                    clampStep(current + 1, tourStepsCount),\n                  )\n                }\n              >\n                Далее\n              </Button>\n            </Box>\n            <LinkButton\n              size=\"s\"\n              view=\"default\"\n              onClick={() => setActiveStepIndex(0)}\n            >\n              Пропустить всё\n            </LinkButton>\n          </Box>\n        </TourWidget.Footer>\n      </TourWidget>\n    </TourView>\n  );\n};"
        },
        {
          "exportName": "Horizontal",
          "displayName": "Горизонтальный тур",
          "type": "full-code",
          "code": "function HorizontalExample() {\n  const tourStepsCount = 14;\n  const [activeStepIndex, setActiveStepIndex] = useState(5);\n\n  return (\n    <TourView>\n      <TourWidget\n        orientation=\"horizontal\"\n        activeStepIndex={activeStepIndex}\n        $css={{ width: '720px', height: '260px' }}\n      >\n        <TourWidget.Content>\n          <MediaPlaceholder width={240} height={240} />\n        </TourWidget.Content>\n        <TourWidget.Header title=\"Title\" description=\"Description\" />\n        <TourWidget.Footer>\n          <Box\n            $css={{\n              display: 'flex',\n              alignItems: 'center',\n              justifyContent: 'space-between',\n              gap: '32px',\n              width: '100%',\n            }}\n          >\n            <Box\n              $css={{\n                display: 'flex',\n                alignItems: 'center',\n                gap: '32px',\n                minWidth: 0,\n              }}\n            >\n              <LinkButton\n                size=\"s\"\n                view=\"default\"\n                onClick={() => setActiveStepIndex(0)}\n              >\n                Пропустить всё\n              </LinkButton>\n              <TourWidget.Bullets count={tourStepsCount} />\n            </Box>\n            <Box\n              $css={{\n                display: 'flex',\n                alignItems: 'center',\n                gap: '4px',\n              }}\n            >\n              <Button\n                size=\"s\"\n                view=\"secondary\"\n                onClick={() =>\n                  setActiveStepIndex((current) =>\n                    clampStep(current - 1, tourStepsCount),\n                  )\n                }\n              >\n                Назад\n              </Button>\n              <Button\n                size=\"s\"\n                view=\"white\"\n                onClick={() =>\n                  setActiveStepIndex((current) =>\n                    clampStep(current + 1, tourStepsCount),\n                  )\n                }\n              >\n                Далее\n              </Button>\n            </Box>\n          </Box>\n        </TourWidget.Footer>\n      </TourWidget>\n    </TourView>\n  );\n};"
        },
        {
          "exportName": "LineBreaks",
          "displayName": "Переносы строк",
          "type": "full-code",
          "code": "function LineBreaksExample() {\n  return (\n    <TourView>\n      <TourWidget $css={{ width: '320px', paddingBottom: '24px' }}>\n        <TourWidget.Header\n          title={'Знакомьтесь:\\nновые возможности'}\n          description={\n            'Режимы просмотра\\nОбщий реестр — все пилоты со статусом «В реестре»\\n• Мои пилоты — только ваши проекты, включая черновики'\n          }\n        />\n      </TourWidget>\n    </TourView>\n  );\n};"
        },
        {
          "exportName": "TourWithPulse",
          "displayName": "Тур рядом с пульсацией",
          "type": "full-code",
          "code": "function TourWithPulseExample() {\n  const tourStepsCount = 14;\n  const [activeStepIndex, setActiveStepIndex] = useState(2);\n\n  return (\n    <TourView>\n      <Box\n        $css={{\n          display: 'grid',\n          gridTemplateColumns: '220px minmax(0, max-content)',\n          gap: '14px',\n          alignItems: 'center',\n        }}\n      >\n        <Box\n          $css={{\n            display: 'flex',\n            alignItems: 'center',\n            justifyContent: 'center',\n            minHeight: '300px',\n          }}\n        >\n          <PulseTarget />\n        </Box>\n        <TourWidget\n          orientation=\"horizontal\"\n          activeStepIndex={activeStepIndex}\n          $css={{ width: '720px', height: '264px' }}\n        >\n          <TourWidget.Content>\n            <MediaPlaceholder width={240} height={240} />\n          </TourWidget.Content>\n          <TourWidget.Header title=\"Title\" description=\"Description\" />\n          <TourWidget.Footer>\n            <Box\n              $css={{\n                display: 'flex',\n                alignItems: 'center',\n                justifyContent: 'space-between',\n                gap: '32px',\n                width: '100%',\n              }}\n            >\n              <Box\n                $css={{\n                  display: 'flex',\n                  alignItems: 'center',\n                  gap: '32px',\n                  minWidth: 0,\n                }}\n              >\n                <LinkButton\n                  size=\"s\"\n                  view=\"default\"\n                  onClick={() => setActiveStepIndex(0)}\n                >\n                  Пропустить всё\n                </LinkButton>\n                <TourWidget.Bullets count={tourStepsCount} />\n              </Box>\n              <Box\n                $css={{\n                  display: 'flex',\n                  alignItems: 'center',\n                  gap: '4px',\n                }}\n              >\n                <Button\n                  size=\"s\"\n                  view=\"secondary\"\n                  onClick={() =>\n                    setActiveStepIndex((current) =>\n                      clampStep(current - 1, tourStepsCount),\n                    )\n                  }\n                >\n                  Назад\n                </Button>\n                <Button\n                  size=\"s\"\n                  view=\"white\"\n                  onClick={() =>\n                    setActiveStepIndex((current) =>\n                      clampStep(current + 1, tourStepsCount),\n                    )\n                  }\n                >\n                  Далее\n                </Button>\n              </Box>\n            </Box>\n          </TourWidget.Footer>\n        </TourWidget>\n      </Box>\n    </TourView>\n  );\n};"
        }
      ]
    },
    "Tree": {
      "name": "Tree",
      "group": "components",
      "folderName": "Tree",
      "role": "primary",
      "description": "Иерархический список с раскрытием узлов, выбором и чекбоксами.",
      "props": [],
      "propsTypeName": "TreeProps",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Tree/Tree.d.ts",
      "type": "wrapper",
      "atomicBase": "Tree",
      "category": "Локальные компоненты",
      "keywords": [
        "древовидный список",
        "иерархия",
        "чекбоксы узлов"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "items",
          "type": "TreeItem[]",
          "required": true,
          "description": "Список элементов.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "allowDrop",
          "type": "((options: AllowDropOptions) => boolean)",
          "required": false,
          "description": "Разрешать ли сброс draggable-элемента на текущем target-элементе.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "arrowPlacement",
          "type": "\"right\" | \"left\"",
          "required": false,
          "description": "Сторона иконки раскрытия элемента.",
          "default": "left",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "autoExpandParent",
          "type": "boolean",
          "required": false,
          "description": "Открывать ли автоматически вышестоящие уровни определенного элемента.\nЕсли есть необходимость открывать нужный уровень без проброса всей иерархии.",
          "default": "false",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "checkable",
          "type": "boolean",
          "required": false,
          "description": "Флаг включения чекбоксов в элементах.",
          "default": "false",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "checkedKeys",
          "type": "Key[]",
          "required": false,
          "description": "Выделенные элементы в controlled-варианте.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultCheckedKeys",
          "type": "Key[]",
          "required": false,
          "description": "Выделенные элементы по умолчанию.\nРаботает только при uncontrolled-варианте.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultExpandAll",
          "type": "boolean",
          "required": false,
          "description": "Флаг раскрытия всех элементов по умолчанию.\nРаботает только при uncontrolled-варианте.",
          "default": "false",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultExpandedKeys",
          "type": "Key[]",
          "required": false,
          "description": "Раскрытые элементы по умолчанию.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "defaultSelectedKeys",
          "type": "Key[]",
          "required": false,
          "description": "Выбранные элементы по умолчанию.\nРаботает только при uncontrolled-варианте.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "draggable",
          "type": "boolean",
          "required": false,
          "description": "Включение режима Drag'n'Drop для элементов и групп в дереве;",
          "default": "false",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "expandedKeys",
          "type": "Key[]",
          "required": false,
          "description": "Раскрытые элементы в controlled-варианте.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "fullWidthItemSelection",
          "type": "boolean",
          "required": false,
          "description": "Флаг включения стиля на всю ширину для выбранного элемента.",
          "default": "false",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasIcon",
          "type": "boolean",
          "required": false,
          "description": "Флаг включения/отключения иконки у элемента.",
          "default": "false",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "height",
          "type": "number",
          "required": false,
          "description": "Высота дерева.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "icon",
          "type": "ReactNode",
          "required": false,
          "description": "Общая иконка для всего дерева.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "itemHeight",
          "type": "number",
          "required": false,
          "description": "Высота item. Обязательное поле для включения виртуализации.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "loadData",
          "type": "((treeNode: EventDataNode) => Promise<any>)",
          "required": false,
          "description": "Функция для асинхронной подгрузки данных.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "mode",
          "type": "\"radio\" | \"default\"",
          "required": false,
          "description": "Режим работы взаимодействия с элементами.\n- default: элемент можно выбрать и можно отменить его выбор.\n- radio: если элемент выбран, то отменить его выбор нельзя. Только для single-режима.",
          "default": "default",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onDragEnd",
          "type": "((info: NodeDragEventParams) => void)",
          "required": false,
          "description": "Нативный обработчик onDragEnd.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onDragEnter",
          "type": "((info: NodeDragEventParams & { expandedKeys: Key[]; }) => void)",
          "required": false,
          "description": "Нативный обработчик onDragEnter.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onDragLeave",
          "type": "((info: NodeDragEventParams) => void)",
          "required": false,
          "description": "Нативный обработчик onDragLeave.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onDragOver",
          "type": "((info: NodeDragEventParams) => void)",
          "required": false,
          "description": "Нативный обработчик onDragOver.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onDragStart",
          "type": "((info: NodeDragEventParams) => void)",
          "required": false,
          "description": "Нативный обработчик onDragStart.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onDrop",
          "type": "((info: NodeDragEventParams & { dragNode: EventDataNode; dragNodesKeys: Key[]; dropPosition: number; dropToGap: boolean; }) => void)",
          "required": false,
          "description": "Нативный обработчик onDrop.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onLoadData",
          "type": "((loadedKeys: Key[], info: LoadInfo) => void)",
          "required": false,
          "description": "Функция обратного вызова, вызываемая при загрузке элемента дерева.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onTreeCheck",
          "type": "((checked: Key[], info: CheckInfo) => void)",
          "required": false,
          "description": "Callback при выделении элемента.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onTreeExpand",
          "type": "((expandedKeys: Key[], info: ExpandInfo) => void)",
          "required": false,
          "description": "Callback при раскрытии элемента.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "onTreeSelect",
          "type": "((selectedKeys: Key[], info: SelectInfo) => void)",
          "required": false,
          "description": "Callback при выборе элемента.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "renderTitle",
          "type": "((item: TreeItem) => ReactNode)",
          "required": false,
          "description": "Callback для кастомной настройки title.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "selectedKeys",
          "type": "Key[]",
          "required": false,
          "description": "Выбранные элементы в controlled-варианте.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "singleLine",
          "type": "boolean",
          "required": false,
          "description": "Заголовок элемента в одну строку или с переносом строк.",
          "default": "true",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"l\" | \"m\" | \"xs\" | \"xl\"",
          "required": false,
          "description": "Размер дерева.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "variant",
          "type": "\"normal\" | \"tight\"",
          "required": false,
          "description": "Вариант: обычный или сжатый",
          "default": "normal",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"default\"",
          "required": false,
          "description": "Вид дерева.",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "virtual",
          "type": "boolean",
          "required": false,
          "description": "Флаг включения виртуализации в дерево со скроллом.",
          "default": "true",
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "className",
          "type": "string",
          "required": false,
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "multiple",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Tree",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Tree } from '@daisforge/ui';",
      "minimalUsage": "<Tree items={[]} />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в Tree.tsx",
          "type": "usage",
          "code": "<Tree items={treeData} defaultExpandAll size=\"m\" arrowPlacement=\"right\" />",
          "sourceFile": "packages/vite-project/src/pages/Tree.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Example 1",
          "type": "vendor",
          "code": "type TreeItem = {\n    /**\n     * Уникальный идентификатор элемента.\n     */\n    key: React.Key;\n    /**\n     * Заголовок элемента.\n     */\n    title?: React.ReactNode | ((data: TreeItem) => React.ReactNode);\n    /**\n     * Classname для текущего элемента.\n     */\n    className?: string;\n    /**\n     * Стиль для текущего элемента.\n     */\n    style?: React.CSSProperties;\n    /**\n     * Флаг выключения элемента.\n     * @default false\n     */\n    disabled?: boolean;\n    /**\n     * Иконка для текущего элемента.\n     */\n    icon?: React.ReactNode;\n    /**\n     * Дочерние items.\n     */\n    children?: TreeItem[];\n    /**\n     * Контент справа.\n     */\n    contentRight?: React.ReactNode;\n};"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Асинхронная загрузка элементов",
          "type": "vendor",
          "code": "export function App() {\n    const [treeData, setTreeData] = React.useState([\n        { title: 'Открыть для загрузки', key: '0' },\n        { title: 'Конечный элемент', key: '1', isLeaf: true },\n    ]);\n    interface DataNode {\n        title: string;\n        key: string;\n        isLeaf?: boolean;\n        children?: DataNode[];\n    }\n    // Носит иллюстрационный характер и должно настраиваться в индивидуальном порядке на стороне пользователя.\n    const updateTreeData = (list: DataNode[], key: React.Key, children: DataNode[]): DataNode[] =>\n        list.map((node) => {\n            if (node.key === key) {\n                return {\n                    ...node,\n                    children,\n                };\n            }\n            if (node.children) {\n                return {\n                    ...node,\n                    children: updateTreeData(node.children, key, children),\n                };\n            }\n            return node;\n        });\n    return <Tree loadData={({ key, children }) =>\n        new Promise<void>((resolve) => {\n            if (children) {\n                resolve();\n                return;\n            }\n            setTimeout(() => {\n                setTreeData((origin) =>\n                    updateTreeData(origin, key, [{ title: 'Загруженный элемент', key: `${ key }-0` }]),\n                );\n                resolve();\n            }, 2000);\n        })} items={ treeData }/>;\n}"
        }
      ]
    },
    "Typography": {
      "name": "Typography",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Универсальная обёртка над всеми размерами шрифтов SDDS через проп variant.",
      "props": [
        {
          "name": "variant",
          "type": "T",
          "required": true,
          "description": ""
        },
        {
          "name": "bold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Полужирное начертание."
        },
        {
          "name": "extraBold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Жирное начертание."
        },
        {
          "name": "medium",
          "type": "boolean | undefined",
          "required": false,
          "description": "Среднее начертание."
        },
        {
          "name": "refTypography",
          "type": "React.LegacyRef<HTMLDivElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof AllowedTextHTMLElements | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "breakWord",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isItalic",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isNumeric",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "m",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mb",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ml",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mr",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mt",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mx",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "my",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "noWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "p",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pb",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pl",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pr",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pt",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "px",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "py",
          "type": "0 | 2 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"m\" | \"s\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"l\" | \"xs\" | \"xxs\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "TypographyProps",
      "rawType": "export type TypographyProps<T extends TypographyVariant> = {\n  variant: T;\n  children: React.ReactNode;\n  refTypography?: LegacyRef<HTMLDivElement> | undefined;\n} & PropsForVariant<T>;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/components/Typography/Typography.tsx",
      "type": "wrapper",
      "atomicBase": "BodyL",
      "category": "Локальные компоненты",
      "keywords": [
        "типографика",
        "шрифты",
        "текстовые стили"
      ],
      "docs": "# Typography\n\nКомпонент `Typography` является оберткой над [атомарными типографическими компонентами SDDS](https://plasma.sberdevices.ru/sdds-finai/components/typography/).\n\n## Ключевые особенности\n\n- Единый интерфейс для работы со всей типографической системой проекта\n- Все варианты шрифтов (от Display до TextXS)\n- Настройка начертания (regular, bold)\n- Гибкое управление отображением текста\n- Компонент автоматически использует шрифт SB Sans Text\n\n> Подробнее о типах и пропсах — [Typography API](?path=/docs/локальные-компоненты-typography-api--docs)",
      "apiDocs": "# Typography API\n\n## TypographyProps\n\n```typescript\ntype TypographyProps<T extends TypographyVariant> = {\n  variant: T;\n  children: React.ReactNode;\n  refTypography?: LegacyRef<HTMLDivElement> | undefined;\n} & PropsForVariant<T>;\n```\n\n## TypographyVariant\n\n```typescript\ntype TypographyVariant = keyof typeof typographyComponents;\n```\n\n> Остальные пропсы зависят от выбранного `variant`",
      "curatedStories": [
        {
          "exportName": "AllVariants",
          "displayName": "AllVariants",
          "type": "full-code",
          "code": "() => (\n    <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n      <Typography variant=\"DsplL\">Display L (DsplL)</Typography>\n      <Typography variant=\"DsplM\">Display M (DsplM)</Typography>\n      <Typography variant=\"DsplS\">Display S (DsplS)</Typography>\n      <Typography variant=\"H1\">Heading 1 (H1)</Typography>\n      <Typography variant=\"H2\">Heading 2 (H2)</Typography>\n      <Typography variant=\"H3\">Heading 3 (H3)</Typography>\n      <Typography variant=\"H4\">Heading 4 (H4)</Typography>\n      <Typography variant=\"H5\">Heading 5 (H5)</Typography>\n      <Typography variant=\"TextL\">Text L (TextL)</Typography>\n      <Typography variant=\"TextM\">Text M (TextM)</Typography>\n      <Typography variant=\"TextS\">Text S (TextS)</Typography>\n      <Typography variant=\"TextXS\">Text XS (TextXS)</Typography>\n      <Typography variant=\"BodyL\">Body L (BodyL)</Typography>\n      <Typography variant=\"BodyM\">Body M (BodyM)</Typography>\n      <Typography variant=\"BodyS\">Body S (BodyS)</Typography>\n      <Typography variant=\"BodyXS\">Body XS (BodyXS)</Typography>\n      <Typography variant=\"BodyXXS\">Body XXS (BodyXXS)</Typography>\n    </div>\n  )"
        },
        {
          "exportName": "WithStyles",
          "displayName": "WithStyles",
          "type": "full-code",
          "code": "() => (\n    <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n      <Typography variant=\"H3\" bold>\n        Жирный заголовок\n      </Typography>\n      <Typography variant=\"TextL\" bold>\n        Жирный текст\n      </Typography>\n    </div>\n  )"
        },
        {
          "exportName": "TextWithDifferentTags",
          "displayName": "TextWithDifferentTags",
          "type": "full-code",
          "code": "() => (\n    <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n      <Typography variant=\"H1\" as=\"h1\">\n        Заголовок h1\n      </Typography>\n      <Typography variant=\"BodyM\" as=\"p\">\n        Абзац текста\n      </Typography>\n      <Typography variant=\"BodyM\" as=\"span\">\n        Текст внутри строки\n      </Typography>\n      <Typography variant=\"BodyM\" as=\"div\">\n        Блочный текст\n      </Typography>\n    </div>\n  )"
        }
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { Typography } from '@daisforge/ui';",
      "minimalUsage": "<Typography variant={{}} />",
      "examples": [
        {
          "exportName": "AllVariants",
          "displayName": "AllVariants",
          "type": "full-code",
          "code": "() => (\n    <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n      <Typography variant=\"DsplL\">Display L (DsplL)</Typography>\n      <Typography variant=\"DsplM\">Display M (DsplM)</Typography>\n      <Typography variant=\"DsplS\">Display S (DsplS)</Typography>\n      <Typography variant=\"H1\">Heading 1 (H1)</Typography>\n      <Typography variant=\"H2\">Heading 2 (H2)</Typography>\n      <Typography variant=\"H3\">Heading 3 (H3)</Typography>\n      <Typography variant=\"H4\">Heading 4 (H4)</Typography>\n      <Typography variant=\"H5\">Heading 5 (H5)</Typography>\n      <Typography variant=\"TextL\">Text L (TextL)</Typography>\n      <Typography variant=\"TextM\">Text M (TextM)</Typography>\n      <Typography variant=\"TextS\">Text S (TextS)</Typography>\n      <Typography variant=\"TextXS\">Text XS (TextXS)</Typography>\n      <Typography variant=\"BodyL\">Body L (BodyL)</Typography>\n      <Typography variant=\"BodyM\">Body M (BodyM)</Typography>\n      <Typography variant=\"BodyS\">Body S (BodyS)</Typography>\n      <Typography variant=\"BodyXS\">Body XS (BodyXS)</Typography>\n      <Typography variant=\"BodyXXS\">Body XXS (BodyXXS)</Typography>\n    </div>\n  )"
        },
        {
          "exportName": "WithStyles",
          "displayName": "WithStyles",
          "type": "full-code",
          "code": "() => (\n    <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n      <Typography variant=\"H3\" bold>\n        Жирный заголовок\n      </Typography>\n      <Typography variant=\"TextL\" bold>\n        Жирный текст\n      </Typography>\n    </div>\n  )"
        },
        {
          "exportName": "TextWithDifferentTags",
          "displayName": "TextWithDifferentTags",
          "type": "full-code",
          "code": "() => (\n    <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n      <Typography variant=\"H1\" as=\"h1\">\n        Заголовок h1\n      </Typography>\n      <Typography variant=\"BodyM\" as=\"p\">\n        Абзац текста\n      </Typography>\n      <Typography variant=\"BodyM\" as=\"span\">\n        Текст внутри строки\n      </Typography>\n      <Typography variant=\"BodyM\" as=\"div\">\n        Блочный текст\n      </Typography>\n    </div>\n  )"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в Typography.stories.tsx",
          "type": "usage",
          "code": "<Typography variant=\"TextL\" bold>\n        Жирный текст\n      </Typography>",
          "sourceFile": "packages/storybook/src/stories/Typography/Typography.stories.tsx"
        }
      ]
    },
    "TypographyWithAutoTooltip": {
      "name": "TypographyWithAutoTooltip",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Текст с автопоказом тултипа при обрезке — удобно для длинных значений.",
      "props": [],
      "propsTypeName": "TypographyWithAutoTooltipProps",
      "rawType": "export type TypographyWithAutoTooltipProps<T extends TypographyVariant> = {\n  tooltipText?: React.ReactNode;\n  tooltipProps?: Omit<TooltipProps, 'text' | 'target' | 'trigger' | 'opened'>;\n  lines?: number;\n} & Omit<TypographyProps<T>, 'frame'>;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/components/Typography/TypographyWithAutoTooltip.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "обрезанный текст",
        "text overflow",
        "ellipsis"
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TypographyWithAutoTooltip } from '@daisforge/ui';",
      "minimalUsage": "<TypographyWithAutoTooltip />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в TypographyWithAutoTooltip.stories.tsx",
          "type": "usage",
          "code": "<TypographyWithAutoTooltip {...args} lines={lines}>\n            Этот текст будет обрезаться в зависимости от выбранной ширины\n            контейнера и количества строк. Наведите курсор на текст, чтобы\n            увидеть подсказку, если текст обрезан\n          </TypographyWithAutoTooltip>",
          "sourceFile": "packages/storybook/src/stories/TypographyWithTooltip/TypographyWithAutoTooltip.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TypographyWithAutoTooltip.stories.tsx",
          "type": "usage",
          "code": "<TypographyWithAutoTooltip {...args} />",
          "sourceFile": "packages/storybook/src/stories/TypographyWithTooltip/TypographyWithAutoTooltip.stories.tsx"
        }
      ]
    },
    "BodyL": {
      "name": "BodyL",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Крупный текст абзаца — для основного контента с увеличенным размером.",
      "props": [
        {
          "name": "bold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Полужирное начертание."
        },
        {
          "name": "extraBold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Жирное начертание."
        },
        {
          "name": "medium",
          "type": "boolean | undefined",
          "required": false,
          "description": "Среднее начертание."
        },
        {
          "name": "breakWord",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isItalic",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isNumeric",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "noWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"l\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof AllowedTextHTMLElements | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "m",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ml",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mx",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "my",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "p",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pl",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "px",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "py",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof BodyL>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Typography/Typography.d.ts",
      "type": "wrapper",
      "atomicBase": "BodyL",
      "category": "Локальные компоненты",
      "keywords": [
        "текст абзаца",
        "typography",
        "крупный шрифт"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { BodyL } from '@daisforge/ui';",
      "minimalUsage": "<BodyL />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в Container.stories.tsx",
          "type": "usage",
          "code": "<BodyL>Some content in container</BodyL>",
          "sourceFile": "packages/storybook/src/stories/Container/Container.stories.tsx"
        },
        {
          "exportName": "Vendor",
          "displayName": "Интерфейсы Интерфейсы Типографика для таких частей интерфейса, как button, label, подписи, и т.п.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { BodyL, BodyM, BodyS, BodyXS, BodyXXS } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'block' }}>\n            <BodyL>BodyL</BodyL>\n            <BodyL bold>BodyL Bold</BodyL>\n            <BodyL medium>BodyL Medium</BodyL>\n            <BodyM>BodyM</BodyM>\n            <BodyM bold>BodyM Bold</BodyM>\n            <BodyM medium>BodyM Medium</BodyM>\n            <BodyS>BodyS</BodyS>\n            <BodyS bold>BodyS Bold</BodyS>\n            <BodyS medium>BodyS Medium</BodyS>\n            <BodyXS>BodyXS</BodyXS>\n            <BodyXS bold>BodyXS Bold</BodyXS>\n            <BodyXS medium>BodyXS Medium</BodyXS>\n            <BodyXXS>BodyXXS</BodyXXS>\n            <BodyXXS bold>BodyXXS Bold</BodyXXS>\n            <BodyXXS medium>BodyXXS Medium</BodyXXS>\n        </div>\n    );\n}"
        }
      ]
    },
    "BodyM": {
      "name": "BodyM",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Базовый текст абзаца — стандартный размер для основного контента.",
      "props": [
        {
          "name": "bold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Полужирное начертание."
        },
        {
          "name": "extraBold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Жирное начертание."
        },
        {
          "name": "medium",
          "type": "boolean | undefined",
          "required": false,
          "description": "Среднее начертание."
        },
        {
          "name": "breakWord",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isItalic",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isNumeric",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "noWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof AllowedTextHTMLElements | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "m",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ml",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mx",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "my",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "p",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pl",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "px",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "py",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof BodyM>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Typography/Typography.d.ts",
      "type": "wrapper",
      "atomicBase": "BodyM",
      "category": "Локальные компоненты",
      "keywords": [
        "текст абзаца",
        "typography",
        "базовый шрифт"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { BodyM } from '@daisforge/ui';",
      "minimalUsage": "<BodyM />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в AnalyticalWidgetInfoAboutAdaptive.tsx",
          "type": "usage",
          "code": "<BodyM as=\"h3\" style={{ marginBottom: '16px' }}>\n      Адаптивность и размеры виджета\n    </BodyM>",
          "sourceFile": "packages/storybook/src/stories/AnalyticalWidget/components/AnalyticalWidgetInfoAboutAdaptive.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Смена тега",
          "type": "vendor",
          "code": "import React from 'react';\nimport { BodyM } from '@daisforge/ui';\nexport function App() {\n    return (\n        <BodyM as=\"h3\">\n            BodyM\n        </BodyM>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Интерфейсы Интерфейсы Типографика для таких частей интерфейса, как button, label, подписи, и т.п.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { BodyL, BodyM, BodyS, BodyXS, BodyXXS } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'block' }}>\n            <BodyL>BodyL</BodyL>\n            <BodyL bold>BodyL Bold</BodyL>\n            <BodyL medium>BodyL Medium</BodyL>\n            <BodyM>BodyM</BodyM>\n            <BodyM bold>BodyM Bold</BodyM>\n            <BodyM medium>BodyM Medium</BodyM>\n            <BodyS>BodyS</BodyS>\n            <BodyS bold>BodyS Bold</BodyS>\n            <BodyS medium>BodyS Medium</BodyS>\n            <BodyXS>BodyXS</BodyXS>\n            <BodyXS bold>BodyXS Bold</BodyXS>\n            <BodyXS medium>BodyXS Medium</BodyXS>\n            <BodyXXS>BodyXXS</BodyXXS>\n            <BodyXXS bold>BodyXXS Bold</BodyXXS>\n            <BodyXXS medium>BodyXXS Medium</BodyXXS>\n        </div>\n    );\n}"
        }
      ]
    },
    "BodyS": {
      "name": "BodyS",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Компактный текст абзаца — для второстепенного или уплотнённого контента.",
      "props": [
        {
          "name": "bold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Полужирное начертание."
        },
        {
          "name": "extraBold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Жирное начертание."
        },
        {
          "name": "medium",
          "type": "boolean | undefined",
          "required": false,
          "description": "Среднее начертание."
        },
        {
          "name": "breakWord",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isItalic",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isNumeric",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "noWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof AllowedTextHTMLElements | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "m",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ml",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mx",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "my",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "p",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pl",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "px",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "py",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof BodyS>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Typography/Typography.d.ts",
      "type": "wrapper",
      "atomicBase": "BodyS",
      "category": "Локальные компоненты",
      "keywords": [
        "текст абзаца",
        "typography",
        "мелкий шрифт"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { BodyS } from '@daisforge/ui';",
      "minimalUsage": "<BodyS />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в Table.customRenderWithContext.stories.tsx",
          "type": "usage",
          "code": "<BodyS bold>Размер строки {rowSize}</BodyS>",
          "sourceFile": "packages/storybook/src/stories/Table/Table.customRender/Table.customRenderWithContext.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FiltersActions.stories.tsx",
          "type": "usage",
          "code": "<BodyS style={{ marginBottom: '8px' }}>Блок</BodyS>",
          "sourceFile": "packages/storybook/src/stories/FiltersActions/FiltersActions.stories.tsx"
        },
        {
          "exportName": "Vendor",
          "displayName": "Интерфейсы Интерфейсы Типографика для таких частей интерфейса, как button, label, подписи, и т.п.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { BodyL, BodyM, BodyS, BodyXS, BodyXXS } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'block' }}>\n            <BodyL>BodyL</BodyL>\n            <BodyL bold>BodyL Bold</BodyL>\n            <BodyL medium>BodyL Medium</BodyL>\n            <BodyM>BodyM</BodyM>\n            <BodyM bold>BodyM Bold</BodyM>\n            <BodyM medium>BodyM Medium</BodyM>\n            <BodyS>BodyS</BodyS>\n            <BodyS bold>BodyS Bold</BodyS>\n            <BodyS medium>BodyS Medium</BodyS>\n            <BodyXS>BodyXS</BodyXS>\n            <BodyXS bold>BodyXS Bold</BodyXS>\n            <BodyXS medium>BodyXS Medium</BodyXS>\n            <BodyXXS>BodyXXS</BodyXXS>\n            <BodyXXS bold>BodyXXS Bold</BodyXXS>\n            <BodyXXS medium>BodyXXS Medium</BodyXXS>\n        </div>\n    );\n}"
        }
      ]
    },
    "BodyXS": {
      "name": "BodyXS",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Мелкий текст абзаца — для подписей и второстепенной информации.",
      "props": [
        {
          "name": "bold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Полужирное начертание."
        },
        {
          "name": "extraBold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Жирное начертание."
        },
        {
          "name": "medium",
          "type": "boolean | undefined",
          "required": false,
          "description": "Среднее начертание."
        },
        {
          "name": "breakWord",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isItalic",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isNumeric",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "noWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof AllowedTextHTMLElements | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "m",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ml",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mx",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "my",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "p",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pl",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "px",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "py",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof BodyXS>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Typography/Typography.d.ts",
      "type": "wrapper",
      "atomicBase": "BodyXS",
      "category": "Локальные компоненты",
      "keywords": [
        "подписи",
        "typography",
        "мелкий текст"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { BodyXS } from '@daisforge/ui';",
      "minimalUsage": "<BodyXS />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в TableCanvas.cellPreview.stories.tsx",
          "type": "usage",
          "code": "<BodyXS style={{ opacity: 0.6 }}>Задача: {row.task}</BodyXS>",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.CellPreview/TableCanvas.cellPreview.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvas.cellPreview.stories.tsx",
          "type": "usage",
          "code": "<BodyXS style={{ marginTop: 4, opacity: 0.6 }}>\n                Задача: {row.task}\n              </BodyXS>",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.CellPreview/TableCanvas.cellPreview.stories.tsx"
        },
        {
          "exportName": "Vendor",
          "displayName": "Интерфейсы Интерфейсы Типографика для таких частей интерфейса, как button, label, подписи, и т.п.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { BodyL, BodyM, BodyS, BodyXS, BodyXXS } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'block' }}>\n            <BodyL>BodyL</BodyL>\n            <BodyL bold>BodyL Bold</BodyL>\n            <BodyL medium>BodyL Medium</BodyL>\n            <BodyM>BodyM</BodyM>\n            <BodyM bold>BodyM Bold</BodyM>\n            <BodyM medium>BodyM Medium</BodyM>\n            <BodyS>BodyS</BodyS>\n            <BodyS bold>BodyS Bold</BodyS>\n            <BodyS medium>BodyS Medium</BodyS>\n            <BodyXS>BodyXS</BodyXS>\n            <BodyXS bold>BodyXS Bold</BodyXS>\n            <BodyXS medium>BodyXS Medium</BodyXS>\n            <BodyXXS>BodyXXS</BodyXXS>\n            <BodyXXS bold>BodyXXS Bold</BodyXXS>\n            <BodyXXS medium>BodyXXS Medium</BodyXXS>\n        </div>\n    );\n}"
        }
      ]
    },
    "BodyXXS": {
      "name": "BodyXXS",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Самый мелкий текст абзаца — для меток и служебных подсказок.",
      "props": [
        {
          "name": "bold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Полужирное начертание."
        },
        {
          "name": "extraBold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Жирное начертание."
        },
        {
          "name": "medium",
          "type": "boolean | undefined",
          "required": false,
          "description": "Среднее начертание."
        },
        {
          "name": "breakWord",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isItalic",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isNumeric",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "noWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"xxs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof AllowedTextHTMLElements | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "m",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ml",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mx",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "my",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "p",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pl",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "px",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "py",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof BodyXXS>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Typography/Typography.d.ts",
      "type": "wrapper",
      "atomicBase": "BodyXXS",
      "category": "Локальные компоненты",
      "keywords": [
        "метки",
        "typography",
        "минимальный шрифт"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { BodyXXS } from '@daisforge/ui';",
      "minimalUsage": "<BodyXXS />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Интерфейсы Интерфейсы Типографика для таких частей интерфейса, как button, label, подписи, и т.п.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { BodyL, BodyM, BodyS, BodyXS, BodyXXS } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'block' }}>\n            <BodyL>BodyL</BodyL>\n            <BodyL bold>BodyL Bold</BodyL>\n            <BodyL medium>BodyL Medium</BodyL>\n            <BodyM>BodyM</BodyM>\n            <BodyM bold>BodyM Bold</BodyM>\n            <BodyM medium>BodyM Medium</BodyM>\n            <BodyS>BodyS</BodyS>\n            <BodyS bold>BodyS Bold</BodyS>\n            <BodyS medium>BodyS Medium</BodyS>\n            <BodyXS>BodyXS</BodyXS>\n            <BodyXS bold>BodyXS Bold</BodyXS>\n            <BodyXS medium>BodyXS Medium</BodyXS>\n            <BodyXXS>BodyXXS</BodyXXS>\n            <BodyXXS bold>BodyXXS Bold</BodyXXS>\n            <BodyXXS medium>BodyXXS Medium</BodyXXS>\n        </div>\n    );\n}"
        }
      ]
    },
    "DsplL": {
      "name": "DsplL",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Крупный заголовок-дисплей — для акцентных, витринных заголовков.",
      "props": [
        {
          "name": "bold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Полужирное начертание."
        },
        {
          "name": "extraBold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Жирное начертание."
        },
        {
          "name": "medium",
          "type": "boolean | undefined",
          "required": false,
          "description": "Среднее начертание."
        },
        {
          "name": "breakWord",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isItalic",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isNumeric",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "noWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"l\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof AllowedTextHTMLElements | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "m",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ml",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mx",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "my",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "p",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pl",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "px",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "py",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof DsplL>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Typography/Typography.d.ts",
      "type": "wrapper",
      "atomicBase": "DsplL",
      "category": "Локальные компоненты",
      "keywords": [
        "заголовок",
        "display heading",
        "крупный текст"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { DsplL } from '@daisforge/ui';",
      "minimalUsage": "<DsplL />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Курсивное начертание текста",
          "type": "vendor",
          "code": "import React from 'react';\nimport { DsplL } from '@daisforge/ui';\nexport function App() {\n    return (\n        <>\n            <DsplL isItalic>Bold</DsplL>\n        </>\n    )\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Управление насыщенностью шрифта",
          "type": "vendor",
          "code": "import React from 'react';\nimport { DsplL } from '@daisforge/ui';\nexport function App() {\n    return (\n        <>\n            <DsplL bold={false}>Regular</DsplL>\n            <DsplL medium>Medium</DsplL>\n            <DsplL>Bold</DsplL>\n        </>\n    )\n}"
        }
      ]
    },
    "DsplM": {
      "name": "DsplM",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Средний заголовок-дисплей — для акцентных заголовков разделов.",
      "props": [
        {
          "name": "bold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Полужирное начертание."
        },
        {
          "name": "extraBold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Жирное начертание."
        },
        {
          "name": "medium",
          "type": "boolean | undefined",
          "required": false,
          "description": "Среднее начертание."
        },
        {
          "name": "breakWord",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isItalic",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isNumeric",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "noWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof AllowedTextHTMLElements | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "m",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ml",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mx",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "my",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "p",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pl",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "px",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "py",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof DsplM>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Typography/Typography.d.ts",
      "type": "wrapper",
      "atomicBase": "DsplM",
      "category": "Локальные компоненты",
      "keywords": [
        "заголовок",
        "display heading",
        "hero-текст"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { DsplM } from '@daisforge/ui';",
      "minimalUsage": "<DsplM />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Hero unit",
          "type": "vendor",
          "code": "import React from 'react';\nimport { DsplL, DsplM, DsplS } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'block' }}>\n            <DsplL bold={false}>DsplL</DsplL>\n            <DsplL>DsplL Bold</DsplL>\n            <DsplL medium>DsplL Medium</DsplL>\n            <DsplM bold={false}>DsplM</DsplM>\n            <DsplM>DsplM Bold</DsplM>\n            <DsplM medium>DsplM Medium</DsplM>\n            <DsplS bold={false}>DsplS</DsplS>\n            <DsplS>DsplS Bold</DsplS>\n            <DsplS medium>DsplS Medium</DsplS>\n        </div>\n    );\n}"
        }
      ]
    },
    "DsplS": {
      "name": "DsplS",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Компактный заголовок-дисплей — для акцентных заголовков блоков.",
      "props": [
        {
          "name": "bold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Полужирное начертание."
        },
        {
          "name": "extraBold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Жирное начертание."
        },
        {
          "name": "medium",
          "type": "boolean | undefined",
          "required": false,
          "description": "Среднее начертание."
        },
        {
          "name": "breakWord",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isItalic",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isNumeric",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "noWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof AllowedTextHTMLElements | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "m",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ml",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mx",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "my",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "p",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pl",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "px",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "py",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof DsplS>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Typography/Typography.d.ts",
      "type": "wrapper",
      "atomicBase": "DsplS",
      "category": "Локальные компоненты",
      "keywords": [
        "заголовок",
        "display heading",
        "секция"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { DsplS } from '@daisforge/ui';",
      "minimalUsage": "<DsplS />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Hero unit",
          "type": "vendor",
          "code": "import React from 'react';\nimport { DsplL, DsplM, DsplS } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'block' }}>\n            <DsplL bold={false}>DsplL</DsplL>\n            <DsplL>DsplL Bold</DsplL>\n            <DsplL medium>DsplL Medium</DsplL>\n            <DsplM bold={false}>DsplM</DsplM>\n            <DsplM>DsplM Bold</DsplM>\n            <DsplM medium>DsplM Medium</DsplM>\n            <DsplS bold={false}>DsplS</DsplS>\n            <DsplS>DsplS Bold</DsplS>\n            <DsplS medium>DsplS Medium</DsplS>\n        </div>\n    );\n}"
        }
      ]
    },
    "TextL": {
      "name": "TextL",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Крупный текст интерфейса — для акцентных элементов UI (кнопки, лейблы).",
      "props": [
        {
          "name": "bold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Полужирное начертание."
        },
        {
          "name": "extraBold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Жирное начертание."
        },
        {
          "name": "medium",
          "type": "boolean | undefined",
          "required": false,
          "description": "Среднее начертание."
        },
        {
          "name": "breakWord",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isItalic",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isNumeric",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "noWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"l\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof AllowedTextHTMLElements | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "m",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ml",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mx",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "my",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "p",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pl",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "px",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "py",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof TextL>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Typography/Typography.d.ts",
      "type": "wrapper",
      "atomicBase": "TextL",
      "category": "Локальные компоненты",
      "keywords": [
        "текст интерфейса",
        "typography",
        "крупный шрифт"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { TextL } from '@daisforge/ui';",
      "minimalUsage": "<TextL />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Текст Текст Типографические элементы для описаний к статьям, дополнительной информации и т.д.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TextL, TextM, TextS, TextXS } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'block' }}>\n            <TextL>TextL</TextL>\n            <TextL bold>TextL Bold</TextL>\n            <TextL medium>TextL Medium</TextL>\n            <TextM>TextM</TextM>\n            <TextM bold>TextM Bold</TextM>\n            <TextM medium>TextM Medium</TextM>\n            <TextS>TextS</TextS>\n            <TextS bold>TextS Bold</TextS>\n            <TextS medium>TextS Medium</TextS>\n            <TextXS>TextXS</TextXS>\n            <TextXS bold>TextXS Bold</TextXS>\n            <TextXS medium>TextXS Medium</TextXS>\n        </div>\n    );\n}"
        }
      ]
    },
    "TextM": {
      "name": "TextM",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Базовый текст интерфейса — стандартный размер для UI-элементов.",
      "props": [
        {
          "name": "bold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Полужирное начертание."
        },
        {
          "name": "extraBold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Жирное начертание."
        },
        {
          "name": "medium",
          "type": "boolean | undefined",
          "required": false,
          "description": "Среднее начертание."
        },
        {
          "name": "breakWord",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isItalic",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isNumeric",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "noWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof AllowedTextHTMLElements | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "m",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ml",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mx",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "my",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "p",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pl",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "px",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "py",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof TextM>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Typography/Typography.d.ts",
      "type": "wrapper",
      "atomicBase": "TextM",
      "category": "Локальные компоненты",
      "keywords": [
        "текст интерфейса",
        "typography",
        "базовый шрифт"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { TextM } from '@daisforge/ui';",
      "minimalUsage": "<TextM />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в Table.rowInstruments.stories.tsx",
          "type": "usage",
          "code": "<TextM>\n            Счетчик, который меняется в инструментах(последняя иконка) первой\n            строки\n          </TextM>",
          "sourceFile": "packages/storybook/src/stories/Table/Table.rowInstruments/Table.rowInstruments.stories.tsx"
        },
        {
          "exportName": "Vendor",
          "displayName": "Текст Текст Типографические элементы для описаний к статьям, дополнительной информации и т.д.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TextL, TextM, TextS, TextXS } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'block' }}>\n            <TextL>TextL</TextL>\n            <TextL bold>TextL Bold</TextL>\n            <TextL medium>TextL Medium</TextL>\n            <TextM>TextM</TextM>\n            <TextM bold>TextM Bold</TextM>\n            <TextM medium>TextM Medium</TextM>\n            <TextS>TextS</TextS>\n            <TextS bold>TextS Bold</TextS>\n            <TextS medium>TextS Medium</TextS>\n            <TextXS>TextXS</TextXS>\n            <TextXS bold>TextXS Bold</TextXS>\n            <TextXS medium>TextXS Medium</TextXS>\n        </div>\n    );\n}"
        }
      ]
    },
    "TextS": {
      "name": "TextS",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Компактный текст интерфейса — для второстепенных UI-элементов.",
      "props": [
        {
          "name": "bold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Полужирное начертание."
        },
        {
          "name": "extraBold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Жирное начертание."
        },
        {
          "name": "medium",
          "type": "boolean | undefined",
          "required": false,
          "description": "Среднее начертание."
        },
        {
          "name": "breakWord",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isItalic",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isNumeric",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "noWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof AllowedTextHTMLElements | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "m",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ml",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mx",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "my",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "p",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pl",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "px",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "py",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof TextS>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Typography/Typography.d.ts",
      "type": "wrapper",
      "atomicBase": "TextS",
      "category": "Локальные компоненты",
      "keywords": [
        "текст интерфейса",
        "typography",
        "мелкий шрифт"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { TextS } from '@daisforge/ui';",
      "minimalUsage": "<TextS />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в ModalDF.stories.tsx",
          "type": "usage",
          "code": "<TextS>\n                    <Link href={window.location.href} view=\"accent\">\n                      ссылка\n                    </Link>\n                  </TextS>",
          "sourceFile": "packages/storybook/src/stories/ModalDF/ModalDF.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TextS, Link } from '@daisforge/ui';\nexport function App() {\n    return (\n        <TextS>\n            Скачайте <Link href=\"/\" target=\"_blank\">приложение.</Link>\n        </TextS>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Подчёркивание Подчёркивание Prop  underline  управляет режимом подчёркивания ссылки",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TextS, Link } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>\n            <TextS><Link href=\"/\" underline=\"none\">Без подчёркивания</Link></TextS>\n            <TextS><Link href=\"/\" underline=\"hover\">Подчёркивание при наведении</Link></TextS>\n            <TextS><Link href=\"/\" underline=\"always\">Всегда подчёркнута</Link></TextS>\n        </div>\n    );\n}"
        }
      ]
    },
    "TextXS": {
      "name": "TextXS",
      "group": "components",
      "folderName": "Typography",
      "role": "primary",
      "description": "Мелкий текст интерфейса — для меток, тегов и служебных элементов.",
      "props": [
        {
          "name": "bold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Полужирное начертание."
        },
        {
          "name": "extraBold",
          "type": "boolean | undefined",
          "required": false,
          "description": "Жирное начертание."
        },
        {
          "name": "medium",
          "type": "boolean | undefined",
          "required": false,
          "description": "Среднее начертание."
        },
        {
          "name": "breakWord",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isItalic",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isNumeric",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "noWrap",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "as",
          "type": "keyof AllowedTextHTMLElements | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "m",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "ml",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "mx",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "my",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "p",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pb",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pl",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pr",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pt",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "px",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "py",
          "type": "0 | \"0x\" | \"1x\" | \"2x\" | \"4x\" | \"5x\" | \"6x\" | \"8x\" | \"9x\" | \"10x\" | \"12x\" | \"16x\" | 2 | 4 | 8 | 10 | 12 | 16 | 18 | 20 | 24 | 32 | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof TextXS>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/Typography/Typography.d.ts",
      "type": "wrapper",
      "atomicBase": "TextXS",
      "category": "Локальные компоненты",
      "keywords": [
        "текст интерфейса",
        "typography",
        "мелкая метка"
      ],
      "hasCuratedMeta": true,
      "atomicDataMissing": true,
      "importPath": "@daisforge/ui",
      "importStatement": "import { TextXS } from '@daisforge/ui';",
      "minimalUsage": "<TextXS />",
      "examples": [
        {
          "exportName": "Vendor",
          "displayName": "Текст Текст Типографические элементы для описаний к статьям, дополнительной информации и т.д.",
          "type": "vendor",
          "code": "import React from 'react';\nimport { TextL, TextM, TextS, TextXS } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div style={{ display: 'block' }}>\n            <TextL>TextL</TextL>\n            <TextL bold>TextL Bold</TextL>\n            <TextL medium>TextL Medium</TextL>\n            <TextM>TextM</TextM>\n            <TextM bold>TextM Bold</TextM>\n            <TextM medium>TextM Medium</TextM>\n            <TextS>TextS</TextS>\n            <TextS bold>TextS Bold</TextS>\n            <TextS medium>TextS Medium</TextS>\n            <TextXS>TextXS</TextXS>\n            <TextXS bold>TextXS Bold</TextXS>\n            <TextXS medium>TextXS Medium</TextXS>\n        </div>\n    );\n}"
        }
      ]
    },
    "ViewContainer": {
      "name": "ViewContainer",
      "group": "components",
      "folderName": "ViewContainer",
      "role": "primary",
      "description": "Контейнер, задающий тему оформления (onDark/onLight) вложенному контенту.",
      "props": [],
      "propsTypeName": "ComponentProps<typeof ViewContainer>",
      "sourceFile": "node_modules/@salutejs/sdds-finai/types/components/ViewContainer/ViewContainer.d.ts",
      "type": "wrapper",
      "atomicBase": "ViewContainer",
      "category": "Локальные компоненты",
      "keywords": [
        "тема оформления",
        "onDark onLight",
        "фон блока"
      ],
      "hasCuratedMeta": true,
      "inheritedProps": [
        {
          "name": "view",
          "type": "\"onDark\" | \"onLight\"",
          "required": false,
          "description": "Вид компонента",
          "inheritedFrom": "ViewContainer",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ViewContainer } from '@daisforge/ui';",
      "minimalUsage": "<ViewContainer />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в CopyCodeAbsoluteButton.tsx",
          "type": "usage",
          "code": "<ViewContainer\n      view=\"onDark\"\n      style={{\n        position: 'absolute',\n        bottom: '8px',\n        right: '8px',\n      }}\n    >\n      <IconButton\n        size=\"xxs\"\n        view=\"clear\"\n        onClick={handleCopy}\n        title={copied ? 'Скопировано' : 'Скопировать код'}\n        onMouseEnter={(e) => {\n          (e.currentTarget as HTMLButtonElement).style.opacity = '1';\n        }}\n        onMouseLeave={(e) => {\n          (e.currentTarget as HTMLButtonElement).style.opacity = '0.6';\n        }}\n      >\n        {copied ? (\n          <IconDone size=\"xs\" color=\"inherit\" />\n        ) : (\n          <IconCopyFill size=\"xs\" color=\"inherit\" />\n        )}\n      </IconButton>\n    </ViewContainer>",
          "sourceFile": "packages/storybook/src/stories/AiChatDAIS/components/CopyCodeAbsoluteButton.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TourWidget.examples.tsx",
          "type": "usage",
          "code": "<ViewContainer view=\"onDark\">{children}</ViewContainer>",
          "sourceFile": "packages/storybook/src/stories/TourWidget/TourWidget.examples.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Пример использования",
          "type": "vendor",
          "code": "import React from 'react'\nimport { useToast, ToastProvider, Button, ViewContainer } from '@daisforge/ui'\nexport function App() {\n    const ToastExample = () => {\n        const { showToast } = useToast()\n        const onShow = () => {}\n        const onHide = () => {}\n        const toastData = {\n            text: 'Подсказка вызванная showToast',\n            textColor: 'cyan',\n            position: 'bottom',\n            role: 'status',\n            hasClose: true,\n            fade: false,\n            size: 'm',\n            view: 'default',\n            timeout: 3000,\n            onShow,\n            onHide\n        }\n        return <Button onClick={() => showToast(toastData)} text=\"Вызвать подсказку\" />\n    }\n    return (\n        <div style={{ display: 'flex', gap: '1rem' }}>\n            <ViewContainer view=\"onLight\">\n                <ToastProvider>\n                    <ToastExample />\n                </ToastProvider>\n            </ViewContainer>\n            <ViewContainer view=\"onDark\">\n                <ToastProvider>\n                    <ToastExample />\n                </ToastProvider>\n            </ViewContainer>\n        </div>\n    )\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Example 1",
          "type": "vendor",
          "code": "import React from 'react';\nimport { ViewContainer, Button, Checkbox, TextField } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <ViewContainer\n                style={{\n                    padding: '1rem',\n                    borderRadius: '1rem',\n                    display: 'flex',\n                    flexDirection: 'column',\n                    gap: '1rem',\n                }}\n            >\n                <h3 style={{ margin: 0 }}>Inside default ViewContainer</h3>\n                <Button text=\"default Button\" />\n                <Checkbox checked label=\"Label\" />\n                <TextField value=\"Example Value\" label=\"Label\" labelPlacement=\"inner\" />\n            </ViewContainer>\n            <br />\n            <ViewContainer\n                view=\"onDark\"\n                style={{\n                    background: '#1a1a1a',\n                    color: 'white',\n                    padding: '1rem',\n                    borderRadius: '1rem',\n                    display: 'flex',\n                    flexDirection: 'column',\n                    gap: '1rem',\n                }}\n            >\n                <h3 style={{ margin: 0 }}>Inside onDark ViewContainer</h3>\n                <Button text=\"default Button\" />\n                <Checkbox checked label=\"Label\" />\n                <TextField value=\"Example Value\" label=\"Label\" labelPlacement=\"inner\" />\n            </ViewContainer>\n            <br />\n            <ViewContainer\n                view=\"onLight\"\n                style={{\n                    background: '#ededed',\n                    color: 'black',\n                    padding: '1rem',\n                    borderRadius: '1rem',\n                    display: 'flex',\n                    flexDirection: 'column',\n                    gap: '1rem',\n                }}\n            >\n                <h3 style={{ margin: 0 }}>Inside onLight ViewContainer</h3>\n                <Button text=\"default Button\" />\n                <Checkbox checked label=\"Label\" />\n                <TextField value=\"Example Value\" label=\"Label\" labelPlacement=\"inner\" />\n            </ViewContainer>\n        </div>\n    );\n}"
        }
      ]
    },
    "WidgetDivider": {
      "name": "WidgetDivider",
      "group": "components",
      "folderName": "Widget",
      "role": "part",
      "description": "Вертикальный разделитель 16px между блоками в шапке карточки Widget",
      "props": [
        {
          "name": "length",
          "type": "string | number | undefined",
          "required": false,
          "description": "Размер разделителя",
          "default": "'100%'"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\" | undefined",
          "required": false,
          "description": "Направление разделителя",
          "default": "'horizontal'"
        },
        {
          "name": "size",
          "type": "\"m\" | undefined",
          "required": false,
          "description": "Размер разделителя",
          "default": "'m'"
        },
        {
          "name": "view",
          "type": "\"default\" | \"dark\" | \"light\" | \"inverse\" | undefined",
          "required": false,
          "description": "Вид разделителя",
          "default": "'default'"
        }
      ],
      "propsTypeName": "ComponentProps<typeof WidgetDivider>",
      "sourceFile": "packages/ui-kit/src/components/Widget/components/WidgetDivider.tsx",
      "type": "wrapper",
      "atomicBase": "Divider",
      "wrapsInternal": "Divider",
      "category": "Локальные компоненты",
      "keywords": [
        "разделитель шапки",
        "vertical divider",
        "header widget"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Widget",
      "atomicDataMissing": true,
      "compoundPartOf": {
        "component": "Widget",
        "part": "Divider"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { WidgetDivider } from '@daisforge/ui';",
      "minimalUsage": "<WidgetDivider />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в Widget.stories.tsx",
          "type": "usage",
          "code": "<Widget.Divider />",
          "sourceFile": "packages/storybook/src/stories/Widget/Widget.stories.tsx"
        }
      ]
    },
    "WidgetFooter": {
      "name": "WidgetFooter",
      "group": "components",
      "folderName": "Widget",
      "role": "part",
      "description": "Футер карточки Widget со слотами left/right/top блоков и верхним разделителем",
      "props": [
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные стили styled-components для Box-контейнера"
        },
        {
          "name": "as",
          "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"view\" | \"article\" | \"button\" | \"dialog\" | \"figure\" | \"form\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"search\" | \"switch\" | \"table\" | \"text\" | \"time\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"big\" | \"blockquote\" | \"body\" | \"br\" | \"canvas\" | \"caption\" | \"center\" | \"cite\"…",
          "required": false,
          "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
        },
        {
          "name": "background",
          "type": "Property.Background<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "backgroundColor",
          "type": "Property.BackgroundColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "border",
          "type": "Property.Border<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderColor",
          "type": "Property.BorderColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderRadius",
          "type": "Property.BorderRadius<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
        },
        {
          "name": "borderStyle",
          "type": "Property.BorderStyle | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderWidth",
          "type": "Property.BorderWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "bottom",
          "type": "Property.Bottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "boxSizing",
          "type": "Property.BoxSizing | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
        },
        {
          "name": "cursor",
          "type": "Property.Cursor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
        },
        {
          "name": "display",
          "type": "Property.Display | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "flexDirection",
          "type": "Property.FlexDirection | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
        },
        {
          "name": "flexGrow",
          "type": "Property.FlexGrow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
        },
        {
          "name": "flexShrink",
          "type": "Property.FlexShrink | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
        },
        {
          "name": "flexWrap",
          "type": "Property.FlexWrap | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "gap",
          "type": "Property.Gap<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
        },
        {
          "name": "height",
          "type": "Property.Height<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "justifyContent",
          "type": "Property.JustifyContent | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "justifyItems",
          "type": "Property.JustifyItems | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
        },
        {
          "name": "justifySelf",
          "type": "Property.JustifySelf | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
        },
        {
          "name": "left",
          "type": "Property.Left<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "margin",
          "type": "Property.Margin<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginBottom",
          "type": "Property.MarginBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginLeft",
          "type": "Property.MarginLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginRight",
          "type": "Property.MarginRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginTop",
          "type": "Property.MarginTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "maxHeight",
          "type": "Property.MaxHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "maxWidth",
          "type": "Property.MaxWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "minHeight",
          "type": "Property.MinHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "minWidth",
          "type": "Property.MinWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "opacity",
          "type": "Property.Opacity | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
        },
        {
          "name": "overflow",
          "type": "Property.Overflow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "padding",
          "type": "Property.Padding<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingBottom",
          "type": "Property.PaddingBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingLeft",
          "type": "Property.PaddingLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingRight",
          "type": "Property.PaddingRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingTop",
          "type": "Property.PaddingTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "position",
          "type": "Property.Position | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "right",
          "type": "Property.Right<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "top",
          "type": "Property.Top<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "width",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "dividerTop",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "leftBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "rightBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "topBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "WidgetFooterProps",
      "sourceFile": "packages/ui-kit/src/components/Widget/components/WidgetFooter.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "футер карточки",
        "action slots",
        "widget actions"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Widget",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "Widget",
        "part": "Footer"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { WidgetFooter } from '@daisforge/ui';",
      "minimalUsage": "<WidgetFooter />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в Widget.stories.tsx",
          "type": "usage",
          "code": "<Widget.Footer\n          leftBlock={\n            <Flow mainAxisGap={s.x4}>\n              <Button text=\"Кнопка 1\" size=\"s\" view=\"secondary\" />\n              <Widget.IconButtonDots size=\"s\" />\n            </Flow>\n          }\n          rightBlock={\n            <Flow mainAxisGap={s.x4}>\n              <Button text=\"Кнопка\" size=\"s\" view=\"secondary\" />\n              <Button text=\"Главная кнопка\" size=\"s\" view=\"accent\" />\n            </Flow>\n          }\n        />",
          "sourceFile": "packages/storybook/src/stories/Widget/Widget.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvas.highlightActiveTypeSplitView.stories.tsx",
          "type": "usage",
          "code": "<Widget.Footer\n        leftBlock={\n          <Flow mainAxisGap={s.x4}>\n            <Button text=\"На согласование\" size=\"xs\" view=\"secondary\" />\n            <Widget.IconButtonDots size=\"xs\" />\n          </Flow>\n        }\n        rightBlock={\n          <Flow mainAxisGap={s.x4}>\n            <Button\n              text=\"Отмена\"\n              size=\"xs\"\n              view=\"secondary\"\n              onClick={onClose}\n            />\n            <Button text=\"Сохранить\" size=\"xs\" view=\"accent\" />\n          </Flow>\n        }\n      />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.HighlightActiveType/TableCanvas.highlightActiveTypeSplitView.stories.tsx"
        }
      ]
    },
    "WidgetHeader": {
      "name": "WidgetHeader",
      "group": "components",
      "folderName": "Widget",
      "role": "part",
      "description": "Шапка Widget: заголовок, бейдж, кнопка назад, разворот на весь экран, закрытие",
      "props": [
        {
          "name": "titleRightSlot",
          "type": "React.ReactNode",
          "required": false,
          "description": "Контент справа от заголовка (и badge, если есть). Например, Chips или другие компоненты"
        },
        {
          "name": "badge",
          "type": "((((Omit<Omit<PropsType<{ view: { default: PolymorphicClassName; accent: PolymorphicClassName; positive: PolymorphicClassName; warning: PolymorphicClassName; negative: PolymorphicClassName; dark: PolymorphicClassName; light: PolymorphicClassName; }; size: { l: PolymorphicClassName; m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; pilled: { true: PolymorphicClassName; …",
          "required": false,
          "description": ""
        },
        {
          "name": "badgeMarginTop",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "bottomBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "dividerBottom",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "fullScreened",
          "type": "boolean | null | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "iconButtonsPin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onBackClick",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onClose",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rightBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "showBackButton",
          "type": "boolean | undefined",
          "required": false,
          "description": "",
          "default": "false"
        },
        {
          "name": "subTitle",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "title",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "titleLeftSlot",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "titleSize",
          "type": "\"BodyL\" | \"BodyM\" | \"BodyS\" | \"BodyXS\" | \"BodyXXS\" | \"DsplL\" | \"DsplM\" | \"DsplS\" | \"H1\" | \"H2\" | \"H3\" | \"H4\" | \"H5\" | \"TextL\" | \"TextM\" | \"TextS\" | \"TextXS\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "titleTooltipProps",
          "type": "Omit<TypographyWithAutoTooltipProps<\"H4\">, \"children\" | \"variant\"> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "toggleFullScreened",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "WidgetHeaderProps",
      "sourceFile": "packages/ui-kit/src/components/Widget/components/WidgetHeader.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "шапка карточки",
        "заголовок с бейджем",
        "fullscreen toggle"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Widget",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "Widget",
        "part": "Header"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { WidgetHeader } from '@daisforge/ui';",
      "minimalUsage": "<WidgetHeader />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в Widget.stories.tsx",
          "type": "usage",
          "code": "<Widget.Header\n          onClose={() => {}}\n          fullScreened={false}\n          toggleFullScreened={() => {}}\n          title=\"Обработка документов по задаче №2\"\n          titleLeftSlot={<Avatar size=\"l\" name=\"Задача №2\" />}\n          rightBlock={\n            <>\n              <Widget.IconButtonDots\n                size=\"xs\"\n                dropdownProps={{\n                  items: [\n                    { label: 'label 1', value: '1' },\n                    { label: 'label 2', value: '2' },\n                  ],\n                }}\n              />\n              <Widget.Divider />\n              <Flow mainAxisGap={s.x2}>\n                <IconButton view=\"secondary\" size=\"xs\">\n                  <IconChevronLeft size=\"xs\" />\n                </IconButton>\n                <IconButton view=\"secondary\" size=\"xs\">\n                  <IconChevronRight size=\"xs\" />\n                </IconButton>\n              </Flow>\n            </>\n          }\n          badge={{ text: 'Бейдж' }}\n          bottomBlock={\n            <div style={{ display: 'flex', gap: s.x2 }}>\n              <Badge size=\"s\" transparent view=\"accent\" text=\"В работе\" />\n              <Badge size=\"s\" transparent view=\"negative\" text=\"2-й раз\" />\n            </div>\n          }\n        />",
          "sourceFile": "packages/storybook/src/stories/Widget/Widget.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в TableCanvas.highlightActiveTypeSplitView.stories.tsx",
          "type": "usage",
          "code": "<Widget.Header\n        onClose={onClose}\n        fullScreened={fullScreened}\n        toggleFullScreened={onToggleFullScreen}\n        title={title}\n        titleLeftSlot={<Avatar size={avatarSize} name={title} />}\n        rightBlock={\n          <>\n            <Widget.IconButtonDots\n              size=\"xs\"\n              iconSize=\"xs\"\n              iconOrientation=\"vertical\"\n              dropdownProps={{\n                items: [\n                  { label: 'Открыть карточку', value: '1' },\n                  { label: 'Скопировать ссылку', value: '2' },\n                ],\n              }}\n            />\n            <Widget.Divider />\n            <Flow mainAxisGap={s.x2}>\n              <IconButton view=\"secondary\" size=\"xs\">\n                <IconChevronLeft size=\"xs\" />\n              </IconButton>\n              <IconButton view=\"secondary\" size=\"xs\">\n                <IconChevronRight size=\"xs\" />\n              </IconButton>\n            </Flow>\n          </>\n        }\n        badge={{ text: LEVEL_LABEL[level] }}\n        bottomBlock={\n          <div style={{ display: 'flex', gap: s.x2 }}>\n            <Badge\n              size=\"s\"\n              transparent\n              view={isActive ? 'accent' : 'negative'}\n              text={row.blockActivity}\n            />\n            {childCount > 0 && (\n              <Badge\n                size=\"s\"\n                transparent\n                view=\"accent\"\n                text={`${level === 0 ? 'Трайбов' : 'Продуктов'}: ${childCount}`}\n              />\n            )}\n          </div>\n        }\n      />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.HighlightActiveType/TableCanvas.highlightActiveTypeSplitView.stories.tsx"
        }
      ]
    },
    "WidgetIconButtonBack": {
      "name": "WidgetIconButtonBack",
      "group": "components",
      "folderName": "Widget",
      "role": "part",
      "description": "Кнопка «назад» (стрелка) в шапке Widget для возврата к предыдущему экрану",
      "props": [
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "iconSize",
          "type": "\"s\" | \"xs\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "additionalContent",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentPlacing",
          "type": "\"default\" | \"relaxed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isLoading",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "loader",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "outlined",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftLeft",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftRight",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "square",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretch",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretching",
          "type": "\"auto\" | \"filled\" | \"fixed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "text",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"submit\" | \"reset\" | \"button\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "value",
          "type": "string | number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"secondary\" | \"clear\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"black\" | \"white\" | \"gradient\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "WidgetIconButtonBackProps",
      "sourceFile": "packages/ui-kit/src/components/Widget/components/WidgetIconButtonBack.tsx",
      "type": "wrapper",
      "atomicBase": "IconButton",
      "wrapsInternal": "IconButton",
      "category": "Локальные компоненты",
      "keywords": [
        "кнопка назад",
        "back navigation",
        "возврат на экран"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Widget",
      "inheritedProps": [
        {
          "name": "additionalContent",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentPlacing",
          "type": "ContentPlacing",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focused",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isLoading",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "loader",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "outlined",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftLeft",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftRight",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "square",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretching",
          "type": "Stretching",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "string",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"secondary\" | \"black\" | \"white\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "Widget",
        "part": "IconButtonBack"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { WidgetIconButtonBack } from '@daisforge/ui';",
      "minimalUsage": "<WidgetIconButtonBack />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Компонент  IconButton  может содержать иконку, которая указывается напрямую через  children .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconButton } from '@daisforge/ui';\nimport { IconClose } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <IconButton>\n                <IconClose color=\"inherit\" />\n            </IconButton>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Границы кнопки",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconButton } from '@daisforge/ui';\nimport { IconClose } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexWrap: 'wrap' }}>\n            <IconButton pin=\"square-square\">\n                <IconClose color=\"inherit\" />\n            </IconButton>\n            <IconButton pin=\"circle-circle\">\n                <IconClose color=\"inherit\" />\n            </IconButton>\n        </div>\n    );\n}"
        }
      ]
    },
    "WidgetIconButtonDots": {
      "name": "WidgetIconButtonDots",
      "group": "components",
      "folderName": "Widget",
      "role": "part",
      "description": "Кнопка-«три точки» для вызова контекстного меню в шапке Widget",
      "props": [],
      "sourceFile": "packages/ui-kit/src/components/Widget/components/WidgetIconButtonDots.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "контекстное меню",
        "три точки",
        "dots menu"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Widget",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "Widget",
        "part": "IconButtonDots"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { WidgetIconButtonDots } from '@daisforge/ui';",
      "minimalUsage": "<WidgetIconButtonDots />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в TableCanvas.highlightActiveTypeSplitView.stories.tsx",
          "type": "usage",
          "code": "<Widget.IconButtonDots\n              size=\"xs\"\n              iconSize=\"xs\"\n              iconOrientation=\"vertical\"\n              dropdownProps={{\n                items: [\n                  { label: 'Открыть карточку', value: '1' },\n                  { label: 'Скопировать ссылку', value: '2' },\n                ],\n              }}\n            />",
          "sourceFile": "packages/storybook/src/stories/TableCanvas/TableCanvas.HighlightActiveType/TableCanvas.highlightActiveTypeSplitView.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в SplitView.stories.tsx",
          "type": "usage",
          "code": "<Widget.IconButtonDots\n                        size=\"xs\"\n                        iconSize=\"xs\"\n                        iconOrientation=\"vertical\"\n                        dropdownProps={{\n                          items: [\n                            { label: 'label 1', value: '1' },\n                            { label: 'label 2', value: '2' },\n                          ],\n                        }}\n                      />",
          "sourceFile": "packages/storybook/src/stories/SplitView/SplitView.stories.tsx"
        }
      ]
    },
    "WidgetServiceButtons": {
      "name": "WidgetServiceButtons",
      "group": "components",
      "folderName": "Widget",
      "role": "part",
      "description": "Группа сервисных кнопок Widget: разворот на весь экран и закрытие окна",
      "props": [
        {
          "name": "$css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": "Кастомные стили styled-components для Box-контейнера"
        },
        {
          "name": "as",
          "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"article\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"big\" | \"blockquote\" | \"body\" | \"br\" | \"button\" | \"canvas\" | \"caption\" | \"center\" | \"cite\" | \"code\" | \"col\" | \"colgroup\" | \"data\" | \"datalist\" | \"dd\" | \"del\" | \"details\" | \"dfn\" | \"dialog\" | \"div\" | \"dl\" | \"dt\" | \"em\" | \"embed\" | \"fieldset…",
          "required": false,
          "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
        },
        {
          "name": "background",
          "type": "Property.Background<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "backgroundColor",
          "type": "Property.BackgroundColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "border",
          "type": "Property.Border<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderColor",
          "type": "Property.BorderColor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderRadius",
          "type": "Property.BorderRadius<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
        },
        {
          "name": "borderStyle",
          "type": "Property.BorderStyle | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "borderWidth",
          "type": "Property.BorderWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "bottom",
          "type": "Property.Bottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "boxSizing",
          "type": "Property.BoxSizing | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
        },
        {
          "name": "cursor",
          "type": "Property.Cursor | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
        },
        {
          "name": "display",
          "type": "Property.Display | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "flexDirection",
          "type": "Property.FlexDirection | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
        },
        {
          "name": "flexGrow",
          "type": "Property.FlexGrow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
        },
        {
          "name": "flexShrink",
          "type": "Property.FlexShrink | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
        },
        {
          "name": "flexWrap",
          "type": "Property.FlexWrap | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "gap",
          "type": "Property.Gap<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
        },
        {
          "name": "height",
          "type": "Property.Height<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "justifyContent",
          "type": "Property.JustifyContent | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
        },
        {
          "name": "justifyItems",
          "type": "Property.JustifyItems | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
        },
        {
          "name": "justifySelf",
          "type": "Property.JustifySelf | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
        },
        {
          "name": "left",
          "type": "Property.Left<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "margin",
          "type": "Property.Margin<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginBottom",
          "type": "Property.MarginBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginLeft",
          "type": "Property.MarginLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginRight",
          "type": "Property.MarginRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "marginTop",
          "type": "Property.MarginTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
        },
        {
          "name": "maxHeight",
          "type": "Property.MaxHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "maxWidth",
          "type": "Property.MaxWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "minHeight",
          "type": "Property.MinHeight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
        },
        {
          "name": "minWidth",
          "type": "Property.MinWidth<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
        },
        {
          "name": "opacity",
          "type": "Property.Opacity | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
        },
        {
          "name": "overflow",
          "type": "Property.Overflow | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "padding",
          "type": "Property.Padding<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingBottom",
          "type": "Property.PaddingBottom<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingLeft",
          "type": "Property.PaddingLeft<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingRight",
          "type": "Property.PaddingRight<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "paddingTop",
          "type": "Property.PaddingTop<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "position",
          "type": "Property.Position | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "right",
          "type": "Property.Right<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
        },
        {
          "name": "top",
          "type": "Property.Top<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
        },
        {
          "name": "width",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
        },
        {
          "name": "fullScreened",
          "type": "boolean | null | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "iconButtonsPin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onClose",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "toggleFullScreened",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "WidgetServiceButtonsProps",
      "sourceFile": "packages/ui-kit/src/components/Widget/components/WidgetServiceButtons.tsx",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "сервисные кнопки",
        "закрыть окно",
        "fullscreen controls"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Widget",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "Widget",
        "part": "ServiceButtons"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { WidgetServiceButtons } from '@daisforge/ui';",
      "minimalUsage": "<WidgetServiceButtons />",
      "examples": []
    },
    "WidgetContent": {
      "name": "WidgetContent",
      "group": "components",
      "folderName": "Widget",
      "role": "part",
      "description": "Прокручиваемая центральная область контента внутри карточки Widget",
      "props": [
        {
          "name": "as",
          "type": "string | React.ComponentType<any> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof WidgetContent>",
      "sourceFile": "packages/ui-kit/src/components/Widget/Widget.styled.ts",
      "type": "composition",
      "category": "Локальные компоненты",
      "keywords": [
        "скролл контента",
        "тело карточки",
        "widget body"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "Widget",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "Widget",
        "part": "Content"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { WidgetContent } from '@daisforge/ui';",
      "minimalUsage": "<WidgetContent />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в PageLayout.stories.tsx",
          "type": "usage",
          "code": "<Widget.Content>Информация о записи</Widget.Content>",
          "sourceFile": "packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в LeftPanelBlock.tsx",
          "type": "usage",
          "code": "<Widget.Content>\n            <List>\n              {contentItems.map((item) => (\n                <ListItem key={item.value} style={{ cursor: 'pointer' }}>\n                  {item.label}\n                </ListItem>\n              ))}\n            </List>\n          </Widget.Content>",
          "sourceFile": "packages/storybook/src/stories/BlockTitle/components/LeftPanelBlock.tsx"
        }
      ]
    },
    "Widget": {
      "name": "Widget",
      "group": "components",
      "folderName": "Widget",
      "role": "primary",
      "description": "Карточка-виджет с шапкой, контентом и футером — для панелей дашборда.",
      "props": [],
      "compoundParts": [
        {
          "name": "Header",
          "typeName": "WidgetHeaderProps",
          "props": [
            {
              "name": "titleRightSlot",
              "type": "React.ReactNode",
              "required": false,
              "description": "Контент справа от заголовка (и badge, если есть). Например, Chips или другие компоненты"
            },
            {
              "name": "badge",
              "type": "((((Omit<Omit<PropsType<{ view: { default: PolymorphicClassName; accent: PolymorphicClassName; positive: PolymorphicClassName; warning: PolymorphicClassName; negative: PolymorphicClassName; dark: PolymorphicClassName; light: PolymorphicClassName; }; size: { l: PolymorphicClassName; m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; pilled: { true: PolymorphicClassName; …",
              "required": false,
              "description": ""
            },
            {
              "name": "badgeMarginTop",
              "type": "number | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "bottomBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "dividerBottom",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "fullScreened",
              "type": "boolean | null | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "iconButtonsPin",
              "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "onBackClick",
              "type": "(() => void) | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "onClose",
              "type": "(() => void) | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "rightBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "showBackButton",
              "type": "boolean | undefined",
              "required": false,
              "description": "",
              "default": "false"
            },
            {
              "name": "subTitle",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "title",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "titleLeftSlot",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "titleSize",
              "type": "\"BodyL\" | \"BodyM\" | \"BodyS\" | \"BodyXS\" | \"BodyXXS\" | \"DsplL\" | \"DsplM\" | \"DsplS\" | \"H1\" | \"H2\" | \"H3\" | \"H4\" | \"H5\" | \"TextL\" | \"TextM\" | \"TextS\" | \"TextXS\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "titleTooltipProps",
              "type": "Omit<TypographyWithAutoTooltipProps<\"H4\">, \"children\" | \"variant\"> | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "toggleFullScreened",
              "type": "(() => void) | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Footer",
          "typeName": "WidgetFooterProps",
          "props": [
            {
              "name": "$css",
              "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
              "required": false,
              "description": "Кастомные стили styled-components для Box-контейнера"
            },
            {
              "name": "as",
              "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"view\" | \"article\" | \"button\" | \"dialog\" | \"figure\" | \"form\" | \"img\" | \"link\" | \"main\" | \"menu\" | \"menuitem\" | \"option\" | \"search\" | \"switch\" | \"table\" | \"text\" | \"time\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"big\" | \"blockquote\" | \"body\" | \"br\" | \"canvas\" | \"caption\" | \"center\" | \"cite\"…",
              "required": false,
              "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
            },
            {
              "name": "background",
              "type": "Property.Background<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "backgroundColor",
              "type": "Property.BackgroundColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "border",
              "type": "Property.Border<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderColor",
              "type": "Property.BorderColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderRadius",
              "type": "Property.BorderRadius<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
            },
            {
              "name": "borderStyle",
              "type": "Property.BorderStyle | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderWidth",
              "type": "Property.BorderWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "bottom",
              "type": "Property.Bottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "boxSizing",
              "type": "Property.BoxSizing | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
            },
            {
              "name": "cursor",
              "type": "Property.Cursor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
            },
            {
              "name": "display",
              "type": "Property.Display | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "flexDirection",
              "type": "Property.FlexDirection | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
            },
            {
              "name": "flexGrow",
              "type": "Property.FlexGrow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
            },
            {
              "name": "flexShrink",
              "type": "Property.FlexShrink | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
            },
            {
              "name": "flexWrap",
              "type": "Property.FlexWrap | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "gap",
              "type": "Property.Gap<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
            },
            {
              "name": "height",
              "type": "Property.Height<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "justifyContent",
              "type": "Property.JustifyContent | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "justifyItems",
              "type": "Property.JustifyItems | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
            },
            {
              "name": "justifySelf",
              "type": "Property.JustifySelf | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
            },
            {
              "name": "left",
              "type": "Property.Left<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "margin",
              "type": "Property.Margin<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginBottom",
              "type": "Property.MarginBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginLeft",
              "type": "Property.MarginLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginRight",
              "type": "Property.MarginRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginTop",
              "type": "Property.MarginTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "maxHeight",
              "type": "Property.MaxHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "maxWidth",
              "type": "Property.MaxWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "minHeight",
              "type": "Property.MinHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "minWidth",
              "type": "Property.MinWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "opacity",
              "type": "Property.Opacity | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
            },
            {
              "name": "overflow",
              "type": "Property.Overflow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "padding",
              "type": "Property.Padding<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingBottom",
              "type": "Property.PaddingBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingLeft",
              "type": "Property.PaddingLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingRight",
              "type": "Property.PaddingRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingTop",
              "type": "Property.PaddingTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "position",
              "type": "Property.Position | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "right",
              "type": "Property.Right<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "top",
              "type": "Property.Top<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "width",
              "type": "Property.Width<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "zIndex",
              "type": "Property.ZIndex | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "dividerTop",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "leftBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "rightBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "topBlock",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Content",
          "typeName": "ComponentProps<typeof StyledContent>",
          "props": [
            {
              "name": "as",
              "type": "string | React.ComponentType<any> | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Divider",
          "typeName": "ComponentProps<typeof WidgetDivider>",
          "props": [
            {
              "name": "length",
              "type": "string | number | undefined",
              "required": false,
              "description": "Размер разделителя",
              "default": "'100%'"
            },
            {
              "name": "orientation",
              "type": "\"horizontal\" | \"vertical\" | undefined",
              "required": false,
              "description": "Направление разделителя",
              "default": "'horizontal'"
            },
            {
              "name": "size",
              "type": "\"m\" | undefined",
              "required": false,
              "description": "Размер разделителя",
              "default": "'m'"
            },
            {
              "name": "view",
              "type": "\"default\" | \"dark\" | \"light\" | \"inverse\" | undefined",
              "required": false,
              "description": "Вид разделителя",
              "default": "'default'"
            }
          ]
        },
        {
          "name": "ServiceButtons",
          "typeName": "WidgetServiceButtonsProps",
          "props": [
            {
              "name": "$css",
              "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
              "required": false,
              "description": "Кастомные стили styled-components для Box-контейнера"
            },
            {
              "name": "as",
              "type": "((string | React.ComponentType<any>) & (\"symbol\" | \"object\" | \"a\" | \"abbr\" | \"address\" | \"area\" | \"article\" | \"aside\" | \"audio\" | \"b\" | \"base\" | \"bdi\" | \"bdo\" | \"big\" | \"blockquote\" | \"body\" | \"br\" | \"button\" | \"canvas\" | \"caption\" | \"center\" | \"cite\" | \"code\" | \"col\" | \"colgroup\" | \"data\" | \"datalist\" | \"dd\" | \"del\" | \"details\" | \"dfn\" | \"dialog\" | \"div\" | \"dl\" | \"dt\" | \"em\" | \"embed\" | \"fieldset…",
              "required": false,
              "description": "Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)"
            },
            {
              "name": "background",
              "type": "Property.Background<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<bg-layer>#? , <final-bg-layer>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "backgroundColor",
              "type": "Property.BackgroundColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>`\n\n**Initial value**: `transparent`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "border",
              "type": "Property.Border<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width> || <line-style> || <color>`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderColor",
              "type": "Property.BorderColor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<color>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderRadius",
              "type": "Property.BorderRadius<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ]?`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n|  **4**  |  **4**  |  **5**  | **12** | **9** |\n| 1 _-x-_ |         | 3 _-x-_ |        |       |"
            },
            {
              "name": "borderStyle",
              "type": "Property.BorderStyle | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-style>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "borderWidth",
              "type": "Property.BorderWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<line-width>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "bottom",
              "type": "Property.Bottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "boxSizing",
              "type": "Property.BoxSizing | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `content-box | border-box`\n\n**Initial value**: `content-box`\n\n| Chrome  | Firefox | Safari  |  Edge  |  IE   |\n| :-----: | :-----: | :-----: | :----: | :---: |\n| **10**  | **29**  | **5.1** | **12** | **8** |\n| 1 _-x-_ | 1 _-x-_ | 3 _-x-_ |        |       |"
            },
            {
              "name": "cursor",
              "type": "Property.Cursor | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since December 2021.\n\n**Syntax**: `[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ]`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.2** | **12** | **4** |"
            },
            {
              "name": "display",
              "type": "Property.Display | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>`\n\n**Initial value**: `inline`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "flexDirection",
              "type": "Property.FlexDirection | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `row | row-reverse | column | column-reverse`\n\n**Initial value**: `row`\n\n|  Chrome  | Firefox | Safari  |  Edge  |    IE    |\n| :------: | :-----: | :-----: | :----: | :------: |\n|  **29**  | **22**  |  **9**  | **12** |  **11**  |\n| 21 _-x-_ |         | 7 _-x-_ |        | 10 _-x-_ |"
            },
            {
              "name": "flexGrow",
              "type": "Property.FlexGrow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `0`\n\n|  Chrome  | Firefox | Safari  |  Edge  |            IE            |\n| :------: | :-----: | :-----: | :----: | :----------------------: |\n|  **29**  | **20**  |  **9**  | **12** |          **11**          |\n| 22 _-x-_ |         | 7 _-x-_ |        | 10 _(-ms-flex-positive)_ |"
            },
            {
              "name": "flexShrink",
              "type": "Property.FlexShrink | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `<number>`\n\n**Initial value**: `1`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **10** |\n| 22 _-x-_ |         | 8 _-x-_ |        |        |"
            },
            {
              "name": "flexWrap",
              "type": "Property.FlexWrap | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `nowrap | wrap | wrap-reverse`\n\n**Initial value**: `nowrap`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **28**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "gap",
              "type": "Property.Gap<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `<'row-gap'> <'column-gap'>?`\n\n| Chrome | Firefox |  Safari  |  Edge  | IE  |\n| :----: | :-----: | :------: | :----: | :-: |\n| **57** | **52**  | **10.1** | **16** | No  |"
            },
            {
              "name": "height",
              "type": "Property.Height<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "justifyContent",
              "type": "Property.JustifyContent | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2015.\n\n**Syntax**: `normal | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]`\n\n**Initial value**: `normal`\n\n|  Chrome  | Firefox | Safari  |  Edge  |   IE   |\n| :------: | :-----: | :-----: | :----: | :----: |\n|  **29**  | **20**  |  **9**  | **12** | **11** |\n| 21 _-x-_ |         | 7 _-x-_ |        |        |"
            },
            {
              "name": "justifyItems",
              "type": "Property.JustifyItems | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2016.\n\n**Syntax**: `normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | legacy | legacy && [ left | right | center ] | anchor-center`\n\n**Initial value**: `legacy`\n\n| Chrome | Firefox | Safari |  Edge  |   IE   |\n| :----: | :-----: | :----: | :----: | :----: |\n| **52** | **20**  | **9**  | **12** | **11** |"
            },
            {
              "name": "justifySelf",
              "type": "Property.JustifySelf | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since October 2017.\n\n**Syntax**: `auto | normal | stretch | <baseline-position> | <overflow-position>? [ <self-position> | left | right ] | anchor-center`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox |  Safari  |  Edge  |   IE   |\n| :----: | :-----: | :------: | :----: | :----: |\n| **57** | **45**  | **10.1** | **16** | **10** |"
            },
            {
              "name": "left",
              "type": "Property.Left<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "margin",
              "type": "Property.Margin<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'margin-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginBottom",
              "type": "Property.MarginBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginLeft",
              "type": "Property.MarginLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginRight",
              "type": "Property.MarginRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "marginTop",
              "type": "Property.MarginTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage> | auto | <anchor-size()>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **3** |"
            },
            {
              "name": "maxHeight",
              "type": "Property.MaxHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **1**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "maxWidth",
              "type": "Property.MaxWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `none | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `none`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "minHeight",
              "type": "Property.MinHeight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari  |  Edge  |  IE   |\n| :----: | :-----: | :-----: | :----: | :---: |\n| **1**  |  **3**  | **1.3** | **12** | **7** |"
            },
            {
              "name": "minWidth",
              "type": "Property.MinWidth<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **7** |"
            },
            {
              "name": "opacity",
              "type": "Property.Opacity | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<opacity-value>`\n\n**Initial value**: `1`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **2**  | **12** | **9** |"
            },
            {
              "name": "overflow",
              "type": "Property.Overflow | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `[ visible | hidden | clip | scroll | auto ]{1,2}`\n\n**Initial value**: `visible`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "padding",
              "type": "Property.Padding<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<'padding-top'>{1,4}`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingBottom",
              "type": "Property.PaddingBottom<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingLeft",
              "type": "Property.PaddingLeft<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingRight",
              "type": "Property.PaddingRight<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "paddingTop",
              "type": "Property.PaddingTop<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `<length-percentage [0,∞]>`\n\n**Initial value**: `0`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "position",
              "type": "Property.Position | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `static | relative | absolute | sticky | fixed`\n\n**Initial value**: `static`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "right",
              "type": "Property.Right<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |   IE    |\n| :----: | :-----: | :----: | :----: | :-----: |\n| **1**  |  **1**  | **1**  | **12** | **5.5** |"
            },
            {
              "name": "top",
              "type": "Property.Top<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage> | <anchor()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **5** |"
            },
            {
              "name": "width",
              "type": "Property.Width<string | number> | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <length-percentage [0,∞]> | min-content | max-content | fit-content | fit-content(<length-percentage [0,∞]>) | <calc-size()> | <anchor-size()>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "zIndex",
              "type": "Property.ZIndex | undefined",
              "required": false,
              "description": "This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.\n\n**Syntax**: `auto | <integer>`\n\n**Initial value**: `auto`\n\n| Chrome | Firefox | Safari |  Edge  |  IE   |\n| :----: | :-----: | :----: | :----: | :---: |\n| **1**  |  **1**  | **1**  | **12** | **4** |"
            },
            {
              "name": "fullScreened",
              "type": "boolean | null | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "iconButtonsPin",
              "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "onClose",
              "type": "(() => void) | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "toggleFullScreened",
              "type": "(() => void) | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "IconButtonDots",
          "props": []
        },
        {
          "name": "IconButtonBack",
          "typeName": "WidgetIconButtonBackProps",
          "props": [
            {
              "name": "as",
              "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
              "required": false,
              "description": "Сменить рендер на другой тип компонента."
            },
            {
              "name": "iconSize",
              "type": "\"s\" | \"xs\" | \"m\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "additionalContent",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "appearance",
              "type": "\"default\" | \"outline\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "blur",
              "type": "\"small\" | \"medium\" | \"large\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentLeft",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "contentPlacing",
              "type": "\"default\" | \"relaxed\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentRight",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "focused",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "isLoading",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "loader",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "outlined",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "pin",
              "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftLeft",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftRight",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "size",
              "type": "\"s\" | \"xs\" | \"xxs\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "square",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretch",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretching",
              "type": "\"auto\" | \"filled\" | \"fixed\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "text",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "type",
              "type": "\"submit\" | \"reset\" | \"button\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "value",
              "type": "string | number | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "view",
              "type": "\"default\" | \"accent\" | \"secondary\" | \"clear\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"black\" | \"white\" | \"gradient\" | undefined",
              "required": false,
              "description": ""
            }
          ]
        }
      ],
      "sourceFile": "packages/ui-kit/src/components/Widget/Widget.tsx",
      "type": "composition",
      "category": "Композиции",
      "hint": "Универсальный виджет. Для специализированного layout рабочих столов — AnalyticalWidget.",
      "keywords": [
        "карточка дашборда",
        "панель виджета",
        "compound-компонент"
      ],
      "docs": "# Widget\n\nКомпонент-layout, который может быть использован как отдельно, так и в рамках ModalDF, DrawerDF.\n\n## Ключевые особенности\n\n- Compound-структура: Header, Footer, Content, Divider, ServiceButtons\n- Поддержка разных контекстов через `containerType`: `'default'`, `'modal'`, `'splitView'`\n- Кастомизация через `$css`, `classes` и `styled`-обёртки\n- Кнопки «назад» и «три точки» с поддержкой Dropdown\n\n## Compound-компоненты\n\n```ts\nWidget.Header = WidgetHeader;\nWidget.Footer = WidgetFooter;\nWidget.Content = StyledContent;\nWidget.Divider = WidgetDivider;\nWidget.ServiceButtons = WidgetServiceButtons;\nWidget.IconButtonDots = WidgetIconButtonDots;\nWidget.IconButtonBack = WidgetIconButtonBack;\n```\n\n- `Widget.Header` — шапка с заголовком, подзаголовком, бейджем, кнопкой «назад» и правым блоком действий\n- `Widget.Footer` — футер с левым и правым блоком\n- `Widget.Content` — контейнер контента, принимает `$css`\n- `Widget.Divider` — разделитель (реэкспорт стандартного Divider)\n- `Widget.ServiceButtons` — сервисные кнопки\n- `Widget.IconButtonDots` — кнопка-иконка «три точки» с поддержкой Dropdown\n- `Widget.IconButtonBack` — кнопка «назад»\n\n## Особенности\n\n- Объект `widgetClassNames` доступен для импорта и используется для обращения к подэлементам компонента. Также можно обернуть в `styled` или использовать `$css`\n- Проп `containerType` влияет на стили: `'default'` — стандартный виджет, `'modal'` — внутри модалки, `'splitView'` — внутри SplitView\n- Для выравнивания Badge в Header используйте `badgeMarginTop`:\n  - `titleSize='H3'` → `badgeMarginTop={5}`\n  - `titleSize='H4'` → `badgeMarginTop={2}` (по умолчанию)\n  - `titleSize='H5'` → `badgeMarginTop={1}`\n\nОписание типов и compound-пропсов — в разделе [API](/docs/композиции-widget-api--docs).",
      "apiDocs": "# Widget API\n\n## WidgetProps\n\n```typescript\ntype WidgetProps = ComponentProps<'div'> & {\n  /**\n   * @default 'default'\n   */\n  containerType?: 'splitView' | 'modal' | 'default';\n  $css?: string | CSSObject | FlattenSimpleInterpolation;\n};\n```\n\n## Compound types\n\n### Widget.Header\n\n<!-- TypeSourceViewer: WidgetHeaderProps из packages/ui-kit/src/components/Widget/components/WidgetHeader.tsx (не найден в types.string.json) -->\n\n- `titleSize` — размер заголовка. По умолчанию `'H4'` - `badgeMarginTop` — отступ\nсверху для Badge. По умолчанию `2`\n\nРекомендуемые значения `badgeMarginTop` в зависимости от `titleSize`:\n\n- `H3` → `badgeMarginTop: 5`\n- `H4` → `badgeMarginTop: 2`\n- `H5` → `badgeMarginTop: 1`\n\n### Widget.Content\n\nПринимает `$css` для локальных правок стилей.\n\n### Widget.Footer\n\n<!-- TypeSourceViewer: WidgetFooterProps из packages/ui-kit/src/components/Widget/components/WidgetFooter.tsx (не найден в types.string.json) -->\n\n### Widget.Divider\n\nРеэкспорт стандартного `Divider`.\n\n### Widget.IconButtonDots\n\n```typescript\ntype IconButtonDotsProps = IconButtonProps & {\n  dropdownProps?: ComponentProps<typeof Dropdown>;\n  iconSize?: ComponentProps<typeof Icon>['size'];\n  iconOrientation?: 'horizontal' | 'vertical';\n};\n```\n\n### Widget.IconButtonBack\n\n```typescript\ntype WidgetIconButtonBackProps = ComponentProps<typeof IconButton> & {\n  iconSize?: ComponentProps<typeof IconArrowLeft>['size'];\n};\n```",
      "curatedStories": [
        {
          "exportName": "WidgetStory",
          "displayName": "Widget",
          "type": "full-code",
          "code": "import {\n  IconChevronLeft,\n  IconChevronRight,\n  Avatar,\n  backgroundPrimary,\n  Badge,\n  Button,\n  Flow,\n  IconButton,\n  s,\n  Widget,\n} from '@daisforge/ui';\n\n() => (\n    <div style={{ backgroundColor: backgroundPrimary }}>\n      <Widget $css={{ marginInline: 'auto', height: 600 }}>\n        <Widget.Header\n          onClose={() => {}}\n          fullScreened={false}\n          toggleFullScreened={() => {}}\n          title=\"Обработка документов по задаче №2\"\n          titleLeftSlot={<Avatar size=\"l\" name=\"Задача №2\" />}\n          rightBlock={\n            <>\n              <Widget.IconButtonDots\n                size=\"xs\"\n                dropdownProps={{\n                  items: [\n                    { label: 'label 1', value: '1' },\n                    { label: 'label 2', value: '2' },\n                  ],\n                }}\n              />\n              <Widget.Divider />\n              <Flow mainAxisGap={s.x2}>\n                <IconButton view=\"secondary\" size=\"xs\">\n                  <IconChevronLeft size=\"xs\" />\n                </IconButton>\n                <IconButton view=\"secondary\" size=\"xs\">\n                  <IconChevronRight size=\"xs\" />\n                </IconButton>\n              </Flow>\n            </>\n          }\n          badge={{ text: 'Бейдж' }}\n          bottomBlock={\n            <div style={{ display: 'flex', gap: s.x2 }}>\n              <Badge size=\"s\" transparent view=\"accent\" text=\"В работе\" />\n              <Badge size=\"s\" transparent view=\"negative\" text=\"2-й раз\" />\n            </div>\n          }\n        />\n\n        <Widget.Content>\n          <div\n            style={{\n              height: '2000px',\n              backgroundColor: 'goldenrod',\n            }}\n          >\n            <span\n              style={{\n                position: 'absolute',\n                right: 0,\n                width: '4px',\n                backgroundColor: 'teal',\n              }}\n            />\n          </div>\n        </Widget.Content>\n\n        <Widget.Footer\n          leftBlock={\n            <Flow mainAxisGap={s.x4}>\n              <Button text=\"Кнопка 1\" size=\"s\" view=\"secondary\" />\n              <Widget.IconButtonDots size=\"s\" />\n            </Flow>\n          }\n          rightBlock={\n            <Flow mainAxisGap={s.x4}>\n              <Button text=\"Кнопка\" size=\"s\" view=\"secondary\" />\n              <Button text=\"Главная кнопка\" size=\"s\" view=\"accent\" />\n            </Flow>\n          }\n        />\n      </Widget>\n    </div>\n  )"
        },
        {
          "exportName": "WidgetStoryText",
          "displayName": "WidgetTextContent",
          "type": "full-code",
          "code": "import {\n  IconChevronLeft,\n  IconChevronRight,\n  Avatar,\n  backgroundPrimary,\n  Badge,\n  Button,\n  Flow,\n  IconButton,\n  s,\n  Widget,\n} from '@daisforge/ui';\n\n() => (\n    <div style={{ backgroundColor: backgroundPrimary }}>\n      <Widget $css={{ marginInline: 'auto', height: 600 }}>\n        <Widget.Header\n          onClose={() => {}}\n          fullScreened={false}\n          toggleFullScreened={() => {}}\n          title=\"Обработка документов по задаче №2\"\n          titleLeftSlot={<Avatar size=\"l\" name=\"Задача №2\" />}\n          rightBlock={\n            <>\n              <Widget.IconButtonDots\n                size=\"xs\"\n                dropdownProps={{\n                  items: [\n                    { label: 'label 1', value: '1' },\n                    { label: 'label 2', value: '2' },\n                  ],\n                }}\n              />\n              <Widget.Divider />\n              <Flow mainAxisGap={s.x2}>\n                <IconButton view=\"secondary\" size=\"xs\">\n                  <IconChevronLeft size=\"xs\" />\n                </IconButton>\n                <IconButton view=\"secondary\" size=\"xs\">\n                  <IconChevronRight size=\"xs\" />\n                </IconButton>\n              </Flow>\n            </>\n          }\n          badge={{ text: 'Бейдж' }}\n          bottomBlock={\n            <div style={{ display: 'flex', gap: s.x2 }}>\n              <Badge size=\"s\" transparent view=\"accent\" text=\"В работе\" />\n              <Badge size=\"s\" transparent view=\"negative\" text=\"2-й раз\" />\n            </div>\n          }\n        />\n\n        <Widget.Content>\n          <div\n            style={{\n              height: '2000px',\n            }}\n          >\n            <span>{longText()}</span>\n            <span\n              style={{\n                position: 'absolute',\n                right: 0,\n                width: '4px',\n                backgroundColor: 'teal',\n              }}\n            />\n          </div>\n        </Widget.Content>\n\n        <Widget.Footer\n          leftBlock={\n            <Flow mainAxisGap={s.x4}>\n              <Button text=\"Кнопка 1\" size=\"s\" view=\"secondary\" />\n              <Widget.IconButtonDots size=\"s\" />\n            </Flow>\n          }\n          rightBlock={\n            <Flow mainAxisGap={s.x4}>\n              <Button text=\"Кнопка\" size=\"s\" view=\"secondary\" />\n              <Button text=\"Главная кнопка\" size=\"s\" view=\"accent\" />\n            </Flow>\n          }\n        />\n      </Widget>\n    </div>\n  )"
        },
        {
          "exportName": "WidgetFooterAlignBug",
          "displayName": "Footer leftBlock — проблема вертикального центрирования",
          "type": "full-code",
          "code": "import {\n  backgroundPrimary,\n  Button,\n  Checkbox,\n  Counter,\n  Flow,\n  s,\n  Widget,\n} from '@daisforge/ui';\n\n() => (\n    <div style={{ backgroundColor: backgroundPrimary }}>\n      <Widget $css={{ marginInline: 'auto', height: 400 }}>\n        <Widget.Header\n          onClose={() => {}}\n          fullScreened={false}\n          toggleFullScreened={() => {}}\n          title=\"Footer leftBlock — баг вертикального центрирования\"\n        />\n\n        <Widget.Content>\n          <div style={{ padding: s.x8 }}>\n            <p>\n              Посмотри на футер: в leftBlock — Checkbox и Counter, в rightBlock\n              — кнопки. Контент leftBlock прижат к верху ячейки, а не\n              центрирован по вертикали относительно rightBlock.\n            </p>\n          </div>\n        </Widget.Content>\n\n        <Widget.Footer\n          leftBlock={\n            <div style={{ display: 'flex', gap: s.x4, alignItems: 'center' }}>\n              <Checkbox size=\"s\" label=\"Выбрать всё\" />\n              <Counter count={5} view=\"accent\" size=\"xs\" />\n            </div>\n          }\n          rightBlock={\n            <Flow mainAxisGap={s.x4}>\n              <Button text=\"Отмена\" size=\"s\" view=\"secondary\" />\n              <Button text=\"Применить\" size=\"s\" view=\"accent\" />\n            </Flow>\n          }\n        />\n      </Widget>\n    </div>\n  )"
        }
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "WidgetDivider",
        "WidgetFooter",
        "WidgetHeader",
        "WidgetIconButtonBack",
        "WidgetIconButtonDots",
        "WidgetServiceButtons",
        "WidgetContent"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Widget } from '@daisforge/ui';",
      "minimalUsage": "<Widget>\n  {/* части: Widget.Header, Widget.Footer, Widget.Content, Widget.Divider, Widget.ServiceButtons, Widget.IconButtonDots, Widget.IconButtonBack */}\n</Widget>",
      "examples": [
        {
          "exportName": "WidgetStory",
          "displayName": "Widget",
          "type": "full-code",
          "code": "import {\n  IconChevronLeft,\n  IconChevronRight,\n  Avatar,\n  backgroundPrimary,\n  Badge,\n  Button,\n  Flow,\n  IconButton,\n  s,\n  Widget,\n} from '@daisforge/ui';\n\n() => (\n    <div style={{ backgroundColor: backgroundPrimary }}>\n      <Widget $css={{ marginInline: 'auto', height: 600 }}>\n        <Widget.Header\n          onClose={() => {}}\n          fullScreened={false}\n          toggleFullScreened={() => {}}\n          title=\"Обработка документов по задаче №2\"\n          titleLeftSlot={<Avatar size=\"l\" name=\"Задача №2\" />}\n          rightBlock={\n            <>\n              <Widget.IconButtonDots\n                size=\"xs\"\n                dropdownProps={{\n                  items: [\n                    { label: 'label 1', value: '1' },\n                    { label: 'label 2', value: '2' },\n                  ],\n                }}\n              />\n              <Widget.Divider />\n              <Flow mainAxisGap={s.x2}>\n                <IconButton view=\"secondary\" size=\"xs\">\n                  <IconChevronLeft size=\"xs\" />\n                </IconButton>\n                <IconButton view=\"secondary\" size=\"xs\">\n                  <IconChevronRight size=\"xs\" />\n                </IconButton>\n              </Flow>\n            </>\n          }\n          badge={{ text: 'Бейдж' }}\n          bottomBlock={\n            <div style={{ display: 'flex', gap: s.x2 }}>\n              <Badge size=\"s\" transparent view=\"accent\" text=\"В работе\" />\n              <Badge size=\"s\" transparent view=\"negative\" text=\"2-й раз\" />\n            </div>\n          }\n        />\n\n        <Widget.Content>\n          <div\n            style={{\n              height: '2000px',\n              backgroundColor: 'goldenrod',\n            }}\n          >\n            <span\n              style={{\n                position: 'absolute',\n                right: 0,\n                width: '4px',\n                backgroundColor: 'teal',\n              }}\n            />\n          </div>\n        </Widget.Content>\n\n        <Widget.Footer\n          leftBlock={\n            <Flow mainAxisGap={s.x4}>\n              <Button text=\"Кнопка 1\" size=\"s\" view=\"secondary\" />\n              <Widget.IconButtonDots size=\"s\" />\n            </Flow>\n          }\n          rightBlock={\n            <Flow mainAxisGap={s.x4}>\n              <Button text=\"Кнопка\" size=\"s\" view=\"secondary\" />\n              <Button text=\"Главная кнопка\" size=\"s\" view=\"accent\" />\n            </Flow>\n          }\n        />\n      </Widget>\n    </div>\n  )"
        },
        {
          "exportName": "WidgetStoryText",
          "displayName": "WidgetTextContent",
          "type": "full-code",
          "code": "import {\n  IconChevronLeft,\n  IconChevronRight,\n  Avatar,\n  backgroundPrimary,\n  Badge,\n  Button,\n  Flow,\n  IconButton,\n  s,\n  Widget,\n} from '@daisforge/ui';\n\n() => (\n    <div style={{ backgroundColor: backgroundPrimary }}>\n      <Widget $css={{ marginInline: 'auto', height: 600 }}>\n        <Widget.Header\n          onClose={() => {}}\n          fullScreened={false}\n          toggleFullScreened={() => {}}\n          title=\"Обработка документов по задаче №2\"\n          titleLeftSlot={<Avatar size=\"l\" name=\"Задача №2\" />}\n          rightBlock={\n            <>\n              <Widget.IconButtonDots\n                size=\"xs\"\n                dropdownProps={{\n                  items: [\n                    { label: 'label 1', value: '1' },\n                    { label: 'label 2', value: '2' },\n                  ],\n                }}\n              />\n              <Widget.Divider />\n              <Flow mainAxisGap={s.x2}>\n                <IconButton view=\"secondary\" size=\"xs\">\n                  <IconChevronLeft size=\"xs\" />\n                </IconButton>\n                <IconButton view=\"secondary\" size=\"xs\">\n                  <IconChevronRight size=\"xs\" />\n                </IconButton>\n              </Flow>\n            </>\n          }\n          badge={{ text: 'Бейдж' }}\n          bottomBlock={\n            <div style={{ display: 'flex', gap: s.x2 }}>\n              <Badge size=\"s\" transparent view=\"accent\" text=\"В работе\" />\n              <Badge size=\"s\" transparent view=\"negative\" text=\"2-й раз\" />\n            </div>\n          }\n        />\n\n        <Widget.Content>\n          <div\n            style={{\n              height: '2000px',\n            }}\n          >\n            <span>{longText()}</span>\n            <span\n              style={{\n                position: 'absolute',\n                right: 0,\n                width: '4px',\n                backgroundColor: 'teal',\n              }}\n            />\n          </div>\n        </Widget.Content>\n\n        <Widget.Footer\n          leftBlock={\n            <Flow mainAxisGap={s.x4}>\n              <Button text=\"Кнопка 1\" size=\"s\" view=\"secondary\" />\n              <Widget.IconButtonDots size=\"s\" />\n            </Flow>\n          }\n          rightBlock={\n            <Flow mainAxisGap={s.x4}>\n              <Button text=\"Кнопка\" size=\"s\" view=\"secondary\" />\n              <Button text=\"Главная кнопка\" size=\"s\" view=\"accent\" />\n            </Flow>\n          }\n        />\n      </Widget>\n    </div>\n  )"
        },
        {
          "exportName": "WidgetFooterAlignBug",
          "displayName": "Footer leftBlock — проблема вертикального центрирования",
          "type": "full-code",
          "code": "import {\n  backgroundPrimary,\n  Button,\n  Checkbox,\n  Counter,\n  Flow,\n  s,\n  Widget,\n} from '@daisforge/ui';\n\n() => (\n    <div style={{ backgroundColor: backgroundPrimary }}>\n      <Widget $css={{ marginInline: 'auto', height: 400 }}>\n        <Widget.Header\n          onClose={() => {}}\n          fullScreened={false}\n          toggleFullScreened={() => {}}\n          title=\"Footer leftBlock — баг вертикального центрирования\"\n        />\n\n        <Widget.Content>\n          <div style={{ padding: s.x8 }}>\n            <p>\n              Посмотри на футер: в leftBlock — Checkbox и Counter, в rightBlock\n              — кнопки. Контент leftBlock прижат к верху ячейки, а не\n              центрирован по вертикали относительно rightBlock.\n            </p>\n          </div>\n        </Widget.Content>\n\n        <Widget.Footer\n          leftBlock={\n            <div style={{ display: 'flex', gap: s.x4, alignItems: 'center' }}>\n              <Checkbox size=\"s\" label=\"Выбрать всё\" />\n              <Counter count={5} view=\"accent\" size=\"xs\" />\n            </div>\n          }\n          rightBlock={\n            <Flow mainAxisGap={s.x4}>\n              <Button text=\"Отмена\" size=\"s\" view=\"secondary\" />\n              <Button text=\"Применить\" size=\"s\" view=\"accent\" />\n            </Flow>\n          }\n        />\n      </Widget>\n    </div>\n  )"
        },
        {
          "exportName": "Usage1",
          "displayName": "Использование в SplitView.stories.tsx",
          "type": "usage",
          "code": "<Widget\n                  containerType={sidebarIsFullScreened ? 'modal' : 'splitView'}\n                  style={{ flex: 1, minWidth: 0 }}\n                >\n                  <Widget.Header\n                    onClose={onSidebarEsc}\n                    fullScreened={sidebarIsFullScreened}\n                    toggleFullScreened={toggleFullScreen}\n                    title={`Обработка документов по ${openedTask?.id}`}\n                    titleLeftSlot={\n                      <Avatar size={avatarSize} name={openedTask?.task ?? ''} />\n                    }\n                    rightBlock={\n                      <>\n                        <Widget.IconButtonDots\n                          size=\"xs\"\n                          iconSize=\"xs\"\n                          iconOrientation=\"vertical\"\n                          dropdownProps={{\n                            items: [\n                              { label: 'label 1', value: '1' },\n                              { label: 'label 2', value: '2' },\n                            ],\n                          }}\n                        />\n                        <Widget.Divider />\n                        <Flow mainAxisGap={s.x2}>\n                          <IconButton view=\"secondary\" size=\"xs\">\n                            <IconChevronLeft size=\"xs\" />\n                          </IconButton>\n                          <IconButton view=\"secondary\" size=\"xs\">\n                            <IconChevronRight size=\"xs\" />\n                          </IconButton>\n                        </Flow>\n                      </>\n                    }\n                    badge={{ text: 'Бейдж' }}\n                    bottomBlock={\n                      <div style={{ display: 'flex', gap: s.x2 }}>\n                        <Badge\n                          size=\"s\"\n                          transparent\n                          view=\"accent\"\n                          text=\"В работе\"\n                        />\n                        <Badge\n                          size=\"s\"\n                          transparent\n                          view=\"negative\"\n                          text=\"2-й раз\"\n                        />\n                      </div>\n                    }\n                  />\n\n                  <Widget.Content>\n                    <div\n                      style={{\n                        height: '2000px',\n                        backgr\n// … (обрезано)",
          "sourceFile": "packages/storybook/src/stories/SplitView/SplitView.stories.tsx"
        }
      ]
    },
    "FormAutocomplete": {
      "name": "FormAutocomplete",
      "group": "formComponents",
      "folderName": "FormAutocomplete",
      "role": "primary",
      "description": "Поле автодополнения с поиском по вариантам для форм на react-hook-form",
      "props": [
        {
          "name": "name",
          "type": "Path<TFieldValues>",
          "required": true,
          "description": ""
        },
        {
          "name": "afterList",
          "type": "React.ReactNode",
          "required": false,
          "description": "Ячейка для контента в конце выпадающего списка."
        },
        {
          "name": "beforeList",
          "type": "React.ReactNode",
          "required": false,
          "description": "Ячейка для контента в начале выпадающего списка."
        },
        {
          "name": "contentLeft",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": "Слот для контента слева."
        },
        {
          "name": "contentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": "Слот для контента справа."
        },
        {
          "name": "defaultValue",
          "type": "string | undefined",
          "required": false,
          "description": "Значение поля ввода по-умолчанию."
        },
        {
          "name": "filter",
          "type": "((data: SuggestionItemType) => boolean) | undefined",
          "required": false,
          "description": "Коллбэк фильтра подсказок."
        },
        {
          "name": "flip",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отображение выпадающего списка сверху, если снизу недостаточно места.",
          "default": "false"
        },
        {
          "name": "hasDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": "отобразить ли divider"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false"
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`."
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": "Видимость стрелки (хвоста)."
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": "Направление раскрытия тултипа."
        },
        {
          "name": "hintPortal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "Портал для окна подсказки. Принимает id контейнера или ref."
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": "Иконка, рядом с которым произойдет вызов всплывающего окна.\nЕсли свойство не задано, применится иконка по умолчанию."
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": "Расположение иконки подсказки, когда отсутствует label\nили же он имеет labelPlacement='inner'.",
          "default": "`outer`"
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": "Текст тултипа"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": "Способ открытия тултипа - наведение или клик мышью"
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": "Ширина окна (в rem)."
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean | undefined",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)"
        },
        {
          "name": "leftHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": "Вспомогательный текст снизу слева для поля ввода.",
          "default": "''"
        },
        {
          "name": "listMaxHeight",
          "type": "string | undefined",
          "required": false,
          "description": "Максимальная высота выпадающего списка подсказок.",
          "default": "25rem"
        },
        {
          "name": "listWidth",
          "type": "string | undefined",
          "required": false,
          "description": "Ширина выпадающего списка подсказок."
        },
        {
          "name": "onClear",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Callback при нажатии на кнопку очистки поля ввода."
        },
        {
          "name": "onScroll",
          "type": "((e: React.UIEvent<HTMLElement, UIEvent>) => void) | undefined",
          "required": false,
          "description": "Коллбэк, срабатывающий при скролле."
        },
        {
          "name": "onSearch",
          "type": "(((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | undefined",
          "required": false,
          "description": "Callback по нажатию Enter"
        },
        {
          "name": "optional",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг необязательности поля"
        },
        {
          "name": "optionalText",
          "type": "string | undefined",
          "required": false,
          "description": "Подпись для указания необязательности поля"
        },
        {
          "name": "portal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "Портал для выпадающего списка. Принимает id контейнера или ref."
        },
        {
          "name": "renderItem",
          "type": "((item: SuggestionItemType) => React.ReactNode) | undefined",
          "required": false,
          "description": "Callback для кастомной настройки элемента в выпадающем списке."
        },
        {
          "name": "renderList",
          "type": "((data?: SuggestionItemType[] | undefined) => React.ReactNode) | undefined",
          "required": false,
          "description": "Коллбэк для рендера кастомного списка подсказок."
        },
        {
          "name": "renderListEnd",
          "type": "(() => React.ReactNode) | undefined",
          "required": false,
          "description": "Коллбэк для рендера элемента в конце выпадающего списка."
        },
        {
          "name": "requiredPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right"
        },
        {
          "name": "rightHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": "Вспомогательный текст снизу справа для поля ввода."
        },
        {
          "name": "rootClassName",
          "type": "string | undefined",
          "required": false,
          "description": "ClassName для внешней обертки компонента."
        },
        {
          "name": "rootStyle",
          "type": "React.CSSProperties | undefined",
          "required": false,
          "description": "Style для внешней обертки компонента."
        },
        {
          "name": "suggestions",
          "type": "SuggestionItemType[] | undefined",
          "required": false,
          "description": "Массив подсказок."
        },
        {
          "name": "textAfter",
          "type": "string | undefined",
          "required": false,
          "description": "Слот для вспомогательного текста справа."
        },
        {
          "name": "textBefore",
          "type": "string | undefined",
          "required": false,
          "description": "Слот для вспомогательного текста слева."
        },
        {
          "name": "threshold",
          "type": "number | undefined",
          "required": false,
          "description": "Минимальное число введенных символов, при котором открывается дропдаун.",
          "default": "2"
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу справа."
        },
        {
          "name": "virtual",
          "type": "boolean | undefined",
          "required": false,
          "description": "Виртуализация в выпадающем списке.",
          "default": "false"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего списка."
        },
        {
          "name": "onChange",
          "type": "THandleChange<string> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChangeInput",
          "type": "THandleChange<string> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"viewMode\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintView",
          "type": "\"default\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "labelPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "options",
          "type": "RegisterOptions<FieldValues, Path<TFieldValues>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "React.HTMLInputTypeAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "clear",
          "type": "boolean | undefined",
          "required": false,
          "description": "view применяется с clear-токенами",
          "deprecated": true
        }
      ],
      "propsTypeName": "FormAutocompleteProps",
      "rawType": "export type FormAutocompleteProps<TFieldValues extends FieldValues> =\n  TMutationRegister<TFieldValues> & TPropsFromAutocomplete & TProps;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/formComponents/FormAutocomplete/FormAutocomplete.tsx",
      "type": "form",
      "wrappedBy": "Autocomplete",
      "category": "Формы",
      "keywords": [
        "autocomplete",
        "поиск по списку",
        "подсказки ввода"
      ],
      "chooseWhen": "Внутри формы на react-hook-form — принимает name/control/rules вместо value/onChange.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormAutocomplete } from '@daisforge/ui';",
      "minimalUsage": "<FormAutocomplete name={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormAutocomplete\n            name=\"autocomplete\"\n            suggestions={mockData}\n            label=\"FormAutocomplete\"\n            options={{\n              minLength: {\n                value: 2,\n                message: 'обязательное больше 2',\n              },\n              required: 'Заполните обязательное поле',\n            }}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormAutocomplete\n            name=\"autocomplete\"\n            suggestions={mockData}\n            label=\"FormAutocomplete\"\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "FormCheckbox": {
      "name": "FormCheckbox",
      "group": "formComponents",
      "folderName": "FormCheckbox",
      "role": "primary",
      "description": "Чекбокс (одиночный или группа) для react-hook-form, без встроенной валидации",
      "props": [
        {
          "name": "name",
          "type": "Path<TFieldValues>",
          "required": true,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "string | undefined",
          "required": false,
          "description": "Стиль для UI конфигурации\nВлияет на выбор предустановленного набора токенов",
          "default": "default"
        },
        {
          "name": "checkIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": "Кастомная иконка галочки."
        },
        {
          "name": "description",
          "type": "React.ReactNode",
          "required": false,
          "description": "Описание элемента"
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": "Компонента находиться в фокусе"
        },
        {
          "name": "indeterminate",
          "type": "boolean | undefined",
          "required": false,
          "description": "Неопределенное состояние компонента - когда часть потомков не выбрана."
        },
        {
          "name": "indeterminateIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": "Кастомная иконка indeterminate-состояния."
        },
        {
          "name": "label",
          "type": "React.ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу"
        },
        {
          "name": "singleLine",
          "type": "boolean | undefined",
          "required": false,
          "description": "Title и description в одну строку или с переносом строк"
        },
        {
          "name": "size",
          "type": "\"s\" | \"m\" | \"l\" | undefined",
          "required": false,
          "description": "Размер компонента"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"secondary\" | \"positive\" | \"warning\" | \"negative\" | \"tertiary\" | \"paragraph\" | undefined",
          "required": false,
          "description": "Вид компонента"
        },
        {
          "name": "onChange",
          "type": "THandleChange<boolean> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "options",
          "type": "RegisterOptions<FieldValues, Path<TFieldValues>> | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "FormCheckboxProps",
      "rawType": "export type FormCheckboxProps<TFieldValues extends FieldValues> =\n  TMutationRegister<TFieldValues> & TPropsFromCheckbox & TProps;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/formComponents/FormCheckbox/FormCheckbox.tsx",
      "type": "form",
      "wrappedBy": "Checkbox",
      "category": "Формы",
      "keywords": [
        "флажок",
        "checkbox group",
        "выбор нескольких вариантов"
      ],
      "chooseWhen": "Внутри формы на react-hook-form — одиночный чекбокс или группа через name/control, правила — через rules.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormCheckbox } from '@daisforge/ui';",
      "minimalUsage": "<FormCheckbox name={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormCheckbox<FormValues>\n            name=\"checkbox\"\n            label=\"Checkbox\"\n            size=\"m\"\n            options={{\n              required: 'Заполните обязательное поле',\n            }}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormCheckbox<FormValues> name=\"checkbox\" label=\"Checkbox\" size=\"m\" />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "FormCombobox": {
      "name": "FormCombobox",
      "group": "formComponents",
      "folderName": "FormCombobox",
      "role": "primary",
      "description": "Комбобокс с поиском и мультивыбором опций, интегрированный с react-hook-form",
      "props": [
        {
          "name": "items",
          "type": "ItemOption[]",
          "required": true,
          "description": "Список элементов."
        },
        {
          "name": "name",
          "type": "Path<TFieldValues>",
          "required": true,
          "description": ""
        },
        {
          "name": "afterList",
          "type": "React.ReactNode",
          "required": false,
          "description": "Ячейка для контента в конце выпадающего списка."
        },
        {
          "name": "alwaysOpened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Дропдаун открыт всегда.",
          "default": "false"
        },
        {
          "name": "arrowPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Сторона расположения стрелки скрытия/раскрытия.",
          "default": "left"
        },
        {
          "name": "beforeList",
          "type": "React.ReactNode",
          "required": false,
          "description": "Ячейка для контента в начале выпадающего списка."
        },
        {
          "name": "closeAfterSelect",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрывать ли выпадающий список после выбора элемента.",
          "default": "если single, то true; если multiple, то false; если передан alwaysOpened, то false"
        },
        {
          "name": "contentLeft",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": "Слот для контента слева."
        },
        {
          "name": "contentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": "Слот для контента справа."
        },
        {
          "name": "emptyStateDescription",
          "type": "React.ReactNode",
          "required": false,
          "description": "Текст для состояния когда нет результата."
        },
        {
          "name": "filter",
          "type": "((item: ItemOption, textValue: string) => boolean) | undefined",
          "required": false,
          "description": "Функция фильтрации элементов."
        },
        {
          "name": "filterValue",
          "type": "((value: string) => boolean) | undefined",
          "required": false,
          "description": "Функция валидации вводимых значений."
        },
        {
          "name": "flip",
          "type": "boolean | undefined",
          "required": false,
          "description": "Коррекция placement, если выпадающий список находится за пределами экрана.",
          "default": "false"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false"
        },
        {
          "name": "helperText",
          "type": "string | undefined",
          "required": false,
          "description": "Вспомогательный текст снизу слева для поля ввода.",
          "default": "''"
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`."
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": "Видимость стрелки (хвоста)."
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": "Направление раскрытия тултипа."
        },
        {
          "name": "hintPortal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "Портал для окна подсказки. Принимает id контейнера или ref."
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": "Иконка, рядом с которым произойдет вызов всплывающего окна.\nЕсли свойство не задано, применится иконка по умолчанию."
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": "Расположение иконки подсказки, когда отсутствует label\nили же он имеет labelPlacement='inner'.",
          "default": "`outer`"
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": "Текст тултипа"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": "Способ открытия тултипа - наведение или клик мышью"
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": "Ширина окна (в rem)."
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean | undefined",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)"
        },
        {
          "name": "labelPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": "Расположение лейбла."
        },
        {
          "name": "listMaxHeight",
          "type": "Property.Height<string | number> | undefined",
          "required": false,
          "description": "Максимальная высота выпадающего списка."
        },
        {
          "name": "listWidth",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "Значение css width для выпадающего списка."
        },
        {
          "name": "mode",
          "type": "\"default\" | \"radio\" | undefined",
          "required": false,
          "description": "Режим работы взаимодействия с элементами.\n- default: элемент можно выбрать и можно отменить его выбор.\n- radio: если элемент выбран, то отменить его выбор нельзя. Только для single-режима.",
          "default": "default"
        },
        {
          "name": "onChangeValue",
          "type": "((value: string) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения значения в строке поиска."
        },
        {
          "name": "onScroll",
          "type": "((e: React.UIEvent<HTMLElement, UIEvent>) => void) | undefined",
          "required": false,
          "description": "Коллбэк, срабатывающий при скролле."
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean) => void) | undefined",
          "required": false,
          "description": "Событие сворачивания/разворачивания выпадающего списка."
        },
        {
          "name": "optional",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг необязательности поля"
        },
        {
          "name": "optionalText",
          "type": "string | undefined",
          "required": false,
          "description": "Подпись для указания необязательности поля"
        },
        {
          "name": "placement",
          "type": "Placement | undefined",
          "required": false,
          "description": "Сторона открытия дропдауна относительно target элемента.",
          "default": "bottom-start"
        },
        {
          "name": "portal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "Портал для выпадающего списка. Принимает id контейнера или ref."
        },
        {
          "name": "renderItem",
          "type": "((item: ItemOption) => React.ReactNode) | undefined",
          "required": false,
          "description": "Callback для кастомной настройки элемента в выпадающем списке."
        },
        {
          "name": "renderSelectionIcon",
          "type": "((selected: boolean | \"indeterminate\") => React.ReactNode) | undefined",
          "required": false,
          "description": "Callback для кастомной настройки иконки выбранного элемента."
        },
        {
          "name": "requiredPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right"
        },
        {
          "name": "shift",
          "type": "boolean | undefined",
          "required": false,
          "description": "Смещение выпадающего списка при соприкосновении с границами экрана.",
          "default": "false"
        },
        {
          "name": "singleLine",
          "type": "boolean | undefined",
          "required": false,
          "description": "Label в элементе выпадающего списка в одну строку или с переносом строк.",
          "default": "true"
        },
        {
          "name": "textAfter",
          "type": "string | undefined",
          "required": false,
          "description": "Слот для вспомогательного текста слева."
        },
        {
          "name": "textBefore",
          "type": "string | undefined",
          "required": false,
          "description": "Слот для вспомогательного текста справа."
        },
        {
          "name": "treeView",
          "type": "boolean | undefined",
          "required": false,
          "description": "Режим отображения выпадающего списка в виде дерева.",
          "default": "false"
        },
        {
          "name": "variant",
          "type": "\"normal\" | \"tight\" | undefined",
          "required": false,
          "description": "Вариант: обычный или сжатый",
          "default": "normal"
        },
        {
          "name": "virtual",
          "type": "boolean | undefined",
          "required": false,
          "description": "Виртуализация в выпадающем списке.\nНе поддерживается в многоуровневых списках.",
          "default": "false"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего списка."
        },
        {
          "name": "multiselect",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChange",
          "type": "THandleChange<string> | THandleChange<string[]> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "_offset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"viewMode\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chipClickArea",
          "type": "\"full\" | \"close-icon\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"accent\" | \"secondary\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "defaultValue",
          "type": "string | string[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintView",
          "type": "\"default\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isTargetAmount",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "options",
          "type": "RegisterOptions<FieldValues, Path<TFieldValues>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "renderValue",
          "type": "((item: ItemOption) => string) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "selectAllOptions",
          "type": "SelectAllProps | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "targetAmount",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "React.HTMLInputTypeAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "FormComboboxProps",
      "rawType": "export type FormComboboxProps<TFieldValues extends FieldValues> =\n  TMutationRegister<TFieldValues> & TPropsFromCombobox & TProps;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/formComponents/FormCombobox/FormCombobox.tsx",
      "type": "form",
      "wrappedBy": "Combobox",
      "category": "Формы",
      "keywords": [
        "combobox",
        "мультиселект",
        "поиск и выбор"
      ],
      "chooseWhen": "Внутри формы на react-hook-form — тот же мультивыбор с поиском через name/control/rules.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormCombobox } from '@daisforge/ui';",
      "minimalUsage": "<FormCombobox items={[]} name={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormCombobox\n            label=\"FormCombobox multiple\"\n            name=\"comboboxMultiple\"\n            multiple\n            items={items}\n            options={{\n              validate: (v) => {\n                if (v.length < 3) {\n                  return 'минимум три выбранных элемента';\n                }\n                return true;\n              },\n              required: 'Заполните обязательное поле',\n            }}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormCombobox\n            label=\"FormCombobox multiple\"\n            name=\"comboboxMultiple\"\n            multiple\n            items={items}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "FormDatePicker": {
      "name": "FormDatePicker",
      "group": "formComponents",
      "folderName": "FormDatePickers",
      "role": "primary",
      "description": "Выбор одной даты с валидацией формата и диапазона min/max для форм",
      "props": [
        {
          "name": "name",
          "type": "Path<TFieldValues>",
          "required": true,
          "description": ""
        },
        {
          "name": "calendarContainerHeight",
          "type": "string | number | undefined",
          "required": false,
          "description": "Высота календаря"
        },
        {
          "name": "calendarContainerWidth",
          "type": "string | number | undefined",
          "required": false,
          "description": "Ширина календаря"
        },
        {
          "name": "closeAfterDateSelect",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрыть календарь после выбора дат"
        },
        {
          "name": "closeOnEsc",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрывать календарь при нажатии Escape.",
          "default": "true"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрывать календарь при нажатии вне области элемента.",
          "default": "true"
        },
        {
          "name": "dateShortcuts",
          "type": "DateShortcutItem[] | undefined",
          "required": false,
          "description": "Список предустановленных дат,\nкоторые можно выбрать в выпадающем календаре"
        },
        {
          "name": "dateShortcutsPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Положение списка предустановленных дат",
          "default": "'left'"
        },
        {
          "name": "dateShortcutsWidth",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "Ширина списка предустановленных дат"
        },
        {
          "name": "disabledList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных дней."
        },
        {
          "name": "disabledMonthList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных месяцев."
        },
        {
          "name": "disabledQuarterList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных кварталов."
        },
        {
          "name": "disabledYearList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных годов."
        },
        {
          "name": "disableFlip",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отключить автоматическое переворачивание дропдауна при нехватке места"
        },
        {
          "name": "eventList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий."
        },
        {
          "name": "eventMonthList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по месяцам."
        },
        {
          "name": "eventQuarterList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по кварталам."
        },
        {
          "name": "eventTooltipOptions",
          "type": "EventTooltipOptions | undefined",
          "required": false,
          "description": "Свойства всплывающей подсказки для событий."
        },
        {
          "name": "eventYearList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по годам."
        },
        {
          "name": "frame",
          "type": "string | React.RefObject<HTMLElement> | undefined",
          "required": false,
          "description": "В каком контейнере позиционируется(по умолчанию document), можно также указать id элемента или ref для него."
        },
        {
          "name": "hasClearDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг наличия разделителя для clear appearance",
          "default": "false"
        },
        {
          "name": "includeEdgeDates",
          "type": "boolean | undefined",
          "required": false,
          "description": "Должны ли значения минимального и максимального дня включаться в диапазон."
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean | undefined",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)"
        },
        {
          "name": "labelPlacement",
          "type": "string | undefined",
          "required": false,
          "description": "Расположение лейбла."
        },
        {
          "name": "lang",
          "type": "\"ru\" | \"en\" | undefined",
          "required": false,
          "description": "Язык в маске ввода"
        },
        {
          "name": "maskWithFormat",
          "type": "boolean | undefined",
          "required": false,
          "description": "Формат применяется в качестве маски ввода.",
          "default": "true"
        },
        {
          "name": "max",
          "type": "Date | undefined",
          "required": false,
          "description": "Максимальное значение даты."
        },
        {
          "name": "min",
          "type": "Date | undefined",
          "required": false,
          "description": "Минимальное значение даты."
        },
        {
          "name": "offset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": "Отступ календаря относительно поля ввода.",
          "default": "[0, 2]"
        },
        {
          "name": "onChangeVisibleDate",
          "type": "((date: Date) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean, event?: Event | React.SyntheticEvent<Element, Event> | undefined) => void) | undefined",
          "required": false,
          "description": "Событие сворачивания/разворачивания календаря."
        },
        {
          "name": "opened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Видимость календаря."
        },
        {
          "name": "placement",
          "type": "DatePickerPlacement | DatePickerPlacementBasic[] | undefined",
          "required": false,
          "description": "Сторона открытия календаря относительно поля ввода.",
          "default": "[\"bottom\", \"top\"]"
        },
        {
          "name": "renderFromDate",
          "type": "Date | undefined",
          "required": false,
          "description": "Дата с которой начинается календарная сетка."
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | undefined",
          "required": false,
          "description": "Размер контрола.",
          "default": "'s'"
        },
        {
          "name": "stretched",
          "type": "boolean | undefined",
          "required": false,
          "description": "Растянуть поле ввода на всю доступную ширину, а календарь — на всю доступную ширину и высоту"
        },
        {
          "name": "type",
          "type": "\"Days\" | \"Months\" | \"Years\" | \"Quarters\" | undefined",
          "required": false,
          "description": "Тип отображения календаря: дни, месяца, года."
        },
        {
          "name": "usePortal",
          "type": "boolean | undefined",
          "required": false,
          "description": "Находится ли в портале.",
          "default": "false"
        },
        {
          "name": "view",
          "type": "\"default\" | undefined",
          "required": false,
          "description": "Вид контрола."
        },
        {
          "name": "zIndex",
          "type": "string | undefined",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего календаря"
        },
        {
          "name": "format",
          "type": "TDatePickerFormat | undefined",
          "required": false,
          "description": "",
          "default": "'DD.MM.YYYY'"
        },
        {
          "name": "invalidFormatMessage",
          "type": "string | undefined",
          "required": false,
          "description": "",
          "default": "'Формат даты указан не верно'"
        },
        {
          "name": "portal",
          "type": "string | React.RefObject<HTMLElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "textHint",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"viewMode\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "defaultDate",
          "type": "Date | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "eventTooltipSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPortal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintView",
          "type": "\"default\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "leftHelper",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChange",
          "type": "(((event: { target: { value?: string | undefined; name?: string | undefined; originalDate?: DateType; isoDate?: string | undefined; }; }) => void) & React.FormEventHandler<HTMLDivElement>) | (((event: { target: { value?: string | undefined; name?: string | undefined; originalDate?: DateType; isoDate?: string | undefined; }; }) => void) & React.FormEventHandler<HTMLDivElement>) | (((event: { target…",
          "required": false,
          "description": ""
        },
        {
          "name": "onChangeValue",
          "type": "((event: React.SyntheticEvent<HTMLInputElement, Event> | null, value?: string | undefined, originalDate?: DateType, isoDate?: string | undefined) => void) | ((event: React.SyntheticEvent<HTMLInputElement, Event> | null, value?: string | undefined, originalDate?: DateType, isoDate?: string | undefined) => void) | ((event: React.SyntheticEvent<HTMLInputElement, Event> | null, value?: string | undefi…",
          "required": false,
          "description": ""
        },
        {
          "name": "onCommitDate",
          "type": "OnCommitDateCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "options",
          "type": "RegisterOptions<FieldValues, Path<TFieldValues>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "preserveInvalidOnBlur",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "requiredPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "",
          "default": "'right'"
        },
        {
          "name": "textAfter",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "textBefore",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "valueEdited",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "valueError",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "valueSuccess",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isOpen",
          "type": "boolean | undefined",
          "required": false,
          "description": "Видимость календаря.",
          "deprecated": true
        }
      ],
      "propsTypeName": "FormDatePickerProps",
      "rawType": "export type FormDatePickerProps<TFieldValues extends FieldValues> =\n  TMutationRegister<TFieldValues> & TPropsFromDatePicker & TProps;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/formComponents/FormDatePickers/FormDatePicker/FormDatePicker.tsx",
      "type": "form",
      "wrappedBy": "DatePicker",
      "category": "Формы",
      "keywords": [
        "date picker",
        "выбор даты",
        "календарь в форме"
      ],
      "chooseWhen": "Внутри формы на react-hook-form — добавляет валидацию формата и диапазона min/max через rules.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormDatePicker } from '@daisforge/ui';",
      "minimalUsage": "<FormDatePicker name={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormDatePicker\n            name=\"date\"\n            label=\"Date\"\n            invalidFormatMessage=\"некорректно\"\n            size=\"s\"\n            options={{\n              required: 'обязательное поле',\n              max: {\n                value: new Date().getTime(),\n                message: 'указанная дата за пределами максимально доступной',\n              },\n              min: {\n                value: new Date().getTime() - 20 * 24 * 60 * 60 * 1000,\n                message: 'указанная дата за пределами минимально доступной',\n              },\n            }}\n            placement={['left', 'top']}\n            placeholder=\"выберите дату\"\n            onChange={(data) => {\n              // eslint-disable-next-line no-console\n              console.debug('FormDatePicker data', data);\n            }}\n            style={{\n              maxWidth: '559px',\n            }}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormDatePicker\n            name=\"date\"\n            label=\"Date\"\n            invalidFormatMessage=\"incorrect date\"\n            onChange={(data) => {\n              // eslint-disable-next-line no-console\n              console.debug('FormDatePicker data', data);\n            }}\n            style={{\n              maxWidth: '559px',\n            }}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "FormDatePickerRange": {
      "name": "FormDatePickerRange",
      "group": "formComponents",
      "folderName": "FormDatePickers",
      "role": "primary",
      "description": "Выбор диапазона дат (от-до) с валидацией периода для react-hook-form",
      "props": [
        {
          "name": "name",
          "type": "Path<TFieldValues>",
          "required": true,
          "description": ""
        },
        {
          "name": "calendarContainerHeight",
          "type": "string | number | undefined",
          "required": false,
          "description": "Высота календаря"
        },
        {
          "name": "calendarContainerWidth",
          "type": "string | number | undefined",
          "required": false,
          "description": "Ширина календаря"
        },
        {
          "name": "closeAfterDateSelect",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрыть календарь после выбора дат"
        },
        {
          "name": "closeOnEsc",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрывать календарь при нажатии Escape.",
          "default": "true"
        },
        {
          "name": "closeOnOverlayClick",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрывать календарь при нажатии вне области элемента.",
          "default": "true"
        },
        {
          "name": "dateShortcutsPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Положение списка предустановленных дат",
          "default": "'left'"
        },
        {
          "name": "dateShortcutsWidth",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "Ширина списка предустановленных дат"
        },
        {
          "name": "disabledList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных дней."
        },
        {
          "name": "disabledMonthList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных месяцев."
        },
        {
          "name": "disabledQuarterList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных кварталов."
        },
        {
          "name": "disabledYearList",
          "type": "DisabledDay[] | undefined",
          "required": false,
          "description": "Список отключенных годов."
        },
        {
          "name": "disableFlip",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отключить автоматическое переворачивание дропдауна при нехватке места"
        },
        {
          "name": "eventList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий."
        },
        {
          "name": "eventMonthList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по месяцам."
        },
        {
          "name": "eventQuarterList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по кварталам."
        },
        {
          "name": "eventTooltipOptions",
          "type": "EventTooltipOptions | undefined",
          "required": false,
          "description": "Свойства всплывающей подсказки для событий."
        },
        {
          "name": "eventYearList",
          "type": "EventDay[] | undefined",
          "required": false,
          "description": "Список событий по годам."
        },
        {
          "name": "frame",
          "type": "string | React.RefObject<HTMLElement> | undefined",
          "required": false,
          "description": "В каком контейнере позиционируется(по умолчанию document), можно также указать id элемента или ref для него."
        },
        {
          "name": "hasClearDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг наличия разделителя для clear appearance",
          "default": "false"
        },
        {
          "name": "includeEdgeDates",
          "type": "boolean | undefined",
          "required": false,
          "description": "Должны ли значения минимального и максимального дня включаться в диапазон."
        },
        {
          "name": "lang",
          "type": "\"ru\" | \"en\" | undefined",
          "required": false,
          "description": "Язык в маске ввода"
        },
        {
          "name": "maskWithFormat",
          "type": "boolean | undefined",
          "required": false,
          "description": "Формат применяется в качестве маски ввода."
        },
        {
          "name": "max",
          "type": "Date | undefined",
          "required": false,
          "description": "Максимальное значение даты."
        },
        {
          "name": "min",
          "type": "Date | undefined",
          "required": false,
          "description": "Минимальное значение даты."
        },
        {
          "name": "offset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": "Отступ календаря относительно поля ввода.",
          "default": "[0, 0]"
        },
        {
          "name": "onChangeVisibleDate",
          "type": "((date: Date) => void) | undefined",
          "required": false,
          "description": "Обработчик изменения отображаемых месяца или года при навигации по календарю."
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean, event?: Event | React.SyntheticEvent<Element, Event> | undefined) => void) | undefined",
          "required": false,
          "description": "Событие сворачивания/разворачивания календаря."
        },
        {
          "name": "opened",
          "type": "boolean | undefined",
          "required": false,
          "description": "Видимость календаря."
        },
        {
          "name": "renderFromDate",
          "type": "Date | undefined",
          "required": false,
          "description": "Дата с которой начинается календарная сетка."
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | undefined",
          "required": false,
          "description": "Размер контрола."
        },
        {
          "name": "stretched",
          "type": "boolean | undefined",
          "required": false,
          "description": "Растянуть поле ввода на всю доступную ширину, а календарь — на всю доступную ширину и высоту"
        },
        {
          "name": "type",
          "type": "\"Days\" | \"Months\" | \"Years\" | \"Quarters\" | undefined",
          "required": false,
          "description": "Тип отображения календаря: дни, месяца, года."
        },
        {
          "name": "usePortal",
          "type": "boolean | undefined",
          "required": false,
          "description": "Находится ли в портале.",
          "default": "false"
        },
        {
          "name": "view",
          "type": "\"default\" | undefined",
          "required": false,
          "description": "Вид контрола."
        },
        {
          "name": "zIndex",
          "type": "string | undefined",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего календаря"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"viewMode\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "dateShortcuts",
          "type": "DateShortcutItem[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "defaultFirstDate",
          "type": "Date | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "defaultSecondDate",
          "type": "Date | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "dividerIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "dividerVariant",
          "type": "\"none\" | \"icon\" | \"dash\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "eventTooltipSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "firstPlaceholder",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "firstTextfieldContentLeft",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "firstTextfieldContentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "firstTextfieldTextAfter",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "firstTextfieldTextBefore",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "firstValueEdited",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "firstValueError",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "firstValueSuccess",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "format",
          "type": "TDatePickerFormat | undefined",
          "required": false,
          "description": "",
          "default": "'DD.MM.YYYY'"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPlacement",
          "type": "Placement | any[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintView",
          "type": "\"default\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "inputWrapperRef",
          "type": "React.Ref<HTMLDivElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "invalidFormatMessage",
          "type": "string | undefined",
          "required": false,
          "description": "",
          "default": "'Формат даты указан не верно'"
        },
        {
          "name": "isCalendarPositionedByInput",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isDoubleCalendar",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "leftHelper",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onBlurFirstTextfield",
          "type": "((event: React.FocusEvent<HTMLInputElement, Element>) => void) | ((event: React.FocusEvent<HTMLInputElement, Element>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onBlurSecondTextfield",
          "type": "((event: React.FocusEvent<HTMLInputElement, Element>) => void) | ((event: React.FocusEvent<HTMLInputElement, Element>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChange",
          "type": "((newValue: string) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChangeFirstValue",
          "type": "ChangeInstanceCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onChangeSecondValue",
          "type": "ChangeInstanceCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onCommitFirstDate",
          "type": "CommitInstanceCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onCommitSecondDate",
          "type": "CommitInstanceCallback | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onFocusFirstTextfield",
          "type": "((event: React.FocusEvent<HTMLInputElement, Element>) => void) | ((event: React.FocusEvent<HTMLInputElement, Element>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onFocusSecondTextfield",
          "type": "((event: React.FocusEvent<HTMLInputElement, Element>) => void) | ((event: React.FocusEvent<HTMLInputElement, Element>) => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "options",
          "type": "RegisterOptions<FieldValues, Path<TFieldValues>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "placement",
          "type": "DatePickerRangePlacement | DatePickerRangePlacementBasic[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "portal",
          "type": "string | React.RefObject<HTMLElement> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "preserveInvalidOnBlur",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "requiredIndicatorPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "requiredPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "secondPlaceholder",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "secondTextfieldContentLeft",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "secondTextfieldContentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "secondTextfieldTextAfter",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "secondTextfieldTextBefore",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "secondValueEdited",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "secondValueError",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "secondValueSuccess",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "textHint",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "isOpen",
          "type": "boolean | undefined",
          "required": false,
          "description": "Видимость календаря.",
          "deprecated": true
        }
      ],
      "propsTypeName": "FormDatePickerRangeProps",
      "sourceFile": "packages/ui-kit/src/formComponents/FormDatePickers/FormDatePickerRange/FormDatePickerRange.tsx",
      "type": "form",
      "wrappedBy": "DatePickerRange",
      "category": "Формы",
      "keywords": [
        "date range",
        "диапазон дат",
        "период дат"
      ],
      "chooseWhen": "Внутри формы на react-hook-form — тот же диапазон дат с валидацией периода через rules.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormDatePickerRange } from '@daisforge/ui';",
      "minimalUsage": "<FormDatePickerRange name={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormDatePickerRange\n            name=\"dateRange\"\n            label=\"DateRange\"\n            invalidFormatMessage=\"incorrect date\"\n            isDoubleCalendar\n            max={new Date(new Date().setDate(new Date().getDate() + 2))}\n            size=\"s\"\n            style={{\n              maxWidth: '559px',\n            }}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormDatePickerRange\n            name=\"dateRange\"\n            label=\"DateRange\"\n            isDoubleCalendar\n            size=\"s\"\n            invalidFormatMessage=\"incorrect date\"\n            options={{\n              required: 'обязательное поле',\n              min: {\n                value: new Date(2024, 0, 1).getTime(),\n                message: 'мероприятия доступны с 2024 года',\n              },\n              max: {\n                value: new Date(2024, 11, 31).getTime(),\n                message: 'только события 2024 года',\n              },\n              validate: {\n                minDuration: (value) => {\n                  if (!value?.dateFrom || !value?.dateTo) return true;\n                  const start = new Date(\n                    value.dateFrom.split('.').reverse().join('-'),\n                  );\n                  const end = new Date(\n                    value.dateTo.split('.').reverse().join('-'),\n                  );\n                  if (\n                    Number.isNaN(start.getTime()) ||\n                    Number.isNaN(end.getTime())\n                  )\n                    return true;\n                  return end.getTime() - start.getTime() < 7 * 86400000\n                    ? 'Минимальный период - 7 дней'\n                    : true;\n                },\n                noWeekends: (value) => {\n                  const start = new Date(\n                    value.dateFrom.split('.').reverse().join('-'),\n                  );\n                  return [0, 6].includes(start.getDay())\n                    ? 'Нельзя начинать в выходные'\n                    : true;\n                },\n              },\n            }}\n            style={{\n              maxWidth: '559px',\n            }}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "FormMask": {
      "name": "FormMask",
      "group": "formComponents",
      "folderName": "FormMask",
      "role": "primary",
      "description": "Поле ввода по маске (телефон, карта и т.п.) с поддержкой чипов для форм",
      "props": [
        {
          "name": "mask",
          "type": "string",
          "required": true,
          "description": ""
        },
        {
          "name": "name",
          "type": "Path<TFieldValues>",
          "required": true,
          "description": ""
        },
        {
          "name": "alwaysShowMask",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отображать ли маску всегда."
        },
        {
          "name": "defaultValue",
          "type": "string | (readonly string[] & string) | undefined",
          "required": false,
          "description": "Значение по умолчанию."
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean | undefined",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)"
        },
        {
          "name": "labelPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": "Расположение лейбла."
        },
        {
          "name": "maskChar",
          "type": "string | undefined",
          "required": false,
          "description": "Символ маскирования."
        },
        {
          "name": "maskFormat",
          "type": "IMaskItem[] | undefined",
          "required": false,
          "description": "Набор соответствий маски и маскируемого значения."
        },
        {
          "name": "maskString",
          "type": "string | undefined",
          "required": false,
          "description": "Строка, которая будет отображена в незаполненную часть маски.\nЕсли передать maskString, то maskChar игнорируется."
        },
        {
          "name": "onValueChange",
          "type": "((params: { maskedValue: string; value: string; }) => void) | undefined",
          "required": false,
          "description": "Callback при изменении значения маски с дополнительной информацией."
        },
        {
          "name": "optional",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг необязательности поля"
        },
        {
          "name": "optionalText",
          "type": "string | undefined",
          "required": false,
          "description": "Подпись для указания необязательности поля"
        },
        {
          "name": "reformat",
          "type": "((params: { value: string | IInputValue[]; selection: ISelectRange; input?: string | undefined; }) => IInputState) | undefined",
          "required": false,
          "description": "Функция форматирования, которая позволяет задать собственные правила форматирования."
        },
        {
          "name": "requiredPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right"
        },
        {
          "name": "showMask",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отображать ли маску во время ввода."
        },
        {
          "name": "showStartChars",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отображать ли префикс маски. Например у маски телефона \"+7\""
        },
        {
          "name": "onChange",
          "type": "THandleChange<string> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"clear\" | \"viewMode\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chips",
          "type": "TextFieldPrimitiveValue[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chipType",
          "type": "\"default\" | \"text\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chipValidator",
          "type": "((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { …",
          "required": false,
          "description": ""
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"accent\" | \"secondary\" | \"positive\" | \"warning\" | \"negative\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "clear",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enumerationType",
          "type": "\"plain\" | \"chip\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hasDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPortal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintView",
          "type": "\"default\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "leftHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": "",
          "default": "''"
        },
        {
          "name": "onChangeChips",
          "type": "((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimit…",
          "required": false,
          "description": ""
        },
        {
          "name": "onSearch",
          "type": "(((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | (((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | (((value: string, event?: React.KeyboardEvent<HT…",
          "required": false,
          "description": ""
        },
        {
          "name": "options",
          "type": "RegisterOptions<FieldValues, Path<TFieldValues>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rightHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "textAfter",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "textBefore",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "FormMaskProps",
      "rawType": "export type FormMaskProps<TFieldValues extends FieldValues> =\n  TMutationRegister<TFieldValues> & TPropsFromMask & TProps;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/formComponents/FormMask/FormMask.tsx",
      "type": "form",
      "wrappedBy": "Mask",
      "category": "Формы",
      "keywords": [
        "маска ввода",
        "input mask",
        "форматированный ввод"
      ],
      "chooseWhen": "Внутри формы на react-hook-form — то же поле с маской, плюс поддержка чипов, через name/control.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormMask } from '@daisforge/ui';",
      "minimalUsage": "<FormMask mask={'значение'} name={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormMask\n            label=\"FormMask\"\n            name=\"mask\"\n            mask=\"*-*-*\"\n            options={{\n              minLength: {\n                value: 3,\n                message: 'значение должно быть длиннее 3',\n              },\n              required: true,\n            }}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormMask label=\"FormMask\" name=\"mask\" mask=\"*-*-*\" />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "FormNumberFormat": {
      "name": "FormNumberFormat",
      "group": "formComponents",
      "folderName": "FormNumberFormat",
      "role": "primary",
      "description": "Поле ввода чисел с форматированием (разряды, валюта) для react-hook-form",
      "props": [
        {
          "name": "name",
          "type": "Path<TFieldValues>",
          "required": true,
          "description": ""
        },
        {
          "name": "allowLeadingZeros",
          "type": "boolean | undefined",
          "required": false,
          "description": "Разрешает ведущие нули (например, \"0123\")."
        },
        {
          "name": "allowNegative",
          "type": "boolean | undefined",
          "required": false,
          "description": "Разрешает ввод отрицательных чисел."
        },
        {
          "name": "decimalScale",
          "type": "number | undefined",
          "required": false,
          "description": "Количество знаков после запятой.",
          "default": "3"
        },
        {
          "name": "decimalSeparator",
          "type": "string | undefined",
          "required": false,
          "description": "Разделитель десятичных знаков (например, \".\").",
          "default": "."
        },
        {
          "name": "fixedDecimalScale",
          "type": "boolean | undefined",
          "required": false,
          "description": "Фиксирует количество знаков после запятой, даже если число их не содержит (добавляет нули)."
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false"
        },
        {
          "name": "isAllowed",
          "type": "((values: NumberFormatValues) => boolean) | undefined",
          "required": false,
          "description": "Функция для валидации входного значения.\nЕсли эта функция возвращает false, метод onChange не будет вызван, и значение ввода не изменится."
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean | undefined",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)"
        },
        {
          "name": "labelPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": "Расположение лейбла."
        },
        {
          "name": "optional",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг необязательности поля"
        },
        {
          "name": "optionalText",
          "type": "string | undefined",
          "required": false,
          "description": "Подпись для указания необязательности поля"
        },
        {
          "name": "requiredPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right"
        },
        {
          "name": "suffix",
          "type": "string | undefined",
          "required": false,
          "description": "Суффикс текста в поле ввода."
        },
        {
          "name": "thousandSeparator",
          "type": "string | boolean | undefined",
          "required": false,
          "description": "Разделитель тысяч.\nМожет быть строкой (например, \",\") или булевым значением.",
          "default": "' ' (пробел)"
        },
        {
          "name": "thousandsGroupStyle",
          "type": "\"none\" | \"thousand\" | \"lakh\" | \"wan\" | undefined",
          "required": false,
          "description": "Стиль группировки тысяч:\n- 'thousand' (123 456 789),\n- 'lakh' (индийский стиль, 12 34 56 789),\n- 'wan' (китайский стиль, 1 2345 6789),\n- 'none' (без группировки)."
        },
        {
          "name": "onChange",
          "type": "THandleChange<string> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"clear\" | \"viewMode\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chips",
          "type": "TextFieldPrimitiveValue[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chipType",
          "type": "\"default\" | \"text\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chipValidator",
          "type": "((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { …",
          "required": false,
          "description": ""
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"accent\" | \"secondary\" | \"positive\" | \"warning\" | \"negative\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "clear",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enumerationType",
          "type": "\"plain\" | \"chip\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hasDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPortal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintView",
          "type": "\"default\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "leftHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "onChangeChips",
          "type": "((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimit…",
          "required": false,
          "description": ""
        },
        {
          "name": "onClear",
          "type": "(() => void) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "onSearch",
          "type": "(((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | (((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | (((value: string, event?: React.KeyboardEvent<HT…",
          "required": false,
          "description": ""
        },
        {
          "name": "options",
          "type": "RegisterOptions<FieldValues, Path<TFieldValues>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rightHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "textAfter",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "textBefore",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "FormNumberFormatProps",
      "rawType": "export type FormNumberFormatProps<TFieldValues extends FieldValues> =\n  TMutationRegister<TFieldValues> & TPropsFromNumberFormat & TProps;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/formComponents/FormNumberFormat/FormNumberFormat.tsx",
      "type": "form",
      "wrappedBy": "NumberFormat",
      "category": "Формы",
      "keywords": [
        "числовой формат",
        "number input",
        "денежный ввод"
      ],
      "chooseWhen": "Внутри формы на react-hook-form — то же форматирование чисел через name/control/rules.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormNumberFormat } from '@daisforge/ui';",
      "minimalUsage": "<FormNumberFormat name={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormNumberFormat\n            name=\"numberFormat\"\n            label=\"FormNumberFormat\"\n            size=\"s\"\n            thousandSeparator=\" \"\n            decimalSeparator=\".\"\n            options={{\n              minLength: {\n                value: 3,\n                message: 'значение должно быть длиннее 3',\n              },\n              required: 'Заполните обязательное поле',\n            }}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormNumberFormat\n            name=\"numberFormat\"\n            label=\"FormNumberFormat\"\n            size=\"s\"\n            thousandSeparator=\" \"\n            decimalSeparator=\".\"\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "FormRadiobox": {
      "name": "FormRadiobox",
      "group": "formComponents",
      "folderName": "FormRadioGroupBox",
      "role": "primary",
      "description": "Одна радио-кнопка — элемент внутри группы FormRadioGroup для форм",
      "props": [
        {
          "name": "value",
          "type": "string | number",
          "required": true,
          "description": ""
        },
        {
          "name": "checkIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": "Кастомная иконка галочки."
        },
        {
          "name": "description",
          "type": "React.ReactNode",
          "required": false,
          "description": "Описание элемента"
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": "Компонента находиться в фокусе"
        },
        {
          "name": "indeterminateIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": "Кастомная иконка indeterminate-состояния."
        },
        {
          "name": "label",
          "type": "React.ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу"
        },
        {
          "name": "onChange",
          "type": "React.ChangeEventHandler<HTMLInputElement> | undefined",
          "required": false,
          "description": "Обработчик изменения элемента формы"
        },
        {
          "name": "singleLine",
          "type": "boolean | undefined",
          "required": false,
          "description": "Title и description в одну строку или с переносом строк"
        },
        {
          "name": "size",
          "type": "\"s\" | \"m\" | \"l\" | undefined",
          "required": false,
          "description": "Размер компонента"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"secondary\" | \"positive\" | \"warning\" | \"negative\" | \"tertiary\" | \"paragraph\" | undefined",
          "required": false,
          "description": "Вид компонента"
        },
        {
          "name": "$isError",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "FormRadioboxProps",
      "sourceFile": "packages/ui-kit/src/formComponents/FormRadioGroupBox/FormRadiobox.tsx",
      "type": "form",
      "wrappedBy": "Radiobox",
      "category": "Формы",
      "keywords": [
        "radio item",
        "переключатель варианта",
        "одиночный радио"
      ],
      "chooseWhen": "Только как элемент внутри FormRadioGroup для форм на react-hook-form — не используется отдельно от группы.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormRadiobox } from '@daisforge/ui';",
      "minimalUsage": "<FormRadiobox value={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormRadiobox value=\"male\" label=\"Мужской\" size=\"m\" />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormRadiobox value=\"female\" label=\"Женский\" size=\"m\" />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "FormRadioGroup": {
      "name": "FormRadioGroup",
      "group": "formComponents",
      "folderName": "FormRadioGroupBox",
      "role": "primary",
      "description": "Группа радио-кнопок с валидацией и подсказкой для форм react-hook-form",
      "props": [
        {
          "name": "name",
          "type": "Path<TFieldValues> & Path<TFieldValues>",
          "required": true,
          "description": ""
        },
        {
          "name": "onChange",
          "type": "THandleChange<string | number> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "radioGroupMode",
          "type": "\"row\" | \"column\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | undefined",
          "required": false,
          "description": "",
          "default": "'s'"
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": "",
          "default": "true"
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": "",
          "default": "'hover'"
        },
        {
          "name": "options",
          "type": "RegisterOptions<FieldValues, Path<TFieldValues>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "FormRadioGroupProps",
      "rawType": "export type FormRadioGroupProps<TFieldValues extends FieldValues> =\n  TMutationRegister<TFieldValues> & {\n    name: Path<TFieldValues>;\n    children: ReactNode;\n    onChange?: THandleChange<string | number>;\n    radioGroupMode?: 'column' | 'row';\n    size?: 'xs' | 's' | 'm' | 'l';\n  } & Omit<NativeRadioGroupProps, 'onChange' | 'name' | 'children'> &\n    Pick<\n      TextFieldProps,\n      | 'label'\n      | 'hintText'\n      | 'hintHasArrow'\n      | 'titleCaption'\n      | 'hintTrigger'\n      | 'titleCaption'\n      | 'size'\n      | 'hintSize'\n    >;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/formComponents/FormRadioGroupBox/FormRadioGroup.tsx",
      "type": "form",
      "wrappedBy": "RadioGroup",
      "category": "Формы",
      "keywords": [
        "radio group",
        "выбор одного варианта",
        "группа переключателей"
      ],
      "chooseWhen": "Внутри формы на react-hook-form — та же группа радиокнопок с валидацией и подсказкой через name/control/rules.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormRadioGroup } from '@daisforge/ui';",
      "minimalUsage": "<FormRadioGroup name={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormRadioGroup\n            hintText=\"Подсказка\"\n            label=\"Label\"\n            titleCaption=\"TitleCaption\"\n            name=\"gender\"\n            options={{\n              required: 'Заполните обязательное поле',\n            }}\n            size=\"s\"\n          >\n            <FormRadiobox value=\"male\" label=\"Мужской\" size=\"m\" />\n            <FormRadiobox value=\"female\" label=\"Женский\" size=\"m\" />\n          </FormRadioGroup>",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormRadioGroup\n            name=\"gender\"\n            label=\"Лейбл группы\"\n            radioGroupMode=\"row\"\n            hintText=\"Подсказка\"\n          >\n            <FormRadiobox value=\"male\" label=\"Мужской\" size=\"m\" />\n            <FormRadiobox value=\"female\" label=\"Женский\" size=\"m\" />\n          </FormRadioGroup>",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "FormSegmentGroup": {
      "name": "FormSegmentGroup",
      "group": "formComponents",
      "folderName": "FormSegments",
      "role": "primary",
      "description": "Сегментированный переключатель с одиночным или множественным выбором для форм",
      "props": [
        {
          "name": "items",
          "type": "(PropsType<{ view: { none: PolymorphicClassName; secondary: PolymorphicClassName; primary: PolymorphicClassName; }; size: { xs: PolymorphicClassName; s: PolymorphicClassName; }; disabled: { true: PolymorphicClassName; }; pilled: { true: PolymorphicClassName; }; }> & React.ButtonHTMLAttributes<HTMLButtonElement> & { value: string; id?: string | undefined; label?: React.ReactNode; pilled?: boolean |…",
          "required": true,
          "description": ""
        },
        {
          "name": "name",
          "type": "Path<TFieldValues>",
          "required": true,
          "description": ""
        },
        {
          "name": "clip",
          "type": "boolean | undefined",
          "required": false,
          "description": "При ограничении ширины разрешает скролл и отображает дополнительные элементы со стрелками",
          "default": "true"
        },
        {
          "name": "filledBackground",
          "type": "boolean | undefined",
          "required": false,
          "description": "Группа сегментов c фоном, используйте свойство hasBackground"
        },
        {
          "name": "hasBackground",
          "type": "boolean | undefined",
          "required": false,
          "description": "Группа сегментов c фоном"
        },
        {
          "name": "hasDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отображать разделители между элементами сегмента"
        },
        {
          "name": "orientation",
          "type": "\"vertical\" | undefined",
          "required": false,
          "description": "Ориентация группы сегментов"
        },
        {
          "name": "pilled",
          "type": "boolean | undefined",
          "required": false,
          "description": "Группа сегментов c округлым border-radius"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | undefined",
          "required": false,
          "description": "Размер группы сегментов"
        },
        {
          "name": "stretch",
          "type": "boolean | undefined",
          "required": false,
          "description": "Группа сегментов растянута на доступную область, только в горизонтальном режиме"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"filled\" | undefined",
          "required": false,
          "description": "Вид группы сегментов"
        },
        {
          "name": "onChange",
          "type": "THandleChange<string[]> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "selectionMode",
          "type": "\"multiple\" | \"single\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "showError",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "singleSelectedRequired",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "options",
          "type": "RegisterOptions<FieldValues, Path<TFieldValues>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "FormSegmentGroupProps",
      "rawType": "export type FormSegmentGroupProps<TFieldValues extends FieldValues> =\n  TMutationRegister<TFieldValues> &\n    TPropsFromSegmentGroup &\n    TProps &\n    TLabelBlockProps & {\n      singleSelectedRequired?: boolean;\n    } & { items: TSegmentItemNativeProps[] } & { showError?: boolean };",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/formComponents/FormSegments/FormSegmentGroup.tsx",
      "type": "form",
      "wrappedBy": "SegmentGroup",
      "category": "Формы",
      "keywords": [
        "segmented control",
        "переключатель вкладок",
        "выбор сегмента"
      ],
      "chooseWhen": "Внутри формы на react-hook-form — тот же переключатель через name/control.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormSegmentGroup } from '@daisforge/ui';",
      "minimalUsage": "<FormSegmentGroup items={'Контент'} name={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormSegmentGroup\n            name=\"status\"\n            label=\"Статус документа\"\n            titleCaption=\"Выберите один\"\n            options={{\n              required: 'Выберите статус',\n            }}\n            size=\"s\"\n            hasBackground\n            stretch\n            pilled\n            onChange={(val) =>\n              // eslint-disable-next-line no-console\n              console.debug('[FormSegmentGroup]:onChange:', val)\n            }\n            hintHasArrow\n            hintText=\"Статус документа\"\n            items={[\n              { label: 'draft', value: 'draft', view: 'secondary' },\n              { label: 'ready', value: 'ready', view: 'secondary' },\n              { label: 'signed', value: 'signed', view: 'secondary' },\n            ]}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormSegmentGroup\n            name=\"status\"\n            label=\"Статус документа\"\n            titleCaption=\"Выберите один\"\n            size=\"s\"\n            hasBackground\n            stretch\n            pilled\n            onChange={(val) =>\n              // eslint-disable-next-line no-console\n              console.debug('[FormSegmentGroup]:onChange', val)\n            }\n            hintHasArrow\n            hintText=\"Статус документа\"\n            items={[\n              { label: 'draft', value: 'draft', view: 'secondary', size: 's' },\n              { label: 'ready', value: 'ready', view: 'secondary', size: 's' },\n              {\n                label: 'signed',\n                value: 'signed',\n                view: 'secondary',\n                size: 's',\n              },\n            ]}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "FormSelect": {
      "name": "FormSelect",
      "group": "formComponents",
      "folderName": "FormSelect",
      "role": "primary",
      "description": "Выпадающий список с одиночным или множественным выбором для react-hook-form",
      "props": [
        {
          "name": "items",
          "type": "ItemOption[]",
          "required": true,
          "description": "Список элементов."
        },
        {
          "name": "name",
          "type": "Path<TFieldValues>",
          "required": true,
          "description": ""
        },
        {
          "name": "afterList",
          "type": "React.ReactNode",
          "required": false,
          "description": "Ячейка для контента в конце выпадающего списка."
        },
        {
          "name": "arrowPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Сторона расположения стрелки скрытия/раскрытия.",
          "default": "left"
        },
        {
          "name": "beforeList",
          "type": "React.ReactNode",
          "required": false,
          "description": "Ячейка для контента в начале выпадающего списка."
        },
        {
          "name": "chipClickArea",
          "type": "\"full\" | \"close-icon\" | undefined",
          "required": false,
          "description": "Область, по которой происходит нажатие.",
          "default": "full"
        },
        {
          "name": "chipType",
          "type": "\"default\" | \"text\" | undefined",
          "required": false,
          "description": "Внешний вид chip.",
          "default": "default"
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"accent\" | \"secondary\" | undefined",
          "required": false,
          "description": "Внешний вид чипа в варианте textfield-like multiselect."
        },
        {
          "name": "closeAfterSelect",
          "type": "boolean | undefined",
          "required": false,
          "description": "Закрывать ли выпадающий список после выбора элемента.",
          "default": "если single, то true; если multiple, то false"
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для контента слева."
        },
        {
          "name": "contentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": "Слот для контента справа."
        },
        {
          "name": "emptyStateDescription",
          "type": "React.ReactNode",
          "required": false,
          "description": "Текст выпадающего списка при пустом массиве items."
        },
        {
          "name": "flip",
          "type": "boolean | undefined",
          "required": false,
          "description": "Коррекция placement, если выпадающий список находится за пределами экрана.",
          "default": "false"
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false"
        },
        {
          "name": "helperText",
          "type": "string | undefined",
          "required": false,
          "description": "Вспомогательный текст снизу слева для поля ввода.",
          "default": "''"
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для контента слева, например `Icon`."
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": "Видимость стрелки (хвоста)."
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": "Отступ окна относительно элемента, у которого оно вызвано.",
          "default": "[0, 8]"
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": "Направление раскрытия тултипа."
        },
        {
          "name": "hintPortal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "Портал для окна подсказки. Принимает id контейнера или ref."
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": "Размер тултипа"
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": "Иконка, рядом с которым произойдет вызов всплывающего окна.\nЕсли свойство не задано, применится иконка по умолчанию."
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": "Расположение иконки подсказки, когда отсутствует label\nили же он имеет labelPlacement='inner'.",
          "default": "`outer`"
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": "Текст тултипа"
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": "Способ открытия тултипа - наведение или клик мышью"
        },
        {
          "name": "hintView",
          "type": "\"default\" | undefined",
          "required": false,
          "description": "Вид тултипа"
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": "Ширина окна (в rem)."
        },
        {
          "name": "isTargetAmount",
          "type": "boolean | undefined",
          "required": false,
          "description": "Если включено - будет выведено общее количество выбранных элементов вместо перечисления.",
          "default": "false"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean | undefined",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)"
        },
        {
          "name": "labelPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": "Расположение лейбла."
        },
        {
          "name": "listMaxHeight",
          "type": "Property.Height<string | number> | undefined",
          "required": false,
          "description": "Максимальная высота выпадающего списка."
        },
        {
          "name": "listWidth",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "Значение css width для выпадающего списка."
        },
        {
          "name": "mode",
          "type": "\"default\" | \"radio\" | undefined",
          "required": false,
          "description": "Режим работы взаимодействия с элементами.\n- default: элемент можно выбрать и можно отменить его выбор.\n- radio: если элемент выбран, то отменить его выбор нельзя. Только для single-режима.",
          "default": "default"
        },
        {
          "name": "onScroll",
          "type": "((e: React.UIEvent<HTMLElement, UIEvent>) => void) | undefined",
          "required": false,
          "description": "Коллбэк, срабатывающий при скролле."
        },
        {
          "name": "onToggle",
          "type": "((isOpen: boolean) => void) | undefined",
          "required": false,
          "description": "Событие сворачивания/разворачивания выпадающего списка."
        },
        {
          "name": "optional",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг необязательности поля"
        },
        {
          "name": "optionalText",
          "type": "string | undefined",
          "required": false,
          "description": "Подпись для указания необязательности поля"
        },
        {
          "name": "placement",
          "type": "SelectPlacement | SelectPlacementBasic[] | undefined",
          "required": false,
          "description": "Сторона открытия дропдауна относительно target элемента.",
          "default": "bottom"
        },
        {
          "name": "portal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": "Портал для выпадающего списка. Принимает id контейнера или ref."
        },
        {
          "name": "renderItem",
          "type": "((item: ItemOption) => React.ReactNode) | undefined",
          "required": false,
          "description": "Callback для кастомной настройки айтема в выпадающем списке."
        },
        {
          "name": "renderSelectionIcon",
          "type": "((selected: boolean | \"indeterminate\") => React.ReactNode) | undefined",
          "required": false,
          "description": "Callback для кастомной настройки иконки выбранного элемента."
        },
        {
          "name": "renderTarget",
          "type": "((value: ItemOption | null, opened?: boolean | undefined) => React.ReactNode) | ((value: ItemOption[], opened?: boolean | undefined) => React.ReactNode) | undefined",
          "required": false,
          "description": "Callback для кастомной настройки значения в селекте."
        },
        {
          "name": "renderValue",
          "type": "((item: ItemOption) => string) | undefined",
          "required": false,
          "description": "Callback для кастомной настройки значения в селекте."
        },
        {
          "name": "requiredPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right"
        },
        {
          "name": "shift",
          "type": "boolean | undefined",
          "required": false,
          "description": "Смещение выпадающего списка при соприкосновении с границами экрана.",
          "default": "false"
        },
        {
          "name": "singleLine",
          "type": "boolean | undefined",
          "required": false,
          "description": "Label в элементе выпадающего списка в одну строку или с переносом строк.",
          "default": "true"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | undefined",
          "required": false,
          "description": "Размер компонента."
        },
        {
          "name": "target",
          "type": "\"textfield-like\" | \"button-like\" | undefined",
          "required": false,
          "description": "Стиль селекта: button-like или textfield-like.",
          "default": "textfield-like"
        },
        {
          "name": "treeView",
          "type": "boolean | undefined",
          "required": false,
          "description": "Режим отображения выпадающего списка в виде дерева.",
          "default": "false"
        },
        {
          "name": "variant",
          "type": "\"normal\" | \"tight\" | undefined",
          "required": false,
          "description": "Вариант: обычный или сжатый",
          "default": "normal"
        },
        {
          "name": "view",
          "type": "\"default\" | \"accent\" | \"secondary\" | \"clear\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"black\" | \"white\" | \"edited\" | undefined",
          "required": false,
          "description": "Вид компонента."
        },
        {
          "name": "virtual",
          "type": "boolean | undefined",
          "required": false,
          "description": "Виртуализация в выпадающем списке.\nНе поддерживается в многоуровневых списках.",
          "default": "false"
        },
        {
          "name": "zIndex",
          "type": "Property.ZIndex | undefined",
          "required": false,
          "description": "CSS-свойство z-index для выпадающего списка."
        },
        {
          "name": "multiselect",
          "type": "boolean | undefined",
          "required": false,
          "description": "",
          "default": "false"
        },
        {
          "name": "onChange",
          "type": "THandleChange<string> | THandleChange<string[]> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "_checkboxAppearance",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "_offset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"viewMode\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "defaultValue",
          "type": "string | string[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "options",
          "type": "RegisterOptions<FieldValues, Path<TFieldValues>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "selectAllOptions",
          "type": "SelectAllProps | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"submit\" | \"reset\" | \"button\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "FormSelectProps",
      "rawType": "export type FormSelectProps<TFieldValues extends FieldValues> =\n  TMutationRegister<TFieldValues> &\n    TPropsFromSelect &\n    TProps & { required?: boolean };",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/formComponents/FormSelect/FormSelect.tsx",
      "type": "form",
      "wrappedBy": "Select",
      "category": "Формы",
      "keywords": [
        "select",
        "выпадающий список",
        "мультиселект"
      ],
      "chooseWhen": "Внутри формы на react-hook-form — тот же список через name/control/rules.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormSelect } from '@daisforge/ui';",
      "minimalUsage": "<FormSelect items={[]} name={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormSelect\n            style={{\n              maxWidth: '50%',\n            }}\n            label=\"FormSelect multiple\"\n            name=\"selectMulti\"\n            multiselect\n            items={items}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormSelect\n            style={{\n              maxWidth: '50%',\n            }}\n            label=\"FormSelect\"\n            name=\"select\"\n            items={items}\n            options={{\n              required: 'Заполните обязательное поле',\n            }}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "FormSwitch": {
      "name": "FormSwitch",
      "group": "formComponents",
      "folderName": "FormSwitch",
      "role": "primary",
      "description": "Переключатель вкл/выкл для форм на react-hook-form, без встроенной валидации",
      "props": [
        {
          "name": "name",
          "type": "Path<TFieldValues>",
          "required": true,
          "description": ""
        },
        {
          "name": "description",
          "type": "string | undefined",
          "required": false,
          "description": "Дополнительное описание"
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": "Добавить рамку при фокусе"
        },
        {
          "name": "hasBackground",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отображение подложки у switch"
        },
        {
          "name": "label",
          "type": "React.ReactNode",
          "required": false,
          "description": "Метка-подпись к элементу"
        },
        {
          "name": "labelPosition",
          "type": "\"before\" | \"after\" | undefined",
          "required": false,
          "description": "Расположение подпись"
        },
        {
          "name": "singleLine",
          "type": "boolean | undefined",
          "required": false,
          "description": "Перенос строки label",
          "default": "true"
        },
        {
          "name": "size",
          "type": "\"s\" | \"m\" | \"l\" | undefined",
          "required": false,
          "description": "Размер компонента."
        },
        {
          "name": "toggleSize",
          "type": "\"s\" | \"l\" | undefined",
          "required": false,
          "description": "Размер toggle."
        },
        {
          "name": "view",
          "type": "\"default\" | undefined",
          "required": false,
          "description": "Вид компонента."
        },
        {
          "name": "onChange",
          "type": "THandleChange<boolean> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "options",
          "type": "RegisterOptions<FieldValues, Path<TFieldValues>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "outlined",
          "type": "boolean | undefined",
          "required": false,
          "description": "Добавить рамку при фокусе",
          "deprecated": true
        },
        {
          "name": "pressed",
          "type": "boolean | undefined",
          "required": false,
          "description": "Нажатие на компонент",
          "deprecated": true
        }
      ],
      "propsTypeName": "FormSwitchProps",
      "rawType": "export type FormSwitchProps<TFieldValues extends FieldValues> =\n  TMutationRegister<TFieldValues> & TPropsFromSwitch & TProps;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/formComponents/FormSwitch/FormSwitch.tsx",
      "type": "form",
      "wrappedBy": "Switch",
      "category": "Формы",
      "keywords": [
        "switch",
        "тумблер",
        "toggle"
      ],
      "chooseWhen": "Внутри формы на react-hook-form — тот же тумблер через name/control.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormSwitch } from '@daisforge/ui';",
      "minimalUsage": "<FormSwitch name={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormSwitch\n            name=\"switch\"\n            label=\"Switch\"\n            labelPosition=\"after\"\n            options={{\n              validate: (v) => {\n                if (!v) {\n                  return 'Заполните обязательное поле';\n                }\n                return true;\n              },\n            }}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormSwitch name=\"switch\" label=\"Switch\" labelPosition=\"after\" />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "FormTextArea": {
      "name": "FormTextArea",
      "group": "formComponents",
      "folderName": "FormTextArea",
      "role": "primary",
      "description": "Многострочное текстовое поле со счётчиком символов и кнопкой очистки",
      "props": [
        {
          "name": "name",
          "type": "Path<TFieldValues>",
          "required": true,
          "description": ""
        },
        {
          "name": "onClear",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Callback при нажатии на кнопку очистки поля ввода."
        },
        {
          "name": "onChange",
          "type": "THandleChange<string> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "showClearButton",
          "type": "boolean | undefined",
          "required": false,
          "description": "",
          "default": "true"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"viewMode\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoResize",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "clear",
          "type": "true | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "dirName",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hasDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "headerSlot",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "helperText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintOpened",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintView",
          "type": "\"default\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "labelAriaHidden",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "labelPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "leftHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": "",
          "default": "''"
        },
        {
          "name": "leftHelperPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "maxAuto",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "minAuto",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "optional",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "optionalText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "options",
          "type": "RegisterOptions<FieldValues, Path<TFieldValues>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "requiredPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "resize",
          "type": "\"none\" | \"both\" | \"horizontal\" | \"vertical\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rightHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "rightHelperPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "status",
          "type": "\"\" | \"warning\" | \"success\" | \"error\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "FormTextAreaProps",
      "rawType": "export type FormTextAreaProps<TFieldValues extends FieldValues> =\n  TMutationRegister<TFieldValues> & TPropsFromTextArea & TProps;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/formComponents/FormTextArea/FormTextArea.tsx",
      "type": "form",
      "wrappedBy": "TextArea",
      "category": "Формы",
      "keywords": [
        "textarea",
        "многострочный ввод",
        "счётчик символов"
      ],
      "chooseWhen": "Внутри формы на react-hook-form — то же поле со счётчиком символов через name/control/rules.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormTextArea } from '@daisforge/ui';",
      "minimalUsage": "<FormTextArea name={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormTextArea\n            label=\"FormTextArea\"\n            name=\"textarea\"\n            autoResize\n            options={{\n              validate: (v) => {\n                if (!(v ?? '').includes('@')) {\n                  return 'должен содержаться символ @';\n                }\n                return true;\n              },\n              maxLength: 50,\n              required: 'Заполните обязательное поле',\n            }}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormTextArea label=\"FormTextArea\" name=\"textarea\" autoResize />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "FormTextField": {
      "name": "FormTextField",
      "group": "formComponents",
      "folderName": "FormTextField",
      "role": "primary",
      "description": "Однострочное текстовое поле с кнопкой очистки и выводом ошибки валидации",
      "props": [
        {
          "name": "name",
          "type": "Path<TFieldValues>",
          "required": true,
          "description": ""
        },
        {
          "name": "hasRequiredIndicator",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг наличия индикатора обязательности поля",
          "default": "false"
        },
        {
          "name": "keepPlaceholder",
          "type": "boolean | undefined",
          "required": false,
          "description": "Одновременно отображает label и placeholder (при пустом вводе)"
        },
        {
          "name": "labelPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": "Расположение лейбла."
        },
        {
          "name": "onClear",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Callback при нажатии на кнопку очистки поля ввода.\nПри наличии value и onClear справа отображается крестик."
        },
        {
          "name": "optional",
          "type": "boolean | undefined",
          "required": false,
          "description": "Флаг необязательности поля"
        },
        {
          "name": "optionalText",
          "type": "string | undefined",
          "required": false,
          "description": "Подпись для указания необязательности поля"
        },
        {
          "name": "requiredPlacement",
          "type": "\"left\" | \"right\" | undefined",
          "required": false,
          "description": "Задает выравнивание индикатора обязательности поля",
          "default": "right"
        },
        {
          "name": "onChange",
          "type": "THandleChange<string> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"clear\" | \"viewMode\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "autoComplete",
          "type": "React.HTMLInputAutoCompleteAttribute | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chips",
          "type": "TextFieldPrimitiveValue[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chipType",
          "type": "\"default\" | \"text\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "chipValidator",
          "type": "((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { …",
          "required": false,
          "description": ""
        },
        {
          "name": "chipView",
          "type": "\"default\" | \"accent\" | \"secondary\" | \"positive\" | \"warning\" | \"negative\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "clear",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enterKeyHint",
          "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "enumerationType",
          "type": "\"plain\" | \"chip\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hasDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintContentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintHasArrow",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintOffset",
          "type": "[number, number] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPlacement",
          "type": "Placement | ComputedPlacement[] | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintPortal",
          "type": "string | React.RefObject<HTMLElement | null> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintSize",
          "type": "\"s\" | \"m\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetIcon",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTargetPlacement",
          "type": "\"inner\" | \"outer\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintText",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintTrigger",
          "type": "\"hover\" | \"click\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintView",
          "type": "\"default\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "hintWidth",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "leftHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": "",
          "default": "''"
        },
        {
          "name": "onChangeChips",
          "type": "((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimit…",
          "required": false,
          "description": ""
        },
        {
          "name": "onSearch",
          "type": "(((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | (((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | (((value: string, event?: React.KeyboardEvent<HT…",
          "required": false,
          "description": ""
        },
        {
          "name": "options",
          "type": "RegisterOptions<FieldValues, Path<TFieldValues>> | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "rightHelper",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "textAfter",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "textBefore",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "titleCaption",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "FormTextFieldProps",
      "rawType": "export type FormTextFieldProps<TFieldValues extends FieldValues> =\n  TMutationRegister<TFieldValues> & TPropsFromTextField & TProps;",
      "isGeneric": true,
      "sourceFile": "packages/ui-kit/src/formComponents/FormTextField/FormTextField.tsx",
      "type": "form",
      "wrappedBy": "TextField",
      "category": "Формы",
      "keywords": [
        "text input",
        "поле ввода текста",
        "инпут с очисткой"
      ],
      "chooseWhen": "Внутри формы на react-hook-form — то же поле с выводом ошибки валидации через name/control/rules.",
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FormTextField } from '@daisforge/ui';",
      "minimalUsage": "<FormTextField name={{}} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormTextField\n            label=\"FormTextField\"\n            name=\"textfield\"\n            options={{\n              minLength: {\n                value: 3,\n                message: 'значение должно быть длиннее 3',\n              },\n              required: true,\n            }}\n          />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FormComponents.stories.tsx",
          "type": "usage",
          "code": "<FormTextField label=\"FormTextField\" name=\"textfield\" />",
          "sourceFile": "packages/storybook/src/stories/FormComponents/FormComponents.stories.tsx"
        }
      ]
    },
    "Container": {
      "name": "Container",
      "group": "layouts",
      "folderName": "Container",
      "role": "primary",
      "description": "Контейнер страницы с режимами разделения на колонки и адаптивностью",
      "props": [
        {
          "name": "roundedInner",
          "type": "boolean | undefined",
          "required": false,
          "description": "Скругление углов внутренних блоков",
          "default": "true"
        },
        {
          "name": "stretch",
          "type": "boolean | undefined",
          "required": false,
          "description": "Растягивать на всю доступную ширину/высоту",
          "default": "false"
        },
        {
          "name": "children",
          "type": "React.ReactNode | [React.ReactElement<any, string | React.JSXElementConstructor<any>>, React.ReactElement<any, string | React.JSXElementConstructor<any>>] | [React.ReactElement<any, string | React.JSXElementConstructor<any>>, React.ReactElement<any, string | React.JSXElementConstructor<any>>, React.ReactElement<any, string | React.JSXElementConstructor<any>>]",
          "required": false,
          "description": ""
        },
        {
          "name": "css",
          "type": "string | CSSObject | FlattenSimpleInterpolation | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "split",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ContainerProps",
      "sourceFile": "packages/ui-kit/src/layouts/Container/Container.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "сетка страницы",
        "split layout",
        "две колонки"
      ],
      "docs": "# Container\n\nКомпонент стандартизации композиции. Может работать как простой контейнер или как split-контейнер с разделением на колонки.\n\n## Ключевые особенности\n\n- Режим split с разными пропорциями колонок: `30/70`, `20/80`, `70/30`, `80/20`, `1/1/1`, `1/3/1`, `fixed-fluid`\n- Растягивание на всё доступное пространство (`stretch`)\n- Поддержка 2- и 3-колоночных раскладок\n- Фиксированная левая колонка с гибкой правой (`fixed-fluid`)\n- Кастомизация через `className` и `css`\n\n## Особенности\n\n- В split-режиме `children` принимает массив из 2 или 3 элементов в зависимости от `view`\n- Для `view='1/1/1'` и `view='1/3/1'` требуется 3 элемента\n- Для остальных view — 2 элемента\n- `view` можно задать только при `split === true`\n- Для `view='fixed-fluid'` ширина левой колонки настраивается через `fixedWidth` (по умолчанию `288px`)\n\n> Подробнее о типах и пропсах — [Container API](?path=/docs/композиции-container-api--docs)",
      "apiDocs": "# Container API\n\n## ContainerProps\n\n```typescript\ntype ContainerProps = ISplitContainerProps | INotSplitContainerProps;\n```\n\n## TContainerView\n\n```typescript\ntype TContainerView =\n  | '30/70'\n  | '20/80'\n  | '70/30'\n  | '80/20'\n  | '1/1'\n  | '1/1/1'\n  | '1/3/1'\n  | 'fixed-fluid';\n```",
      "curatedStories": [
        {
          "exportName": "Default",
          "displayName": "Контейнер",
          "type": "args-only",
          "code": "{\n    children: (\n      <Box height=\"100%\" background=\"#ffdfdf\">\n        <BodyL>Some content in container</BodyL>\n      </Box>\n    ),\n  }"
        },
        {
          "exportName": "Stretch",
          "displayName": "Растянуть",
          "type": "args-only",
          "code": "{\n    children: <Box height=\"100%\" background=\"#ffdfdf\" />,\n    stretch: true,\n  }"
        },
        {
          "exportName": "Split",
          "displayName": "Сплит (30/70)",
          "type": "args-only",
          "code": "{\n    children: [\n      <Box height=\"100%\" background=\"#ffdfdf\" />,\n      <Box height=\"100%\" background=\"#dfffdf\" />,\n    ],\n    stretch: true,\n    split: true,\n    view: '30/70',\n  }"
        },
        {
          "exportName": "SplitThreeEqualColumns",
          "displayName": "Сплит (1/1/1)",
          "type": "args-only",
          "code": "{\n    children: [\n      <Box key=\"left\" height=\"100%\" background=\"#ffdfdf\" />,\n      <Box key=\"center\" height=\"100%\" background=\"#dfffdf\" />,\n      <Box key=\"right\" height=\"100%\" background=\"#dfdfff\" />,\n    ],\n    stretch: true,\n    split: true,\n    view: '1/1/1',\n  }"
        },
        {
          "exportName": "SplitWideCenterColumn",
          "displayName": "Сплит (1/3/1)",
          "type": "args-only",
          "code": "{\n    children: [\n      <Box key=\"left\" height=\"100%\" background=\"#ffdfdf\" />,\n      <Box key=\"center\" height=\"100%\" background=\"#dfffdf\" />,\n      <Box key=\"right\" height=\"100%\" background=\"#dfdfff\" />,\n    ],\n    stretch: true,\n    split: true,\n    view: '1/3/1',\n  }"
        },
        {
          "exportName": "SplitFixedFluid",
          "displayName": "Сплит (fixed-fluid)",
          "type": "args-only",
          "code": "{\n    children: [\n      <Box key=\"left\" height=\"100%\" background=\"#ffdfdf\" />,\n      <Box key=\"right\" height=\"100%\" background=\"#dfffdf\" />,\n    ],\n    stretch: true,\n    split: true,\n    view: 'fixed-fluid',\n    fixedWidth: '300px',\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Container } from '@daisforge/ui';",
      "minimalUsage": "<Container />",
      "examples": [
        {
          "exportName": "Default",
          "displayName": "Контейнер",
          "type": "args-only",
          "code": "{\n    children: (\n      <Box height=\"100%\" background=\"#ffdfdf\">\n        <BodyL>Some content in container</BodyL>\n      </Box>\n    ),\n  }"
        },
        {
          "exportName": "Stretch",
          "displayName": "Растянуть",
          "type": "args-only",
          "code": "{\n    children: <Box height=\"100%\" background=\"#ffdfdf\" />,\n    stretch: true,\n  }"
        },
        {
          "exportName": "Split",
          "displayName": "Сплит (30/70)",
          "type": "args-only",
          "code": "{\n    children: [\n      <Box height=\"100%\" background=\"#ffdfdf\" />,\n      <Box height=\"100%\" background=\"#dfffdf\" />,\n    ],\n    stretch: true,\n    split: true,\n    view: '30/70',\n  }"
        },
        {
          "exportName": "SplitThreeEqualColumns",
          "displayName": "Сплит (1/1/1)",
          "type": "args-only",
          "code": "{\n    children: [\n      <Box key=\"left\" height=\"100%\" background=\"#ffdfdf\" />,\n      <Box key=\"center\" height=\"100%\" background=\"#dfffdf\" />,\n      <Box key=\"right\" height=\"100%\" background=\"#dfdfff\" />,\n    ],\n    stretch: true,\n    split: true,\n    view: '1/1/1',\n  }"
        }
      ]
    },
    "ErrorPage": {
      "name": "ErrorPage",
      "group": "layouts",
      "folderName": "ErrorPage",
      "role": "primary",
      "description": "Готовая страница ошибки (400-503): иллюстрация, текст и кнопки по коду статуса",
      "props": [
        {
          "name": "buttonHandler",
          "type": "((statusCode: StatusCode, statusObj: CustomStatusObj, e: React.MouseEvent<HTMLElement, MouseEvent>) => void) | undefined",
          "required": false,
          "description": "`buttonHandler` - обработка клика по кнопке при разных ошибках"
        },
        {
          "name": "containerProps",
          "type": "BoxProps | undefined",
          "required": false,
          "description": "`containerProps` - Пропсы для контейнера компонента. Например, `$css`, `style`."
        },
        {
          "name": "customStatuses",
          "type": "Record<number, CustomStatusObj> | undefined",
          "required": false,
          "description": "`customStatuses` - кастомные статусы и содержимое для их отображения.\nЕсли переданы статусы, которые компонентом по умолчанию поддерживаются, то кастомный перезапишет дефолтный."
        },
        {
          "name": "errorId",
          "type": "string | undefined",
          "required": false,
          "description": "Идентификатор ошибки. Отображается под кнопками (или под subtitle, если кнопок нет).\nФормат отображения: \"Идентификатор ошибки: {значение}\""
        },
        {
          "name": "showStatusCode",
          "type": "boolean | undefined",
          "required": false,
          "description": "Показывать код ошибки перед заголовком. Например, \"503: Сервис временно недоступен\"",
          "default": "false"
        },
        {
          "name": "size",
          "type": "\"s\" | \"m\" | \"l\" | undefined",
          "required": false,
          "description": "Размер страницы ошибки. Влияет на изображение, типографику и отступы\n(размерная сетка та же, что у `EmptyState`).",
          "default": "'l'"
        },
        {
          "name": "statusCode",
          "type": "StatusCode",
          "required": false,
          "description": "`statusCode` - статус-код ошибки. Поддерживаются по умолчанию: 400 | 403 | 404 | 409 | 500 | 502 | 503"
        },
        {
          "name": "unknownStatus",
          "type": "CustomStatusObj | undefined",
          "required": false,
          "description": "`unknownStatus` - содержимое для отображения, если статус не передан или статуса нет среди известных.\n\nЕсли данное свойство не передано, то при неизвестных статусах будет выбрано отображение по умолчанию."
        }
      ],
      "propsTypeName": "ErrorPageProps",
      "sourceFile": "packages/ui-kit/src/layouts/ErrorPage/ErrorPage.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "error page",
        "404 страница",
        "страница недоступности сервиса"
      ],
      "docs": "# ErrorPage\n\nКомпонент для отображения страниц ошибок. Предполагается использовать при ошибках основных запросов на странице (например, в `onError` RTKQuery) и при ошибках на уровне всего приложения (например, в `ErrorBoundary`).\n\n## Ключевые особенности\n\n- Встроенные описания для статусов: 400, 401, 403, 404, 500, 502, 503\n- При неизвестном статусе или `'unknown'` / `undefined` показывается общее описание\n- Поддержка кастомных статусов через `customStatuses`\n- Переопределение описания неизвестных ошибок через `unknownStatus`\n- Отображение кода статуса (`showStatusCode`)\n- Кастомизация контейнера через `containerProps`\n- Размерная сетка `size`: `l` (по умолчанию), `m`, `s`\n\n## Особенности\n\n- Картинки подставляются в зависимости от статуса на продуктовых сборках. В Storybook при смене вариантов картинка не меняется\n- `buttonHandler` вызывается с текущим `statusCode` и объектом статуса — можно реализовать кастомную навигацию\n\n> Подробнее о типах и пропсах — [ErrorPage API](?path=/docs/композиции-errorpage-страницы-ошибок-api--docs)",
      "apiDocs": "# ErrorPage API\n\n## ErrorPageProps\n\n```typescript\ntype ErrorPageProps = {\n  /**\n   * `statusCode` - статус-код ошибки. Поддерживаются по умолчанию: 400 | 403 | 404 | 409 | 500 | 502 | 503\n   */\n  statusCode?: StatusCode;\n  /**\n   * `buttonHandler` - обработка клика по кнопке при разных ошибках\n   */\n  buttonHandler?: (\n    statusCode: StatusCode,\n    statusObj: CustomStatusObj,\n    e: React.MouseEvent<HTMLElement, MouseEvent>,\n  ) => void;\n  /**\n   * `customStatuses` - кастомные статусы и содержимое для их отображения.\n   * Если переданы статусы, которые компонентом по умолчанию поддерживаются, то кастомный перезапишет дефолтный.\n   */\n  customStatuses?: Record<number, CustomStatusObj>;\n  /**\n   * `unknownStatus` - содержимое для отображения, если статус не передан или статуса нет среди известных.\n   *\n   * Если данное свойство не передано, то при неизвестных статусах будет выбрано отображение по умолчанию.\n   */\n  unknownStatus?: CustomStatusObj;\n  /**\n   * `containerProps` - Пропсы для контейнера компонента. Например, `$css`, `style`.\n   */\n  containerProps?: BoxProps;\n  /**\n   * Показывать код ошибки перед заголовком. Например, \"503: Сервис временно недоступен\"\n   * @default false\n   */\n  showStatusCode?: boolean;\n  /**\n   * Идентификатор ошибки. Отображается под кнопками (или под subtitle, если кнопок нет).\n   * Формат отображения: \"Идентификатор ошибки: {значение}\"\n   */\n  errorId?: string;\n  /**\n   * Размер страницы ошибки. Влияет на изображение, типографику и отступы\n   * (размерная сетка та же, что у `EmptyState`).\n   * @default 'l'\n   */\n  size?: 's' | 'm' | 'l';\n};\n```\n\n## CustomStatusObj\n\n```typescript\ntype CustomStatusObj = {\n  title: ReactNode;\n  description: ReactNode;\n  button?: StatusButton;\n  buttons?: StatusButton[];\n};\n```\n\n## StatusButton\n\n```typescript\ntype StatusButton = {\n  label: ReactNode;\n  view?: NonNullable<ButtonCompProps['view']>;\n};\n```",
      "curatedStories": [
        {
          "exportName": "Default",
          "displayName": "400",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 400,\n  }"
        },
        {
          "exportName": "S401",
          "displayName": "401",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 401,\n  }"
        },
        {
          "exportName": "S403",
          "displayName": "403",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 403,\n  }"
        },
        {
          "exportName": "S403WithTwoButtons",
          "displayName": "403 - Две кнопки",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 403,\n    customStatuses: {\n      403: {\n        title: 'Доступ к странице ограничен',\n        description:\n          'Вы можете запросить право доступа в Друге или вернуться на главную страницу',\n        buttons: [\n          // Используем buttons вместо button\n          {\n            label: 'Запросить доступ',\n            view: 'secondary',\n          },\n          {\n            label: 'Вернуться назад',\n            view: 'accent',\n          },\n        ],\n      },\n    },\n    buttonHandler: (statusCode, statusObj, e) => {\n      const buttonText = e.currentTarget.textContent;\n      // eslint-disable-next-line no-alert\n      alert(\n        `Нажата кнопка \"${buttonText}\" для статуса ${statusCode} info ${statusObj}`,\n      );\n    },\n  }"
        },
        {
          "exportName": "S404",
          "displayName": "404",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 404,\n  }"
        },
        {
          "exportName": "S409",
          "displayName": "409",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 409,\n  }"
        },
        {
          "exportName": "S500",
          "displayName": "500",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 500,\n  }"
        },
        {
          "exportName": "S502",
          "displayName": "502",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 502,\n  }"
        },
        {
          "exportName": "S503",
          "displayName": "503",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 503,\n  }"
        },
        {
          "exportName": "S503WithStatusCode",
          "displayName": "503 - с кодом ошибки",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 503,\n    showStatusCode: true,\n    customStatuses: {\n      503: {\n        title: (\n          <>\n            Сервис временно недоступен.\n            <br />\n            Попробуйте зайти позже\n          </>\n        ),\n        description: 'Обновите страницу или зайдите позже',\n      },\n    },\n  }"
        },
        {
          "exportName": "SUnknown",
          "displayName": "Неизвестная ошибка - заполнение по умолчанию",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 'unknown',\n  }"
        },
        {
          "exportName": "UnknownError",
          "displayName": "Неизвестная ошибка - кастомное заполнение",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    unknownStatus: {\n      title: 'Unknown Error',\n      description: 'Unknown Error description',\n    },\n  }"
        },
        {
          "exportName": "CustomError",
          "displayName": "Дополнительные статусы и их заполнение",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    customStatuses: {\n      501: {\n        title: 'Метод запроса не поддерживается сервером',\n        description:\n          'Метод запроса не поддерживается сервером и поэтому он не может быть обработан.',\n        button: { label: 'На главную' },\n      },\n      405: {\n        title: 'Метод запроса известен серверу',\n        description:\n          'Метод запроса известен серверу, но не поддерживается целевым ресурсом. Например, API может не разрешать вызов DELETE для удаления ресурса.',\n      },\n    },\n  }"
        },
        {
          "exportName": "WithErrorId",
          "displayName": "500 - с идентификатором ошибки",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 500,\n    errorId: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',\n  }"
        },
        {
          "exportName": "WithErrorIdNoButtons",
          "displayName": "503 - идентификатор без кнопок",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 503,\n    errorId: 'err-timeout-xyz-9876',\n  }"
        },
        {
          "exportName": "SizeM",
          "displayName": "Размер m",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 404,\n    size: 'm',\n  }"
        },
        {
          "exportName": "SizeS",
          "displayName": "Размер s",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 404,\n    size: 's',\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ErrorPage } from '@daisforge/ui';",
      "minimalUsage": "<ErrorPage />",
      "examples": [
        {
          "exportName": "Default",
          "displayName": "400",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 400,\n  }"
        },
        {
          "exportName": "S401",
          "displayName": "401",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 401,\n  }"
        },
        {
          "exportName": "S403",
          "displayName": "403",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 403,\n  }"
        },
        {
          "exportName": "S403WithTwoButtons",
          "displayName": "403 - Две кнопки",
          "type": "full-code",
          "code": "(args) => (\n    <ErrorPage {...args} containerProps={{ $css: { minHeight: 600 } }} />\n  )\n\n// Props:\n{\n    statusCode: 403,\n    customStatuses: {\n      403: {\n        title: 'Доступ к странице ограничен',\n        description:\n          'Вы можете запросить право доступа в Друге или вернуться на главную страницу',\n        buttons: [\n          // Используем buttons вместо button\n          {\n            label: 'Запросить доступ',\n            view: 'secondary',\n          },\n          {\n            label: 'Вернуться назад',\n            view: 'accent',\n          },\n        ],\n      },\n    },\n    buttonHandler: (statusCode, statusObj, e) => {\n      const buttonText = e.currentTarget.textContent;\n      // eslint-disable-next-line no-alert\n      alert(\n        `Нажата кнопка \"${buttonText}\" для статуса ${statusCode} info ${statusObj}`,\n      );\n    },\n  }"
        }
      ]
    },
    "FiltersActionsDotsIconButton": {
      "name": "FiltersActionsDotsIconButton",
      "group": "layouts",
      "folderName": "FiltersActions",
      "role": "part",
      "description": "Кнопка с иконкой троеточия и выпадающим меню доп. действий в панели фильтров",
      "props": [
        {
          "name": "dropdownProps",
          "type": "(Omit<DropdownProps<ItemOption>, \"view\" | \"size\"> & Pick<PropsType<{ size: { m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; view: { default: PolymorphicClassName; }; }> & { items: ItemOption[]; trigger?: DropdownTrigger | undefined; placement?: DropdownPlacement | undefined; children?: React.ReactNode; variant?: \"normal\" | \"tight\" | undefined; zIndex?: Property.ZInd…",
          "required": false,
          "description": "Пропсы выпадающего меню"
        },
        {
          "name": "iconSize",
          "type": "\"xs\" | \"s\" | \"m\" | undefined",
          "required": false,
          "description": "Размер иконки"
        },
        {
          "name": "as",
          "type": "React.ComponentType<any> | keyof JSX.IntrinsicElements | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "additionalContent",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "contentPlacing",
          "type": "\"default\" | \"relaxed\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "focused",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "isLoading",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "loader",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "outlined",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftLeft",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "shiftRight",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"xs\" | \"s\" | \"xxs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "square",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretch",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "stretching",
          "type": "\"filled\" | \"fixed\" | \"auto\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "text",
          "type": "string | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"button\" | \"submit\" | \"reset\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "value",
          "type": "string | number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"clear\" | \"black\" | \"white\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"accent\" | \"dark\" | \"gradient\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "FiltersActionsDotsIconButtonProps",
      "sourceFile": "packages/ui-kit/src/layouts/FiltersActions/components/DotsIconButton.tsx",
      "type": "wrapper",
      "atomicBase": "IconButton",
      "wrapsInternal": "IconButton",
      "category": "Локальные компоненты",
      "keywords": [
        "доп действия",
        "кнопка меню",
        "overflow menu"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "FiltersActions",
      "inheritedProps": [
        {
          "name": "additionalContent",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentPlacing",
          "type": "ContentPlacing",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focused",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isLoading",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "loader",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "outlined",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftLeft",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftRight",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "square",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretching",
          "type": "Stretching",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "string",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"secondary\" | \"black\" | \"white\"",
          "required": false,
          "inheritedFrom": "IconButton",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "FiltersActions",
        "part": "DotsIconButton"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { FiltersActionsDotsIconButton } from '@daisforge/ui';",
      "minimalUsage": "<FiltersActionsDotsIconButton />",
      "examples": [
        {
          "exportName": "Usage",
          "displayName": "Использование в FiltersActions.stories.tsx",
          "type": "usage",
          "code": "<FiltersActions.DotsIconButton\n            dropdownProps={{\n              items: dropdownItems,\n            }}\n            iconOrientation=\"vertical\"\n          />",
          "sourceFile": "packages/storybook/src/stories/FiltersActions/FiltersActions.stories.tsx"
        },
        {
          "exportName": "Vendor1",
          "displayName": "Использование Использование Компонент  IconButton  может содержать иконку, которая указывается напрямую через  children .",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconButton } from '@daisforge/ui';\nimport { IconClose } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div>\n            <IconButton>\n                <IconClose color=\"inherit\" />\n            </IconButton>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Границы кнопки",
          "type": "vendor",
          "code": "import React from 'react';\nimport { IconButton } from '@daisforge/ui';\nimport { IconClose } from '@salutejs/plasma-icons';\nexport function App() {\n    return (\n        <div style={{ display: 'flex', flexWrap: 'wrap' }}>\n            <IconButton pin=\"square-square\">\n                <IconClose color=\"inherit\" />\n            </IconButton>\n            <IconButton pin=\"circle-circle\">\n                <IconClose color=\"inherit\" />\n            </IconButton>\n        </div>\n    );\n}"
        }
      ]
    },
    "FiltersActionsFiltersButton": {
      "name": "FiltersActionsFiltersButton",
      "group": "layouts",
      "folderName": "FiltersActions",
      "role": "part",
      "description": "Кнопка «Ещё фильтры» с индикатором активных условий для панели фильтров и действий",
      "props": [
        {
          "name": "buttonProps",
          "type": "Partial<FiltersActionsFiltersButtonProps> | undefined",
          "required": false,
          "description": "Пропсы для кнопки-таргета FiltersActionsFiltersButton. onClick декорируется: сначала вызовется внешний, потом внутренний toggle."
        },
        {
          "name": "content",
          "type": "React.ReactNode",
          "required": false,
          "description": "Основной контент для отображения"
        },
        {
          "name": "emptySearchContent",
          "type": "React.ReactNode",
          "required": false,
          "description": "Контент отображаемый когда ничего не найдено"
        },
        {
          "name": "footer",
          "type": "React.ReactNode",
          "required": false,
          "description": "Контент footer (опционально)"
        },
        {
          "name": "onClose",
          "type": "(() => void) | undefined",
          "required": false,
          "description": "Callback при закрытии"
        },
        {
          "name": "onSearchChange",
          "type": "((value: string) => void) | undefined",
          "required": false,
          "description": "Callback изменения поискового запроса"
        },
        {
          "name": "popoverProps",
          "type": "Omit<PropsType<{ view: { default: PolymorphicClassName; }; }> & React.HTMLAttributes<HTMLDivElement> & CustomPopoverProps & React.RefAttributes<HTMLDivElement>, \"onToggle\" | \"opened\" | \"target\"> | undefined",
          "required": false,
          "description": "Пропсы для popover"
        },
        {
          "name": "redSquare",
          "type": "boolean | undefined",
          "required": false,
          "description": "Красный индикатор на кнопке фильтров"
        },
        {
          "name": "renderTarget",
          "type": "((api: FilterTargetRenderApi) => React.ReactElement<any, string | React.JSXElementConstructor<any>>) | undefined",
          "required": false,
          "description": "Рендер-проп для полной замены кнопки-таргета Popover собственным элементом\n(иконкой, кнопкой, любым узлом) — при сохранении нативной логики открытия\nPopover и красной точки-индикатора. Когда задан, `buttonProps` и дефолтная\nкнопка «Ещё фильтры» игнорируются.\n\nВАЖНО: повесьте переданный `onClick` на корневой кликабельный элемент вашего\nтаргета. Для красной точки оберните таргет в контейнер с `position: relative`\nи отрендерьте `<RedDot visible={isRedDotVisible} />`."
        },
        {
          "name": "searchable",
          "type": "boolean | undefined",
          "required": false,
          "description": "Включить поиск"
        },
        {
          "name": "searchingProps",
          "type": "Pick<TextFieldProps, \"name\" | \"type\" | \"onFocus\" | \"onBlur\" | \"contentLeft\" | \"contentRight\" | \"textBefore\" | \"textAfter\" | \"maxLength\" | \"minLength\" | \"placeholder\"> | undefined",
          "required": false,
          "description": "Пропсы для поля поиска"
        },
        {
          "name": "searchValue",
          "type": "string | undefined",
          "required": false,
          "description": "Значение поиска (контролируемый режим)"
        },
        {
          "name": "state",
          "type": "[boolean, React.Dispatch<React.SetStateAction<boolean>>] | undefined",
          "required": false,
          "description": "Внешнее состояние открытия/закрытия [isOpen, setIsOpen]"
        },
        {
          "name": "subtitle",
          "type": "string | undefined",
          "required": false,
          "description": "Подзаголовок (опционально)"
        }
      ],
      "propsTypeName": "FiltersActionsFiltersButtonWithPopoverProps",
      "sourceFile": "packages/ui-kit/src/layouts/FiltersActions/components/FiltersButton.tsx",
      "type": "wrapper",
      "atomicBase": "Button",
      "wrapsInternal": "Button",
      "category": "Локальные компоненты",
      "keywords": [
        "ещё фильтры",
        "открыть панель фильтров",
        "filter button"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "FiltersActions",
      "inheritedProps": [
        {
          "name": "additionalContent",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "appearance",
          "type": "\"default\" | \"outline\"",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "blur",
          "type": "\"small\" | \"medium\" | \"large\"",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentLeft",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentPlacing",
          "type": "ContentPlacing",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "contentRight",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "focused",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "isLoading",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "loader",
          "type": "ReactNode",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "outlined",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pin",
          "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\"",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftLeft",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "shiftRight",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"xxs\"",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "square",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretching",
          "type": "\"auto\" | \"filled\" | \"fixed\"",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "text",
          "type": "string",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "value",
          "type": "string | number",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"default\" | \"accent\" | \"positive\" | \"warning\" | \"negative\" | \"dark\" | \"secondary\" | \"black\" | \"white\"",
          "required": false,
          "inheritedFrom": "Button",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "FiltersActions",
        "part": "FiltersButton"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { FiltersActionsFiltersButton } from '@daisforge/ui';",
      "minimalUsage": "<FiltersActionsFiltersButton />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Гиперссылка Гиперссылка Компонент поддерживает вывод в виде тега  <a> , для этого необходимо указать свойство  as",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Button } from '@daisforge/ui';\nexport function App() {\n    return (\n        <Button as=\"a\" text=\"Гиперссылка\" />\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Размер кнопки",
          "type": "vendor",
          "code": "import React from 'react';\nimport { Button } from '@daisforge/ui';\nexport function App() {\n    return (\n        <div>\n            <Button text=\"Button\" size=\"s\" />\n            <Button text=\"Button\" size=\"xs\" />\n            <Button text=\"Button\" size=\"xxs\" />\n        </div>\n    );\n}"
        }
      ]
    },
    "FiltersActionsListOfFilters": {
      "name": "FiltersActionsListOfFilters",
      "group": "layouts",
      "folderName": "FiltersActions",
      "role": "part",
      "description": "Список выбранных фильтров в виде чипов с группировкой, подгружается лениво",
      "props": [
        {
          "name": "clearAll",
          "type": "() => void",
          "required": true,
          "description": ""
        },
        {
          "name": "items",
          "type": "ItemOrGroup[]",
          "required": true,
          "description": ""
        },
        {
          "name": "opened",
          "type": "boolean",
          "required": true,
          "description": ""
        },
        {
          "name": "ellipsisLabel",
          "type": "boolean | undefined",
          "required": false,
          "description": "Обрезает название группы фильтров в одну строку с троеточием.",
          "default": "false"
        },
        {
          "name": "showResetAllFiltersButton",
          "type": "boolean | undefined",
          "required": false,
          "description": "Показывать ли кнопку \"Сбросить все\" в блоке примененных фильтров",
          "default": "true"
        },
        {
          "name": "chipStyle",
          "type": "((itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "extraCss",
          "type": "React.CSSProperties | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "leftSlot",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "maxHeight",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "maxLengthInGroup",
          "type": "number | undefined",
          "required": false,
          "description": "",
          "default": "maxLengthInGroup=2"
        },
        {
          "name": "paddingInline",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "paddingTop",
          "type": "number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "renderChipLabel",
          "type": "((group: Group | null, item: Item) => string) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "renderGroupLabel",
          "type": "((group: Group) => string) | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"xs\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "sizeOnOpen",
          "type": "number | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof FiltersActionsListOfFilters>",
      "sourceFile": "packages/ui-kit/src/layouts/FiltersActions/components/ListOfFilters.ts",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "чипы фильтров",
        "активные фильтры",
        "filter chips"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "FiltersActions",
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "FiltersActions",
        "part": "ListOfFilters"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { FiltersActionsListOfFilters } from '@daisforge/ui';",
      "minimalUsage": "<FiltersActionsListOfFilters clearAll={() => {}} items={[]} opened={true} />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в FiltersActions.stories.tsx",
          "type": "usage",
          "code": "<FiltersActions.ListOfFilters\n            clearAll={clearAll}\n            opened={items.length > 0}\n            items={items}\n            showResetAllFiltersButton={false}\n          />",
          "sourceFile": "packages/storybook/src/stories/FiltersActions/FiltersActions.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в FiltersActions.stories.tsx",
          "type": "usage",
          "code": "<FiltersActions.ListOfFilters\n              clearAll={clearAll}\n              opened={filterListOpened}\n              items={filterList}\n              showResetAllFiltersButton={false}\n            />",
          "sourceFile": "packages/storybook/src/stories/FiltersActions/FiltersActions.stories.tsx"
        }
      ]
    },
    "RedDot": {
      "name": "RedDot",
      "group": "layouts",
      "folderName": "FiltersActions",
      "role": "internal",
      "description": "Красная точка-индикатор активных фильтров, позиционируется в углу кнопки",
      "props": [
        {
          "name": "offset",
          "type": "string | number | undefined",
          "required": false,
          "description": "Смещение точки от правого верхнего угла контейнера (top/right).\nПо умолчанию `0` — точка прижата к углу."
        },
        {
          "name": "visible",
          "type": "boolean | undefined",
          "required": false,
          "description": "Показывать ли точку. Обычно прокидывается из `isRedDotVisible` рендер-API."
        }
      ],
      "propsTypeName": "RedDotProps",
      "sourceFile": "packages/ui-kit/src/layouts/FiltersActions/components/RedDot.tsx",
      "type": "standalone",
      "category": "Локальные компоненты",
      "keywords": [
        "индикатор фильтров",
        "активный фильтр",
        "красная метка"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "FiltersActions",
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { RedDot } from '@daisforge/ui';",
      "minimalUsage": "<RedDot />",
      "examples": []
    },
    "FiltersActionsTabItem": {
      "name": "FiltersActionsTabItem",
      "group": "layouts",
      "folderName": "FiltersActions",
      "role": "part",
      "description": "Пункт вкладки для переключения наборов фильтров в панели фильтров и действий",
      "props": [
        {
          "name": "$css",
          "type": "CSSObject | TemplateStringsArray | undefined",
          "required": false,
          "description": "Кастомные стили"
        },
        {
          "name": "actionContent",
          "type": "React.ReactNode",
          "required": false,
          "description": "Слот для интерактивных элементов (крестик)"
        },
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "contentRight",
          "type": "React.ReactNode",
          "required": false,
          "description": "Контент справа"
        },
        {
          "name": "disableScroll",
          "type": "boolean | undefined",
          "required": false,
          "description": "Отключает скролл к TabItem при его выборе",
          "default": "false"
        },
        {
          "name": "itemIndex",
          "type": "number | undefined",
          "required": false,
          "description": "Индекс TabItem внутри Tabs - необходим для клавиатурной навигации"
        },
        {
          "name": "maxItemWidth",
          "type": "Property.Width<string | number> | undefined",
          "required": false,
          "description": "Обрезает контент по максимальной ширине и добавляет ...",
          "default": "'auto'"
        },
        {
          "name": "onIndexChange",
          "type": "((index: number) => void) | undefined",
          "required": false,
          "description": "Callback, необходимый для клавиатурной навигации"
        },
        {
          "name": "contentLeft",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "pilled",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "size",
          "type": "\"s\" | \"xs\" | \"m\" | \"h6\" | \"h5\" | \"h4\" | \"h3\" | \"h2\" | \"h1\" | \"l\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "truncate",
          "type": "boolean | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "type",
          "type": "\"button\" | \"submit\" | \"reset\" | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "value",
          "type": "string | number | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "view",
          "type": "\"default\" | \"secondary\" | \"clear\" | \"divider\" | undefined",
          "required": false,
          "description": ""
        }
      ],
      "propsTypeName": "ComponentProps<typeof FiltersActionsTabItem>",
      "sourceFile": "packages/ui-kit/src/layouts/FiltersActions/components/Tabs.tsx",
      "type": "wrapper",
      "atomicBase": "TabItem",
      "wrapsInternal": "TabItem",
      "category": "Локальные компоненты",
      "keywords": [
        "пункт вкладки",
        "переключатель фильтров",
        "tab item"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "FiltersActions",
      "atomicDataMissing": true,
      "compoundPartOf": {
        "component": "FiltersActions",
        "part": "TabItem"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { FiltersActionsTabItem } from '@daisforge/ui';",
      "minimalUsage": "<FiltersActionsTabItem />",
      "examples": []
    },
    "FiltersActionsTabs": {
      "name": "FiltersActionsTabs",
      "group": "layouts",
      "folderName": "FiltersActions",
      "role": "part",
      "description": "Контейнер вкладок для переключения между наборами фильтров и действий",
      "props": [
        {
          "name": "$css",
          "type": "CSSObject | TemplateStringsArray | undefined",
          "required": false,
          "description": "Кастомные стили"
        },
        {
          "name": "as",
          "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
          "required": false,
          "description": "Сменить рендер на другой тип компонента."
        },
        {
          "name": "clip",
          "type": "\"scroll\" | \"showAll\" | undefined",
          "required": false,
          "description": "Как ведет себя компонент при ограничении ширины",
          "default": "'scroll'"
        },
        {
          "name": "hasDivider",
          "type": "boolean | undefined",
          "required": false,
          "description": "Наличие divider",
          "default": "true"
        },
        {
          "name": "index",
          "type": "number | undefined",
          "required": false,
          "description": "Индекс активного элемента, необходим для клавиатурной навигации"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\" | undefined",
          "required": false,
          "description": "Расположение табов"
        },
        {
          "name": "size",
          "type": "string | undefined",
          "required": false,
          "description": "Размер табов"
        },
        {
          "name": "view",
          "type": "string | undefined",
          "required": false,
          "description": "Вид табов"
        },
        {
          "name": "pilled",
          "type": "boolean | undefined",
          "required": false,
          "description": "Табы c округлым border-radius",
          "deprecated": true,
          "default": "false"
        }
      ],
      "propsTypeName": "ComponentProps<typeof FiltersActionsTabs>",
      "sourceFile": "packages/ui-kit/src/layouts/FiltersActions/components/Tabs.tsx",
      "type": "wrapper",
      "atomicBase": "Tabs",
      "wrapsInternal": "Tabs",
      "category": "Локальные компоненты",
      "keywords": [
        "вкладки фильтров",
        "переключение наборов",
        "filter tabs"
      ],
      "hasCuratedMeta": true,
      "parentComponent": "FiltersActions",
      "inheritedProps": [
        {
          "name": "clip",
          "type": "\"scroll\" | \"showAll\"",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "disabled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "dividerAlign",
          "type": "\"right\" | \"left\"",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "hasDivider",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "index",
          "type": "number",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "orientation",
          "type": "\"horizontal\" | \"vertical\"",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "outsideScroll",
          "type": "boolean | { left?: string; right?: string; } | undefined",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "pilled",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "size",
          "type": "\"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"s\" | \"l\" | \"m\" | \"xs\"",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "stretch",
          "type": "boolean",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        },
        {
          "name": "view",
          "type": "\"clear\" | \"filled\" | \"divider\"",
          "required": false,
          "inheritedFrom": "Tabs",
          "inheritedPackage": "@salutejs/sdds-finai"
        }
      ],
      "atomicMcpVersion": "0.355.0",
      "compoundPartOf": {
        "component": "FiltersActions",
        "part": "Tabs"
      },
      "importPath": "@daisforge/ui",
      "importStatement": "import { FiltersActionsTabs } from '@daisforge/ui';",
      "minimalUsage": "<FiltersActionsTabs />",
      "examples": [
        {
          "exportName": "Vendor1",
          "displayName": "Стандартное подключение, без клавиатурной навигации",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { Tabs, TabItem } from '@daisforge/ui';\nimport { IconClock } from '@salutejs/plasma-icons';\nexport function App() {\n    const items = Array(4).fill(0);\n    const [index, setIndex] = useState(0);\n    return (\n        <div>\n            <Tabs view=\"filled\" stretch size=\"xs\">\n                {items.map((_, i) => (\n                    <TabItem\n                        view=\"secondary\"\n                        key={`item:${i}`}\n                        size=\"xs\"\n                        selected={i === index}\n                        tabIndex={0}\n                        contentLeft={<IconClock size=\"xs\" color=\"inherit\" />}\n                        onClick={() => setIndex(i)}\n                    >\n                        {`Label${i + 1}`}\n                    </TabItem>\n                ))}\n            </Tabs>\n        </div>\n    );\n}"
        },
        {
          "exportName": "Vendor2",
          "displayName": "Расположение Tabs",
          "type": "vendor",
          "code": "import React, { useState } from 'react';\nimport { Tabs, TabItem } from '@daisforge/ui';\nimport { IconClock } from '@salutejs/plasma-icons';\nexport function App() {\n    const items = Array(8).fill(0);\n    const [index, setIndex] = useState(0);\n    return (\n        <div>\n            <Tabs view=\"divider\" orientation=\"vertical\" size=\"xs\" style={{ width: '15rem' }}>\n                {items.map((_, i) => (\n                    <TabItem\n                        view=\"divider\"\n                        orientation=\"vertical\"\n                        key={`item:${i}`}\n                        size=\"xs\"\n                        selected={i === index}\n                        tabIndex={0}\n                        contentLeft={<IconClock size=\"xs\" color=\"inherit\" />}\n                        onClick={() => setIndex(i)}\n                    >\n                        {`Label${i + 1}`}\n                    </TabItem>\n                ))}\n            </Tabs>\n        </div>\n    );\n}"
        }
      ]
    },
    "FiltersActions": {
      "name": "FiltersActions",
      "group": "layouts",
      "folderName": "FiltersActions",
      "role": "primary",
      "description": "Панель фильтров и действий над списком: табы, кнопки, поиск, применённые фильтры",
      "props": [
        {
          "name": "activeButtonsBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": "блок активных действий"
        },
        {
          "name": "containerProps",
          "type": "BoxProps | undefined",
          "required": false,
          "description": "пропсы для контейнера всего компонента"
        },
        {
          "name": "listOfFilters",
          "type": "React.ReactNode",
          "required": false,
          "description": "блок списка примененных фильтров"
        },
        {
          "name": "mainBlock",
          "type": "React.ReactNode",
          "required": false,
          "description": "блок фильтров и табов"
        },
        {
          "name": "mainBlockElementsWidth",
          "type": "string | undefined",
          "required": false,
          "description": "пропс для ширины для дочерних элементов - слева направо (Например, \"auto 30% 30%\")"
        },
        {
          "name": "mainBlockProps",
          "type": "BoxProps | undefined",
          "required": false,
          "description": "пропсы для контейнера блока фильтров и табов",
          "default": "{}"
        },
        {
          "name": "onResize",
          "type": "((dimensions: FiltersActionsResizeDimensions) => void) | undefined",
          "required": false,
          "description": "Колбэк, вызываемый при изменении размеров блоков\nПолучает актуальные размеры контейнера, mainBlock и buttonsBlock"
        }
      ],
      "propsTypeName": "FiltersActionsProps",
      "compoundParts": [
        {
          "name": "FiltersButton",
          "typeName": "FiltersActionsFiltersButtonWithPopoverProps",
          "props": [
            {
              "name": "buttonProps",
              "type": "Partial<FiltersActionsFiltersButtonProps> | undefined",
              "required": false,
              "description": "Пропсы для кнопки-таргета FiltersActionsFiltersButton. onClick декорируется: сначала вызовется внешний, потом внутренний toggle."
            },
            {
              "name": "content",
              "type": "React.ReactNode",
              "required": false,
              "description": "Основной контент для отображения"
            },
            {
              "name": "emptySearchContent",
              "type": "React.ReactNode",
              "required": false,
              "description": "Контент отображаемый когда ничего не найдено"
            },
            {
              "name": "footer",
              "type": "React.ReactNode",
              "required": false,
              "description": "Контент footer (опционально)"
            },
            {
              "name": "onClose",
              "type": "(() => void) | undefined",
              "required": false,
              "description": "Callback при закрытии"
            },
            {
              "name": "onSearchChange",
              "type": "((value: string) => void) | undefined",
              "required": false,
              "description": "Callback изменения поискового запроса"
            },
            {
              "name": "popoverProps",
              "type": "Omit<PropsType<{ view: { default: PolymorphicClassName; }; }> & React.HTMLAttributes<HTMLDivElement> & CustomPopoverProps & React.RefAttributes<HTMLDivElement>, \"onToggle\" | \"opened\" | \"target\"> | undefined",
              "required": false,
              "description": "Пропсы для popover"
            },
            {
              "name": "redSquare",
              "type": "boolean | undefined",
              "required": false,
              "description": "Красный индикатор на кнопке фильтров"
            },
            {
              "name": "renderTarget",
              "type": "((api: FilterTargetRenderApi) => React.ReactElement<any, string | React.JSXElementConstructor<any>>) | undefined",
              "required": false,
              "description": "Рендер-проп для полной замены кнопки-таргета Popover собственным элементом\n(иконкой, кнопкой, любым узлом) — при сохранении нативной логики открытия\nPopover и красной точки-индикатора. Когда задан, `buttonProps` и дефолтная\nкнопка «Ещё фильтры» игнорируются.\n\nВАЖНО: повесьте переданный `onClick` на корневой кликабельный элемент вашего\nтаргета. Для красной точки оберните таргет в контейнер с `position: relative`\nи отрендерьте `<RedDot visible={isRedDotVisible} />`."
            },
            {
              "name": "searchable",
              "type": "boolean | undefined",
              "required": false,
              "description": "Включить поиск"
            },
            {
              "name": "searchingProps",
              "type": "Pick<TextFieldProps, \"name\" | \"type\" | \"onFocus\" | \"onBlur\" | \"contentLeft\" | \"contentRight\" | \"textBefore\" | \"textAfter\" | \"maxLength\" | \"minLength\" | \"placeholder\"> | undefined",
              "required": false,
              "description": "Пропсы для поля поиска"
            },
            {
              "name": "searchValue",
              "type": "string | undefined",
              "required": false,
              "description": "Значение поиска (контролируемый режим)"
            },
            {
              "name": "state",
              "type": "[boolean, React.Dispatch<React.SetStateAction<boolean>>] | undefined",
              "required": false,
              "description": "Внешнее состояние открытия/закрытия [isOpen, setIsOpen]"
            },
            {
              "name": "subtitle",
              "type": "string | undefined",
              "required": false,
              "description": "Подзаголовок (опционально)"
            }
          ]
        },
        {
          "name": "DotsIconButton",
          "typeName": "FiltersActionsDotsIconButtonProps",
          "props": [
            {
              "name": "dropdownProps",
              "type": "(Omit<DropdownProps<ItemOption>, \"view\" | \"size\"> & Pick<PropsType<{ size: { m: PolymorphicClassName; s: PolymorphicClassName; xs: PolymorphicClassName; }; view: { default: PolymorphicClassName; }; }> & { items: ItemOption[]; trigger?: DropdownTrigger | undefined; placement?: DropdownPlacement | undefined; children?: React.ReactNode; variant?: \"normal\" | \"tight\" | undefined; zIndex?: Property.ZInd…",
              "required": false,
              "description": "Пропсы выпадающего меню"
            },
            {
              "name": "iconSize",
              "type": "\"xs\" | \"s\" | \"m\" | undefined",
              "required": false,
              "description": "Размер иконки"
            },
            {
              "name": "as",
              "type": "React.ComponentType<any> | keyof JSX.IntrinsicElements | undefined",
              "required": false,
              "description": "Сменить рендер на другой тип компонента."
            },
            {
              "name": "additionalContent",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "appearance",
              "type": "\"default\" | \"outline\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "blur",
              "type": "\"small\" | \"medium\" | \"large\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentLeft",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "contentPlacing",
              "type": "\"default\" | \"relaxed\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentRight",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "focused",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "isLoading",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "loader",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "outlined",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "pin",
              "type": "\"square-square\" | \"square-clear\" | \"clear-square\" | \"clear-clear\" | \"clear-circle\" | \"circle-clear\" | \"circle-circle\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftLeft",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "shiftRight",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "size",
              "type": "\"xs\" | \"s\" | \"xxs\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "square",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretch",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "stretching",
              "type": "\"filled\" | \"fixed\" | \"auto\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "text",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "type",
              "type": "\"button\" | \"submit\" | \"reset\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "value",
              "type": "string | number | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "view",
              "type": "\"default\" | \"clear\" | \"black\" | \"white\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"accent\" | \"dark\" | \"gradient\" | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "ListOfFilters",
          "typeName": "ComponentProps<typeof FiltersActionsListOfFilters>",
          "props": [
            {
              "name": "clearAll",
              "type": "() => void",
              "required": true,
              "description": ""
            },
            {
              "name": "items",
              "type": "ItemOrGroup[]",
              "required": true,
              "description": ""
            },
            {
              "name": "opened",
              "type": "boolean",
              "required": true,
              "description": ""
            },
            {
              "name": "ellipsisLabel",
              "type": "boolean | undefined",
              "required": false,
              "description": "Обрезает название группы фильтров в одну строку с троеточием.",
              "default": "false"
            },
            {
              "name": "showResetAllFiltersButton",
              "type": "boolean | undefined",
              "required": false,
              "description": "Показывать ли кнопку \"Сбросить все\" в блоке примененных фильтров",
              "default": "true"
            },
            {
              "name": "chipStyle",
              "type": "((itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject) | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "extraCss",
              "type": "React.CSSProperties | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "leftSlot",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "maxHeight",
              "type": "number | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "maxLengthInGroup",
              "type": "number | undefined",
              "required": false,
              "description": "",
              "default": "maxLengthInGroup=2"
            },
            {
              "name": "paddingInline",
              "type": "number | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "paddingTop",
              "type": "number | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "renderChipLabel",
              "type": "((group: Group | null, item: Item) => string) | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "renderGroupLabel",
              "type": "((group: Group) => string) | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "size",
              "type": "\"xs\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "sizeOnOpen",
              "type": "number | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "TextFieldSearch",
          "typeName": "ComponentProps<typeof TextFieldSearch>",
          "props": [
            {
              "name": "labelPlacement",
              "type": "\"inner\" | \"outer\" | undefined",
              "required": false,
              "description": "Расположение лейбла."
            },
            {
              "name": "onClear",
              "type": "((() => void) & (() => void)) | ((() => void) & (() => void)) | ((() => void) & (() => void)) | ((() => void) & (() => void)) | ((() => void) & (() => void)) | ((() => void) & (() => void)) | ((() => void) & (() => void)) | ((() => void) & (() => void)) | ((() => void) & (() => void)) | ((() => void) & (() => void)) | ((() => void) & (() => void)) | ((() => void) & (() => void)) | ((() => void) & …",
              "required": false,
              "description": "Действие при выполнении нажатия на кнопку очистки поля ввода"
            },
            {
              "name": "size",
              "type": "\"s\" | \"xs\" | undefined",
              "required": false,
              "description": "Размер Поля ввода",
              "default": "'s'"
            },
            {
              "name": "hasRequiredIndicator",
              "type": "boolean | undefined",
              "required": false,
              "description": "Флаг наличия индикатора обязательности поля",
              "default": "false"
            },
            {
              "name": "keepPlaceholder",
              "type": "boolean | undefined",
              "required": false,
              "description": "Одновременно отображает label и placeholder (при пустом вводе)"
            },
            {
              "name": "onChange",
              "type": "React.ChangeEventHandler<HTMLInputElement> | undefined",
              "required": false,
              "description": "Обработчик изменения элемента формы"
            },
            {
              "name": "optional",
              "type": "boolean | undefined",
              "required": false,
              "description": "Флаг необязательности поля"
            },
            {
              "name": "optionalText",
              "type": "string | undefined",
              "required": false,
              "description": "Подпись для указания необязательности поля"
            },
            {
              "name": "requiredPlacement",
              "type": "\"left\" | \"right\" | undefined",
              "required": false,
              "description": "Задает выравнивание индикатора обязательности поля",
              "default": "right"
            },
            {
              "name": "appearance",
              "type": "\"default\" | \"clear\" | \"viewMode\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "chips",
              "type": "TextFieldPrimitiveValue[] | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "chipType",
              "type": "\"default\" | \"text\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "chipValidator",
              "type": "((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { view?: string | undefined; }) | ((value: string) => { …",
              "required": false,
              "description": ""
            },
            {
              "name": "chipView",
              "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"accent\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "clear",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentLeft",
              "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "contentRight",
              "type": "React.ReactElement<any, string | React.JSXElementConstructor<any>> | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "enumerationType",
              "type": "\"plain\" | \"chip\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "hasDivider",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "hintContentLeft",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "hintHasArrow",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "hintOffset",
              "type": "[number, number] | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "hintPlacement",
              "type": "Placement | ComputedPlacement[] | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "hintPortal",
              "type": "string | React.RefObject<HTMLElement | null> | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "hintSize",
              "type": "\"s\" | \"m\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "hintTargetIcon",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "hintTargetPlacement",
              "type": "\"inner\" | \"outer\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "hintText",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "hintTrigger",
              "type": "\"hover\" | \"click\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "hintView",
              "type": "\"default\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "hintWidth",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "leftHelper",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "onChangeChips",
              "type": "((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimitiveValue[]) => void) | ((value: TextFieldPrimit…",
              "required": false,
              "description": ""
            },
            {
              "name": "onSearch",
              "type": "(((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | (((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void) & ((value: string, event?: React.KeyboardEvent<HTMLInputElement> | undefined) => void)) | (((value: string, event?: React.KeyboardEvent<HT…",
              "required": false,
              "description": ""
            },
            {
              "name": "rightHelper",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "textAfter",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "textBefore",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "titleCaption",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "view",
              "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"edited\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "autoComplete",
              "type": "React.HTMLInputAutoCompleteAttribute | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "enterKeyHint",
              "type": "\"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "handlerClear",
              "type": "(() => void) | undefined",
              "required": false,
              "description": "Действие при выполнении нажатия на кнопку очистки поля ввода",
              "deprecated": true
            }
          ]
        },
        {
          "name": "Tabs",
          "typeName": "FiltersActionsTabsProps",
          "props": [
            {
              "name": "$css",
              "type": "CSSObject | TemplateStringsArray | undefined",
              "required": false,
              "description": "Кастомные стили"
            },
            {
              "name": "as",
              "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
              "required": false,
              "description": "Сменить рендер на другой тип компонента."
            },
            {
              "name": "clip",
              "type": "\"scroll\" | \"showAll\" | undefined",
              "required": false,
              "description": "Как ведет себя компонент при ограничении ширины",
              "default": "'scroll'"
            },
            {
              "name": "hasDivider",
              "type": "boolean | undefined",
              "required": false,
              "description": "Наличие divider",
              "default": "true"
            },
            {
              "name": "index",
              "type": "number | undefined",
              "required": false,
              "description": "Индекс активного элемента, необходим для клавиатурной навигации"
            },
            {
              "name": "orientation",
              "type": "\"horizontal\" | \"vertical\" | undefined",
              "required": false,
              "description": "Расположение табов"
            },
            {
              "name": "size",
              "type": "string | undefined",
              "required": false,
              "description": "Размер табов"
            },
            {
              "name": "view",
              "type": "string | undefined",
              "required": false,
              "description": "Вид табов"
            },
            {
              "name": "pilled",
              "type": "boolean | undefined",
              "required": false,
              "description": "Табы c округлым border-radius",
              "deprecated": true,
              "default": "false"
            }
          ]
        },
        {
          "name": "TabItem",
          "typeName": "FiltersActionsTabItemProps",
          "props": [
            {
              "name": "$css",
              "type": "CSSObject | TemplateStringsArray | undefined",
              "required": false,
              "description": "Кастомные стили"
            },
            {
              "name": "actionContent",
              "type": "React.ReactNode",
              "required": false,
              "description": "Слот для интерактивных элементов (крестик)"
            },
            {
              "name": "as",
              "type": "keyof JSX.IntrinsicElements | React.ComponentType<any> | undefined",
              "required": false,
              "description": "Сменить рендер на другой тип компонента."
            },
            {
              "name": "contentRight",
              "type": "React.ReactNode",
              "required": false,
              "description": "Контент справа"
            },
            {
              "name": "disableScroll",
              "type": "boolean | undefined",
              "required": false,
              "description": "Отключает скролл к TabItem при его выборе",
              "default": "false"
            },
            {
              "name": "itemIndex",
              "type": "number | undefined",
              "required": false,
              "description": "Индекс TabItem внутри Tabs - необходим для клавиатурной навигации"
            },
            {
              "name": "maxItemWidth",
              "type": "Property.Width<string | number> | undefined",
              "required": false,
              "description": "Обрезает контент по максимальной ширине и добавляет ...",
              "default": "'auto'"
            },
            {
              "name": "onIndexChange",
              "type": "((index: number) => void) | undefined",
              "required": false,
              "description": "Callback, необходимый для клавиатурной навигации"
            },
            {
              "name": "contentLeft",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "orientation",
              "type": "\"horizontal\" | \"vertical\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "pilled",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "size",
              "type": "\"s\" | \"xs\" | \"m\" | \"h6\" | \"h5\" | \"h4\" | \"h3\" | \"h2\" | \"h1\" | \"l\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "truncate",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "type",
              "type": "\"button\" | \"submit\" | \"reset\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "value",
              "type": "string | number | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "view",
              "type": "\"default\" | \"secondary\" | \"clear\" | \"divider\" | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "SegmentItem",
          "typeName": "FiltersActionsSegmentItemProps",
          "props": [
            {
              "name": "value",
              "type": "string | (readonly string[] & string)",
              "required": true,
              "description": "Значение сегмента"
            },
            {
              "name": "$css",
              "type": "CSSObject | TemplateStringsArray | undefined",
              "required": false,
              "description": "Кастомные стили"
            },
            {
              "name": "contentLeft",
              "type": "React.ReactNode",
              "required": false,
              "description": "Слот для контента слева."
            },
            {
              "name": "contentRight",
              "type": "React.ReactNode",
              "required": false,
              "description": "Слот для контента справа."
            },
            {
              "name": "customHandleSelect",
              "type": "((e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void) | undefined",
              "required": false,
              "description": "Коллбек для обработки выбора сегмента"
            },
            {
              "name": "label",
              "type": "React.ReactNode",
              "required": false,
              "description": "Метка-подпись к элементу"
            },
            {
              "name": "maxItemWidth",
              "type": "Property.Width<string | number> | undefined",
              "required": false,
              "description": "Обрезает контент по максимальной ширине и добавляет ...",
              "default": "'auto'"
            },
            {
              "name": "pilled",
              "type": "boolean | undefined",
              "required": false,
              "description": "Сегмент c округлым border-radius"
            },
            {
              "name": "size",
              "type": "string | undefined",
              "required": false,
              "description": "Размер сегмента"
            },
            {
              "name": "view",
              "type": "string | undefined",
              "required": false,
              "description": "Вид сегмента",
              "default": "'default'"
            },
            {
              "name": "type",
              "type": "\"button\" | \"submit\" | \"reset\" | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "Tooltip",
          "typeName": "FiltersActionsTooltipProps",
          "props": [
            {
              "name": "items",
              "type": "string[]",
              "required": true,
              "description": ""
            },
            {
              "name": "animated",
              "type": "boolean | undefined",
              "required": false,
              "description": "Анимированное появление/сокрытие."
            },
            {
              "name": "contentLeft",
              "type": "React.ReactNode",
              "required": false,
              "description": "Слот для контента слева, например `Icon`."
            },
            {
              "name": "frame",
              "type": "string | React.RefObject<HTMLElement> | undefined",
              "required": false,
              "description": "В каком контейнере позиционируется(по умолчанию document), можно также указать id элемента или ref для него."
            },
            {
              "name": "hasArrow",
              "type": "boolean | undefined",
              "required": false,
              "description": "Видимость стрелки (хвоста)."
            },
            {
              "name": "maxWidth",
              "type": "string | number | undefined",
              "required": false,
              "description": "Максимальная ширина окна (в rem)."
            },
            {
              "name": "minWidth",
              "type": "string | number | undefined",
              "required": false,
              "description": "Минимальная ширина окна (в rem)."
            },
            {
              "name": "mouseEnterDelay",
              "type": "number | undefined",
              "required": false,
              "description": "Задержка открытия тултипа в ms.",
              "default": "0"
            },
            {
              "name": "mouseLeaveDelay",
              "type": "number | undefined",
              "required": false,
              "description": "Задержка скрытия тултипа в ms.",
              "default": "300"
            },
            {
              "name": "offset",
              "type": "[number, number] | undefined",
              "required": false,
              "description": "Отступ окна относительно элемента, у которого оно вызвано.",
              "default": "[0, 8]"
            },
            {
              "name": "onDismiss",
              "type": "(() => void) | undefined",
              "required": false,
              "description": "Событие закрытия тултипа по кнопке Esc."
            },
            {
              "name": "opened",
              "type": "boolean | undefined",
              "required": false,
              "description": "Видимость тултипа."
            },
            {
              "name": "placement",
              "type": "Placement | ComputedPlacement[] | undefined",
              "required": false,
              "description": "Направление раскрытия тултипа."
            },
            {
              "name": "size",
              "type": "string | undefined",
              "required": false,
              "description": "Размер тултипа."
            },
            {
              "name": "target",
              "type": "string | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | ((instance: HTMLElement | null) => void) | React.RefObject<HTMLElement> | null | undefined",
              "required": false,
              "description": "Элемент, рядом с которым произойдет вызов всплывающего окна."
            },
            {
              "name": "trigger",
              "type": "\"none\" | \"hover\" | \"click\" | undefined",
              "required": false,
              "description": "Действие по target для отображения тултипа"
            },
            {
              "name": "usePortal",
              "type": "boolean | undefined",
              "required": false,
              "description": "Находится ли в портале.",
              "default": "true"
            },
            {
              "name": "view",
              "type": "string | undefined",
              "required": false,
              "description": "Вид тултипа."
            },
            {
              "name": "zIndex",
              "type": "string | undefined",
              "required": false,
              "description": "Значение z-index для Tooltip.",
              "default": "9200"
            },
            {
              "name": "groupLabel",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "arrow",
              "type": "boolean | undefined",
              "required": false,
              "description": "Видимость стрелки (хвоста).",
              "deprecated": true
            },
            {
              "name": "hoverTimeout",
              "type": "number | undefined",
              "required": false,
              "description": "Время автоматического скрытия тултипа по ховеру в ms",
              "deprecated": true,
              "default": "300"
            },
            {
              "name": "isOpen",
              "type": "boolean | undefined",
              "required": false,
              "description": "Видимость тултипа.",
              "deprecated": true
            },
            {
              "name": "isVisible",
              "type": "boolean | undefined",
              "required": false,
              "description": "Видимость тултипа.",
              "deprecated": true
            }
          ]
        },
        {
          "name": "TooltipList",
          "typeName": "ComponentProps<typeof TooltipList>",
          "props": [
            {
              "name": "items",
              "type": "string[]",
              "required": true,
              "description": ""
            },
            {
              "name": "animated",
              "type": "boolean | undefined",
              "required": false,
              "description": "Анимированное появление/сокрытие."
            },
            {
              "name": "contentLeft",
              "type": "React.ReactNode",
              "required": false,
              "description": "Слот для контента слева, например `Icon`."
            },
            {
              "name": "frame",
              "type": "string | React.RefObject<HTMLElement> | undefined",
              "required": false,
              "description": "В каком контейнере позиционируется(по умолчанию document), можно также указать id элемента или ref для него."
            },
            {
              "name": "fullWidth",
              "type": "boolean | undefined",
              "required": false,
              "description": "Растягивает внутренние обёртки Tooltip (popover-target, popover-wrapper) на 100% ширины родителя.\nИспользуйте при размещении TooltipList внутри Popover-контента (например, FiltersActions.FiltersButtonWithPopover),\nчтобы дочерний элемент (Combobox и т.д.) занимал всю доступную ширину."
            },
            {
              "name": "hasArrow",
              "type": "boolean | undefined",
              "required": false,
              "description": "Видимость стрелки (хвоста)."
            },
            {
              "name": "maxWidth",
              "type": "string | number | undefined",
              "required": false,
              "description": "Максимальная ширина окна (в rem)."
            },
            {
              "name": "minWidth",
              "type": "string | number | undefined",
              "required": false,
              "description": "Минимальная ширина окна (в rem)."
            },
            {
              "name": "mouseEnterDelay",
              "type": "number | undefined",
              "required": false,
              "description": "Задержка открытия тултипа в ms.",
              "default": "0"
            },
            {
              "name": "mouseLeaveDelay",
              "type": "number | undefined",
              "required": false,
              "description": "Задержка скрытия тултипа в ms.",
              "default": "300"
            },
            {
              "name": "offset",
              "type": "[number, number] | undefined",
              "required": false,
              "description": "Отступ окна относительно элемента, у которого оно вызвано.",
              "default": "[0, 8]"
            },
            {
              "name": "onDismiss",
              "type": "(() => void) | undefined",
              "required": false,
              "description": "Событие закрытия тултипа по кнопке Esc."
            },
            {
              "name": "opened",
              "type": "boolean | undefined",
              "required": false,
              "description": "Видимость тултипа."
            },
            {
              "name": "placement",
              "type": "Placement | ComputedPlacement[] | undefined",
              "required": false,
              "description": "Направление раскрытия тултипа."
            },
            {
              "name": "size",
              "type": "string | undefined",
              "required": false,
              "description": "Размер тултипа."
            },
            {
              "name": "target",
              "type": "string | number | boolean | React.ReactElement<any, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | ((instance: HTMLElement | null) => void) | React.RefObject<HTMLElement> | null | undefined",
              "required": false,
              "description": "Элемент, рядом с которым произойдет вызов всплывающего окна."
            },
            {
              "name": "trigger",
              "type": "\"click\" | \"hover\" | \"none\" | undefined",
              "required": false,
              "description": "Действие по target для отображения тултипа"
            },
            {
              "name": "usePortal",
              "type": "boolean | undefined",
              "required": false,
              "description": "Находится ли в портале.",
              "default": "true"
            },
            {
              "name": "view",
              "type": "string | undefined",
              "required": false,
              "description": "Вид тултипа."
            },
            {
              "name": "zIndex",
              "type": "string | undefined",
              "required": false,
              "description": "Значение z-index для Tooltip.",
              "default": "9200"
            },
            {
              "name": "groupLabel",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "arrow",
              "type": "boolean | undefined",
              "required": false,
              "description": "Видимость стрелки (хвоста).",
              "deprecated": true
            },
            {
              "name": "hoverTimeout",
              "type": "number | undefined",
              "required": false,
              "description": "Время автоматического скрытия тултипа по ховеру в ms",
              "deprecated": true,
              "default": "300"
            },
            {
              "name": "isOpen",
              "type": "boolean | undefined",
              "required": false,
              "description": "Видимость тултипа.",
              "deprecated": true
            },
            {
              "name": "isVisible",
              "type": "boolean | undefined",
              "required": false,
              "description": "Видимость тултипа.",
              "deprecated": true
            }
          ]
        },
        {
          "name": "FilterPopover",
          "typeName": "FiltersActionsFiltersButtonWithPopoverProps",
          "props": [
            {
              "name": "buttonProps",
              "type": "Partial<FiltersActionsFiltersButtonProps> | undefined",
              "required": false,
              "description": "Пропсы для кнопки-таргета FiltersActionsFiltersButton. onClick декорируется: сначала вызовется внешний, потом внутренний toggle."
            },
            {
              "name": "content",
              "type": "React.ReactNode",
              "required": false,
              "description": "Основной контент для отображения"
            },
            {
              "name": "emptySearchContent",
              "type": "React.ReactNode",
              "required": false,
              "description": "Контент отображаемый когда ничего не найдено"
            },
            {
              "name": "footer",
              "type": "React.ReactNode",
              "required": false,
              "description": "Контент footer (опционально)"
            },
            {
              "name": "onClose",
              "type": "(() => void) | undefined",
              "required": false,
              "description": "Callback при закрытии"
            },
            {
              "name": "onSearchChange",
              "type": "((value: string) => void) | undefined",
              "required": false,
              "description": "Callback изменения поискового запроса"
            },
            {
              "name": "popoverProps",
              "type": "Omit<PropsType<{ view: { default: PolymorphicClassName; }; }> & React.HTMLAttributes<HTMLDivElement> & CustomPopoverProps & React.RefAttributes<HTMLDivElement>, \"opened\" | \"target\" | \"onToggle\"> | undefined",
              "required": false,
              "description": "Пропсы для popover",
              "default": "{}"
            },
            {
              "name": "redSquare",
              "type": "boolean | undefined",
              "required": false,
              "description": "Красный индикатор на кнопке фильтров",
              "default": "false"
            },
            {
              "name": "renderTarget",
              "type": "((api: FilterTargetRenderApi) => React.ReactElement<any, string | React.JSXElementConstructor<any>>) | undefined",
              "required": false,
              "description": "Рендер-проп для полной замены кнопки-таргета Popover собственным элементом\n(иконкой, кнопкой, любым узлом) — при сохранении нативной логики открытия\nPopover и красной точки-индикатора. Когда задан, `buttonProps` и дефолтная\nкнопка «Ещё фильтры» игнорируются.\n\nВАЖНО: повесьте переданный `onClick` на корневой кликабельный элемент вашего\nтаргета. Для красной точки оберните таргет в контейнер с `position: relative`\nи отрендерьте `<RedDot visible={isRedDotVisible} />`."
            },
            {
              "name": "searchable",
              "type": "boolean | undefined",
              "required": false,
              "description": "Включить поиск"
            },
            {
              "name": "searchingProps",
              "type": "Pick<TextFieldProps, \"contentLeft\" | \"onFocus\" | \"onBlur\" | \"type\" | \"name\" | \"placeholder\" | \"minLength\" | \"maxLength\" | \"contentRight\" | \"textBefore\" | \"textAfter\"> | undefined",
              "required": false,
              "description": "Пропсы для поля поиска"
            },
            {
              "name": "searchValue",
              "type": "string | undefined",
              "required": false,
              "description": "Значение поиска (контролируемый режим)"
            },
            {
              "name": "state",
              "type": "[boolean, React.Dispatch<React.SetStateAction<boolean>>] | undefined",
              "required": false,
              "description": "Внешнее состояние открытия/закрытия [isOpen, setIsOpen]"
            },
            {
              "name": "subtitle",
              "type": "string | undefined",
              "required": false,
              "description": "Подзаголовок (опционально)"
            }
          ]
        },
        {
          "name": "FiltersButtonWithPopover",
          "typeName": "FiltersActionsFiltersButtonWithPopoverProps",
          "props": [
            {
              "name": "buttonProps",
              "type": "Partial<FiltersActionsFiltersButtonProps> | undefined",
              "required": false,
              "description": "Пропсы для кнопки-таргета FiltersActionsFiltersButton. onClick декорируется: сначала вызовется внешний, потом внутренний toggle."
            },
            {
              "name": "content",
              "type": "React.ReactNode",
              "required": false,
              "description": "Основной контент для отображения"
            },
            {
              "name": "emptySearchContent",
              "type": "React.ReactNode",
              "required": false,
              "description": "Контент отображаемый когда ничего не найдено"
            },
            {
              "name": "footer",
              "type": "React.ReactNode",
              "required": false,
              "description": "Контент footer (опционально)"
            },
            {
              "name": "onClose",
              "type": "(() => void) | undefined",
              "required": false,
              "description": "Callback при закрытии"
            },
            {
              "name": "onSearchChange",
              "type": "((value: string) => void) | undefined",
              "required": false,
              "description": "Callback изменения поискового запроса"
            },
            {
              "name": "popoverProps",
              "type": "Omit<PropsType<{ view: { default: PolymorphicClassName; }; }> & React.HTMLAttributes<HTMLDivElement> & CustomPopoverProps & React.RefAttributes<HTMLDivElement>, \"opened\" | \"target\" | \"onToggle\"> | undefined",
              "required": false,
              "description": "Пропсы для popover",
              "default": "{}"
            },
            {
              "name": "redSquare",
              "type": "boolean | undefined",
              "required": false,
              "description": "Красный индикатор на кнопке фильтров",
              "default": "false"
            },
            {
              "name": "renderTarget",
              "type": "((api: FilterTargetRenderApi) => React.ReactElement<any, string | React.JSXElementConstructor<any>>) | undefined",
              "required": false,
              "description": "Рендер-проп для полной замены кнопки-таргета Popover собственным элементом\n(иконкой, кнопкой, любым узлом) — при сохранении нативной логики открытия\nPopover и красной точки-индикатора. Когда задан, `buttonProps` и дефолтная\nкнопка «Ещё фильтры» игнорируются.\n\nВАЖНО: повесьте переданный `onClick` на корневой кликабельный элемент вашего\nтаргета. Для красной точки оберните таргет в контейнер с `position: relative`\nи отрендерьте `<RedDot visible={isRedDotVisible} />`."
            },
            {
              "name": "searchable",
              "type": "boolean | undefined",
              "required": false,
              "description": "Включить поиск"
            },
            {
              "name": "searchingProps",
              "type": "Pick<TextFieldProps, \"contentLeft\" | \"onFocus\" | \"onBlur\" | \"type\" | \"name\" | \"placeholder\" | \"minLength\" | \"maxLength\" | \"contentRight\" | \"textBefore\" | \"textAfter\"> | undefined",
              "required": false,
              "description": "Пропсы для поля поиска"
            },
            {
              "name": "searchValue",
              "type": "string | undefined",
              "required": false,
              "description": "Значение поиска (контролируемый режим)"
            },
            {
              "name": "state",
              "type": "[boolean, React.Dispatch<React.SetStateAction<boolean>>] | undefined",
              "required": false,
              "description": "Внешнее состояние открытия/закрытия [isOpen, setIsOpen]"
            },
            {
              "name": "subtitle",
              "type": "string | undefined",
              "required": false,
              "description": "Подзаголовок (опционально)"
            }
          ]
        },
        {
          "name": "ResetAllFiltersButton",
          "typeName": "ResetAllFiltersButtonProps",
          "props": [
            {
              "name": "$css",
              "type": "CSSObject | TemplateStringsArray | undefined",
              "required": false,
              "description": "Кастомные стили"
            },
            {
              "name": "isVisible",
              "type": "boolean | undefined",
              "required": false,
              "description": "Видимость кнопки"
            },
            {
              "name": "additionalContent",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "contentLeft",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "contentRight",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "isLoading",
              "type": "boolean | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "loader",
              "type": "React.ReactNode",
              "required": false,
              "description": ""
            },
            {
              "name": "ping",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "referrerPolicy",
              "type": "React.HTMLAttributeReferrerPolicy | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "size",
              "type": "\"s\" | \"xs\" | \"xxs\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "target",
              "type": "React.HTMLAttributeAnchorTarget | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "text",
              "type": "string | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "view",
              "type": "\"default\" | \"positive\" | \"warning\" | \"negative\" | \"secondary\" | \"accent\" | \"gradient\" | \"info\" | undefined",
              "required": false,
              "description": ""
            }
          ]
        },
        {
          "name": "SwitcherFilter",
          "typeName": "SwitcherFilterProps",
          "props": [
            {
              "name": "description",
              "type": "string | undefined",
              "required": false,
              "description": "Дополнительное описание"
            },
            {
              "name": "focused",
              "type": "boolean | undefined",
              "required": false,
              "description": "Добавить рамку при фокусе"
            },
            {
              "name": "hasBackground",
              "type": "boolean | undefined",
              "required": false,
              "description": "Отображение подложки у switch"
            },
            {
              "name": "label",
              "type": "React.ReactNode",
              "required": false,
              "description": "Метка-подпись к элементу"
            },
            {
              "name": "labelPosition",
              "type": "\"before\" | \"after\" | undefined",
              "required": false,
              "description": "Расположение подпись"
            },
            {
              "name": "onChange",
              "type": "React.ChangeEventHandler<HTMLInputElement> | undefined",
              "required": false,
              "description": "Обработчик изменения элемента формы"
            },
            {
              "name": "singleLine",
              "type": "boolean | undefined",
              "required": false,
              "description": "Перенос строки label",
              "default": "true"
            },
            {
              "name": "size",
              "type": "\"s\" | \"m\" | \"l\" | undefined",
              "required": false,
              "description": "Размер компонента."
            },
            {
              "name": "toggleSize",
              "type": "\"s\" | \"l\" | undefined",
              "required": false,
              "description": "Размер toggle."
            },
            {
              "name": "view",
              "type": "\"default\" | undefined",
              "required": false,
              "description": "Вид компонента."
            },
            {
              "name": "autoComplete",
              "type": "React.HTMLInputAutoCompleteAttribute | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "enterKeyHint",
              "type": "\"search\" | \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"send\" | undefined",
              "required": false,
              "description": ""
            },
            {
              "name": "outlined",
              "type": "boolean | undefined",
              "required": false,
              "description": "Добавить рамку при фокусе",
              "deprecated": true
            },
            {
              "name": "pressed",
              "type": "boolean | undefined",
              "required": false,
              "description": "Нажатие на компонент",
              "deprecated": true
            }
          ]
        },
        {
          "name": "RedDot",
          "typeName": "RedDotProps",
          "props": [
            {
              "name": "offset",
              "type": "string | number | undefined",
              "required": false,
              "description": "Смещение точки от правого верхнего угла контейнера (top/right).\nПо умолчанию `0` — точка прижата к углу."
            },
            {
              "name": "visible",
              "type": "boolean | undefined",
              "required": false,
              "description": "Показывать ли точку. Обычно прокидывается из `isRedDotVisible` рендер-API."
            }
          ]
        }
      ],
      "sourceFile": "packages/ui-kit/src/layouts/FiltersActions/FiltersActions.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "панель фильтров",
        "toolbar",
        "filter bar"
      ],
      "docs": "# FilterActions\n\nКомпозиция для создания панели фильтров и действий. Компонент предоставляет базовые строительные блоки (кнопки, поля поиска, Popover и т.д.), оставляя логику адаптивности и размещения за командой-пользователем.\n\n## Ключевые особенности\n\n- Набор строительных блоков: кнопки, поля поиска, Popover для фильтров\n- Compound-компоненты: `FiltersActions.FiltersButtonWithPopover`, `FiltersActions.ListOfFilters` и др.\n- Колбек `onResize` для отслеживания размеров контейнера\n- Хук `useFiltersList` для управления списком активных фильтров\n- Адаптивность опциональна — реализуется на стороне проекта через `useAdaptiveFilters`\n\n## Основная структура\n\n```tsx\n<FiltersActions\n  mainBlock={/* Основные фильтры, табы, сегменты */}\n  activeButtonsBlock={/* Блок действий справа */}\n  listOfFilters={/* Список примененных фильтров */}\n  onResize={(dimensions) => {\n    /* Отслеживание размеров */\n  }}\n/>\n```\n\n## Об адаптивности\n\n**Важно:** Адаптивность фильтров **не является обязательной частью** компонента FiltersActions. Решение о том, какие фильтры показывать, куда перемещать и в каком порядке располагать — полностью на стороне команды-пользователя.\n\n### Пример адаптивности (необязательно)\n\nВ истории ниже показан **пример реализации адаптивности**, который можно взять за основу:\n\n#### 1. Колбек `onResize`\n\nКомпонент FiltersActions предоставляет колбек `onResize`, который возвращает актуальные размеры:\n\n```tsx\n<FiltersActions\n  onResize={(dimensions) => {\n    // dimensions.containerWidth - полная ширина\n    // dimensions.mainBlockWidth - ширина левого блока\n    // dimensions.buttonsBlockWidth - ширина правого блока\n    // dimensions.availableMainBlockWidth - доступная ширина для фильтров\n  }}\n/>\n```\n\n#### 2. Хук `useAdaptiveFilters`\n\nХук принимает массив элементов (`FilterItem[]`), текущую ширину и конфигурацию брейкпоинтов:\n\n```tsx\nconst { visibleItems, overlayItems, modifications, customActions } =\n  useAdaptiveFilters({\n    items: allFilterItems, // Массив всех фильтров\n    width: dimensions.availableMainBlockWidth, // Доступная ширина\n    breakpoints: {\n      1920: {\n        visible: ['search', 'filter1', 'filter2'], // Видимые ID\n        inOverlay: ['filter3'], // ID в Popover\n        modifications: {\n          // Модификации стилей\n          search: { width: '300px' },\n        },\n      },\n      1400: {\n        visible: ['search'],\n        inOverlay: ['filter1', 'filter2', 'filter3'],\n      },\n    },\n  });\n```\n\nХук определяет на основании ширины контейнера:\n\n- Какие элементы остаются видимыми (`visibleItems`)\n- Какие перемещаются в Popover (`overlayItems`)\n- Какие модификации применить (`modifications`)\n- Дополнительные действия (`customActions`)\n\n#### 3. Контент Popover\n\n**Контент Popover полностью контролируется использующей стороной:**\n\n```tsx\n<FiltersActions.FiltersButtonWithPopover\n  content={\n    // ВЫ решаете, что рендерить внутри\n    overlayItems.map((item) => (\n      <div key={item.id}>{item.element}</div>\n    ))\n  }\n  footer={\n    // ВЫ решаете, что показывать в footer\n    <Button onClick={resetAll}>Сбросить</Button>\n  }\n/>\n```\n\n### Кастомизация кнопки Popover\n\nПо умолчанию кнопка-таргет `FiltersActions.FiltersButtonWithPopover` рендерится с текстом «Ещё фильтры» и иконкой размера `s`. Через проп `buttonProps` можно переопределить поведение кнопки:\n\n```tsx\n// Скрыть текст — останется только иконка\n<FiltersActions.FiltersButtonWithPopover\n  buttonProps={{ hideLabel: true }}\n/>\n\n// Поменять текст и размер иконки\n<FiltersActions.FiltersButtonWithPopover\n  buttonProps={{ text: 'Фильтры', iconSize: 'xs' }}\n/>\n\n// Заблокировать кнопку\n<FiltersActions.FiltersButtonWithPopover\n  buttonProps={{ disabled: true }}\n/>\n```\n\nПринимает любые пропсы `FiltersActionsFiltersButton`. `onClick` декорируется — сначала вызовется внешний, потом внутренний toggle Popover.\n\n### Кастомный таргет Popover — `renderTarget`\n\nКогда `buttonProps` недостаточно и нужно полностью заменить кнопку-таргет собственным элементом (иконкой, кнопкой, любым узлом) — используйте рендер-проп `renderTarget`. Он оставляет за компонентом логику открытия Popover и красную точку-индикатор, а разметку таргета отдаёт вам.\n\n`renderTarget` получает объект `FilterTargetRenderApi`:\n\n- **`onClick`** — обработчик открытия/закрытия Popover. **Обязательно** повесьте его на корневой кликабельный элемент таргета — иначе Popover не откроется.\n- **`isOpen`** — открыт ли Popover сейчас (например, чтобы подсветить активный таргет).\n- **`isRedDotVisible`** — нужно ли показывать красную точку (значение пропа `redSquare`).\n- **`RedDot`** — компонент точки-индикатора. Позиционируется в правый верхний угол ближайшего контейнера с `position: relative`.\n\n```tsx\n<FiltersActions.FiltersButtonWithPopover\n  title=\"Фильтры\"\n  redSquare={hasActiveFilters}\n  renderTarget={({ onClick, isOpen, isRedDotVisible, RedDot }) => (\n    <IconButton\n      onClick={onClick}\n      size=\"s\"\n      view={isOpen ? 'accent' : 'secondary'}\n      style={{ position: 'relative' }} // Важно — якорь для RedDot\n    >\n      <IconSettingsFilter size=\"s\" />\n      <RedDot visible={isRedDotVisible} />\n    </IconButton>\n  )}\n  content={/* ... */}\n/>\n```\n\nКогда задан `renderTarget`, проп `buttonProps` и дефолтная кнопка «Ещё фильтры» игнорируются. Красную точку рисуете вы — компонент `RedDot` доступен и в API рендер-пропа, и как `FiltersActions.RedDot`, вид индикатора остаётся единым.\n\nЖивой пример — в истории **«FiltersActions с кастомным таргетом Popover»** ниже.\n\n## Размещение фильтров внутри Popover\n\n**Контент Popover (`FiltersActions.FiltersButtonWithPopover`) полностью контролируется использующей стороной.** Компонент предоставляет layout (шапка, контент, футер) — всё остальное (логика, стили, компоненты) реализуется на стороне проекта.\n\nНиже — рекомендации, которые помогут избежать типичных проблем с шириной и позиционированием элементов внутри Popover.\n\n### 1. Реф на Popover — `popoverRef`\n\nСоздайте реф и передайте его в `popoverProps.ref`. Этот реф нужен дочерним компонентам внутри Popover:\n\n```tsx\nconst popoverRef = useRef<HTMLDivElement>(null);\n\n<FiltersActions.FiltersButtonWithPopover\n  popoverProps={{ ref: popoverRef }} // Важно\n  content={...}\n/>\n```\n\n**Зачем:** Popover рендерится через портал (вне основного DOM-дерева). Без `popoverRef` выпадающие списки Combobox и тултипы будут рендериться в основном дереве — позади Popover или с обрезкой по `overflow`.\n\n### 2. Combobox: `portal` и `zIndex`\n\nКаждому Combobox внутри Popover передайте `portal={popoverRef}` и `zIndex=\"9001\"`:\n\n```tsx\n<Combobox\n  portal={popoverRef}  // Важно — dropdown рендерится внутри Popover\n  zIndex=\"9001\"         // Важно — dropdown поверх контента Popover\n  ...\n/>\n```\n\n### 3. TooltipList: `frame` и `fullWidth`\n\nЕсли Combobox обёрнут в `FiltersActions.TooltipList`, передайте `frame={popoverRef}` и `fullWidth`:\n\n```tsx\n<FiltersActions.TooltipList\n  groupLabel=\"Название фильтра\"\n  fullWidth              // Важно — растягивает обёртки тултипа на 100% ширины\n  frame={popoverRef}     // Важно — тултип позиционируется внутри Popover\n  items={selectedLabels}\n  trigger={selectedValues.length > 0 ? 'hover' : 'none'}\n>\n  ...\n</FiltersActions.TooltipList>\n```\n\nПроп `fullWidth` устанавливает `width: 100%` на внутренние обёртки Tooltip (`.popover-target`, `.popover-wrapper`), чтобы дочерний элемент занял всю доступную ширину контента Popover.\n\n### 4. Combobox: обёртка `div` с `width: 100%`\n\nCombobox по умолчанию занимает ширину по содержимому. Оберните его в `div` с `width: 100%`:\n\n```tsx\n<div style={{ width: '100%' }}>\n  <Combobox\n    portal={popoverRef}\n    zIndex=\"9001\"\n    ...\n  />\n</div>\n```\n\n### 5. Контейнер каждого фильтра\n\nКаждый элемент внутри `content` оберните в `div` с `width: 100%`:\n\n```tsx\ncontent={\n  <>\n    {overlayItems.map((item) => (\n      <div key={item.id} style={{ width: '100%' }}>\n        <BodyS style={{ marginBottom: '8px' }}>{item.label}</BodyS>\n        {item.element}\n      </div>\n    ))}\n  </>\n}\n```\n\n### Итого: полный пример фильтра в Popover\n\n```tsx\nconst popoverRef = useRef<HTMLDivElement>(null);\n\n<FiltersActions.FiltersButtonWithPopover\n  popoverProps={{ ref: popoverRef }}\n  title=\"Фильтры\"\n  content={\n    <div style={{ width: '100%' }}>\n      <BodyS style={{ marginBottom: '8px' }}>Блок</BodyS>\n      <FiltersActions.TooltipList\n        groupLabel=\"Блок\"\n        fullWidth\n        frame={popoverRef}\n        items={selectedBlockLabels}\n        trigger={blocks.length > 0 ? 'hover' : 'none'}\n      >\n        <div style={{ width: '100%' }}>\n          <Combobox\n            size=\"s\"\n            multiple\n            value={blocks}\n            onChange={setBlocks}\n            items={blockOptions}\n            portal={popoverRef}\n            zIndex=\"9001\"\n          />\n        </div>\n      </FiltersActions.TooltipList>\n    </div>\n  }\n/>\n```\n\n## Хук `useFiltersList`\n\nБазовый хук для управления списком активных фильтров. Принимает текущие значения фильтров, метаинформацию и опции — возвращает готовый список для отображения в `FiltersActions.ListOfFilters`, а также функцию сброса.\n\n```tsx\nconst { filterList, filterListOpened, clearAll } = useFiltersList({\n  filters,\n  filtersInfo: {\n    search: { label: 'Поиск', clearedValue: '' },\n    blocks: { label: 'Блок', clearedValue: [] },\n    tribes: { label: 'Трайб', clearedValue: [] },\n    allocation: { label: 'Аллокация', clearedValue: '' },\n  },\n  options: {\n    blocks: blocksOptions,\n    tribes: tribesOptions,\n    allocation: allocationOptions,\n  },\n  updateFilters: (key, newValue) => updateFilters({ [key]: newValue }),\n  order: ['switcher'], // опционально: порядок отображения групп\n});\n```\n\n**Параметры:**\n\n- **`filters`** — объект с текущими значениями фильтров (`Record<FilterKey, unknown>`)\n- **`filtersInfo`** — метаинформация: `label` (отображаемое имя группы) и `clearedValue` (значение при сбросе)\n- **`options`** — массивы `{ label, value }` для каждого фильтра (используются для маппинга value → label)\n- **`updateFilters`** — колбек для обновления конкретного фильтра\n- **`order`** — порядок отображения групп: массив ключей, функция сортировки или `'default'`\n\n**Возвращает:**\n\n- **`filterList`** — массив групп с элементами (для передачи в `ListOfFilters`)\n- **`filterListOpened`** — `true`, если есть хотя бы один активный фильтр\n- **`clearAll`** — функция сброса всех фильтров в `clearedValue`\n\n### Резюме\n\n- **FiltersActions** — набор строительных блоков\n- **`useFiltersList`** — хук для управления списком активных фильтров\n- **Адаптивность** — опциональная, реализуется на стороне проекта\n- **`onResize`** — для получения размеров контейнера\n- **`useAdaptiveFilters`** — пример хука для управления брейкпоинтами\n- **Контент Popover** — ответственность проекта\n- **`buttonProps`** — кастомизация кнопки-таргета Popover\n- **`renderTarget`** — полная замена таргета Popover своим элементом (с сохранением открытия и красной точки)\n\n---\n\nОписание compound-компонентов и информация о ренейминге — в разделе [API](/docs/композиции-filtersactions-api--docs).",
      "apiDocs": "# FiltersActions API\n\nКомпонент `FiltersActions` построен на основе **compound-паттерна**. Корневой компонент предоставляет набор вложенных компонентов для сборки панели фильтров.\n\n## FiltersActionsProps\n\n```typescript\ntype FiltersActionsProps = {\n  /**\n   * блок фильтров и табов\n   *   */\n  mainBlock?: React.ReactNode;\n\n  /**\n   * блок активных действий\n   *   */\n  activeButtonsBlock?: React.ReactNode;\n\n  /**\n   * блок списка примененных фильтров\n   * */\n  listOfFilters?: React.ReactNode;\n\n  /**\n   * пропс для ширины для дочерних элементов - слева направо (Например, \"auto 30% 30%\")\n   *   */\n  mainBlockElementsWidth?: string;\n\n  /**\n   * пропсы для контейнера всего компонента\n   *   */\n  containerProps?: BoxProps;\n\n  /**\n   * пропсы для контейнера блока фильтров и табов\n   *   */\n  mainBlockProps?: BoxProps;\n  /**\n   * Колбэк, вызываемый при изменении размеров блоков\n   * Получает актуальные размеры контейнера, mainBlock и buttonsBlock\n   */\n  onResize?: (dimensions: FiltersActionsResizeDimensions) => void;\n};\n```\n\n## FiltersActionsResizeDimensions\n\n```typescript\ninterface FiltersActionsResizeDimensions {\n  /** Полная ширина контейнера */\n  containerWidth: number;\n  /** Ширина левого блока (mainBlock) - вычисляется как containerWidth - buttonsBlockWidth - gap */\n  mainBlockWidth: number;\n  /** Ширина правого блока (activeButtonsBlock), 0 если блок отсутствует */\n  buttonsBlockWidth: number;\n  /** Доступная ширина для элементов mainBlock (за вычетом padding и gap) */\n  availableMainBlockWidth: number;\n}\n```\n\n## Compound-компоненты\n\n### FiltersActions.FiltersButton\n\nКнопка фильтра. Наследует пропсы `Button` из `@salutejs/sdds-finai`.\n\n```typescript\ntype FiltersActionsFiltersButtonProps = ButtonCompProps & {\n  redSquare?: boolean;\n  hideLabel?: boolean;\n  iconSize?: ComponentProps<typeof Icon>['size'];\n};\n```\n\n### FiltersActions.FiltersButtonWithPopover\n\nКнопка с Popover для содержимого фильтра.\n\n```typescript\ntype FiltersActionsFiltersButtonWithPopoverProps = {\n  /** Заголовок Popover */\n  title: string;\n  /** Подзаголовок (опционально) */\n  subtitle?: string;\n  /** Основной контент для отображения */\n  content?: React.ReactNode;\n  /** Внешнее состояние открытия/закрытия [isOpen, setIsOpen] */\n  state?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /** Callback при закрытии */\n  onClose?: () => void;\n  /** Контент footer (опционально) */\n  footer?: React.ReactNode;\n  /** Красный индикатор на кнопке фильтров */\n  redSquare?: boolean;\n  /**\n   * Включить поиск\n   */\n  searchable?: boolean;\n  /**\n   * Значение поиска (контролируемый режим)\n   */\n  searchValue?: string;\n  /**\n   * Callback изменения поискового запроса\n   */\n  onSearchChange?: (value: string) => void;\n  /**\n   * Пропсы для поля поиска\n   */\n  searchingProps?: Pick<\n    TextFieldProps,\n    | 'placeholder'\n    | 'onBlur'\n    | 'onFocus'\n    | 'contentLeft'\n    | 'contentRight'\n    | 'textBefore'\n    | 'textAfter'\n    | 'name'\n    | 'type'\n    | 'minLength'\n    | 'maxLength'\n  >;\n  /**\n   * Контент отображаемый когда ничего не найдено\n   */\n  emptySearchContent?: React.ReactNode;\n  /**\n   * Пропсы для popover\n   */\n  popoverProps?: Omit<CompPopoverProps, 'opened' | 'target' | 'onToggle'>;\n  /** Пропсы для кнопки-таргета FiltersActionsFiltersButton. onClick декорируется: сначала вызовется внешний, потом внутренний toggle. */\n  buttonProps?: Partial<FiltersActionsFiltersButtonProps>;\n  /**\n   * Рендер-проп для полной замены кнопки-таргета Popover собственным элементом\n   * (иконкой, кнопкой, любым узлом) — при сохранении нативной логики открытия\n   * Popover и красной точки-индикатора. Когда задан, `buttonProps` и дефолтная\n   * кнопка «Ещё фильтры» игнорируются.\n   *\n   * ВАЖНО: повесьте переданный `onClick` на корневой кликабельный элемент вашего\n   * таргета. Для красной точки оберните таргет в контейнер с `position: relative`\n   * и отрендерьте `<RedDot visible={isRedDotVisible} />`.\n   *\n   * @example\n   * renderTarget={({ onClick, isRedDotVisible, RedDot }) => (\n   *   <IconButton onClick={onClick} style={{ position: 'relative' }}>\n   *     <IconSettingsFilter />\n   *     <RedDot visible={isRedDotVisible} />\n   *   </IconButton>\n   * )}\n   */\n  renderTarget?: (api: FilterTargetRenderApi) => React.ReactElement;\n};\n```\n\n#### FilterTargetRenderApi\n\nАргумент рендер-пропа `renderTarget` — «рычаги» для сборки собственного таргета Popover (иконки, кнопки, любого элемента) с сохранением логики открытия и красной точки-индикатора. Подробнее — в разделе Docs, «Кастомный таргет Popover».\n\n```typescript\ntype FilterTargetRenderApi = {\n  /**\n   * Обработчик открытия/закрытия Popover. Повесьте его на `onClick` корневого\n   * кликабельного элемента вашего таргета — иначе Popover не будет открываться.\n   */\n  onClick: (event?: React.MouseEvent) => void;\n  /** Открыт ли Popover сейчас — удобно для смены вида таргета в активном состоянии. */\n  isOpen: boolean;\n  /**\n   * Нужно ли показывать красную точку-индикатор (значение пропа `redSquare`).\n   * Передайте в `<RedDot visible={isRedDotVisible} />`.\n   */\n  isRedDotVisible: boolean;\n  /**\n   * Компонент красной точки-индикатора. Позиционируется абсолютно в правый\n   * верхний угол ближайшего контейнера с `position: relative`.\n   */\n  RedDot: typeof RedDot;\n};\n```\n\n### FiltersActions.RedDot\n\nКрасная точка-индикатор активных фильтров. Позиционируется абсолютно в правом верхнем углу контейнера с `position: relative`. Приходит в `renderTarget` (поле `RedDot`), но доступна и как `FiltersActions.RedDot` для использования на своём таргете.\n\n```typescript\ntype RedDotProps = {\n  /** Показывать ли точку. Обычно прокидывается из `isRedDotVisible` рендер-API. */\n  visible?: boolean;\n  /**\n   * Смещение точки от правого верхнего угла контейнера (top/right).\n   * По умолчанию `0` — точка прижата к углу.\n   */\n  offset?: string | number;\n};\n```\n\n### FiltersActions.DotsIconButton\n\nКнопка-иконка «три точки» с выпадающим меню. Наследует пропсы `IconButton` из `@salutejs/sdds-finai`.\n\n```typescript\ntype FiltersActionsDotsIconButtonProps = ComponentProps<\n  typeof IconButton\n> & {\n  /** Пропсы выпадающего меню */\n  dropdownProps?: ComponentProps<typeof Dropdown>;\n  /** Размер иконки */\n  iconSize?: ComponentProps<typeof Icon>['size'];\n};\n```\n\n### FiltersActions.ListOfFilters\n\nСписок применённых фильтров (чипы).\n\n```typescript\ntype ListOfFiltersProps = {\n  opened: boolean;\n  clearAll: () => void;\n  items: ItemOrGroup[];\n  size?: 'xs';\n  paddingTop?: number;\n  /**\n   * @default maxLengthInGroup=2\n   */\n  maxLengthInGroup?: number;\n  /**\n   * Обрезает название группы фильтров в одну строку с троеточием.\n   * @default false\n   */\n  ellipsisLabel?: boolean;\n  sizeOnOpen?: number;\n  leftSlot?: ReactNode;\n  paddingInline?: number;\n  maxHeight?: number;\n  extraCss?: React.CSSProperties;\n  chipStyle?: (itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject;\n  renderGroupLabel?: (group: Group) => string;\n  renderChipLabel?: (group: Group | null, item: Item) => string;\n  /**\n   * Показывать ли кнопку \"Сбросить все\" в блоке примененных фильтров\n   * @default true\n   */\n  showResetAllFiltersButton?: boolean;\n};\n```\n\n### FiltersActions.TextFieldSearch\n\nПоле поиска. Наследует пропсы `TextField` из `@salutejs/sdds-finai`.\n\n```typescript\ntype TextFieldSearchProps = ComponentProps<typeof TextField> &\n  TextFieldSearchBaseProps;\n```\n\n### FiltersActions.Tabs\n\nКонтейнер табов. Наследует пропсы `Tabs` из `@salutejs/sdds-finai`. Размер по умолчанию: `xs`, вид: `filled`.\n\n```typescript\ntype FiltersActionsTabsProps = TabsProps & {\n  /** Кастомные стили */\n  $css?: CSSObject | TemplateStringsArray;\n};\n```\n\n### FiltersActions.TabItem\n\nЭлемент таба. Наследует пропсы `TabItem` из `@salutejs/sdds-finai`. Размер по умолчанию: `s`, вид: `default`.\n\n```typescript\ntype FiltersActionsTabItemProps = TabItemProps & {\n  /** Кастомные стили */\n  $css?: CSSObject | TemplateStringsArray;\n};\n```\n\n### FiltersActions.SegmentItem\n\nЭлемент сегмента. Наследует пропсы `SegmentItem` из `@salutejs/sdds-finai`. Размер по умолчанию: `s`, вид: `default`.\n\n```typescript\ntype FiltersActionsSegmentItemProps = SegmentItemProps & {\n  /** Кастомные стили */\n  $css?: CSSObject | TemplateStringsArray;\n};\n```\n\n### FiltersActions.TooltipList\n\nТултип со списком элементов. Наследует пропсы `Tooltip` из `@salutejs/sdds-finai` (кроме `text` и `children`).\n\n```typescript\ninterface FiltersActionsTooltipProps\n  extends Omit<TooltipProps, 'text' | 'children'> {\n  groupLabel?: string;\n  items: string[];\n  children: React.ReactNode;\n}\n```\n\n### FiltersActions.ResetAllFiltersButton\n\nКнопка «Сбросить все фильтры». Наследует пропсы `LinkButton` из `@salutejs/sdds-finai`.\n\n```typescript\ntype ResetAllFiltersButtonProps = LinkButtonCompProps & {\n  /** Видимость кнопки */\n  isVisible?: boolean;\n  /** Кастомные стили */\n  $css?: CSSObject | TemplateStringsArray;\n};\n```\n\n### FiltersActions.SwitcherFilter\n\nПереключатель-фильтр. Наследует пропсы `Switch` из `@salutejs/sdds-finai`.\n\n```typescript\ntype SwitcherFilterProps = SwitchProps;\n```\n\n## Ренейминг\n\nВ целях улучшения читаемости и единообразия именования некоторые compound-компоненты были переименованы.\n\n**Обратная совместимость сохранена** — старые имена продолжают работать. Оба варианта ссылаются на один и тот же компонент. Рекомендуем использовать новые имена:\n\n- `FiltersActions.FilterPopover` → `FiltersActions.FiltersButtonWithPopover`\n- `FiltersActions.Tooltip` → `FiltersActions.TooltipList`\n\n```diff\n- <FiltersActions.FilterPopover\n+ <FiltersActions.FiltersButtonWithPopover\n    content={...}\n    footer={...}\n    buttonProps={{ hideLabel: true }}\n  />\n\n- <FiltersActions.Tooltip ... />\n+ <FiltersActions.TooltipList ... />\n```",
      "curatedStories": [
        {
          "exportName": "FilterActionsStory",
          "displayName": "FiltersActions с адаптивностью",
          "type": "full-code",
          "code": "import {\n      IconChevronLeft,\n      IconChevronRight,\n      Avatar,\n      SplitView,\n      backgroundPrimary,\n      Badge,\n      Button,\n      ColumnConfig,\n      Flow,\n      H2,\n      IconButton,\n      s,\n      Table,\n      Widget,\n      useDebouncedValue\n    } from '@daisforge/ui';\n    import React, { useMemo, useState } from 'react';\n\n    type Filters = {\n      searchedV: string;\n      switcher: boolean;\n      blocks: string[];\n      tribes: string[];\n      allocation: string;\n      brics: string[];\n    };\n\n    const filtersReducer = (\n      state: Filters,\n      newState: Partial<Filters>\n    ): Filters => ({\n      ...state,\n      ...newState,\n    });\n\n    const DEFAULT_FILTERS: Filters = {\n      searchedV: '',\n      switcher: false,\n      blocks: [],\n      tribes: [],\n      allocation: '',\n      brics: [],\n    };\n\n    const LABELS: { [key in keyof Filters]: string } = {\n      searchedV: 'Поиск',\n      blocks: 'Блок',\n      tribes: 'Трайб',\n      allocation: 'Аллокация',\n      switcher: 'Switcher filter',\n      brics: 'Брикс',\n    };\n\n\n    const COMBOBOX_MODIFICATION = {\n      width: '168px',\n      style: {\n        flexShrink: 0, // Чтобы блок combobox не сжимался\n      },\n    };\n\n    const SEARCH_MODIFICATION = {\n      width: 'auto',\n      style: {\n        minWidth: '168px',\n        maxWidth: '700px',\n        flex: 1,\n      },\n    };\n\n    const SegmentContentStyled = styled.div({\n      backgroundColor: 'pink',\n      borderRadius: borderRadiusS,\n      minHeight: 400,\n      padding: 16,\n      marginTop: 16,\n    });\n\n    ${getFuncAsString(\n      'packages/storybook/src/stories/FiltersActions/FiltersActions.stories.tsx',\n      'SegmentContentWrapper',\n    )}\n\n() => {\n    const [filters, updateFilters] = useReducer(\n      filtersReducer,\n      DEFAULT_FILTERS,\n    );\n    const [dimensions, setDimensions] =\n      useState<FiltersActionsResizeDimensions>({\n        containerWidth: 0,\n        mainBlockWidth: 0,\n        buttonsBlockWidth: 0,\n        availableMainBlockWidth: 0,\n      });\n    const stateAndSetterPopoverFilterOpened = useState(false);\n    const [searchQueryInPopover, setSearchQueryInPopover] = useState('');\n    const debouncedSearchQueryInPopover = useDebouncedValue(\n      searchQueryInPopover,\n      300,\n    );\n\n    /**\n     * Реф контейнера поповера с фильтрами. Нужен для того, чтобы тултип и выпадающие списки\n     * Combobox, которые будут отображаться в popover могли получить контейнер, где им отрисовываться\n     */\n    const popoverRef = useRef<HTMLDivElement>(null);\n\n    // Опции для combobox'ов\n    const blocksOptions = useFetch('blocks', 10);\n    const tribesOptions = useFetch('tribes', 10);\n    const allocationOptions = useFetch('allocation', 10);\n    const bricsOptions = useFetch('brics', 10);\n\n    // Обработчик Resize блока фильтров\n    const handleResize = useCallback(\n      (newDimensions: FiltersActionsResizeDimensions) => {\n        setDimensions(newDimensions);\n      },\n      [setDimensions],\n    );\n\n    // Работа с фильтрами\n    const { filterList, filterListOpened, clearAll } = useFiltersList({\n      filters,\n      options: {\n        blocks: blocksOptions,\n        tribes: tribesOptions,\n        allocation: allocationOptions,\n        brics: bricsOptions,\n      } as Record<keyof Filters, { label: string; value: string }[]>,\n      updateFilters: (key, newV) => updateFilters({ [key]: newV }),\n      filtersInfo: {\n        searchedV: { label: 'Поиск', clearedValue: '' },\n        switcher: { label: 'Чекбокс', clearedValue: false },\n        blocks: { label: 'Блок', clearedValue: [] },\n        tribes: { label: 'Трайб', clearedValue: [] },\n        allocation: { label: 'Аллокация', clearedValue: '' },\n        brics: { label: 'Брикс', clearedValue: [] },\n      },\n      order: ['switcher'], // Первым отображаются switch кнопки\n    });\n\n    // Массив элементов левой части\n    const allLeftItems: FilterItem[] = useMemo(\n      () => [\n        // 1. Сегменты\n        {\n          id: 'segments',\n          element: (\n            <SegmentGroup\n              hasBackground\n              size=\"xs\"\n              style={{ marginRight: '8px' }}\n            >\n              {Array(3)\n                .fill(0)\n                .map((_, i) => (\n                  <FiltersActions.SegmentItem\n                    key={`item:${i}`}\n                    value={`item_${i}`}\n                    label={`Сегмент${i + 1}`}\n                  />\n                ))}\n            </SegmentGroup>\n          ),\n        },\n\n        // 2. Поиск\n        {\n          id: 'search',\n          element: (\n            <TextFieldSearch\n              value={filters.searchedV}\n              onChange={(e) => updateFilters({ searchedV: e.target.value })}\n              autoComplete=\"off\"\n              style={{ marginRight: '8px' }}\n            />\n          ),\n        },\n\n        // 3. Чекбокс/Switcher\n        {\n          id: 'switcher',\n          element: (\n            <FiltersActions.SwitcherFilter\n              checked={filters.switcher}\n              label=\"Активные\"\n              onChange={(e) => updateFilters({ switcher: e.target.checked })}\n            />\n          ),\n          metadata: {\n            // Можно использовать для поиска элемента в массиве overlayItems при включенном поиске в Popover\n            labelForSearchingInPopover: 'switcher',\n          },\n        },\n\n        // 4. Combobox 1 (множественный выбор)\n        {\n          id: 'blocks',\n          element: (\n            <FiltersActions.TooltipList\n              groupLabel=\"Блок\"\n              fullWidth\n              items={filters.blocks\n                .map((item) => {\n                  const option = blocksOptions.find(\n                    (opt) => opt.value === item,\n                  );\n                  return option?.label;\n                })\n                .filter((label): label is string => Boolean(label))}\n              trigger={filters.blocks.length > 0 ? 'hover' : 'none'}\n              mouseEnterDelay={750}\n              frame={popoverRef} // Важно\n            >\n              <div\n                style={{\n                  width: '100%',\n                }}\n              >\n                <Combobox\n                  placeholder=\"Placeholder\"\n                  isTargetAmount\n                  size=\"s\"\n                  multiple\n                  value={filters.blocks}\n                  onChange={(v) => updateFilters({ blocks: v })}\n                  items={blocksOptions}\n                  listMaxHeight=\"350px\"\n                  portal={popoverRef} // Важно\n                  zIndex=\"9001\" // Важно\n                />\n              </div>\n            </FiltersActions.TooltipList>\n          ),\n          metadata: {\n            // Можно использовать для заголовков фильтров в Popover\n            labelInPopoverFilter: 'Blocks',\n            // Можно использовать для поиска элемента в массиве overlayItems при включенном поиске в Popover\n            labelForSearchingInPopover: 'blocks',\n          },\n        },\n\n        // 5. Combobox 2 (множественный выбор)\n        {\n          id: 'tribes',\n          element: (\n            <FiltersActions.TooltipList\n              groupLabel=\"Трайб\"\n              fullWidth\n              items={filters.tribes\n                .map((item) => {\n                  const option = tribesOptions.find(\n                    (opt) => opt.value === item,\n                  );\n                  return option?.label;\n                })\n                .filter((label): label is string => Boolean(label))}\n              trigger={filters.tribes.length > 0 ? 'hover' : 'none'}\n              mouseEnterDelay={750}\n              frame={popoverRef} // Важно\n            >\n              {/* Важно делать обертку для регулирования ширины Combobox. Подробнее: https://plasma.sberdevices.ru/sdds-finai/components/combobox/ */}\n              <div\n                style={{\n                  width: '100%',\n                }}\n              >\n                <Combobox\n                  placeholder=\"Placeholder\"\n                  isTargetAmount\n                  size=\"s\"\n                  multiple\n                  value={filters.tribes}\n                  onChange={(v) => updateFilters({ tribes: v })}\n                  items={tribesOptions}\n                  listMaxHeight=\"350px\"\n                  portal={popoverRef} // Важно\n                  zIndex=\"9001\" // Важно\n                />\n              </div>\n            </FiltersActions.TooltipList>\n          ),\n          // Можно использовать для заголовков фильтров в Popover\n          metadata: {\n            labelInPopoverFilter: 'Tribes',\n            // Можно использовать для поиска элемента в массиве overlayItems при включенном поиске в Popover\n            labelForSearchingInPopover: 'tribes',\n          },\n        },\n\n        // 6. Combobox 3 (одиночный выбор)\n        {\n          id: 'allocation',\n          element: (\n            <Combobox\n              placeholder=\"Placeholder\"\n              size=\"s\"\n              value={filters.allocation}\n              onChange={(v) => updateFilters({ allocation: v })}\n              items={allocationOptions}\n              listMaxHeight=\"350px\"\n              portal={popoverRef}\n              zIndex=\"9001\"\n            />\n          ),\n          // Можно использовать для заголовков фильтров в Popover\n          metadata: {\n            labelInPopoverFilter: 'Allocation',\n            // Можно использовать для поиска элемента в массиве overlayItems при включенном поиске в Popover\n            labelForSearchingInPopover: 'allocation',\n          },\n        },\n\n        // 5. Combobox 4 (множественный выбор)\n        {\n          id: 'brics',\n          element: (\n            <FiltersActions.TooltipList\n              groupLabel=\"Брикс\"\n              fullWidth\n              items={filters.brics\n                .map((item) => {\n                  const option = bricsOptions.find((opt) => opt.value === item);\n                  return option?.label;\n                })\n                .filter((label): label is string => Boolean(label))}\n              trigger={filters.brics.length > 0 ? 'hover' : 'none'}\n              mouseEnterDelay={750}\n              frame={popoverRef} // Важно\n            >\n              {/* Важно делать обертку дл регулирования ширины Combobox. Подробнее: https://plasma.sberdevices.ru/sdds-finai/components/combobox/ */}\n              <div\n                style={{\n                  width: '100%',\n                }}\n              >\n                <Combobox\n                  placeholder=\"Placeholder\"\n                  isTargetAmount\n                  size=\"s\"\n                  multiple\n                  value={filters.brics}\n                  onChange={(v) => updateFilters({ brics: v })}\n                  items={bricsOptions}\n                  listMaxHeight=\"350px\"\n                  portal={popoverRef} // Важно\n                  zIndex=\"9001\" // Важно\n                />\n              </div>\n            </FiltersActions.TooltipList>\n          ),\n          // Можно использовать для заголовков фильтров в Popover\n          metadata: {\n            labelInPopoverFilter: 'Brics',\n            // Можно использовать для поиска элемента в массиве overlayItems при включенном поиске в Popover\n            labelForSearchingInPopover: 'brics',\n          },\n        },\n\n        // 7. Кнопка \"Сбросить все\"\n        {\n          id: 'resetButton',\n          element: (\n            <FiltersActions.ResetAllFiltersButton\n              isVisible={filterList.length > 0}\n              onClick={clearAll}\n              disabled={filterList.length === 0}\n            />\n          ),\n        },\n      ],\n      [\n        filters.searchedV,\n        filters.switcher,\n        filters.blocks,\n        filters.tribes,\n        filters.allocation,\n        filters.brics,\n        bricsOptions,\n        blocksOptions,\n        tribesOptions,\n        allocationOptions,\n        filterList.length,\n        clearAll,\n      ],\n    );\n\n    // Конфигурация брейкпоинтов для адаптивности\n    const breakpointsConfig: Record<number, AdaptiveFiltersBreakpointConfig> =\n      useMemo(\n        () => ({\n          // >= 1754px: Все элементы видны\n          1754: {\n            visible: [\n              'segments',\n              'search',\n              'switcher',\n              'blocks',\n              'tribes',\n              'allocation',\n              'resetButton',\n            ],\n            inOverlay: ['brics'],\n            modifications: {\n              segments: { width: 'auto' },\n              search: SEARCH_MODIFICATION,\n              blocks: COMBOBOX_MODIFICATION,\n              tribes: COMBOBOX_MODIFICATION,\n              allocation: COMBOBOX_MODIFICATION,\n            },\n            customActions: {\n              secondaryButtonVisible: true,\n              resetInPopoverFooter: false,\n            },\n          },\n\n          // >= 1578px: allocation в popup\n          1578: {\n            visible: [\n              'segments',\n              'search',\n              'switcher',\n              'blocks',\n              'tribes',\n              'resetButton',\n            ],\n            inOverlay: ['brics', 'allocation'],\n            modifications: {\n              segments: { width: 'auto' },\n              search: SEARCH_MODIFICATION,\n              blocks: COMBOBOX_MODIFICATION,\n              tribes: COMBOBOX_MODIFICATION,\n              allocation: COMBOBOX_MODIFICATION,\n            },\n            customActions: {\n              secondaryButtonVisible: true,\n              resetInPopoverFooter: false,\n            },\n          },\n\n          // >= 1486px: tribes в popup\n          1486: {\n            visible: [\n              'segments',\n              'search',\n              'switcher',\n              'blocks',\n              'resetButton',\n            ],\n            inOverlay: ['tribes', 'allocation', 'brics'],\n            modifications: {\n              segments: { width: 'auto' },\n              search: SEARCH_MODIFICATION,\n              blocks: COMBOBOX_MODIFICATION,\n              tribes: COMBOBOX_MODIFICATION,\n              allocation: COMBOBOX_MODIFICATION,\n            },\n            customActions: {\n              secondaryButtonVisible: true,\n              resetInPopoverFooter: false,\n            },\n          },\n\n          // >= 1260px: blocks в popup\n          1260: {\n            visible: ['segments', 'search', 'switcher', 'resetButton'],\n            inOverlay: ['blocks', 'tribes', 'allocation', 'brics'], // ← blocks в popup\n            modifications: {\n              segments: { width: 'auto' },\n              search: SEARCH_MODIFICATION,\n              blocks: COMBOBOX_MODIFICATION,\n              tribes: COMBOBOX_MODIFICATION,\n              allocation: COMBOBOX_MODIFICATION,\n            },\n            customActions: {\n              secondaryButtonVisible: true,\n              resetInPopoverFooter: false,\n            },\n          },\n\n          // >= 1068px: switcher в popup\n          1068: {\n            visible: ['segments', 'search', 'resetButton'],\n            inOverlay: ['switcher', 'blocks', 'tribes', 'allocation', 'brics'], // ← switcher в popup\n            modifications: {\n              segments: { width: 'auto' },\n              search: SEARCH_MODIFICATION,\n              blocks: COMBOBOX_MODIFICATION,\n              tribes: COMBOBOX_MODIFICATION,\n              allocation: COMBOBOX_MODIFICATION,\n            },\n            customActions: {\n              secondaryButtonVisible: true,\n              resetInPopoverFooter: false,\n            },\n          },\n\n          // >= 960px: ResetButton в footer popover\n          960: {\n            visible: ['segments', 'search'],\n            inOverlay: ['switcher', 'blocks', 'allocation', 'tribes', 'brics'],\n            hidden: ['resetButton'], // ← Технически скрыт из main, будет в footer popover\n            modifications: {\n              segments: { width: 'auto' },\n              search: SEARCH_MODIFICATION,\n              blocks: COMBOBOX_MODIFICATION,\n              tribes: COMBOBOX_MODIFICATION,\n              allocation: COMBOBOX_MODIFICATION,\n            },\n            customActions: {\n              secondaryButtonVisible: true,\n              resetInPopoverFooter: true, // ← ResetButton в footer popover\n            },\n          },\n\n          // >= 960px: Вторая secondary кнопка cкрывается в dropdown\n          0: {\n            visible: ['segments', 'search'],\n            inOverlay: ['switcher', 'blocks', 'tribes', 'allocation', 'brics'],\n            hidden: ['resetButton'], // ← Технически скрыт из main, будет в footer popover\n            modifications: {\n              segments: { width: 'auto' },\n              search: SEARCH_MODIFICATION,\n              blocks: COMBOBOX_MODIFICATION,\n              tribes: COMBOBOX_MODIFICATION,\n              allocation: COMBOBOX_MODIFICATION,\n            },\n            customActions: {\n              secondaryButtonVisible: false,\n              resetInPopoverFooter: true, // ← ResetButton в footer popover\n            },\n          },\n        }),\n        [],\n      );\n\n    // Адаптивность\n    const {\n      visibleItems,\n      overlayItems,\n      modifications,\n      customActions,\n      hiddenItems,\n      getItemStyle,\n      hasActiveFilters,\n    } = useAdaptiveFilters({\n      items: allLeftItems,\n      width: dimensions.availableMainBlockWidth,\n      breakpoints: breakpointsConfig,\n    });\n\n    // Проверяем активные фильтры в popup\n    const hasActiveFilterInPopover = hasActiveFilters(overlayItems, filters);\n\n    // Определяем видимость второстепенной кнопки\n    const secondaryButtonVisible = customActions.secondaryButtonVisible ?? true;\n    const resetInPopoverFooter = customActions.resetInPopoverFooter ?? false;\n\n    const resetButtonItem = resetInPopoverFooter\n      ? hiddenItems.find((item) => item.id === 'resetButton')\n      : visibleItems.find((item) => item.id === 'resetButton');\n\n    const visibleItemsWithoutResetFilterButton = visibleItems.filter(\n      (item) => item.id !== 'resetButton',\n    );\n\n    // Фильтрация элементов по поиску в Popover\n    const filteredOverlayItems = useMemo(() => {\n      if (!debouncedSearchQueryInPopover.trim()) return overlayItems;\n      const query = debouncedSearchQueryInPopover.toLowerCase();\n      return overlayItems.filter((item) =>\n        item?.metadata?.labelForSearchingInPopover\n          ?.toLowerCase()\n          ?.includes(query),\n      );\n    }, [overlayItems, debouncedSearchQueryInPopover]);\n\n    // Элементы для dropdown (блок справа)\n    const dropdownItems = useMemo(() => {\n      const items = [\n        { value: 'action1', label: 'Действие 1' },\n        { value: 'action2', label: 'Действие 2' },\n      ];\n\n      // Если второстепенная кнопка скрыта - добавляем в dropdown\n      if (!secondaryButtonVisible) {\n        items.push({\n          value: 'secondary',\n          label: 'Согласовать (второстепенное)',\n        });\n      }\n\n      return items;\n    }, [secondaryButtonVisible]);\n\n    const renderActiveButtonsBlock = useCallback(\n      () => (\n        <>\n          {/* Кнопка с троеточием */}\n          <FiltersActions.DotsIconButton\n            dropdownProps={{\n              items: dropdownItems,\n            }}\n            iconOrientation=\"vertical\"\n          />\n\n          {/* Второстепенная кнопка (скрывается при < 600px) */}\n          {secondaryButtonVisible && (\n            <Button size=\"s\" view=\"secondary\">\n              Согласовать\n            </Button>\n          )}\n\n          {/* Целевая кнопка - всегда видна */}\n          <Button size=\"s\" view=\"accent\">\n            Создать\n          </Button>\n        </>\n      ),\n      [secondaryButtonVisible, dropdownItems],\n    );\n\n    return (\n      <SegmentProvider defaultSelected={['item_0']}>\n        {/* Индикатор состояния */}\n        <div\n          style={{\n            marginBottom: 16,\n            padding: 12,\n            backgroundColor: '#f0f0f0',\n            borderRadius: 8,\n            fontFamily: 'monospace',\n            fontSize: '12px',\n            minHeight: '146px',\n          }}\n        >\n          <div>\n            <strong>📐 Размеры:</strong>\n          </div>\n          <div>\n            Available width: {Math.round(dimensions.availableMainBlockWidth)}px\n          </div>\n          <div style={{ marginTop: 8 }}>\n            <strong>✅ Видимые:</strong>{' '}\n            {visibleItems.map((i) => i.id).join(', ')}\n          </div>\n          {overlayItems.length > 0 && (\n            <div style={{ color: 'orange' }}>\n              <strong>📤 В popover:</strong>{' '}\n              {overlayItems.map((i) => i.id).join(', ')}\n              {hasActiveFilterInPopover && ' 🔴'}\n            </div>\n          )}\n          <div style={{ marginTop: 8 }}>\n            <div style={{ color: secondaryButtonVisible ? 'green' : 'red' }}>\n              🔘 Второстепенная кнопка \"Согласовать\" в правой части:{' '}\n              {secondaryButtonVisible ? 'Видна' : 'В dropdown'}\n            </div>\n            <div style={{ color: resetInPopoverFooter ? 'orange' : 'green' }}>\n              🔄 Reset кнопка:{' '}\n              {resetInPopoverFooter ? 'В footer popover' : 'В mainBlock'}\n            </div>\n          </div>\n        </div>\n\n        <FiltersActions\n          containerProps={{ $css: { maxWidth: 'calc(100vw - 32px)' } }}\n          onResize={handleResize}\n          mainBlock={\n            <>\n              {/* Видимые элементы с модификациями (без кнопки сбросить фильтры, она правее кнопки фильтров) */}\n              {visibleItemsWithoutResetFilterButton.map((item) => {\n                const itemMods = modifications[item.id];\n                const style = getItemStyle(\n                  itemMods,\n                  dimensions.availableMainBlockWidth,\n                );\n\n                return (\n                  <div key={item.id} style={{ ...style }}>\n                    {item.element}\n                  </div>\n                );\n              })}\n\n              {/* Popover с фильтрами - кнопка фильтров встроена внутрь */}\n              <FiltersActions.FiltersButtonWithPopover\n                popoverProps={{\n                  // Передаем ref, чтобы Tooltip и Combobox, которые будут в Popover, передать frame и portal\n                  ref: popoverRef,\n                }}\n                state={stateAndSetterPopoverFilterOpened}\n                title=\"Ещё фильтры\"\n                subtitle=\"Какой-то сабтайтл, если нужен.\"\n                redSquare={hasActiveFilterInPopover}\n                searchable\n                searchValue={searchQueryInPopover}\n                onSearchChange={setSearchQueryInPopover}\n                content={\n                  <>\n                    {filteredOverlayItems.map((item) => (\n                      <div key={item.id} style={{ width: '100%' }}>\n                        {item?.metadata?.labelInPopoverFilter && (\n                          <BodyS style={{ marginBottom: '8px' }}>\n                            {item?.metadata?.labelInPopoverFilter}\n                          </BodyS>\n                        )}\n                        {item.element}\n                      </div>\n                    ))}\n                  </>\n                }\n                emptySearchContent={\n                  filteredOverlayItems.length === 0 && searchQueryInPopover ? (\n                    <div>По запросу ничего не найдено</div>\n                  ) : null\n                }\n                footer={\n                  resetInPopoverFooter &&\n                  resetButtonItem &&\n                  hasActiveFilterInPopover ? (\n                    <div\n                      style={{\n                        display: 'flex',\n                        width: '100%',\n                        justifyContent: 'end',\n                      }}\n                    >\n                      {resetButtonItem.element}\n                    </div>\n                  ) : undefined\n                }\n              />\n              {/* Кнопка \"Сбросить фильтры\" за кнопкой фильтров */}\n              {resetButtonItem && !resetInPopoverFooter && (\n                <div>{resetButtonItem.element}</div>\n              )}\n            </>\n          }\n          listOfFilters={\n            <FiltersActions.ListOfFilters\n              clearAll={clearAll}\n              opened={filterListOpened}\n              items={filterList}\n              showResetAllFiltersButton={false}\n            />\n          }\n          activeButtonsBlock={renderActiveButtonsBlock()}\n        />\n        <SegmentContentWrapper />\n      </SegmentProvider>\n    );\n  }"
        },
        {
          "exportName": "SimpleFiltersActionsStory",
          "displayName": "FiltersActions без адаптивности",
          "type": "full-code",
          "code": "import { createRows, type Row } from './tableData';\n    import {\n      IconChevronLeft,\n      IconChevronRight,\n      Avatar,\n      SplitView,\n      backgroundPrimary,\n      Badge,\n      Button,\n      ColumnConfig,\n      Flow,\n      H2,\n      IconButton,\n      s,\n      Table,\n      Widget,\n    } from '@daisforge/ui';\n    import React, { useMemo, useState } from 'react';\n\n    type Filters = {\n      searchedV: string;\n      switcher: boolean;\n      blocks: string[];\n      tribes: string[];\n      allocation: string;\n      brics: string[];\n    };\n\n    const filtersReducer = (\n      state: Filters,\n      newState: Partial<Filters>\n    ): Filters => ({\n      ...state,\n      ...newState,\n    });\n\n    const DEFAULT_FILTERS: Filters = {\n      searchedV: '',\n      switcher: false,\n      blocks: [],\n      tribes: [],\n      allocation: '',\n      brics: [],\n    };\n\n    const LABELS: { [key in keyof Filters]: string } = {\n      searchedV: 'Поиск',\n      blocks: 'Блок',\n      tribes: 'Трайб',\n      allocation: 'Аллокация',\n      switcher: 'Switcher filter',\n      brics: 'Брикс',\n    };\n\n    const useFetch = (\n      key: 'blocks' | 'tribes' | 'allocation' | 'brics',\n      num = 10\n    ) =>\n      useMemo(\n        () =>\n          Array(num)\n            .fill(0)\n            .map((_, i) => ({\n              label: \\\n\n() => {\n    const [filters, updateFilters] = useReducer(\n      filtersReducer,\n      DEFAULT_FILTERS,\n    );\n    const [popupFilterOpened, setPopupFilterOpened] = useState(false);\n\n    /**\n     * Реф контейнера Popover с фильтрами. Нужен для того, чтобы тултип и выпадающие списки\n     * Combobox, которые будут отображаться в popover могли получить контейнер, где им отрисовываться\n     */\n    const popoverRef = useRef<HTMLDivElement>(null);\n\n    // Опции для combobox'ов\n    const blocksOptions = useFetch('blocks', 10);\n    const tribesOptions = useFetch('tribes', 10);\n    const allocationOptions = useFetch('allocation', 10);\n    const bricsOptions = useFetch('brics', 10);\n\n    // Работа с фильтрами\n    const { filterList, filterListOpened, clearAll } = useFiltersList({\n      filters,\n      options: {\n        blocks: blocksOptions,\n        tribes: tribesOptions,\n        allocation: allocationOptions,\n        brics: bricsOptions,\n      } as Record<keyof Filters, { label: string; value: string }[]>,\n      updateFilters: (key, newV) => updateFilters({ [key]: newV }),\n      filtersInfo: {\n        searchedV: { label: 'Поиск', clearedValue: '' },\n        switcher: { label: 'Чекбокс', clearedValue: false },\n        blocks: { label: 'Блок', clearedValue: [] },\n        tribes: { label: 'Трайб', clearedValue: [] },\n        allocation: { label: 'Аллокация', clearedValue: '' },\n        brics: { label: 'Брикс', clearedValue: [] },\n      },\n      order: ['switcher'], // Первым отображаются switch кнопки\n    });\n\n    // Элементы, которые будут видны статически\n    const visibleItems = useMemo(\n      () => [\n        // 1. Сегменты\n        {\n          id: 'segments',\n          element: (\n            <SegmentGroup\n              hasBackground\n              size=\"xs\"\n              style={{ marginRight: '8px' }}\n            >\n              {Array(3)\n                .fill(0)\n                .map((_, i) => (\n                  <FiltersActions.SegmentItem\n                    key={`item:${i}`}\n                    value={`item_${i}`}\n                    label={`Сегмент ${i + 1}`}\n                  />\n                ))}\n            </SegmentGroup>\n          ),\n        },\n\n        // 2. Поиск\n        {\n          id: 'search',\n          element: (\n            <FiltersActions.TextFieldSearch\n              value={filters.searchedV}\n              onChange={(e) => updateFilters({ searchedV: e.target.value })}\n              autoComplete=\"off\"\n              placeholder=\"Поиск\"\n              style={{ marginRight: '8px' }}\n            />\n          ),\n        },\n\n        // 3. Чекбокс/Switcher\n        {\n          id: 'switcher',\n          element: (\n            <FiltersActions.SwitcherFilter\n              checked={filters.switcher}\n              label=\"Активные\"\n              onChange={(e) => updateFilters({ switcher: e.target.checked })}\n            />\n          ),\n        },\n\n        // 4. Combobox 3 (одиночный выбор)\n        {\n          id: 'allocation',\n          element: (\n            <Combobox\n              size=\"s\"\n              placeholder=\"Allocation\"\n              value={filters.allocation}\n              onChange={(v) => updateFilters({ allocation: v })}\n              items={allocationOptions}\n              listMaxHeight=\"350px\"\n              portal={popoverRef}\n              zIndex=\"9001\"\n            />\n          ),\n        },\n      ],\n      [\n        filters.searchedV,\n        filters.switcher,\n        filters.allocation,\n        allocationOptions,\n      ],\n    );\n\n    // Элементы, которые будут в Popover (последние 3 чекбокса)\n    const popoverItems = useMemo(\n      () => [\n        // 1. Combobox 1 (множественный выбор) - blocks\n        {\n          id: 'blocks',\n          element: (\n            <FiltersActions.TooltipList\n              groupLabel=\"Блок\"\n              fullWidth\n              items={filters.blocks\n                .map((item) => {\n                  const option = blocksOptions.find(\n                    (opt) => opt.value === item,\n                  );\n                  return option?.label;\n                })\n                .filter((label): label is string => Boolean(label))}\n              trigger={filters.blocks.length > 0 ? 'hover' : 'none'}\n              mouseEnterDelay={750}\n              frame={popoverRef} // Важно\n            >\n              {/* Важно делать обертку дл регулирования ширины Combobox. Подробнее: https://plasma.sberdevices.ru/sdds-finai/components/combobox/ */}\n              <div\n                style={{\n                  width: '100%',\n                }}\n              >\n                <Combobox\n                  isTargetAmount\n                  size=\"s\"\n                  multiple\n                  value={filters.blocks}\n                  onChange={(v) => updateFilters({ blocks: v })}\n                  items={blocksOptions}\n                  listMaxHeight=\"350px\"\n                  portal={popoverRef} // Важно\n                  zIndex=\"9001\" // Важно\n                />\n              </div>\n            </FiltersActions.TooltipList>\n          ),\n          metadata: {\n            labelInPopoverFilter: 'Blocks',\n          },\n        },\n\n        // 2. Combobox 2 (множественный выбор) - tribes\n        {\n          id: 'tribes',\n          element: (\n            <FiltersActions.TooltipList\n              groupLabel=\"Трайб\"\n              fullWidth\n              items={filters.tribes\n                .map((item) => {\n                  const option = tribesOptions.find(\n                    (opt) => opt.value === item,\n                  );\n                  return option?.label;\n                })\n                .filter((label): label is string => Boolean(label))}\n              trigger={filters.tribes.length > 0 ? 'hover' : 'none'}\n              mouseEnterDelay={750}\n              frame={popoverRef} // Важно\n            >\n              {/* Важно делать обертку дл регулирования ширины Combobox. Подробнее: https://plasma.sberdevices.ru/sdds-finai/components/combobox/ */}\n              <div\n                style={{\n                  width: '100%',\n                }}\n              >\n                <Combobox\n                  isTargetAmount\n                  size=\"s\"\n                  multiple\n                  value={filters.tribes}\n                  onChange={(v) => updateFilters({ tribes: v })}\n                  items={tribesOptions}\n                  listMaxHeight=\"350px\"\n                  portal={popoverRef} // Важно\n                  zIndex=\"9001\" // Важно\n                />\n              </div>\n            </FiltersActions.TooltipList>\n          ),\n          metadata: {\n            labelInPopoverFilter: 'Tribes',\n          },\n        },\n\n        // 3. Combobox 4 (множественный выбор) - brics\n        {\n          id: 'brics',\n          element: (\n            <FiltersActions.TooltipList\n              groupLabel=\"Брикс\"\n              fullWidth\n              items={filters.brics\n                .map((item) => {\n                  const option = bricsOptions.find((opt) => opt.value === item);\n                  return option?.label;\n                })\n                .filter((label): label is string => Boolean(label))}\n              trigger={filters.brics.length > 0 ? 'hover' : 'none'}\n              mouseEnterDelay={750}\n              frame={popoverRef} // Важно\n            >\n              {/* Важно делать обертку дл регулирования ширины Combobox. Подробнее: https://plasma.sberdevices.ru/sdds-finai/components/combobox/ */}\n              <div\n                style={{\n                  width: '100%',\n                }}\n              >\n                <Combobox\n                  isTargetAmount\n                  size=\"s\"\n                  multiple\n                  value={filters.brics}\n                  onChange={(v) => updateFilters({ brics: v })}\n                  items={bricsOptions}\n                  listMaxHeight=\"350px\"\n                  portal={popoverRef} // Важно\n                  zIndex=\"9001\" // Важно\n                />\n              </div>\n            </FiltersActions.TooltipList>\n          ),\n          metadata: {\n            labelInPopoverFilter: 'Brics',\n          },\n        },\n      ],\n      [\n        filters.blocks,\n        filters.tribes,\n        filters.brics,\n        bricsOptions,\n        blocksOptions,\n        tribesOptions,\n      ],\n    );\n\n    // Проверяем активные фильтры в popover\n    const hasActiveFilterInPopover = popoverItems.some((item) => {\n      if (item.id === 'blocks') return filters.blocks.length > 0;\n      if (item.id === 'tribes') return filters.tribes.length > 0;\n      if (item.id === 'brics') return filters.brics.length > 0;\n      return false;\n    });\n\n    // Элементы для dropdown (блок справа)\n    const dropdownItems = useMemo(\n      () => [\n        { value: 'action1', label: 'Действие 1' },\n        { value: 'action2', label: 'Действие 2' },\n      ],\n      [],\n    );\n\n    const renderActiveButtonsBlock = useCallback(\n      () => (\n        <>\n          {/* Кнопка с троеточием */}\n          <FiltersActions.DotsIconButton\n            dropdownProps={{\n              items: dropdownItems,\n            }}\n            iconOrientation=\"vertical\"\n          />\n\n          {/* Второстепенная кнопка */}\n          <Button size=\"s\" view=\"secondary\">\n            Согласовать\n          </Button>\n\n          {/* Целевая кнопка */}\n          <Button size=\"s\" view=\"accent\">\n            Создать\n          </Button>\n        </>\n      ),\n      [dropdownItems],\n    );\n\n    return (\n      <SegmentProvider defaultSelected={['item_0']}>\n        <FiltersActions\n          mainBlock={\n            <>\n              {/* Видимые элементы */}\n              {visibleItems.map((item) => (\n                <div key={item.id}>{item.element}</div>\n              ))}\n\n              {/* Popover с фильтрами */}\n              <FiltersActions.FilterPopover\n                popoverProps={{\n                  // Передаем ref, чтобы Tooltip и Combobox, которые будут в Popover, передать frame и portal\n                  ref: popoverRef,\n                }}\n                state={[popupFilterOpened, setPopupFilterOpened]}\n                title=\"Дополнительные фильтры\"\n                subtitle=\"Фильтры с множественным выбором\"\n                redSquare={hasActiveFilterInPopover}\n                content={\n                  <>\n                    {popoverItems.map((item) => (\n                      <div\n                        key={item.id}\n                        style={{ width: '100%', marginBottom: '16px' }}\n                      >\n                        <BodyS style={{ marginBottom: '8px' }}>\n                          {item?.metadata?.labelInPopoverFilter}\n                        </BodyS>\n                        {item.element}\n                      </div>\n                    ))}\n                  </>\n                }\n              />\n\n              {/* Кнопка сбросить все */}\n              <FiltersActions.ResetAllFiltersButton\n                isVisible={filterList.length > 0}\n                onClick={clearAll}\n                disabled={filterList.length === 0}\n              />\n            </>\n          }\n          listOfFilters={\n            <FiltersActions.ListOfFilters\n              clearAll={clearAll}\n              opened={filterListOpened}\n              items={filterList}\n              showResetAllFiltersButton={false}\n            />\n          }\n          activeButtonsBlock={renderActiveButtonsBlock()}\n        />\n        <SegmentContentWrapper />\n      </SegmentProvider>\n    );\n  }"
        },
        {
          "exportName": "CustomTargetFiltersActionsStory",
          "displayName": "FiltersActions с кастомным таргетом Popover",
          "type": "full-code",
          "code": "import {\n      FiltersActions,\n      IconButton,\n      IconSettingsFilter,\n      Combobox,\n      BodyS,\n    } from '@daisforge/ui';\n    import React, { useRef, useState } from 'react';\n\n    ${getFuncAsString(\n      'packages/storybook/src/stories/FiltersActions/FiltersActions.stories.tsx',\n      'CustomTargetFiltersExample',\n    )}\n\n() => <CustomTargetFiltersExample />"
        },
        {
          "exportName": "ScrollArrowsAppearWithoutManualScrollStory",
          "displayName": "Список применённых фильтров: стрелки-скролл появляются сами при переполнении",
          "type": "full-code",
          "code": "() => <ScrollArrowsExample />"
        }
      ],
      "hasCuratedMeta": true,
      "relatedExports": [
        "FiltersActionsDotsIconButton",
        "FiltersActionsFiltersButton",
        "FiltersActionsListOfFilters",
        "RedDot",
        "FiltersActionsTabItem",
        "FiltersActionsTabs"
      ],
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FiltersActions } from '@daisforge/ui';",
      "minimalUsage": "<FiltersActions>\n  {/* части: FiltersActions.FiltersButton, FiltersActions.DotsIconButton, FiltersActions.ListOfFilters, FiltersActions.TextFieldSearch, FiltersActions.Tabs, FiltersActions.TabItem, FiltersActions.SegmentItem, FiltersActions.Tooltip, FiltersActions.TooltipList, FiltersActions.FilterPopover, FiltersActions.FiltersButtonWithPopover, FiltersActions.ResetAllFiltersButton, FiltersActions.SwitcherFilter, FiltersActions.RedDot */}\n</FiltersActions>",
      "examples": [
        {
          "exportName": "FilterActionsStory",
          "displayName": "FiltersActions с адаптивностью",
          "type": "full-code",
          "code": "import {\n      IconChevronLeft,\n      IconChevronRight,\n      Avatar,\n      SplitView,\n      backgroundPrimary,\n      Badge,\n      Button,\n      ColumnConfig,\n      Flow,\n      H2,\n      IconButton,\n      s,\n      Table,\n      Widget,\n      useDebouncedValue\n    } from '@daisforge/ui';\n    import React, { useMemo, useState } from 'react';\n\n    type Filters = {\n      searchedV: string;\n      switcher: boolean;\n      blocks: string[];\n      tribes: string[];\n      allocation: string;\n      brics: string[];\n    };\n\n    const filtersReducer = (\n      state: Filters,\n      newState: Partial<Filters>\n    ): Filters => ({\n      ...state,\n      ...newState,\n    });\n\n    const DEFAULT_FILTERS: Filters = {\n      searchedV: '',\n      switcher: false,\n      blocks: [],\n      tribes: [],\n      allocation: '',\n      brics: [],\n    };\n\n    const LABELS: { [key in keyof Filters]: string } = {\n      searchedV: 'Поиск',\n      blocks: 'Блок',\n      tribes: 'Трайб',\n      allocation: 'Аллокация',\n      switcher: 'Switcher filter',\n      brics: 'Брикс',\n    };\n\n\n    const COMBOBOX_MODIFICATION = {\n      width: '168px',\n      style: {\n        flexShrink: 0, // Чтобы блок combobox не сжимался\n      },\n    };\n\n    const SEARCH_MODIFICATION = {\n      width: 'auto',\n      style: {\n        minWidth: '168px',\n        maxWidth: '700px',\n        flex: 1,\n      },\n    };\n\n    const SegmentContentStyled = styled.div({\n      backgroundColor: 'pink',\n      borderRadius: borderRadiusS,\n      minHeight: 400,\n      padding: 16,\n      marginTop: 16,\n    });\n\n    ${getFuncAsString(\n      'packages/storybook/src/stories/FiltersActions/FiltersActions.stories.tsx',\n      'SegmentContentWrapper',\n    )}\n\n() => {\n    const [filters, updateFilters] = useReducer(\n      filtersReducer,\n      DEFAULT_FILTERS,\n    );\n    const [dimensions, setDimensions] =\n      useState<FiltersActionsResizeDimensions>({\n        containerWidth: 0,\n        mainBlockWidth: 0,\n        buttonsBlockWidth: 0,\n        availableMainBlockWidth: 0,\n      });\n    const stateAndSetterPopoverFilterOpened = useState(false);\n    const [searchQueryInPopover, setSearchQueryInPopover] = useState('');\n    const debouncedSearchQueryInPopover = useDebouncedValue(\n      searchQueryInPopover,\n      300,\n    );\n\n    /**\n     * Реф контейнера поповера с фильтрами. Нужен для того, чтобы тултип и выпадающие списки\n     * Combobox, которые будут отображаться в popover могли получить контейнер, где им отрисовываться\n     */\n    const popoverRef = useRef<HTMLDivElement>(null);\n\n    // Опции для combobox'ов\n    const blocksOptions = useFetch('blocks', 10);\n    const tribesOptions = useFetch('tribes', 10);\n    const allocationOptions = useFetch('allocation', 10);\n    const bricsOptions = useFetch('brics', 10);\n\n    // Обработчик Resize блока фильтров\n    const handleResize = useCallback(\n      (newDimensions: FiltersActionsResizeDimensions) => {\n        setDimensions(newDimensions);\n      },\n      [setDimensions],\n    );\n\n    // Работа с фильтрами\n    const { filterList, filterListOpened, clearAll } = useFiltersList({\n      filters,\n      options: {\n        blocks: blocksOptions,\n        tribes: tribesOptions,\n        allocation: allocationOptions,\n        brics: bricsOptions,\n      } as Record<keyof Filters, { label: string; value: string }[]>,\n      updateFilters: (key, newV) => updateFilters({ [key]: newV }),\n      filtersInfo: {\n        searchedV: { label: 'Поиск', clearedValue: '' },\n        switcher: { label: 'Чекбокс', clearedValue: false },\n        blocks: { label: 'Блок', clearedValue: [] },\n        tribes: { label: 'Трайб', clearedValue: [] },\n        allocation: { label: 'Аллокация', clearedValue: '' },\n        brics: { label: 'Брикс', clearedValue: [] },\n      },\n      order: ['switcher'], // Первым отображаются switch кнопки\n    });\n\n    // Массив элементов левой части\n    const allLeftItems: FilterItem[] = useMemo(\n      () => [\n        // 1. Сегменты\n        {\n          id: 'segments',\n          element: (\n            <SegmentGroup\n              hasBackground\n              size=\"xs\"\n              style={{ marginRight: '8px' }}\n            >\n              {Array(3)\n                .fill(0)\n                .map((_, i) => (\n                  <FiltersActions.SegmentItem\n                    key={`item:${i}`}\n                    value={`item_${i}`}\n                    label={`Сегмент${i + 1}`}\n                  />\n                ))}\n            </SegmentGroup>\n          ),\n        },\n\n        // 2. Поиск\n        {\n          id: 'search',\n          element: (\n            <TextFieldSearch\n              value={filters.searchedV}\n              onChange={(e) => updateFilters({ searchedV: e.target.value })}\n              autoComplete=\"off\"\n              style={{ marginRight: '8px' }}\n            />\n          ),\n        },\n\n        // 3. Чекбокс/Switcher\n        {\n          id: 'switcher',\n          element: (\n            <FiltersActions.SwitcherFilter\n              checked={filters.switcher}\n              label=\"Активные\"\n              onChange={(e) => updateFilters({ switcher: e.target.checked })}\n            />\n          ),\n          metadata: {\n            // Можно использовать для поиска элемента в массиве overlayItems при включенном поиске в Popover\n            labelForSearchingInPopover: 'switcher',\n          },\n        },\n\n        // 4. Combobox 1 (множественный выбор)\n        {\n          id: 'blocks',\n          element: (\n            <FiltersActions.TooltipList\n              groupLabel=\"Блок\"\n              fullWidth\n              items={filters.blocks\n                .map((item) => {\n                  const option = blocksOptions.find(\n                    (opt) => opt.value === item,\n                  );\n                  return option?.label;\n                })\n                .filter((label): label is string => Boolean(label))}\n              trigger={filters.blocks.length > 0 ? 'hover' : 'none'}\n              mouseEnterDelay={750}\n              frame={popoverRef} // Важно\n            >\n              <div\n                style={{\n                  width: '100%',\n                }}\n              >\n                <Combobox\n                  placeholder=\"Placeholder\"\n                  isTargetAmount\n                  size=\"s\"\n                  multiple\n                  value={filters.blocks}\n                  onChange={(v) => updateFilters({ blocks: v })}\n                  items={blocksOptions}\n                  listMaxHeight=\"350px\"\n                  portal={popoverRef} // Важно\n                  zIndex=\"9001\" // Важно\n                />\n              </div>\n            </FiltersActions.TooltipList>\n          ),\n          metadata: {\n            // Можно использовать для заголовков фильтров в Popover\n            labelInPopoverFilter: 'Blocks',\n            // Можно использовать для поиска элемента в массиве overlayItems при включенном поиске в Popover\n            labelForSearchingInPopover: 'blocks',\n          },\n        },\n\n        // 5. Combobox 2 (множественный выбор)\n        {\n          id: 'tribes',\n          element: (\n            <FiltersActions.TooltipList\n              groupLabel=\"Трайб\"\n              fullWidth\n              items={filters.tribes\n                .map((item) => {\n                  const option = tribesOptions.find(\n                    (opt) => opt.value === item,\n                  );\n                  return option?.label;\n                })\n                .filter((label): label is string => Boolean(label))}\n              trigger={filters.tribes.length > 0 ? 'hover' : 'none'}\n              mouseEnterDelay={750}\n              frame={popoverRef} // Важно\n            >\n              {/* Важно делать обертку для регулирования ширины Combobox. Подробнее: https://plasma.sberdevices.ru/sdds-finai/components/combobox/ */}\n              <div\n                style={{\n                  width: '100%',\n                }}\n              >\n                <Combobox\n                  placeholder=\"Placeholder\"\n              \n// … (обрезано)"
        },
        {
          "exportName": "SimpleFiltersActionsStory",
          "displayName": "FiltersActions без адаптивности",
          "type": "full-code",
          "code": "import { createRows, type Row } from './tableData';\n    import {\n      IconChevronLeft,\n      IconChevronRight,\n      Avatar,\n      SplitView,\n      backgroundPrimary,\n      Badge,\n      Button,\n      ColumnConfig,\n      Flow,\n      H2,\n      IconButton,\n      s,\n      Table,\n      Widget,\n    } from '@daisforge/ui';\n    import React, { useMemo, useState } from 'react';\n\n    type Filters = {\n      searchedV: string;\n      switcher: boolean;\n      blocks: string[];\n      tribes: string[];\n      allocation: string;\n      brics: string[];\n    };\n\n    const filtersReducer = (\n      state: Filters,\n      newState: Partial<Filters>\n    ): Filters => ({\n      ...state,\n      ...newState,\n    });\n\n    const DEFAULT_FILTERS: Filters = {\n      searchedV: '',\n      switcher: false,\n      blocks: [],\n      tribes: [],\n      allocation: '',\n      brics: [],\n    };\n\n    const LABELS: { [key in keyof Filters]: string } = {\n      searchedV: 'Поиск',\n      blocks: 'Блок',\n      tribes: 'Трайб',\n      allocation: 'Аллокация',\n      switcher: 'Switcher filter',\n      brics: 'Брикс',\n    };\n\n    const useFetch = (\n      key: 'blocks' | 'tribes' | 'allocation' | 'brics',\n      num = 10\n    ) =>\n      useMemo(\n        () =>\n          Array(num)\n            .fill(0)\n            .map((_, i) => ({\n              label: \\\n\n() => {\n    const [filters, updateFilters] = useReducer(\n      filtersReducer,\n      DEFAULT_FILTERS,\n    );\n    const [popupFilterOpened, setPopupFilterOpened] = useState(false);\n\n    /**\n     * Реф контейнера Popover с фильтрами. Нужен для того, чтобы тултип и выпадающие списки\n     * Combobox, которые будут отображаться в popover могли получить контейнер, где им отрисовываться\n     */\n    const popoverRef = useRef<HTMLDivElement>(null);\n\n    // Опции для combobox'ов\n    const blocksOptions = useFetch('blocks', 10);\n    const tribesOptions = useFetch('tribes', 10);\n    const allocationOptions = useFetch('allocation', 10);\n    const bricsOptions = useFetch('brics', 10);\n\n    // Работа с фильтрами\n    const { filterList, filterListOpened, clearAll } = useFiltersList({\n      filters,\n      options: {\n        blocks: blocksOptions,\n        tribes: tribesOptions,\n        allocation: allocationOptions,\n        brics: bricsOptions,\n      } as Record<keyof Filters, { label: string; value: string }[]>,\n      updateFilters: (key, newV) => updateFilters({ [key]: newV }),\n      filtersInfo: {\n        searchedV: { label: 'Поиск', clearedValue: '' },\n        switcher: { label: 'Чекбокс', clearedValue: false },\n        blocks: { label: 'Блок', clearedValue: [] },\n        tribes: { label: 'Трайб', clearedValue: [] },\n        allocation: { label: 'Аллокация', clearedValue: '' },\n        brics: { label: 'Брикс', clearedValue: [] },\n      },\n      order: ['switcher'], // Первым отображаются switch кнопки\n    });\n\n    // Элементы, которые будут видны статически\n    const visibleItems = useMemo(\n      () => [\n        // 1. Сегменты\n        {\n          id: 'segments',\n          element: (\n            <SegmentGroup\n              hasBackground\n              size=\"xs\"\n              style={{ marginRight: '8px' }}\n            >\n              {Array(3)\n                .fill(0)\n                .map((_, i) => (\n                  <FiltersActions.SegmentItem\n                    key={`item:${i}`}\n                    value={`item_${i}`}\n                    label={`Сегмент ${i + 1}`}\n                  />\n                ))}\n            </SegmentGroup>\n          ),\n        },\n\n        // 2. Поиск\n        {\n          id: 'search',\n          element: (\n            <FiltersActions.TextFieldSearch\n              value={filters.searchedV}\n              onChange={(e) => updateFilters({ searchedV: e.target.value })}\n              autoComplete=\"off\"\n              placeholder=\"Поиск\"\n              style={{ marginRight: '8px' }}\n            />\n          ),\n        },\n\n        // 3. Чекбокс/Switcher\n        {\n          id: 'switcher',\n          element: (\n            <FiltersActions.SwitcherFilter\n              checked={filters.switcher}\n              label=\"Активные\"\n              onChange={(e) => updateFilters({ switcher: e.target.checked })}\n            />\n          ),\n        },\n\n        // 4. Combobox 3 (одиночный выбор)\n        {\n          id: 'allocation',\n          element: (\n            <Combobox\n              size=\"s\"\n              placeholder=\"Allocation\"\n              value={filters.allocation}\n              onChange={(v) => updateFilters({ allocation: v })}\n              items={allocationOptions}\n              listMaxHeight=\"350px\"\n              portal={popoverRef}\n              zIndex=\"9001\"\n            />\n          ),\n        },\n      ],\n      [\n        filters.searchedV,\n        filters.switcher,\n        filters.allocation,\n        allocationOptions,\n      ],\n    );\n\n    // Элементы, которые будут в Popover (последние 3 чекбокса)\n    const popoverItems = useMemo(\n      () => [\n        // 1. Combobox 1 (множественный выбор) - blocks\n        {\n          id: 'blocks',\n          element: (\n            <FiltersActions.TooltipList\n              groupLabel=\"Блок\"\n              fullWidth\n              items={filters.blocks\n                .map((item) => {\n                  const option = blocksOptions.find(\n                    (opt) => opt.value === item,\n                  );\n                  return option?.label;\n                })\n                .filter((label): label is string => Boolean(label))}\n              trigger={filters.blocks.length > 0 ? 'hover' : 'none'}\n              mouseEnterDelay={750}\n              frame={popoverRef} // Важно\n            >\n              {/* Важно делать обертку дл регулирования ширины Combobox. Подробнее: https://plasma.sberdevices.ru/sdds-finai/components/combobox/ */}\n              <div\n                style={{\n                  width: '100%',\n                }}\n              >\n                <Combobox\n                  isTargetAmount\n                  size=\"s\"\n                  multiple\n                  value={filters.blocks}\n                  onChange={(v) => updateFilters({ blocks: v })}\n                  items={blocksOptions}\n                  listMaxHeight=\"350px\"\n                  portal={popoverRef} // Важно\n                  zIndex=\"9001\" // Важно\n                />\n              </div>\n            </FiltersActions.TooltipList>\n          ),\n          metadata: {\n            labelInPopoverFilter: 'Blocks',\n          },\n        },\n\n        // 2. Combobox 2 (множественный выбор) - tribes\n        {\n          id: 'tribes',\n          element: (\n            <FiltersActions.TooltipList\n              groupLabel=\"Трайб\"\n              fullWidth\n              items={filters.tribes\n                .map((item) => {\n                  const option = tribesOptions.find(\n                    (opt) => opt.value === item,\n                  );\n                  return option?.label;\n                })\n                .filter((label): label is string => Boolean(label))}\n              trigger={filters.tribes.length > 0 ? 'hover' : 'none'}\n              mouseEnterDelay={750}\n              frame={popoverRef} // Важно\n            >\n              {/* Важно делать обертку дл регулирования ширины Combobox. Подробнее: https://plasma.sberdevices.ru/sdds-finai/components/combobox/ */}\n              <div\n                style={{\n                  width: '100%',\n                }}\n              >\n                <Combobox\n                  isTargetAmount\n                  size=\"s\"\n                  multiple\n                  value={filters.tribes}\n                  onChange={(v) => updateFilters({ tribes: v })}\n                  items={tribesOptions}\n                  listMaxHeight=\"350px\"\n                  portal={popoverRef} // Важно\n                  zIndex=\"9001\" // Важно\n                />\n              </div>\n            </FiltersActions.TooltipList>\n          ),\n          metadata: {\n            labelInPopoverFilter: 'Tribes',\n          },\n        },\n\n        // 3. Combobo\n// … (обрезано)"
        },
        {
          "exportName": "CustomTargetFiltersActionsStory",
          "displayName": "FiltersActions с кастомным таргетом Popover",
          "type": "full-code",
          "code": "import {\n      FiltersActions,\n      IconButton,\n      IconSettingsFilter,\n      Combobox,\n      BodyS,\n    } from '@daisforge/ui';\n    import React, { useRef, useState } from 'react';\n\n    ${getFuncAsString(\n      'packages/storybook/src/stories/FiltersActions/FiltersActions.stories.tsx',\n      'CustomTargetFiltersExample',\n    )}\n\n() => <CustomTargetFiltersExample />"
        },
        {
          "exportName": "ScrollArrowsAppearWithoutManualScrollStory",
          "displayName": "Список применённых фильтров: стрелки-скролл появляются сами при переполнении",
          "type": "full-code",
          "code": "() => <ScrollArrowsExample />"
        }
      ]
    },
    "Layout": {
      "name": "Layout",
      "group": "layouts",
      "folderName": "Layout",
      "role": "primary",
      "description": "Готовый layout страницы с шапкой и вариантами колоночной сетки",
      "props": [
        {
          "name": "marginBottom",
          "type": "string | undefined",
          "required": false,
          "description": "margin-bottom. Если передан — отключает дефолтный и адаптивный margin-bottom"
        },
        {
          "name": "marginLeft",
          "type": "string | undefined",
          "required": false,
          "description": "margin-left. Если передан — перебивает customSpacing.horizontal"
        },
        {
          "name": "marginRight",
          "type": "string | undefined",
          "required": false,
          "description": "margin-right. Если передан — перебивает customSpacing.horizontal"
        },
        {
          "name": "marginTop",
          "type": "string | undefined",
          "required": false,
          "description": "margin-top. Если передан — отключает дефолтный и адаптивный margin-top"
        },
        {
          "name": "paddingBottom",
          "type": "string | undefined",
          "required": false,
          "description": "padding-bottom. Добавляет внутренний отступ снизу"
        },
        {
          "name": "paddingLeft",
          "type": "string | undefined",
          "required": false,
          "description": "padding-left. Добавляет внутренний отступ слева"
        },
        {
          "name": "paddingRight",
          "type": "string | undefined",
          "required": false,
          "description": "padding-right. Добавляет внутренний отступ справа"
        },
        {
          "name": "paddingTop",
          "type": "string | undefined",
          "required": false,
          "description": "padding-top. Добавляет внутренний отступ сверху"
        },
        {
          "name": "classes",
          "type": "string | LayoutClasses | undefined",
          "required": false,
          "description": ""
        },
        {
          "name": "headerSlot",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "mainSlot",
          "type": "React.ReactNode",
          "required": false,
          "description": ""
        },
        {
          "name": "variant",
          "type": "\"V1_1\" | \"V2_1\" | \"V2_2\" | \"V3_1\" | \"V3_2\" | \"V3_3\" | \"V4_1\" | \"V4_2\" | \"V5_1\" | undefined",
          "required": false,
          "description": "",
          "default": "'V1_1'"
        },
        {
          "name": "customSpacing",
          "type": "LayoutSpacing | undefined",
          "required": false,
          "description": "",
          "deprecated": true,
          "default": "{}"
        }
      ],
      "propsTypeName": "LayoutProps",
      "sourceFile": "packages/ui-kit/src/layouts/Layout/Layout.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "сетка страницы",
        "page layout",
        "колонки страницы",
        "шаблон разметки"
      ],
      "docs": "# Layout\n\nКомпонент сетки страницы с поддержкой одноколоночных и многоколоночных макетов.\n\n## Ключевые особенности\n\n- 9 вариантов раскладки: `V1_1` (одна колонка), `V2_1`/`V2_2` (две колонки), `V3_1`/`V3_2`/`V3_3` (асимметричные), `V4_1`/`V4_2` (равные колонки), `V5_1` (фиксированная + центрированная)\n- Адаптивное поведение на разных устройствах\n- Кастомизация отступов через отдельные пропсы margin/padding\n- Гибкое управление через CSS-переменные и классы\n\n## Доступные варианты раскладки\n\n- **V1_1** — одноколоночная\n- **V2_1** — две колонки (основная слева)\n- **V2_2** — две колонки (основная справа)\n- **V3_1** — очень широкая колонка слева\n- **V3_2** — очень широкая колонка справа\n- **V3_3** — три колонки (центр шире)\n- **V4_1** — две равные колонки\n- **V4_2** — три равные колонки\n- **V5_1** — фиксированная левая + центрированная\n\n## CSS-переменные\n\n- `--layout-margin-horizontal` — горизонтальные отступы (по умолчанию: auto)\n- `--layout-margin-vertical` — вертикальные отступы (зависит от breakpoint)\n- `--layout-gutter` — расстояние между колонками (зависит от breakpoint)\n- `--layout-header-height` — высота хедера (auto)\n- `--layout-max-width` — максимальная ширина (1856px)\n- `--layout-grid-template-columns` — шаблон колонок\n\n## Особенности\n\n- При передаче строки в проп `classes` она применяется к корневому элементу; для точечной стилизации передайте объект `LayoutClasses`\n- Встроенные CSS-классы: `layout__root`, `layout__header`, `layout__main`, `layout__item`, `layout__centeredItem` (для V5_1)\n- Адаптивные отступы и гаттеры автоматически меняются по брейкпоинтам\n- Максимальная ширина по умолчанию — 1856px\n\nОписание типов — в разделе [API](/docs/композиции-layout-api--docs).",
      "apiDocs": "# Layout API\n\n## LayoutProps\n\n```typescript\ntype LayoutProps = {\n  variant?: LayoutVariant;\n  headerSlot?: ReactNode;\n  mainSlot?: ReactNode;\n  /** @deprecated Используйте прямые пропсы marginTop, marginBottom, paddingTop, paddingBottom */\n  customSpacing?: LayoutSpacing;\n  /** margin-top. Если передан — отключает дефолтный и адаптивный margin-top */\n  marginTop?: string;\n  /** margin-bottom. Если передан — отключает дефолтный и адаптивный margin-bottom */\n  marginBottom?: string;\n  /** padding-top. Добавляет внутренний отступ сверху */\n  paddingTop?: string;\n  /** padding-bottom. Добавляет внутренний отступ снизу */\n  paddingBottom?: string;\n  /** margin-left. Если передан — перебивает customSpacing.horizontal */\n  marginLeft?: string;\n  /** margin-right. Если передан — перебивает customSpacing.horizontal */\n  marginRight?: string;\n  /** padding-left. Добавляет внутренний отступ слева */\n  paddingLeft?: string;\n  /** padding-right. Добавляет внутренний отступ справа */\n  paddingRight?: string;\n  classes?: string | LayoutClasses;\n} & Omit<HTMLAttributes<HTMLDivElement>, 'className'>;\n```\n\n## LayoutClasses\n\n```typescript\ntype LayoutClasses = {\n  root?: string;\n  header?: string;\n  main?: string;\n  item?: string;\n  centeredItem?: string;\n};\n```\n\n## LayoutSpacing (deprecated)\n\n```typescript\ntype LayoutSpacing = {\n  horizontal?: string;\n  vertical?: string | { top?: string; bottom?: string };\n  gutter?: string;\n  headerHeight?: string;\n};\n```",
      "curatedStories": [
        {
          "exportName": "V1_1",
          "displayName": "V1_1: Одноколоночная",
          "type": "args-only",
          "code": "{\n    variant: 'V1_1',\n    headerSlot: DefaultHeader,\n    mainSlot: (\n      <Box width=\"100%\" height=\"100%\" background=\"#dfffdf\">\n        <DefaultContent />\n      </Box>\n    ),\n  }"
        },
        {
          "exportName": "V2_1",
          "displayName": "V2_1: Две колонки (основная слева)",
          "type": "args-only",
          "code": "{\n    variant: 'V2_1',\n    headerSlot: DefaultHeader,\n    mainSlot: [\n      <Box width=\"100%\" height=\"100%\" key=\"left\" background=\"#dfffdf\">\n        <DefaultContent />\n      </Box>,\n      <Box width=\"100%\" height=\"100%\" key=\"right\" background=\"#dfdfff\">\n        <DefaultContent />\n      </Box>,\n    ],\n  }"
        },
        {
          "exportName": "V2_2",
          "displayName": "V2_2: Две колонки (основная справа)",
          "type": "args-only",
          "code": "{\n    variant: 'V2_2',\n    headerSlot: DefaultHeader,\n    mainSlot: [\n      <Box key=\"left\" background=\"#dfffdf\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n      <Box key=\"right\" background=\"#dfdfff\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n    ],\n  }"
        },
        {
          "exportName": "V3_1",
          "displayName": "V3_1: Две колонки справа узкая",
          "type": "args-only",
          "code": "{\n    variant: 'V3_1',\n    headerSlot: DefaultHeader,\n    mainSlot: [\n      <Box key=\"left\" background=\"#dfffdf\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n      <Box key=\"right\" background=\"#dfdfff\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n    ],\n  }"
        },
        {
          "exportName": "V3_2",
          "displayName": "V3_2: Две колонки слева узкая",
          "type": "args-only",
          "code": "{\n    variant: 'V3_2',\n    headerSlot: DefaultHeader,\n    mainSlot: [\n      <Box key=\"left\" background=\"#dfffdf\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n      <Box key=\"right\" background=\"#dfdfff\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n    ],\n  }"
        },
        {
          "exportName": "V3_3",
          "displayName": "V3_3: Три колонки (центр шире)",
          "type": "args-only",
          "code": "{\n    variant: 'V3_3',\n    headerSlot: DefaultHeader,\n    mainSlot: [\n      <Box key=\"left\" background=\"#dfffdf\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n      <Box key=\"center\" background=\"#ffdfff\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n      <Box key=\"right\" background=\"#dfdfff\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n    ],\n  }"
        },
        {
          "exportName": "V4_1",
          "displayName": "V4_1: Две равные колонки",
          "type": "args-only",
          "code": "{\n    variant: 'V4_1',\n    headerSlot: DefaultHeader,\n    mainSlot: [\n      <Box key=\"left\" background=\"#dfffdf\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n      <Box key=\"right\" background=\"#dfdfff\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n    ],\n  }"
        },
        {
          "exportName": "V4_2",
          "displayName": "V4_2: Три равные колонки",
          "type": "args-only",
          "code": "{\n    variant: 'V4_2',\n    headerSlot: DefaultHeader,\n    mainSlot: [\n      <Box key=\"left\" background=\"#dfffdf\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n      <Box key=\"center\" background=\"#ffdfff\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n      <Box key=\"right\" background=\"#dfdfff\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n    ],\n  }"
        },
        {
          "exportName": "V5_1",
          "displayName": "V5_1: Фиксир. слева + центрир.",
          "type": "args-only",
          "code": "{\n    variant: 'V5_1',\n    headerSlot: DefaultHeader,\n    mainSlot: [\n      <Box key=\"left\" background=\"#dfffdf\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n      <Box key=\"right\" background=\"#dfdfff\" width=\"100%\" height=\"100%\">\n        <DefaultContent />\n      </Box>,\n    ],\n  }"
        },
        {
          "exportName": "CustomSpacing",
          "displayName": "Кастомные отступы",
          "type": "args-only",
          "code": "{\n    variant: 'V1_1',\n    headerSlot: DefaultHeader,\n    mainSlot: (\n      <Box width=\"100%\" height=\"100%\" background=\"#dfffdf\">\n        <DefaultContent />\n      </Box>\n    ),\n    customSpacing: {\n      horizontal: 'auto',\n      vertical: '24px',\n      gutter: '32px',\n      headerHeight: '250px',\n    },\n  }"
        },
        {
          "exportName": "CustomClasses",
          "displayName": "Кастомные классы",
          "type": "args-only",
          "code": "{\n    variant: 'V1_1',\n    headerSlot: DefaultHeader,\n    mainSlot: (\n      <Box width=\"100%\" height=\"100%\" background=\"#dfffdf\">\n        <DefaultContent />\n      </Box>\n    ),\n    classes: {\n      root: 'custom-root-class',\n      header: 'custom-header-class',\n      main: 'custom-main-class',\n    },\n  }"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Layout } from '@daisforge/ui';",
      "minimalUsage": "<Layout />",
      "examples": [
        {
          "exportName": "Usage1",
          "displayName": "Использование в PageLayout.stories.tsx",
          "type": "usage",
          "code": "<Layout\n              variant=\"V1_1\"\n              marginTop=\"0\"\n              marginBottom=\"0\"\n              paddingTop=\"16px\"\n              style={{\n                height: '100%',\n              }}\n              headerSlot={DefaultPageHeader}\n              mainSlot={\n                <FlexContainer>\n                  <LeftPanel\n                    collapseState={[collapsed, setCollapsed]}\n                    widthState={[panelWidth, setPanelWidth]}\n                    maxWidth={360}\n                    expandedContent={<LeftPanelExpandedContent />}\n                    collapsedContent={<LeftPanelCollapsedContent />}\n                    collapsedFooterContent={\n                      <IconButton size=\"s\" view=\"secondary\">\n                        <IconGroupOutline />\n                      </IconButton>\n                    }\n                  />\n                  <MainArea>\n                    <LongContentBlocks count={20} />\n                  </MainArea>\n                </FlexContainer>\n              }\n            />",
          "sourceFile": "packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx"
        },
        {
          "exportName": "Usage2",
          "displayName": "Использование в PageLayout.stories.tsx",
          "type": "usage",
          "code": "<Layout\n              variant=\"V1_1\"\n              marginTop=\"0\"\n              marginBottom=\"0\"\n              paddingTop=\"16px\"\n              style={{\n                height: '100%',\n              }}\n              headerSlot={DefaultPageHeader}\n              mainSlot={\n                <FlexContainer>\n                  <LeftPanel\n                    collapseState={[collapsed, setCollapsed]}\n                    widthState={[panelWidth, setPanelWidth]}\n                    maxWidth={360}\n                    expandedContent={<LeftPanelExpandedContent />}\n                    collapsedContent={<LeftPanelCollapsedContent />}\n                    collapsedFooterContent={\n                      <IconButton size=\"s\" view=\"secondary\">\n                        <IconGroupOutline />\n                      </IconButton>\n                    }\n                  />\n                  <MainArea>\n                    <ContentBlock>\n                      Таблица или список записей. Выбор записи открывает панель\n                      деталей справа через SplitView.\n                    </ContentBlock>\n                    <ContentBlock style={{ marginTop: 12 }}>\n                      Ещё один блок контента\n                    </ContentBlock>\n                  </MainArea>\n                </FlexContainer>\n              }\n            />",
          "sourceFile": "packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx"
        },
        {
          "exportName": "V1_1",
          "displayName": "V1_1: Одноколоночная",
          "type": "args-only",
          "code": "{\n    variant: 'V1_1',\n    headerSlot: DefaultHeader,\n    mainSlot: (\n      <Box width=\"100%\" height=\"100%\" background=\"#dfffdf\">\n        <DefaultContent />\n      </Box>\n    ),\n  }"
        },
        {
          "exportName": "V2_1",
          "displayName": "V2_1: Две колонки (основная слева)",
          "type": "args-only",
          "code": "{\n    variant: 'V2_1',\n    headerSlot: DefaultHeader,\n    mainSlot: [\n      <Box width=\"100%\" height=\"100%\" key=\"left\" background=\"#dfffdf\">\n        <DefaultContent />\n      </Box>,\n      <Box width=\"100%\" height=\"100%\" key=\"right\" background=\"#dfdfff\">\n        <DefaultContent />\n      </Box>,\n    ],\n  }"
        }
      ]
    },
    "PageLayout": {
      "name": "PageLayout",
      "group": "layouts",
      "folderName": "PageLayout",
      "role": "primary",
      "description": "Обёртка страницы: отступ под fixed-шапку, центрирование, адаптивные паддинги",
      "props": [
        {
          "name": "minHeight",
          "type": "CSSValue | undefined",
          "required": false,
          "description": "Минимальная высота. По умолчанию 100dvh. 0 или 'auto' — для шапки микрофронта"
        },
        {
          "name": "paddingBottom",
          "type": "CSSValue | undefined",
          "required": false,
          "description": "Нижний отступ. По умолчанию адаптивный (24px / 32px). 0 — для шапки микрофронта"
        },
        {
          "name": "paddingTop",
          "type": "CSSValue | undefined",
          "required": false,
          "description": "Верхний отступ. По умолчанию var(--global-header-height, 72px). 0 — для шапки микрофронта"
        }
      ],
      "propsTypeName": "PageLayoutProps",
      "sourceFile": "packages/ui-kit/src/layouts/PageLayout/PageLayout.tsx",
      "type": "composition",
      "category": "Композиции",
      "keywords": [
        "макет страницы",
        "page wrapper",
        "отступ под шапку"
      ],
      "docs": "# PageLayout\n\nОбёртка страницы микрофронта. Управляет отступом под fixed-шапку (`padding-top`), боковыми/нижними паддингами по брейкпоинтам и центрированием контента.\n\n## Ключевые особенности\n\n- **Отступ под fixed-шапку** — `padding-top` по CSS-переменной `--global-header-height` (fallback 72px)\n- **Центрирование** — `max-width: 1920px` + `margin-inline: auto`\n- **Адаптивные паддинги** — боковые и нижние отступы меняются по брейкпоинтам\n- **min-height: 100dvh** — страница всегда занимает минимум один экран\n- **display: flex** — дочерний контент автоматически растягивается на всю высоту\n\n## Типичные композиции\n\n### PageLayout + Layout\n\nБазовый сценарий — обёртка страницы с сеткой контента:\n\n```tsx\n<PageLayout>\n  <Layout variant=\"V1_1\" headerSlot={...} mainSlot={...} />\n</PageLayout>\n```\n\n### PageLayout + SplitView\n\nSplitView внутри PageLayout. Sidebar ограничен шириной контейнера, не прижимается к краю viewport:\n\n```tsx\n<PageLayout>\n  <SplitView\n    mainContent={\n      <Layout variant=\"V1_1\" headerSlot={...} mainSlot={...} />\n    }\n    sidebar={{ content: ..., isOpened: sidebarOpen }}\n  />\n</PageLayout>\n```\n\n### PageLayout + SplitView + LeftPanel\n\nLeftPanel — часть `mainSlot` внутри Layout:\n\n```tsx\n<PageLayout>\n  <SplitView\n    mainContent={\n      <Layout\n        variant=\"V1_1\"\n        headerSlot={...}\n        mainSlot={\n          <FlexContainer>\n            <LeftPanel ... />\n            <MainArea>контент</MainArea>\n          </FlexContainer>\n        }\n      />\n    }\n    sidebar={{ content: ..., isOpened: sidebarOpen }}\n  />\n</PageLayout>\n```\n\n## Особенности\n\n- `PageLayout` — это **viewport-level** обёртка. Используйте как корневой контейнер страницы, внутри которого размещается `Layout` и другие композиционные компоненты\n- **PageLayout** отвечает за отступы от шапки, padding краёв и центрирование (`max-width`). Используется 1 раз на страницу\n- **Layout** отвечает за колонки, гаттеры, хедер контента. Размещается внутри `PageLayout`\n\nОписание типов и CSS-переменных — в разделе [API](?path=/docs/композиции-pagelayout-api--docs).",
      "apiDocs": "# PageLayout API\n\n## PageLayoutProps\n\n```typescript\ntype PageLayoutProps = {\n  /** Верхний отступ. По умолчанию var(--global-header-height, 72px). 0 — для шапки микрофронта */\n  paddingTop?: CSSValue;\n  /** Нижний отступ. По умолчанию адаптивный (24px / 32px). 0 — для шапки микрофронта */\n  paddingBottom?: CSSValue;\n  /** Минимальная высота. По умолчанию 100dvh. 0 или 'auto' — для шапки микрофронта */\n  minHeight?: CSSValue;\n  children: ReactNode;\n  className?: string;\n};\n```\n\n## CSS-переменные\n\nКомпонент устанавливает CSS-переменные, которые можно переопределить или использовать в дочерних элементах:\n\n- `--global-header-height` — задаётся микрофронтом шапки (fallback 72px). PageLayout использует для `padding-top`\n- `--page-layout-padding-top` — верхний отступ. По умолчанию `var(--global-header-height, 72px)`\n- `--page-layout-padding-inline` — боковые отступы. &lt;= 1280px: `24px`, >1280px: `32px`\n- `--page-layout-padding-bottom` — нижний отступ. &lt;= 1280px: `24px`, >1280px: `32px`\n\n## Стили\n\n```css\ndisplay: flex;\nmax-width: 1920px;\npadding-top: var(--page-layout-padding-top);\nmargin-inline: auto;\nmin-height: calc(100dvh - var(--page-layout-padding-top));\npadding-inline: var(--page-layout-padding-inline);\npadding-bottom: var(--page-layout-padding-bottom);\nbox-sizing: border-box;\n```",
      "curatedStories": [
        {
          "exportName": "Basic",
          "displayName": "Базовый",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Button,\n        Dropdown,\n        IconButton,\n        Layout,\n        LeftPanel,\n        List,\n        ListItem,\n        PageLayout,\n        PageTitle,\n        SplitView,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n    import styled from 'styled-components';\n\n    const FlexContainer = styled.div\\\n\n() => (\n    <>\n      <FakeHeader>Шапка микрофронта (fixed)</FakeHeader>\n      <PageLayout>\n        <Layout\n          variant=\"V1_1\"\n          marginBottom=\"0\"\n          headerSlot={DefaultPageHeader}\n          mainSlot={\n            <>\n              <ContentBlock>Основной контент</ContentBlock>\n              <ContentBlock>Ещё один блок контента</ContentBlock>\n            </>\n          }\n        />\n      </PageLayout>\n    </>\n  )"
        },
        {
          "exportName": "WithTwoColumns",
          "displayName": "Двухколоночная раскладка",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Button,\n        Dropdown,\n        IconButton,\n        Layout,\n        LeftPanel,\n        List,\n        ListItem,\n        PageLayout,\n        PageTitle,\n        SplitView,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n    import styled from 'styled-components';\n\n    const FlexContainer = styled.div\\\n\n() => (\n    <>\n      <FakeHeader>Шапка микрофронта (fixed)</FakeHeader>\n      <PageLayout>\n        <Layout\n          variant=\"V2_1\"\n          marginBottom=\"0\"\n          headerSlot={DefaultPageHeader}\n          mainSlot={[\n            <ContentBlock key=\"left\" $bg=\"#dfffdf\">\n              Левая колонка (основная)\n            </ContentBlock>,\n            <ContentBlock key=\"right\" $bg=\"#dfdfff\">\n              Правая колонка\n            </ContentBlock>,\n          ]}\n        />\n      </PageLayout>\n    </>\n  )"
        },
        {
          "exportName": "WithLongContent",
          "displayName": "Страничный скролл",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Button,\n        Dropdown,\n        IconButton,\n        Layout,\n        LeftPanel,\n        List,\n        ListItem,\n        PageLayout,\n        PageTitle,\n        SplitView,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n    import styled from 'styled-components';\n\n    const FlexContainer = styled.div\\\n\n() => (\n    <>\n      <FakeHeader>Шапка микрофронта (fixed)</FakeHeader>\n      <PageLayout>\n        <Layout\n          variant=\"V1_1\"\n          marginBottom=\"0\"\n          headerSlot={DefaultPageHeader}\n          mainSlot={<LongContentBlocks count={20} />}\n        />\n      </PageLayout>\n    </>\n  )"
        },
        {
          "exportName": "WithSplitView",
          "displayName": "SplitView (toggle sidebar)",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Button,\n        Dropdown,\n        IconButton,\n        Layout,\n        LeftPanel,\n        List,\n        ListItem,\n        PageLayout,\n        PageTitle,\n        SplitView,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n    import styled from 'styled-components';\n\n    const FlexContainer = styled.div\\\n${getFuncAsString(\n  'packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx',\n  'WithSplitViewTemplate',\n)}"
        },
        {
          "exportName": "SplitViewWithLongContent",
          "displayName": "SplitView + длинный контент",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Button,\n        Dropdown,\n        IconButton,\n        Layout,\n        LeftPanel,\n        List,\n        ListItem,\n        PageLayout,\n        PageTitle,\n        SplitView,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n    import styled from 'styled-components';\n\n    const FlexContainer = styled.div\\\n${getFuncAsString(\n  'packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx',\n  'SplitViewLongContentTemplate',\n)}"
        },
        {
          "exportName": "WithLeftPanel",
          "displayName": "LeftPanel + Layout",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Button,\n        Dropdown,\n        IconButton,\n        Layout,\n        LeftPanel,\n        List,\n        ListItem,\n        PageLayout,\n        PageTitle,\n        SplitView,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n    import styled from 'styled-components';\n\n    const FlexContainer = styled.div\\\n${getFuncAsString(\n  'packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx',\n  'WithLeftPanelTemplate',\n)}"
        },
        {
          "exportName": "LeftPanelWithSplitView",
          "displayName": "LeftPanel + SplitView",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Button,\n        Dropdown,\n        IconButton,\n        Layout,\n        LeftPanel,\n        List,\n        ListItem,\n        PageLayout,\n        PageTitle,\n        SplitView,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n    import styled from 'styled-components';\n\n    const FlexContainer = styled.div\\\n${getFuncAsString(\n  'packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx',\n  'LeftPanelWithSplitViewTemplate',\n)}"
        },
        {
          "exportName": "FullComboLongContent",
          "displayName": "LeftPanel + SplitView + скролл",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Button,\n        Dropdown,\n        IconButton,\n        Layout,\n        LeftPanel,\n        List,\n        ListItem,\n        PageLayout,\n        PageTitle,\n        SplitView,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n    import styled from 'styled-components';\n\n    const FlexContainer = styled.div\\\n${getFuncAsString(\n  'packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx',\n  'FullComboLongTemplate',\n)}"
        },
        {
          "exportName": "ForMicroFrontHeader",
          "displayName": "Для шапки микрофронта",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Button,\n        Dropdown,\n        IconButton,\n        Layout,\n        LeftPanel,\n        List,\n        ListItem,\n        PageLayout,\n        PageTitle,\n        SplitView,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n    import styled from 'styled-components';\n\n    const FlexContainer = styled.div\\\n\n() => (\n    <>\n      <FixedHeaderWrapper>\n        <PageLayout paddingTop={0} paddingBottom={0} minHeight={0}>\n          <MicroFrontHeaderContent>\n            <span style={{ fontWeight: 600 }}>Логотип</span>\n            <Flow mainAxisGap={8}>\n              <Button size=\"s\" view=\"secondary\">\n                Раздел 1\n              </Button>\n              <Button size=\"s\" view=\"secondary\">\n                Раздел 2\n              </Button>\n              <Button size=\"s\" view=\"accent\">\n                Профиль\n              </Button>\n            </Flow>\n          </MicroFrontHeaderContent>\n        </PageLayout>\n      </FixedHeaderWrapper>\n      <PageLayout>\n        <Layout\n          variant=\"V1_1\"\n          marginBottom=\"0\"\n          headerSlot={DefaultPageHeader}\n          mainSlot={\n            <>\n              <ContentBlock>\n                Основной контент страницы. Шапка сверху обёрнута в PageLayout с\n                paddingTop={'{0}'}, paddingBottom={'{0}'} и minHeight={'{0}'}.\n              </ContentBlock>\n              <ContentBlock>Ещё один блок контента</ContentBlock>\n              <ContentBlock>Третий блок</ContentBlock>\n            </>\n          }\n        />\n      </PageLayout>\n    </>\n  )"
        }
      ],
      "hasCuratedMeta": true,
      "atomicMcpVersion": "0.355.0",
      "importPath": "@daisforge/ui",
      "importStatement": "import { PageLayout } from '@daisforge/ui';",
      "minimalUsage": "<PageLayout />",
      "examples": [
        {
          "exportName": "Basic",
          "displayName": "Базовый",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Button,\n        Dropdown,\n        IconButton,\n        Layout,\n        LeftPanel,\n        List,\n        ListItem,\n        PageLayout,\n        PageTitle,\n        SplitView,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n    import styled from 'styled-components';\n\n    const FlexContainer = styled.div\\\n\n() => (\n    <>\n      <FakeHeader>Шапка микрофронта (fixed)</FakeHeader>\n      <PageLayout>\n        <Layout\n          variant=\"V1_1\"\n          marginBottom=\"0\"\n          headerSlot={DefaultPageHeader}\n          mainSlot={\n            <>\n              <ContentBlock>Основной контент</ContentBlock>\n              <ContentBlock>Ещё один блок контента</ContentBlock>\n            </>\n          }\n        />\n      </PageLayout>\n    </>\n  )"
        },
        {
          "exportName": "WithTwoColumns",
          "displayName": "Двухколоночная раскладка",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Button,\n        Dropdown,\n        IconButton,\n        Layout,\n        LeftPanel,\n        List,\n        ListItem,\n        PageLayout,\n        PageTitle,\n        SplitView,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n    import styled from 'styled-components';\n\n    const FlexContainer = styled.div\\\n\n() => (\n    <>\n      <FakeHeader>Шапка микрофронта (fixed)</FakeHeader>\n      <PageLayout>\n        <Layout\n          variant=\"V2_1\"\n          marginBottom=\"0\"\n          headerSlot={DefaultPageHeader}\n          mainSlot={[\n            <ContentBlock key=\"left\" $bg=\"#dfffdf\">\n              Левая колонка (основная)\n            </ContentBlock>,\n            <ContentBlock key=\"right\" $bg=\"#dfdfff\">\n              Правая колонка\n            </ContentBlock>,\n          ]}\n        />\n      </PageLayout>\n    </>\n  )"
        },
        {
          "exportName": "WithLongContent",
          "displayName": "Страничный скролл",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Button,\n        Dropdown,\n        IconButton,\n        Layout,\n        LeftPanel,\n        List,\n        ListItem,\n        PageLayout,\n        PageTitle,\n        SplitView,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n    import styled from 'styled-components';\n\n    const FlexContainer = styled.div\\\n\n() => (\n    <>\n      <FakeHeader>Шапка микрофронта (fixed)</FakeHeader>\n      <PageLayout>\n        <Layout\n          variant=\"V1_1\"\n          marginBottom=\"0\"\n          headerSlot={DefaultPageHeader}\n          mainSlot={<LongContentBlocks count={20} />}\n        />\n      </PageLayout>\n    </>\n  )"
        },
        {
          "exportName": "WithSplitView",
          "displayName": "SplitView (toggle sidebar)",
          "type": "full-code",
          "code": "import { useState } from 'react';\n    import {\n        IconGroupOutline,\n        IconHierarchy,\n        IconSearch,\n    } from '@daisforge/ui/icons';\n    import {\n        Button,\n        Dropdown,\n        IconButton,\n        Layout,\n        LeftPanel,\n        List,\n        ListItem,\n        PageLayout,\n        PageTitle,\n        SplitView,\n        TextFieldSearch,\n        Widget,\n    } from '@daisforge/ui';\n    import styled from 'styled-components';\n\n    const FlexContainer = styled.div\\\n${getFuncAsString(\n  'packages/storybook/src/stories/PageLayout/PageLayout.stories.tsx',\n  'WithSplitViewTemplate',\n)}"
        }
      ]
    }
  },
  "features": [
    {
      "component": "TableCanvas",
      "feature": "CanvasElements/CanvasBadge",
      "legacy": false,
      "summary": "Бейдж для отображения статусов и меток в ячейках `TableCanvas`.",
      "docs": "# Canvas.Badge\n\nБейдж для отображения статусов и меток в ячейках `TableCanvas`.\n\n## Ключевые особенности\n\n- Несколько встроенных `view` и `size`\n- Режимы `transparent`, `clear`, `pilled`\n- Кастомные цвета через `customColor` / `customBackgroundColor`\n- Поддержка `leftIcon` / `rightIcon`\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvasbadge-api--docs).",
      "apiDocs": "# Canvas.Badge API\n\n## CanvasBadgeOptions\n\n```typescript\ninterface CanvasBadgeOptions {\n  view?: BadgeView;\n  size?: BadgeSize;\n  transparent?: boolean;\n  clear?: boolean;\n  leftIcon?: ButtonIcon;\n  rightIcon?: ButtonIcon;\n  pilled?: boolean;\n  theme?: Theme;\n  /** Кастомный цвет текста (аналог customColor в базовом Badge из sdds-finai).\n   * Принимает конкретные значения цвета: hex (#0B7ECB), rgb(), rgba().\n   * CSS-переменные (var(--...)) не поддерживаются — Canvas API работает только с конкретными цветами. */\n  customColor?: string;\n  /** Кастомный цвет фона (аналог customBackgroundColor в базовом Badge из sdds-finai).\n   * Принимает конкретные значения цвета: hex (#0B7ECB), rgb(), rgba().\n   * CSS-переменные (var(--...)) не поддерживаются — Canvas API работает только с конкретными цветами. */\n  customBackgroundColor?: string;\n}\n```\n\n## BadgeView\n\n```typescript\ntype BadgeView =\n  | 'default'\n  | 'accent'\n  | 'positive'\n  | 'warning'\n  | 'negative'\n  | 'dark'\n  | 'light';\n```\n\n## BadgeSize\n\n```typescript\ntype BadgeSize = 'xs' | 's' | 'm' | 'l';\n```",
      "api": [
        {
          "typeName": "CanvasBadgeOptions",
          "source": "interface CanvasBadgeOptions {\n  view?: BadgeView;\n  size?: BadgeSize;\n  transparent?: boolean;\n  clear?: boolean;\n  leftIcon?: ButtonIcon;\n  rightIcon?: ButtonIcon;\n  pilled?: boolean;\n  theme?: Theme;\n  /** Кастомный цвет текста (аналог customColor в базовом Badge из sdds-finai).\n   * Принимает конкретные значения цвета: hex (#0B7ECB), rgb(), rgba().\n   * CSS-переменные (var(--...)) не поддерживаются — Canvas API работает только с конкретными цветами. */\n  customColor?: string;\n  /** Кастомный цвет фона (аналог customBackgroundColor в базовом Badge из sdds-finai).\n   * Принимает конкретные значения цвета: hex (#0B7ECB), rgb(), rgba().\n   * CSS-переменные (var(--...)) не поддерживаются — Canvas API работает только с конкретными цветами. */\n  customBackgroundColor?: string;\n}"
        },
        {
          "typeName": "BadgeView",
          "source": "type BadgeView =\n  | 'default'\n  | 'accent'\n  | 'positive'\n  | 'warning'\n  | 'negative'\n  | 'dark'\n  | 'light';"
        },
        {
          "typeName": "BadgeSize",
          "source": "type BadgeSize = 'xs' | 's' | 'm' | 'l';"
        }
      ],
      "stories": [
        {
          "exportName": "CustomColors",
          "displayName": "Custom Colors",
          "type": "full-code",
          "code": "import { Canvas, ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst columnConfig: ColumnConfig[] = [\n  {\n    key: 'status',\n    name: 'Статус',\n    width: 200,\n    renderCell: ({ row }) => (\n      <Canvas.Container direction=\"row\" alignItems=\"center\" padding={8}>\n        <Canvas.Badge\n          text={row.status}\n          view=\"default\"\n          customColor=\"#FFFFFF\"\n          customBackgroundColor=\"#0B7ECB\"\n        />\n      </Canvas.Container>\n    ),\n  },\n];\n\n<TableCanvas\n  tableConfig={{ containerStyle: { height: '300px' } }}\n  columnConfig={columnConfig}\n  rows={rows}\n/>"
        },
        {
          "exportName": "Default",
          "displayName": "Default",
          "type": "full-code",
          "code": "import { Canvas, ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst columnConfig: ColumnConfig[] = [\n  {\n    key: 'status',\n    name: 'Статус',\n    width: 120,\n    renderCell: ({ row }) => (\n      <Canvas.Container direction=\"row\" alignItems=\"center\" padding={8}>\n        <Canvas.Badge text={row.status} view=\"accent\" size=\"s\" />\n      </Canvas.Container>\n    ),\n  },\n];\n\n<TableCanvas\n  tableConfig={{ containerStyle: { height: '400px' } }}\n  columnConfig={columnConfig}\n  rows={rows}\n/>"
        },
        {
          "exportName": "IconOnly",
          "displayName": "Only Icon",
          "type": "full-code",
          "code": "import { Canvas, ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport { IconSearch } from '@daisforge/ui/icons';\n\nconst icon = Canvas.icon(<IconSearch />);\n\nconst columnConfig: ColumnConfig[] = [\n  {\n    key: 'badge',\n    name: 'Бейдж',\n    width: 120,\n    renderCell: ({ row }) => (\n      <Canvas.Container direction=\"row\" alignItems=\"center\" padding={8}>\n        <Canvas.Badge text=\"\" leftIcon={icon} view={row.view} size=\"s\" />\n      </Canvas.Container>\n    ),\n  },\n];\n\n<TableCanvas\n  tableConfig={{ containerStyle: { height: '400px' } }}\n  columnConfig={columnConfig}\n  rows={rows}\n/>"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "CanvasElements/CanvasButton",
      "legacy": false,
      "summary": "Кнопка внутри canvas-ячейки `TableCanvas`.",
      "docs": "# Canvas.Button\n\nКнопка внутри canvas-ячейки `TableCanvas`.\n\n## Ключевые особенности\n\n- Несколько вариантов `view` и `size`\n- Поддержка `disabled`, `leftIcon` / `rightIcon`\n- `onClick` выполняется перед `tableConfig.onCellClicked` — используйте `event.stopPropagation()` для предотвращения всплытия\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvasbutton-api--docs).",
      "apiDocs": "# Canvas.Button API\n\n## CanvasButtonOptions\n\n```typescript\ninterface CanvasButtonOptions {\n  /** @deprecated Use `view` instead */\n  variant?: 'primary' | 'secondary' | 'danger';\n  /** Button view style based on sdds_finai__light theme */\n  view?: ButtonView;\n  /** Button size */\n  size?: ButtonSize;\n  /** Left icon (SVG string or image) */\n  leftIcon?: ButtonIcon;\n  /** Right icon (SVG string or image) */\n  rightIcon?: ButtonIcon;\n  disabled?: boolean;\n  onClick?: (event: CanvasEvent) => void;\n  theme?: Theme;\n}\n```\n\n## ButtonView\n\n```typescript\ntype ButtonView =\n  | 'default'\n  | 'primary'\n  | 'accent'\n  | 'secondary'\n  | 'clear'\n  | 'success'\n  | 'warning'\n  | 'critical'\n  | 'dark'\n  | 'black'\n  | 'white';\n```\n\n## ButtonSize\n\n```typescript\ntype ButtonSize = 'xs' | 's' | 'm' | 'l';\n```",
      "api": [
        {
          "typeName": "CanvasButtonOptions",
          "source": "interface CanvasButtonOptions {\n  /** @deprecated Use `view` instead */\n  variant?: 'primary' | 'secondary' | 'danger';\n  /** Button view style based on sdds_finai__light theme */\n  view?: ButtonView;\n  /** Button size */\n  size?: ButtonSize;\n  /** Left icon (SVG string or image) */\n  leftIcon?: ButtonIcon;\n  /** Right icon (SVG string or image) */\n  rightIcon?: ButtonIcon;\n  disabled?: boolean;\n  onClick?: (event: CanvasEvent) => void;\n  theme?: Theme;\n}"
        },
        {
          "typeName": "ButtonView",
          "source": "type ButtonView =\n  | 'default'\n  | 'primary'\n  | 'accent'\n  | 'secondary'\n  | 'clear'\n  | 'success'\n  | 'warning'\n  | 'critical'\n  | 'dark'\n  | 'black'\n  | 'white';"
        },
        {
          "typeName": "ButtonSize",
          "source": "type ButtonSize = 'xs' | 's' | 'm' | 'l';"
        }
      ],
      "stories": [
        {
          "exportName": "Default",
          "displayName": "Default",
          "type": "full-code",
          "code": "(args) => {\n    const { text, disabled } = args as {\n      text: string;\n      disabled: boolean;\n    };\n\n    const columnConfig = useMemo<readonly ColumnConfig<ViewRow>[]>(\n      () =>\n        SIZES.map((size) => ({\n          key: size,\n          name: size,\n          width: 160,\n          renderCell: ({ row }) => (\n            <Canvas.Container direction=\"row\" alignItems=\"center\" padding={8}>\n              <Canvas.Button view={row.view} size={size} disabled={disabled}>\n                {text}\n              </Canvas.Button>\n            </Canvas.Container>\n          ),\n        })),\n      [text, disabled],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{ containerStyle: { height: '700px' } }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "CanvasElements/CanvasCheckbox",
      "legacy": false,
      "summary": "Чекбокс для canvas-ячеек `TableCanvas`.",
      "docs": "# Canvas.Checkbox\n\nЧекбокс для canvas-ячеек `TableCanvas`.\n\n## Ключевые особенности\n\n- Состояния: `checked`, `indeterminate`\n- Поддержка `view`, `buttonSize`, `disabled`\n- `onClick` для обработки нажатия\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvascheckbox-api--docs).",
      "apiDocs": "# Canvas.Checkbox API\n\n## CanvasCheckboxOptions\n\n```typescript\ninterface CanvasCheckboxOptions {\n  /** @deprecated Use `buttonSize` with ButtonSize type instead */\n  size?: number | 'auto';\n  theme?: GlideThemeForRender;\n\n  /** Button view style based on sdds_finai__light theme */\n  view?: ButtonView;\n  /** Button size */\n  buttonSize?: ButtonSize;\n  disabled?: boolean;\n  onClick?: (event: CanvasEvent) => void;\n}\n```\n\n## ButtonView\n\n```typescript\ntype ButtonView =\n  | 'default'\n  | 'primary'\n  | 'accent'\n  | 'secondary'\n  | 'clear'\n  | 'success'\n  | 'warning'\n  | 'critical'\n  | 'dark'\n  | 'black'\n  | 'white';\n```\n\n## ButtonSize\n\n```typescript\ntype ButtonSize = 'xs' | 's' | 'm' | 'l';\n```",
      "api": [
        {
          "typeName": "CanvasCheckboxOptions",
          "source": "interface CanvasCheckboxOptions {\n  /** @deprecated Use `buttonSize` with ButtonSize type instead */\n  size?: number | 'auto';\n  theme?: GlideThemeForRender;\n\n  /** Button view style based on sdds_finai__light theme */\n  view?: ButtonView;\n  /** Button size */\n  buttonSize?: ButtonSize;\n  disabled?: boolean;\n  onClick?: (event: CanvasEvent) => void;\n}"
        },
        {
          "typeName": "ButtonView",
          "source": "type ButtonView =\n  | 'default'\n  | 'primary'\n  | 'accent'\n  | 'secondary'\n  | 'clear'\n  | 'success'\n  | 'warning'\n  | 'critical'\n  | 'dark'\n  | 'black'\n  | 'white';"
        },
        {
          "typeName": "ButtonSize",
          "source": "type ButtonSize = 'xs' | 's' | 'm' | 'l';"
        }
      ],
      "stories": [
        {
          "exportName": "Default",
          "displayName": "Checkbox",
          "type": "full-code",
          "code": "(args) => {\n    const { checked, indeterminate, disabled } = args as {\n      checked: boolean;\n      indeterminate: boolean;\n      disabled: boolean;\n    };\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'checkbox',\n          name: 'Checkbox',\n          width: 300,\n          renderCell: () => (\n            <Canvas.Container direction=\"row\" alignItems=\"center\" padding={8}>\n              <Canvas.Checkbox\n                checked={checked}\n                indeterminate={indeterminate}\n                disabled={disabled}\n              />\n            </Canvas.Container>\n          ),\n        },\n      ],\n      [checked, indeterminate, disabled],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{ containerStyle: { height: '200px' } }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "CanvasElements/CanvasContainer",
      "legacy": false,
      "summary": "Flex-контейнер для компоновки canvas-элементов внутри ячейки `TableCanvas`.",
      "docs": "# Canvas.Container\n\nFlex-контейнер для компоновки canvas-элементов внутри ячейки `TableCanvas`.\n\n## Ключевые особенности\n\n- Flex-свойства: `direction`, `alignItems`, `justifyContent`, `gap`, `padding`\n- `backgroundColor` для визуального выделения\n- `position=\"relative\"` / `position=\"absolute\"` для абсолютного позиционирования\n- Поддержка `tooltip`, `onClick`, `onMouseEnter` / `onMouseLeave`\n- Вложенность: контейнеры можно комбинировать для сложных layout-ов\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvascontainer-api--docs).",
      "apiDocs": "# Canvas.Container API\n\n## ContainerProps\n\n```typescript\ninterface ContainerProps\n  extends CanvasInteractionProps,\n    CanvasLayerProps,\n    Omit<FlexBoxOptions, 'columnGap' | 'rowGap'> {\n  children?: ReactNode;\n  style?: Partial<CanvasFlexStyle>;\n  backgroundColor?: string;\n  id?: string;\n  gap?: number;\n  columnGap?: number;\n  rowGap?: number;\n  portalHoverEnabled?: boolean;\n  position?: 'relative' | 'absolute';\n  left?: PositionValue;\n  top?: PositionValue;\n  right?: PositionValue;\n  bottom?: PositionValue;\n  /** Конфиг тултипа при hover: строка (текст) или объект с text и опциональными пропсами Tooltip */\n  tooltip?: CanvasNodeTooltipConfig;\n  onClick?: (event: CanvasEvent<CanvasContainer>) => void;\n  onMouseEnter?: (event: CanvasEvent<CanvasContainer>) => void;\n  onMouseLeave?: (event: CanvasEvent<CanvasContainer>) => void;\n  onMouseDown?: (event: CanvasEvent<CanvasContainer>) => void;\n}\n```",
      "api": [
        {
          "typeName": "ContainerProps",
          "source": "interface ContainerProps\n  extends CanvasInteractionProps,\n    CanvasLayerProps,\n    Omit<FlexBoxOptions, 'columnGap' | 'rowGap'> {\n  children?: ReactNode;\n  style?: Partial<CanvasFlexStyle>;\n  backgroundColor?: string;\n  id?: string;\n  gap?: number;\n  columnGap?: number;\n  rowGap?: number;\n  portalHoverEnabled?: boolean;\n  position?: 'relative' | 'absolute';\n  left?: PositionValue;\n  top?: PositionValue;\n  right?: PositionValue;\n  bottom?: PositionValue;\n  /** Конфиг тултипа при hover: строка (текст) или объект с text и опциональными пропсами Tooltip */\n  tooltip?: CanvasNodeTooltipConfig;\n  onClick?: (event: CanvasEvent<CanvasContainer>) => void;\n  onMouseEnter?: (event: CanvasEvent<CanvasContainer>) => void;\n  onMouseLeave?: (event: CanvasEvent<CanvasContainer>) => void;\n  onMouseDown?: (event: CanvasEvent<CanvasContainer>) => void;\n}"
        }
      ],
      "stories": [
        {
          "exportName": "Default",
          "displayName": "Container",
          "type": "full-code",
          "code": "(args) => {\n    const {\n      direction,\n      alignItems,\n      justifyContent,\n      gap,\n      padding,\n      width,\n      height,\n      backgroundColor,\n    } = args as {\n      direction: (typeof DIRECTIONS)[number];\n      alignItems: (typeof ALIGN_ITEMS)[number];\n      justifyContent: (typeof JUSTIFY)[number];\n      gap: number;\n      padding: number;\n      width: number;\n      height: number;\n      backgroundColor: string;\n    };\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'container',\n          name: 'Container',\n          width: 500,\n          renderCell: () => (\n            <Canvas.Container\n              direction={direction}\n              alignItems={alignItems}\n              justifyContent={justifyContent}\n              gap={gap}\n              padding={padding}\n              style={{\n                ...(width > 0 ? { width } : {}),\n                ...(height > 0 ? { height } : {}),\n              }}\n              backgroundColor={backgroundColor || 'gray'}\n            >\n              <Canvas.Badge text=\"Badge\" view=\"accent\" size=\"s\" />\n              <Canvas.Text>Text</Canvas.Text>\n              <Canvas.Button view=\"accent\" size=\"xs\">\n                Button\n              </Canvas.Button>\n            </Canvas.Container>\n          ),\n        },\n      ],\n      [\n        direction,\n        alignItems,\n        justifyContent,\n        gap,\n        padding,\n        width,\n        height,\n        backgroundColor,\n      ],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{ containerStyle: { height: '200px' } }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "CanvasElements/CanvasIcon",
      "legacy": false,
      "summary": "Иконка внутри canvas-ячейки `TableCanvas`.",
      "docs": "# Canvas.Icon\n\nИконка внутри canvas-ячейки `TableCanvas`.\n\n## Ключевые особенности\n\n- Принимает иконку через `Canvas.icon(<IconName />)` — преобразует React-иконку в canvas-формат\n- Настраиваемый `size` и `color`\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvasicon-api--docs).",
      "apiDocs": "# Canvas.Icon API\n\n## CanvasIconOptions\n\n```typescript\ninterface CanvasIconOptions {\n  size?: number;\n  color?: string;\n}\n```",
      "api": [
        {
          "typeName": "CanvasIconOptions",
          "source": "interface CanvasIconOptions {\n  size?: number;\n  color?: string;\n}"
        }
      ],
      "stories": [
        {
          "exportName": "Default",
          "displayName": "Icon",
          "type": "full-code",
          "code": "(args) => {\n    const { icon, size, color } = args as {\n      icon: string;\n      size: number;\n      color: string;\n    };\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'icon',\n          name: 'Icon',\n          width: 300,\n          renderCell: () => (\n            <Canvas.Container direction=\"row\" alignItems=\"center\" padding={8}>\n              <Canvas.Icon icon={ICON_MAP[icon]} size={size} color={color} />\n            </Canvas.Container>\n          ),\n        },\n      ],\n      [icon, size, color],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{ containerStyle: { height: '200px' } }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "CanvasElements/CanvasIconButton",
      "legacy": false,
      "summary": "Кнопка-иконка внутри canvas-ячейки `TableCanvas`.",
      "docs": "# Canvas.IconButton\n\nКнопка-иконка внутри canvas-ячейки `TableCanvas`.\n\n## Ключевые особенности\n\n- Иконка через `Canvas.icon(<IconName />)`\n- Несколько вариантов `view` и `buttonSize`\n- Поддержка `disabled`\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvasiconbutton-api--docs).",
      "apiDocs": "# Canvas.IconButton API\n\n## CanvasIconButtonOptions\n\n```typescript\ninterface CanvasIconButtonOptions {\n  /** @deprecated Use `buttonSize` with ButtonSize type instead */\n  size?: number | 'auto';\n  /** @deprecated Use `view` instead */\n  variant?: 'primary' | 'secondary' | 'danger';\n  /** Button view style based on sdds_finai__light theme */\n  view?: ButtonView;\n  /** Button size */\n  buttonSize?: ButtonSize;\n  disabled?: boolean;\n  onClick?: (event: CanvasEvent) => void;\n}\n```\n\n## ButtonView\n\n```typescript\ntype ButtonView =\n  | 'default'\n  | 'primary'\n  | 'accent'\n  | 'secondary'\n  | 'clear'\n  | 'success'\n  | 'warning'\n  | 'critical'\n  | 'dark'\n  | 'black'\n  | 'white';\n```\n\n## ButtonSize\n\n```typescript\ntype ButtonSize = 'xs' | 's' | 'm' | 'l';\n```",
      "api": [
        {
          "typeName": "CanvasIconButtonOptions",
          "source": "interface CanvasIconButtonOptions {\n  /** @deprecated Use `buttonSize` with ButtonSize type instead */\n  size?: number | 'auto';\n  /** @deprecated Use `view` instead */\n  variant?: 'primary' | 'secondary' | 'danger';\n  /** Button view style based on sdds_finai__light theme */\n  view?: ButtonView;\n  /** Button size */\n  buttonSize?: ButtonSize;\n  disabled?: boolean;\n  onClick?: (event: CanvasEvent) => void;\n}"
        },
        {
          "typeName": "ButtonView",
          "source": "type ButtonView =\n  | 'default'\n  | 'primary'\n  | 'accent'\n  | 'secondary'\n  | 'clear'\n  | 'success'\n  | 'warning'\n  | 'critical'\n  | 'dark'\n  | 'black'\n  | 'white';"
        },
        {
          "typeName": "ButtonSize",
          "source": "type ButtonSize = 'xs' | 's' | 'm' | 'l';"
        }
      ],
      "stories": [
        {
          "exportName": "Default",
          "displayName": "Default",
          "type": "full-code",
          "code": "import { Canvas, ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport { IconSearch } from '@daisforge/ui/icons';"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "CanvasElements/CanvasLink",
      "legacy": false,
      "summary": "Ссылка с навигацией и underline внутри canvas-ячейки `TableCanvas`.",
      "docs": "# Canvas.Link\n\nСсылка с навигацией и underline внутри canvas-ячейки `TableCanvas`.\n\n## Ключевые особенности\n\n- Несколько вариантов `view`\n- `view=\"clear\"` использует цвета `default` как fallback — canvas не поддерживает `inherit`\n- Поддержка `href`, `target`, `disabled`\n- Наследует текстовые свойства от `Canvas.Text`: `wordWrap`, `overflow`, `textOverflow`, `ellipsis`, `maxLines`\n\n## Перехват навигации\n\nПо умолчанию `Canvas.Link` выполняет навигацию по `href` после вызова `onClick`.\nДля отмены навигации вызовите `event.preventDefault()`:\n\n```tsx\n<Canvas.Link\n  view=\"accent\"\n  href=\"/some-page\"\n  onClick={(event) => {\n    event.preventDefault();\n    openModal(row.id);\n  }}\n>\n  Открыть\n</Canvas.Link>\n```\n\n## Многострочный режим\n\nПри многострочном переносе underline не рисуется, поэтому многострочные ссылки лучше использовать там, где underline не критичен.\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvaslink-api--docs).",
      "apiDocs": "# Canvas.Link API\n\n## CanvasLinkOptions\n\n```typescript\ninterface CanvasLinkOptions extends CanvasTextOptions {\n  href?: string;\n  target?: string;\n  rel?: string;\n  view?: LinkView;\n  disabled?: boolean;\n  theme?: Theme;\n}\n```\n\n## LinkView\n\n```typescript\ntype LinkView = Extract<LinkAllProps['view'], string>;\n```",
      "api": [
        {
          "typeName": "CanvasLinkOptions",
          "source": "interface CanvasLinkOptions extends CanvasTextOptions {\n  href?: string;\n  target?: string;\n  rel?: string;\n  view?: LinkView;\n  disabled?: boolean;\n  theme?: Theme;\n}"
        },
        {
          "typeName": "LinkView",
          "source": "type LinkView = Extract<LinkAllProps['view'], string>;"
        }
      ],
      "stories": [
        {
          "exportName": "Default",
          "displayName": "View",
          "type": "full-code",
          "code": "(args) => {\n    const { text, href, disabled } = args as {\n      text: string;\n      href: string;\n      disabled: boolean;\n    };\n\n    const columnConfig = useMemo<readonly ColumnConfig<ViewRow>[]>(\n      () => [\n        {\n          key: 'view',\n          name: 'View',\n          width: 100,\n          renderCell: ({ row }) => (\n            <Canvas.Container padding={8} alignItems=\"center\">\n              <Canvas.Text>{row.view}</Canvas.Text>\n            </Canvas.Container>\n          ),\n        },\n        {\n          key: 'link',\n          name: 'Link',\n          width: 200,\n          renderCell: ({ row }) => (\n            <Canvas.Container direction=\"row\" alignItems=\"center\" padding={8}>\n              <Canvas.Link\n                view={row.view}\n                href={href}\n                target=\"_blank\"\n                disabled={disabled}\n              >\n                {text}\n              </Canvas.Link>\n            </Canvas.Container>\n          ),\n        },\n      ],\n      [text, href, disabled],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{ containerStyle: { height: '600px' } }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "CanvasElements/CanvasSkeleton",
      "legacy": false,
      "summary": "Скелетон-заглушка для состояния загрузки в ячейках `TableCanvas`.",
      "docs": "# Canvas.Skeleton\n\nСкелетон-заглушка для состояния загрузки в ячейках `TableCanvas`.\n\n## Ключевые особенности\n\n- Настраиваемый `roundness` (набор фиксированных значений)\n- Режим `lighter` для светлого фона\n- Анимация через `animated` (включена по умолчанию), настраиваемая `shimmerDuration`\n- Кастомный градиент через `customGradientColor`\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvasskeleton-api--docs).",
      "apiDocs": "# Canvas.Skeleton API\n\n## CanvasSkeletonOptions\n\n```typescript\ninterface CanvasSkeletonOptions {\n  /**\n   * Радиус скругления углов.\n   * Ключи: 0, 8, 12, 14, 16, 18, 20, 24, 28, 32, 250\n   * Или CSS-строки: \"8px\", \"1rem\"\n   * По умолчанию: 16 (= 16px)\n   */\n  roundness?: Roundness | string;\n\n  /** CSS linear-gradient для скелетона */\n  customGradientColor?: string;\n\n  /** Более контрастный градиент */\n  lighter?: boolean;\n\n  /** Включить shimmer-анимацию (по умолчанию: true) */\n  animated?: boolean;\n\n  /** Длительность цикла анимации в мс (по умолчанию: 4000) */\n  shimmerDuration?: number;\n}\n```\n\n## Roundness\n\n```typescript\ntype Roundness = keyof typeof ROUNDNESS_MAP;\n```\n\n## ROUNDNESS\\_MAP\n\n```typescript\nconst ROUNDNESS_MAP = {\n  250: 15.625,\n  32: 2,\n  28: 1.75,\n  24: 1.5,\n  20: 1.25,\n  18: 1.125,\n  16: 1,\n  14: 0.875,\n  12: 0.75,\n  8: 0.5,\n  0: 0,\n} as const;\n```",
      "api": [
        {
          "typeName": "CanvasSkeletonOptions",
          "source": "interface CanvasSkeletonOptions {\n  /**\n   * Радиус скругления углов.\n   * Ключи: 0, 8, 12, 14, 16, 18, 20, 24, 28, 32, 250\n   * Или CSS-строки: \"8px\", \"1rem\"\n   * По умолчанию: 16 (= 16px)\n   */\n  roundness?: Roundness | string;\n\n  /** CSS linear-gradient для скелетона */\n  customGradientColor?: string;\n\n  /** Более контрастный градиент */\n  lighter?: boolean;\n\n  /** Включить shimmer-анимацию (по умолчанию: true) */\n  animated?: boolean;\n\n  /** Длительность цикла анимации в мс (по умолчанию: 4000) */\n  shimmerDuration?: number;\n}"
        },
        {
          "typeName": "Roundness",
          "source": "type Roundness = keyof typeof ROUNDNESS_MAP;"
        },
        {
          "typeName": "Unknown",
          "source": "const ROUNDNESS_MAP = {\n  250: 15.625,\n  32: 2,\n  28: 1.75,\n  24: 1.5,\n  20: 1.25,\n  18: 1.125,\n  16: 1,\n  14: 0.875,\n  12: 0.75,\n  8: 0.5,\n  0: 0,\n} as const;"
        }
      ],
      "stories": [
        {
          "exportName": "Default",
          "displayName": "Skeleton",
          "type": "full-code",
          "code": "(args) => {\n    const { width, height, roundness, lighter, animated } = args as {\n      width: number;\n      height: number;\n      roundness: number;\n      lighter: boolean;\n      animated: boolean;\n    };\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'skeleton',\n          name: 'Skeleton',\n          width: 300,\n          renderCell: () => (\n            <Canvas.Container direction=\"row\" alignItems=\"center\" padding={8}>\n              <Canvas.Skeleton\n                width={width}\n                height={height}\n                roundness={roundness}\n                lighter={lighter}\n                animated={animated}\n              />\n            </Canvas.Container>\n          ),\n        },\n      ],\n      [width, height, roundness, lighter, animated],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{ containerStyle: { height: '300px' } }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "CanvasElements/CanvasText",
      "legacy": false,
      "summary": "Текстовый элемент для canvas-ячеек `TableCanvas` с поддержкой ellipsis и многострочного clamp.",
      "docs": "# Canvas.Text\n\nТекстовый элемент для canvas-ячеек `TableCanvas` с поддержкой ellipsis и многострочного clamp.\n\n## Ключевые особенности\n\n- Однострочный ellipsis через `overflow=\"hidden\"` + `textOverflow=\"ellipsis\"`\n- Многострочный clamp через `wordWrap` + `maxLines`\n- Clip без маркера: `textOverflow=\"clip\"`\n- Кастомный маркер обрезки через `ellipsis` (по умолчанию `…`)\n- Авто-тултип с полным текстом при обрезке через `autoTooltip`\n\n## Однострочный ellipsis\n\n```tsx\n<Canvas.Text overflow=\"hidden\" textOverflow=\"ellipsis\" style={{ flexGrow: 1 }}>\n  Очень длинный текст\n</Canvas.Text>\n```\n\n## Многострочный clamp\n\n```tsx\n<Canvas.Text\n  wordWrap\n  maxLines={2}\n  overflow=\"hidden\"\n  textOverflow=\"ellipsis\"\n  lineHeight={1.2}\n  style={{ flexGrow: 1 }}\n>\n  Длинный текст на несколько строк\n</Canvas.Text>\n```\n\n`maxLines` работает только при `wordWrap` и `overflow=\"hidden\"`. `maxLines={1}` ведёт себя как однострочный ellipsis.\n\n## Высота строки\n\nДля многострочного текста высота строки таблицы должна оставлять место под нужное количество строк с учётом `lineHeight` и padding.\n\n## Авто-тултип при обрезке (`autoTooltip`)\n\nЕсли текст обрезается в многоточие, `Canvas.Text` может сам показывать тултип с полным текстом — без ручного `portalHoverEnabled` и `tooltip`:\n\n```tsx\n<Canvas.Text overflow=\"hidden\" textOverflow=\"ellipsis\" autoTooltip style={{ flexGrow: 1 }}>\n  {row.longText}\n</Canvas.Text>\n```\n\nПравила:\n\n- Тултип показывается **только когда текст реально обрезан в многоточие**. Если текст помещается целиком — тултипа нет.\n- Работает и для многострочного clamp (`wordWrap` + `maxLines`): тултип появляется, когда есть скрытые строки ниже `maxLines`.\n- При `textOverflow=\"clip\"` (обрезка без маркера `…`) тултип не показывается.\n- `autoTooltip` сам делает ноду hover-таргетом (неявно включает `portalHoverEnabled`).\n- Явный проп `tooltip` приоритетнее: если заданы оба — показывается `tooltip` (always-on, без условия обрезки).\n- Обрезанность определяется по фактической ширине ноды после layout, поэтому при ресайзе колонки тултип автоматически появляется/исчезает вместе с многоточием.\n\nКастомизация — объектом (тип `CanvasTextAutoTooltip`):\n\n```tsx\n<Canvas.Text\n  overflow=\"hidden\"\n  textOverflow=\"ellipsis\"\n  autoTooltip={{\n    placement: 'top',\n    mouseEnterDelay: 300,\n    // По умолчанию текст тултипа = полный текст ноды.\n    // Строка — заменить, функция — трансформировать, null из функции — не показывать.\n    text: (fullText) => `Полностью: ${fullText}`,\n  }}\n  style={{ flexGrow: 1 }}\n>\n  {row.longText}\n</Canvas.Text>\n```\n\n`autoTooltip={{ enabled: false }}` (или `autoTooltip={false}`) выключает авто-тултип. Доступные пропсы оформления — те же, что у обычного node-тултипа: `placement`, `view`, `minWidth`, `maxWidth`, `mouseEnterDelay`, `mouseLeaveDelay`.\n\n> Авто-тултип действует только на `Canvas.Text` внутри canvas-разметки (`renderCell` / `renderHeaderCell`, включая хедеры и групп-хедеры). Обычные текстовые ячейки таблицы (примитивные значения без `renderCell`) рисуются встроенным text-рендерером glide и в этой механике не участвуют.\n\nОбщая механика тултипов таблицы описана в разделе [Tooltip](?path=/docs/локальные-компоненты-tablecanvas-tooltip--docs).\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvastext-api--docs).",
      "apiDocs": "# Canvas.Text API\n\n## CanvasTextOptions\n\n```typescript\ninterface CanvasTextOptions {\n  font?: string;\n  fontSize?: number;\n  lineHeightPx?: number;\n  color?: string;\n  wordWrap?: boolean;\n  lineHeight?: number;\n  overflow?: CanvasTextOverflowMode;\n  textOverflow?: CanvasTextOverflow;\n  ellipsis?: string;\n  maxLines?: number;\n  autoTooltip?: CanvasTextAutoTooltip;\n}\n```\n\n## CanvasTextAutoTooltip\n\nКонфиг авто-тултипа при обрезке текста (проп `autoTooltip`). `boolean` — включить/выключить с дефолтным поведением (полный текст ноды), объект — кастомизация:\n\n```typescript\ntype CanvasTextAutoTooltip =\n  | boolean\n  | (CanvasNodeTooltipProps & {\n      /** @default true — скрыть можно через false */\n      enabled?: boolean;\n      /**\n       * Переопределение/трансформация текста тултипа. По умолчанию — собственный\n       * текст ноды. Вернуть `null` — не показывать.\n       */\n      text?: string | ((fullText: string) => string | null);\n      mouseEnterDelay?: number;\n      mouseLeaveDelay?: number;\n    });\n```",
      "api": [
        {
          "typeName": "CanvasTextOptions",
          "source": "interface CanvasTextOptions {\n  font?: string;\n  fontSize?: number;\n  lineHeightPx?: number;\n  color?: string;\n  wordWrap?: boolean;\n  lineHeight?: number;\n  overflow?: CanvasTextOverflowMode;\n  textOverflow?: CanvasTextOverflow;\n  ellipsis?: string;\n  maxLines?: number;\n  autoTooltip?: CanvasTextAutoTooltip;\n}"
        },
        {
          "typeName": "CanvasTextAutoTooltip",
          "source": "type CanvasTextAutoTooltip =\n  | boolean\n  | (CanvasNodeTooltipProps & {\n      /** @default true — скрыть можно через false */\n      enabled?: boolean;\n      /**\n       * Переопределение/трансформация текста тултипа. По умолчанию — собственный\n       * текст ноды. Вернуть `null` — не показывать.\n       */\n      text?: string | ((fullText: string) => string | null);\n      mouseEnterDelay?: number;\n      mouseLeaveDelay?: number;\n    });"
        }
      ],
      "stories": [
        {
          "exportName": "Default",
          "displayName": "Canvas.Text",
          "type": "full-code",
          "code": "import { Canvas, ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst columnConfig: ColumnConfig[] = [\n  {\n    key: 'description',\n    name: 'Описание',\n    width: 230,\n    renderCell: ({ row, theme }) => (\n      <Canvas.Container padding={8} alignItems=\"center\">\n        <Canvas.Text\n          color={theme.textDark}\n          font={theme.baseFontStyle}\n          wordWrap\n          overflow=\"hidden\"\n          textOverflow=\"ellipsis\"\n          maxLines={2}\n          lineHeight={1.2}\n          style={{ flexGrow: 1 }}\n        >\n          {row.description}\n        </Canvas.Text>\n      </Canvas.Container>\n    ),\n  },\n];\n\n<TableCanvas\n  tableConfig={{\n    containerStyle: { height: '320px' },\n    rowHeight: () => 72,\n  }}\n  columnConfig={columnConfig}\n  rows={rows}\n/>"
        },
        {
          "exportName": "BuiltInTreeChevronEllipsisRegression",
          "displayName": "Canvas.Text / built-in tree chevron ellipsis",
          "type": "full-code",
          "code": "import { Canvas, ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const columnConfig = useMemo<\n      readonly ColumnConfig<CanvasTextTreeRow>[]\n    >(() => {\n      const renderCellContent = (\n        row: CanvasTextTreeRow,\n        theme: CanvasTextTreeCellTheme,\n      ) => (\n        <Canvas.Container\n          direction=\"column\"\n          gap={10}\n          padding={{ top: theme.cellVerticalPadding }}\n          style={{\n            width: '100%',\n          }}\n        >\n          <Canvas.Link>{row.shortName}</Canvas.Link>\n\n          <Canvas.Text\n            color={theme.tokens.textSecondary}\n            wordWrap\n            overflow=\"hidden\"\n            textOverflow=\"ellipsis\"\n            maxLines={1}\n            style={{ width: '100%' }}\n          >\n            {row.departPath}\n          </Canvas.Text>\n        </Canvas.Container>\n      );\n\n      const renderCell: CanvasTextTreeRenderCell = ({ row, theme }) =>\n        renderCellContent(row, theme);\n\n      const renderSubRowCell: CanvasTextTreeSubRowRenderCell = ({\n        row,\n        theme,\n      }) =>\n        renderCellContent(\n          row as CanvasTextTreeRow,\n          theme as CanvasTextTreeCellTheme,\n        );\n\n      return [\n        {\n          key: 'shortName',\n          name: 'Краткое название',\n          width: 360,\n          renderCell,\n          subRow: {\n            isColumnWithArrow: true,\n            renderSubRowCell,\n          },\n        },\n      ];\n    }, []);\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '320px' },\n          rowHeight: () => 72,\n          subRows: {\n            getSubRows: (row) => row.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={treeEllipsisRows}\n      />\n    );\n  }"
        },
        {
          "exportName": "BuiltInTreeChevronTwoLineEllipsisRegression",
          "displayName": "Canvas.Text / built-in tree chevron two-line ellipsis",
          "type": "full-code",
          "code": "import { Canvas, ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const columnConfig = useMemo<\n      readonly ColumnConfig<CanvasTextTreeRow>[]\n    >(() => {\n      const renderCellContent = (\n        row: CanvasTextTreeRow,\n        theme: CanvasTextTreeCellTheme,\n      ) => (\n        <Canvas.Container\n          direction=\"column\"\n          gap={10}\n          padding={{ top: theme.cellVerticalPadding }}\n          style={{\n            width: '100%',\n          }}\n        >\n          <Canvas.Link>{row.shortName}</Canvas.Link>\n\n          <Canvas.Text\n            color={theme.tokens.textSecondary}\n            wordWrap\n            overflow=\"hidden\"\n            textOverflow=\"ellipsis\"\n            maxLines={2}\n            style={{ width: '100%' }}\n          >\n            {row.departPath}\n          </Canvas.Text>\n        </Canvas.Container>\n      );\n\n      const renderCell: CanvasTextTreeRenderCell = ({ row, theme }) =>\n        renderCellContent(row, theme);\n\n      const renderSubRowCell: CanvasTextTreeSubRowRenderCell = ({\n        row,\n        theme,\n      }) =>\n        renderCellContent(\n          row as CanvasTextTreeRow,\n          theme as CanvasTextTreeCellTheme,\n        );\n\n      return [\n        {\n          key: 'shortName',\n          name: 'Краткое название',\n          width: 360,\n          renderCell,\n          subRow: {\n            isColumnWithArrow: true,\n            renderSubRowCell,\n          },\n        },\n      ];\n    }, []);\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '380px' },\n          rowHeight: () => 96,\n          subRows: {\n            getSubRows: (row) => row.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={treeEllipsisRows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "CellsMerging",
      "legacy": false,
      "summary": "Объединение ячеек тела таблицы: по строкам (rowSpan), по колонкам (colSpan) и",
      "docs": "# CellsMerging (TableCanvas)\n\nОбъединение ячеек тела таблицы: по строкам (rowSpan), по колонкам (colSpan) и\nпрямоугольными блоками. Несколько одинаковых ячеек рисуются одной большой, а всё\nвзаимодействие — клики, выделение, навигация, копирование, вставка, протяжка,\nредактирование — обращается с блоком как с одной ячейкой.\n\nЭта страница — обзор: как выбрать способ и с чего начать, плюс живые примеры.\nПодробности (совмещение способов, работа с деревом, выравнивание, сводные\nограничения) — в\n[Справочнике](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-справочник--docs),\nтипы — в\n[API](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-api--docs).\n\n## Как это устроено\n\nГлавная идея простая: объединение — это способ показа, а не способ хранения.\n\n- В данных значение повторяется в каждой строке блока. Если «Отдел А» тянется на\n  три строки, то во всех трёх строках в поле отдела записано «Отдел А».\n- Таблица замечает повторы (или получает границы блока явно) и вместо трёх\n  одинаковых ячеек рисует одну высокую. Содержимое берётся из верхней-левой\n  ячейки блока.\n- Данные при этом не меняются. Уберите объединение — увидите те же строки с теми\n  же значениями.\n\nОтсюда следует и поведение, знакомое по Excel: клик в любую точку блока выделяет\nблок целиком, правка блока меняет значение во всех его строках, копирование\nотдаёт значение один раз.\n\n## Три способа включить объединение\n\nМеханика под всеми способами одна. Отличие — кто вычисляет границы блоков:\nпотребитель или таблица. Способы можно совмещать в одной таблице — правила в\nСправочнике, глава «Если включено несколько способов сразу».\n\n### 1. mergeCells.mergedCellsRegions — блоки, заданные снаружи\n\n«Слей вот эти конкретные ячейки». Список блоков по стабильным ключам строк и\nколонок; списком владеет потребитель, как выделением. Таблица переводит ключи в\nтекущие видимые позиции. Если сортировка, перестановка или скрытие колонки\nразорвали блок — он не рисуется (как ограничение сортировки в Excel).\n\n```tsx\ntableConfig={{\n  mergeCells: {\n    mergedCellsRegions: [\n      { rowKeys: ['r1', 'r2'], colKeys: ['dept'] },\n      { rowKeys: ['r4', 'r5'], colKeys: ['plan', 'fact'] }, // прямоугольник 2×2\n    ],\n    rowKeyGetter: (row) => row.id,\n  },\n}}\n```\n\nПримеры — стори с префиксом `mergedCellsRegions:` ниже.\n\n### 2. mergeCells.mergeByCellValues — по одинаковым значениям\n\n«В этих колонках сливай подряд идущие одинаковые значения». Границы блоков\nтаблица вычисляет сама из данных; после сортировки или фильтра блоки\nпересобираются.\n\n```tsx\ntableConfig={{\n  mergeCells: {\n    mergeByCellValues: [\n      'dept',                                             // по значению колонки\n      { colKey: 'role', value: (row) => row.roleGroup },  // по своей функции\n    ],\n  },\n}}\n```\n\nОдинаковые названия в разных ветках иерархии могут ложно слиться — лечится\nсоставным ключом, разбор в Справочнике, глава «Объединение по значению: где\nпроходит граница». Примеры — стори с префиксом `mergeByCellValues:` ниже.\n\n### 3. Merged-виды группировки и subRows — полный автомат\n\nПотребитель включает вид — всю работу с блоками делает таблица: строки\nупорядочиваются по группам, колонки уровней сливаются по границам групп, чекбокс\nи нумерация работают по верхней группе.\n\nЧерез группировку (структуру задают значения группирующих колонок):\n\n```tsx\ntableConfig={{\n  rowsGrouping: {\n    view: 'merged',\n    groupByState: [groupBy, setGroupBy], // например ['dept', 'role']\n    rowKeyGetter: (row) => row.id,\n  },\n}}\n```\n\nЧерез subRows (структуру задаёт готовое дерево потребителя):\n\n```tsx\ntableConfig={{\n  subRows: {\n    view: 'merged',\n    mergedColumns: ['dept', 'role'], // колонки уровней дерева\n    getSubRows: (row) => row.children,\n    rowKeyGetter: (row) => row.id,\n  },\n}}\n```\n\nПримеры — «subRows: дерево с пагинацией» и «rowsGrouping: группировка\nпользователем» в конце страницы.\n\n## Какой способ выбрать\n\nКартинка у способов похожая, поэтому выбирать стоит не по внешнему виду, а по\nтому, кто владеет данными и что нужно пользователю.\n\n### Дерево приходит с сервера, нужна постраничная загрузка — subRows\n\nЕсли данные уже иерархические (дивизион, управление, команда, сотрудники) и\nприходят от сервера частями, берите `subRows` с `view: 'merged'`. Дерево остаётся\nу вас: вы отдаёте таблице страницу дерева, она разворачивает её в строки и сама\nсливает колонки-предки. Именно поэтому здесь работает пагинация по верхним\nблокам — таблице не нужно видеть все данные сразу.\n\nОбратная сторона: раз данными владеете вы, то поиск, сортировка и фильтрация\nдерева — тоже на вашей стороне. Формат дерева, пагинация и возврат правок —\nв Справочнике, глава «Дерево через subRows».\n\n### Плоские строки, пользователь сам выбирает группировку — rowsGrouping\n\nЕсли строки плоские, а пользователь должен на лету решать, по каким колонкам\nгруппировать, — берите `rowsGrouping` с `view: 'merged'`. Состав группировки живёт\nв `groupByState`, а с настройкой `groupButton` в блоке управления появляется\nкнопка: пользователь сам выбирает колонки, таблица пересобирает блоки. Встроенные\nпоиск, сортировка и фильтры работают — таблица применяет их до сборки групп.\n\nОбратная сторона: пагинации в этом виде нет — таблице нужны все строки сразу.\nНе действует и всё, что привязано к строкам-групп и шевронам дерева\n(`groupedColumnProps`, `renderGroupCell`, `expandAllBtn`) — полный список в\nСправочнике, глава «Что не работает и почему».\n\n### Плоские строки, группировка фиксированная, всё считает сервер — mergeByCellValues\n\nЕсли структура известна заранее и не меняется пользователем, а данные (включая\nстраницы, сортировку и фильтры) готовит сервер, — самый прямой путь это\n`mergeByCellValues`. Вы упорядочиваете строки как нужно, таблица сливает соседние\nодинаковые значения. Никакой лишней механики: ни кнопок, ни дерева.\n\n### Отдельные ручные блоки — mergedCellsRegions\n\nШапки секций внутри таблицы, нестандартные прямоугольники, объединение по кнопке\nили из контекстного меню — всё, что не выводится из значений, делается регионами.\nПотребитель добавляет блок в свой список — таблица его рисует.\n\n## Смежные разделы\n\n- [Справочник](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-справочник--docs) —\n  совмещение способов, составные ключи, дерево, выравнивание, сводные ограничения.\n- [CellsMerging API](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-api--docs) —\n  типы.\n- Объединение ячеек шапки — раздел ColumnsGrouping (`squashEmptyCells`).\n\n## Полные примеры\n\nТри больших примера ниже собраны как заготовки для продуктов: в каждом —\nобъединение ячеек в связке с поиском, сортировкой, фильтрами, пагинацией,\nредактированием и выделением. Различаются они тем, кто владеет данными, поэтому\nи код обвязки разный. Полный код каждого примера открывается кнопкой «Show code»\nи снабжён комментариями по ключевым местам.\n\n### mergeByCellValues: пример с серверными данными\n\nДанные плоские, всё считает «сервер» (в примере его заменяет функция\n`selectPage`), таблица только рисует полученную страницу.\n\nЧто здесь показано:\n\n- поиск, фильтры, сортировка и пагинация в `manual`-режиме — считает потребитель;\n- составные ключи пути (`divPath` / `unitPath` / `teamPath`) против ложного\n  слияния одинаковых имён из разных веток;\n- сортировка внутри команды — блоки не рассыпаются;\n- закрепление колонок вместе с групповой шапкой;\n- редактирование с возвратом правок страницы в полный набор.\n\n<Canvas of={CellsMergingExamples.Showcase} />\n\n### subRows: дерево с пагинацией\n\nДанные — дерево, и оно остаётся у потребителя: таблице отдаётся страница целых\nподдеревьев.\n\nЧто здесь показано:\n\n- пагинация по верхним блокам (дивизионам) со своим списком «показывать по»;\n- `manual`-поиск, сортировка и фильтры, посчитанные по дереву\n  (функция `selectTreePage`);\n- сортировка показателей внутри команды и перестановка веток по имени;\n- возврат правок листьев обратно в дерево.\n\n<Canvas of={CellsMergingExamples.SubRowsMerged} />\n\n### rowsGrouping: группировка пользователем\n\nДанные плоские и передаются целиком, остальное делает таблица. Самый короткий\nкод из трёх.\n\nЧто здесь показано:\n\n- встроенные поиск, сортировка и фильтры — применяются до сборки групп;\n- выбор состава группировки пользователем (кнопка `groupButton`);\n- полный стейт фильтров: ключ на каждый фильтр из колонок;\n- без пагинации — чтобы собрать группы, таблице нужны все строки сразу.\n\n<Canvas of={CellsMergingExamples.GroupingMerged} />\n\n## Как перенести пример к себе\n\n1. Замените данные и типы строк на свои. Сохраните стабильный `id` строки — на\n   нём держатся выделение и возврат правок, между страницами он меняться не\n   должен.\n2. Замените `selectPage` / `selectTreePage` реальным запросом к серверу. Контракт\n   тот же: параметры выборки на входе, страница и общее количество на выходе.\n3. Проверьте, что в `filtering.state` есть ключ каждого фильтра из колонок (со\n   значением «показать всё»), — селект-фильтр без своего ключа молча отсеет все\n   строки.\n4. Для `mergeByCellValues` заведите составные ключи пути, если одинаковые\n   названия возможны в разных ветках иерархии.\n5. Уберите фичи, которые вам не нужны, — настройки в примерах независимы друг от\n   друга: пагинация, закрепление, чекбоксы, редактирование отключаются по\n   отдельности.\n\n# CellsMerging: справочник\n\nПодробности объединения ячеек: совмещение способов, составные ключи, работа с\nдеревом, взаимодействие с остальными фичами таблицы, выравнивание и сводный\nсписок ограничений. Обзор способов и живые примеры — на странице\n[Docs](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging--docs), типы —\nна странице\n[API](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-api--docs).\n\n## Если включено несколько способов сразу\n\nСпособы можно совмещать в одной таблице — правила простые и считаются по колонке:\n\n- Если колонка входит хотя бы в один регион из `mergedCellsRegions`, её\n  объединения описывают только регионы. `mergeByCellValues` на этой колонке не\n  действует.\n- Колонка merged-вида (группировки или subRows) сливается по границам групп.\n  Пользовательский `mergeByCellValues` на той же колонке не действует — иначе два\n  механизма спорили бы за одни ячейки.\n- В остальных случаях работает `mergeByCellValues`.\n- Разные колонки живут независимо: регион на одной колонке и слияние по значению\n  на другой — обычная рабочая комбинация.\n\nПример: таблица с группировкой по «Отделу» (merged-вид) может дополнительно\nсливать колонку «Статус» через `mergeByCellValues`, а строки-заголовки секций\nрисовать регионами на всю ширину — все три способа уживаются, потому что заняты\nразными колонками.\n\n## Объединение по значению: где проходит граница\n\nУ `mergeByCellValues` есть классическая ловушка. Допустим, регионы «Север» и «Юг»,\nи в каждом есть «Команда 1» и «Команда 2»:\n\n```\nСевер | Команда 1 | Иванов\nСевер | Команда 2 | Петров\nЮг    | Команда 2 | Сидоров\nЮг    | Команда 1 | Смирнов\n```\n\nЕсли сливать колонку команды по её значению, «Команда 2» из Севера и «Команда 2»\nиз Юга стоят рядом — и сольются в один блок через границу региона. Визуально это\nвыглядит как ошибка: одна команда, а на деле две разные.\n\nРешение — сливать не по тексту в ячейке, а по составному ключу, в котором зашит\nпуть от корня:\n\n```tsx\nmergeCells: {\n  mergeByCellValues: [\n    'region',\n    // Сравнивается результат функции, а не текст в ячейке.\n    { colKey: 'team', value: (row) => `${row.region} / ${row.team}` },\n  ],\n}\n```\n\nТеперь у «Команды 2» из Севера ключ «Север / Команда 2», а у южной —\n«Юг / Команда 2». Ключи разные, слияние останавливается на границе региона само,\nбез какой-либо отдельной логики. В ячейке при этом показывается обычное значение\nколонки — функция влияет только на сравнение.\n\nВ полном примере (стори «mergeByCellValues: пример с серверными данными») такие\nключи собраны заранее в полях строки: `divPath`, `unitPath`, `teamPath` — по\nодному на каждый уровень иерархии.\n\nMerged-виды группировки и subRows строят такие ключи сами — там об этой ловушке\nдумать не нужно.\n\n## Дерево через subRows: как передавать данные\n\nРазберём подробнее самый ёмкий сценарий — `subRows` с `view: 'merged'`.\n\n### Какое дерево ждёт таблица\n\nВ `rows` передаются корневые узлы, детей таблица достаёт через `getSubRows`.\nРоли узлов распределены так:\n\n- **Внутренние узлы** (дивизион, управление, команда) — ярлыки уровней. Каждый\n  несёт поле с именем своей колонки из `mergedColumns`: узел дивизиона — поле\n  `division`, узел управления — поле `unit`, и так далее.\n- **Листья** — строки данных. Именно они становятся строками таблицы со своими\n  показателями; внутренние узлы отдельными строками не показываются.\n\n```tsx\nconst tree = [\n  {\n    id: 'd1',\n    division: 'Розничный бизнес', // узел уровня 0\n    subRows: [\n      {\n        id: 'u1',\n        unit: 'Управление продаж', // узел уровня 1\n        subRows: [\n          {\n            id: 't1',\n            team: 'Команда Север', // узел уровня 2\n            subRows: [\n              { id: 'e1', employee: 'Иванов', plan: 100, fact: 90 }, // лист\n              { id: 'e2', employee: 'Петров', plan: 80, fact: 85 },\n            ],\n          },\n        ],\n      },\n    ],\n  },\n];\n```\n\n```tsx\ntableConfig={{\n  subRows: {\n    view: 'merged',\n    mergedColumns: ['division', 'unit', 'team'], // порядок = уровни дерева\n    getSubRows: (row) => row.subRows,\n    rowKeyGetter: (row) => row.id,\n  },\n}}\n```\n\n`mergedColumns` — это соответствие уровней дерева и колонок: первый элемент\nпоказывает узлы верхнего уровня, второй — следующего, и так далее. Колонка\n`division` возьмёт значение из узла дивизиона и сольётся на все его листья,\n`unit` — на листья своего управления, вложенно.\n\nСворачивания в этом виде нет: таблица показывает всё переданное дерево целиком.\nХотите меньше строк на экране — передайте меньший кусок дерева (следующий\nраздел).\n\n### Пагинация по верхним блокам\n\nДерево у вас, поэтому страницы нарезаете вы — по верхним узлам. Таблице отдаётся\nсрез дерева, а в `pagination.count` — общее число верхних узлов:\n\n```tsx\nconst [page, setPage] = useState(1);\nconst [perPage, setPerPage] = useState(2); // дивизионов на страницу\nconst pageTree = tree.slice((page - 1) * perPage, page * perPage);\n\ntableConfig={{\n  pagination: {\n    count: tree.length,     // всего верхних узлов, не листьев\n    perPage,\n    perPageList: [1, 2, 3], // варианты «показывать по» — в блоках\n    value: page,\n    onChange: (nextPage, nextPerPage) => {\n      if (typeof nextPerPage === 'number' && nextPerPage !== perPage) {\n        setPerPage(nextPerPage);\n        setPage(1);\n      } else if (typeof nextPage === 'number') {\n        setPage(nextPage);\n      }\n    },\n  },\n  subRows: { /* как выше */ },\n}}\n// ...\nrows={pageTree}\n```\n\nСтраница «2 дивизиона» может содержать разное число строк-листьев — это нормально:\nединица пагинации здесь блок, а не строка. По той же причине настройте селектор\n«Показывать по»: его стандартные варианты (20/50/100) рассчитаны на строки и для\nблоков не имеют смысла — задайте свой список `perPageList` в блоках, как выше,\nлибо спрячьте селектор (`hasPerPage: false`). Если дерево приходит с сервера\nчастями, вместо `slice` будет запрос следующей страницы — контракт тот же.\n\n### Редактирование: правки возвращаются листьями\n\nРедактируются листья. В `editing.onRowsChange` приходят изменённые строки-листья —\nзаписать их обратно в своё дерево должен потребитель, например по `id`:\n\n```tsx\nediting: {\n  rowKeyGetter: (r) => r.id,\n  onRowsChange: (updatedLeaves) => {\n    const byId = new Map(updatedLeaves.map((r) => [r.id, r]));\n    // Обойдите дерево и замените листья с совпавшими id.\n    setTree((prev) => writeLeavesBack(prev, byId));\n  },\n},\n```\n\nЭто следствие владения данными: таблица не знает, как устроено ваше дерево,\nпоэтому отдаёт плоский результат, а раскладываете его вы.\n\n### Что остаётся на вашей стороне\n\n- **Поиск, сортировка, фильтрация** — встроенные механизмы к структурному дереву\n  пока не применяются. Отфильтровали или отсортировали своё дерево — передали\n  результат в `rows`, таблица показала.\n- **Выделение** при этом работает из коробки: один чекбокс на верхний блок, клик\n  выделяет все его листья (подробнее — в разделе про выделение ниже).\n\nЖивой пример всего вместе — стори «subRows: дерево с пагинацией» на странице\n[Docs](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging--docs).\n\n## Объединение и остальные возможности таблицы\n\nБлоки — не отдельный мир: выделение, сортировка, буфер обмена и редактирование\nпродолжают работать. Здесь собрано, как именно.\n\n### Выделение, нумерация и навигация\n\nВыделение настраивается как обычно — `selecting` со стейтом и `rowKeyGetter`.\nА вот ведёт оно себя по-разному в зависимости от способа объединения:\n\n- **Плоский вид с mergeByCellValues** — чекбокс у каждой строки, номер у каждой\n  строки. Объединение колонок на выделение не влияет: в стори\n  «mergeByCellValues: пример с серверными данными» можно выделить одного\n  сотрудника внутри слитого блока.\n- **Merged-виды группировки и subRows** — один чекбокс и один номер на группу\n  верхнего уровня. Клик по чекбоксу выделяет все строки группы разом, повторный —\n  снимает. «Выделить всё» в шапке тоже работает. Счётчик выбранного внизу\n  считает строки, а не группы: выделили дивизион из 12 сотрудников — внизу\n  «выбрано 12».\n\nСпециально настраивать групповое поведение не нужно: таблица включает его сама,\nкогда активен merged-вид.\n\nНавигация тоже понимает блоки: клик в любую точку блока выделяет его целиком,\nрамка фокуса рисуется вокруг всего блока, один шаг стрелкой перепрыгивает блок.\nПопасть «внутрь» блока с клавиатуры нельзя — для таблицы это одна ячейка.\n\n### Сортировка, фильтрация, поиск и пагинация\n\nВозможности зависят от того, кто владеет данными.\n\n**mergeByCellValues (плоский вид).** Встроенные сортировка, фильтр и поиск\nработают как обычно, а блоки пересобираются после каждого изменения порядка —\nобъединение всегда отражает текущий видимый список строк. Если данные приходят с\nсервера постранично, следите, чтобы сортировка на сервере не разрывала группы:\nполовина группы на одной странице и половина на другой будут выглядеть как два\nотдельных блока.\n\n**rowsGrouping (view: 'merged').** Встроенные поиск, сортировка и фильтры\nработают: таблица применяет их к строкам до сборки групп, поэтому группы всегда\nсобираются из уже отфильтрованного списка. Пагинации нет: группировке нужны все\nстроки сразу. Сортировку по группирующим колонкам можно снять настройкой\n`disableGroupColumnsSort` — как в дереве, где сгруппированные колонки не\nсортируются.\n\nЧастая ошибка при встроенных фильтрах (не только в этом виде): в стейте\n`filtering.state` должен быть ключ каждого фильтра, объявленного в колонках.\nSelect-фильтр без своего ключа получит пустое значение вместо «показать всё» и\nможет отсеять все строки — таблица окажется пустой без единой ошибки.\n\n**subRows (view: 'merged').** Дерево у потребителя, поэтому пагинация по верхним\nблокам работает: отдаёте страницу дерева — таблица её показывает. Встроенные\nпоиск, сортировка и фильтрация к структурному дереву пока не применяются — эти\nоперации делаются на стороне потребителя над его данными.\n\n### Копирование, вставка и протяжка\n\n- Копирование отдаёт значение в позиции верхней-левой ячейки блока, остальные\n  ячейки блока в буфере пустые — как в Excel.\n- Вставка пишет во весь блок: значение попадает во все его строки.\n- Протяжка (fill) растягивается только до целых блоков — залить пол-блока нельзя;\n  пунктирная рамка протяжки сама прилипает к границам блоков.\n\n### Редактирование\n\n- Правка ячейки блока записывает значение во все его строки — данные под блоком\n  всегда совпадают с тем, что на экране.\n- При объединении по значению правка пересобирает блоки: изменили «Отдел» у\n  блока — он разъедется или сольётся с соседним, потому что объединение выводится\n  из данных.\n- У редактируемых Select-ячеек редактор открывается по выравниванию блока: текст\n  прижат к низу — редактор откроется у нижнего края, а выпадающий список\n  раскроется вверх.\n\n## Выравнивание контента в блоке\n\nПо умолчанию контент блока выравнивается по горизонтали как обычная ячейка\nэтой колонки — из `contentFormat.alignContent` (у числового формата это правый\nкрай), иначе слева. По вертикали — по центру: у обычной ячейки вертикального\nвыравнивания нет, это чисто блочная настройка. Настраивается лестницей «точечное важнее\nобщего»:\n\n- `mergedCellsAlign` конкретного региона (только для `mergedCellsRegions`);\n- `mergedCellsAlign` на колонке — все блоки этой колонки, работает для всех\n  способов включения;\n- дефолт фичи: `mergeCells.mergedCellsAlign` или `rowsGrouping.mergedCellsAlign`.\n\n```tsx\ncolumnConfig={[\n  { key: 'dept', name: 'Отдел', mergedCellsAlign: { horizontal: 'center', vertical: 'top' } },\n]}\n```\n\nКолоночный `mergedCellsAlign` может быть и функцией `(row) => MergedCellsAlign`\nпо данным строки блока — так разные блоки одной колонки получают разное\nвыравнивание. Это единственный способ управлять выравниванием поблочно в\nmerged-видах группировки и subRows, где границы блоков решает таблица, а не\nпотребитель.\n\n```tsx\ncolumnConfig={[\n  { key: 'dept', mergedCellsAlign: (row) =>\n      row.critical ? { vertical: 'top' } : { vertical: 'center' } },\n]}\n```\n\n### Свой рендер в блоке\n\nВыравнивание действует на текстовый контент. Кастомный `renderCell` получает весь\nпрямоугольник блока и выравнивает содержимое сам — через свойства своих\nконтейнеров.\n\nУ колонок со своим рендером есть неочевидность: предпросмотр значения (по\nдвойному клику на ячейке без редактирования) у них по умолчанию выключен.\nСо стороны это выглядит как «у блоков не открывается предпросмотр», хотя дело в\nколонке, а не в объединении. Включается настройкой колонки:\n\n```tsx\n{ key: 'dept', renderCell: ..., renderCellPreview: 'cellEditorAsPreview' }\n```\n\n## Что не работает и почему\n\nСводный список ограничений. Если «что-то не рисуется» — сначала сюда.\n\n### Во всех способах\n\n- Все ячейки блока обязаны нести одинаковые данные — это контракт\n  `mergeByCellValues` (значения реально повторяются в строках) и регионов.\n  Причина проста: блок показывает верхнюю-левую **видимую** ячейку, а какая\n  ячейка окажется верхней-левой — зависит от закрепления и порядка колонок.\n  Если данные одинаковые, блок выглядит одинаково при любой перестановке.\n- Попасть «внутрь» блока с клавиатуры нельзя — для таблицы это одна ячейка.\n  Это поведение, а не ошибка.\n- Выравнивание пока не поддерживает письмо справа налево (RTL).\n- Горизонтальная протяжка через colSpan-блок не растягивается до границ блока\n  (в работе).\n- У колонок со своим `renderCell` по умолчанию выключен предпросмотр значения —\n  включается `renderCellPreview: 'cellEditorAsPreview'` (см. «Свой рендер в\n  блоке» выше).\n\n### mergedCellsRegions\n\n- Разорванный регион исчезает молча: если после сортировки, перестановки или\n  скрытия колонок ключи региона перестали идти подряд, блок просто не рисуется.\n  Ошибок и предупреждений нет — следите за порядком сами.\n\n### rowsGrouping (view: 'merged')\n\n- Пагинации нет: чтобы собрать группы, таблице нужны все строки сразу.\n- Отдельная колонка «Группировка» не создаётся, поэтому не действует всё, что к\n  ней привязано: `groupedColumnProps`, свой контент ячейки группы\n  (`renderGroupCell` у колонки) и кнопка «развернуть всё» (`expandAllBtn`) —\n  строк-групп и шевронов в этом виде нет.\n\n### subRows (view: 'merged')\n\n- Встроенные поиск, сортировка и фильтрация к структурному дереву не\n  применяются — эти операции делает потребитель над своими данными.\n- `column.subRow` целиком не действует: шеврон (`isColumnWithArrow`), свой\n  контент и ключи вложенных уровней (`renderSubRowCell`, `keyOfColumnInSubRow`,\n  `parentKeyAsDefault`, `contentFormat`), свой редактор уровня. Листья рисуются\n  как обычные строки — работают их обычные `renderCell`, `contentFormat` и\n  `editingCell`.\n- `expandedIdsState` и сворачивание не действуют: раскрывать нечего, дерево\n  показано целиком.\n\nЭто осознанное поведение: один и тот же конфиг `subRows` или `rowsGrouping`\nможно переключать между `view: 'tree'` и `view: 'merged'` — лишние настройки\nдругого вида не мешают. Пометки «работает только в виде дерева» есть и в\nподсказках типов.\n\n> Подробнее о типах — [CellsMerging API](?path=/docs/локальные-компоненты-tablecanvas-cellsmerging-api--docs)",
      "apiDocs": "# CellsMerging API\n\n## tableConfig.mergeCells\n\nТочка входа для объединения ячеек тела. Все поля опциональны:\n\n```ts\nmergeCells?: {\n  /** Колонки, объединяемые по подряд идущим одинаковым значениям. */\n  mergeByCellValues?: Array<string | { colKey: string; value: (row) => unknown }>;\n  /** Управляемый список объединений по ключам строк и колонок. */\n  mergedCellsRegions?: MergedCellsRegion[];\n  /** Нужен для mergedCellsRegions: сопоставляет rowKeys со строками. */\n  rowKeyGetter?: (row) => string | number;\n  /** Общий (табличный) дефолт выравнивания контента в блоках. */\n  mergedCellsAlign?: MergedCellsAlign;\n};\n```\n\n## MergedCellsRegion\n\nОдин управляемый регион: ключи строк, ключи колонок и точечное выравнивание.\n\n```typescript\ntype MergedCellsRegion = {\n  rowKeys: Array<string | number>;\n  colKeys: string[];\n  /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n  mergedCellsAlign?: MergedCellsAlign;\n};\n```\n\n## MergedCellsAlign\n\nВыравнивание контента в блоке. Задаётся на трёх уровнях: `mergedCellsAlign` региона,\n`columnConfig[].mergedCellsAlign` (колонка), `mergeCells.mergedCellsAlign` или\n`rowsGrouping.mergedCellsAlign` (дефолт). Точечное важнее общего.\n\nКолоночный `mergedCellsAlign` — это `MergedCellsAlign` (одно на все блоки колонки) или\nфункция `(row) => MergedCellsAlign | undefined` по данным верхней строки блока. Функция\nдаёт разное выравнивание разным блокам, включая merged-виды группировки/subRows, где\nграницы блоков решает таблица.\n\n```tsx\ncolumnConfig={[\n  { key: 'dept', mergedCellsAlign: (row) =>\n      row.critical ? { vertical: 'top' } : { vertical: 'center' } },\n]}\n```\n\n```typescript\ntype MergedCellsAlign = {\n  /** По горизонтали. @default из `contentFormat.alignContent` колонки, иначе 'left' */\n  horizontal?: 'left' | 'center' | 'right';\n  /** По вертикали. @default 'center' */\n  vertical?: 'top' | 'center' | 'bottom';\n};\n```\n\n## rowsGrouping (merged-вид)\n\nПоля группировки, относящиеся к merged-виду: `view: 'merged'`,\n`mergedCellsAlign`, `disableGroupColumnsSort`.\n\n```typescript\ntype RowsGrouping<\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n  ColumnConfig extends LocalColumnInstance = LocalColumnInstance,\n> = {\n  /**\n   * массив группированных колонок и его setter\n   */\n  groupByState: [string[], React.Dispatch<React.SetStateAction<string[]>>];\n  /**\n   * Как показывать группировку.\n   * 'tree' (по умолчанию) — дерево с раскрытием (шевроны) и колонкой группировки.\n   * 'merged' — плоский вид: строки идут по группам, а группирующие колонки\n   * показаны объединёнными ячейками. Раскрытия нет; чекбокс и номер — на всю\n   * группу верхнего уровня.\n   * @default 'tree'\n   */\n  view?: 'tree' | 'merged';\n  /**\n   * Только для view: 'merged'. Выравнивание по умолчанию в объединённых ячейках\n   * группирующих колонок. Колоночный mergedCellsAlign важнее.\n   */\n  mergedCellsAlign?: MergedCellsAlign;\n  /**\n   * Только для view: 'merged'. Запретить сортировку по группирующим колонкам\n   * (как в дереве). По остальным колонкам сортировка остаётся.\n   * @default false\n   */\n  disableGroupColumnsSort?: boolean;\n  /**\n   * Функция определения уникального id строки\n   */\n  rowKeyGetter: (row: RowType) => string | number;\n  /**\n   * Показывать ли кнопку «Группировать» в controlBlock.\n   * При `false` кнопка скрыта и не участвует в компрессии,\n   * но группировка строк продолжает работать от внешнего `groupByState`.\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * Настройки колонки «Группировка» (имя, ширина, свои рендеры). Работает только\n   * в виде дерева: при view: 'merged' эта колонка не создаётся, а сгруппированные\n   * колонки остаются на своих местах.\n   * @default 'Группировка'\n   */\n  groupedColumnProps?: Partial<Pick<ColumnConfig, 'name' | 'width'>> & {\n    renderCell?: (\n      props: CellInfoGlideInstance<RowType, SummaryRowType> & {\n        parentGroupKey: string | undefined;\n        groupByArr: string[];\n      },\n    ) => CanvasContent;\n    rowsGrouping?: Pick<\n      ColumnRowsGrouping<RowType, ColumnConfig>,\n      'renderGroupCell'\n    >;\n  };\n  /** Кнопка «развернуть всё». Работает только в виде дерева: при view: 'merged' шевронов нет. */\n  expandAllBtn?: {\n    /**\n     * Функция для расчета состояния открытости всех раскрываемых строк. Функция должна быть чистой.\n     * @returns boolean\n     */\n    expandedAll: (p: {\n      /**\n       * allRowsIds - уникальные идентификаторы всех строк (группировок и обычных)\n       */\n      allRowsIds: Set<string | number> | null;\n      /**\n       * shownRows - представленные прямо сейчас строки (группировки и обычные). Или видимые строки - видимые не во viewport-е, а которые должны быть показаны из-за раскрытий)\n       */\n      shownRows: readonly RowType[];\n      expandedRowsIds: Set<string | number>;\n    }) => boolean;\n  };\n  /**\n   * `groupButton` - свойство для кастомизации кнопки с выпадающим списком\n   */\n  groupButton?: {\n    getGroupedCount?: (props: {\n      /**\n       * высчитанное автоматически количество активных группировок.\n       */\n      currCount: number;\n      /**\n       * активные группировки.\n       */\n      groupedCols: string[];\n      columns: {\n        /**\n         * `visible` - видимые в выпадающем списке колонки-группировки.\n         */\n        visible: string[];\n        /**\n         * `hidden` - невидимые  или не участвующие в группировке колонки\n         *\n         * (columnConfig.rowsGrouping=undefined ||\n         *  columnConfig.rowsGrouping.groupByColumn=false).\n         */\n        hidden: string[];\n      };\n    }) => number;\n    /**\n     * `defaultCustomItems` - свойство для добавления ключей группировки, которых нет в таблице.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    defaultCustomItems?: DropdownItemOption[];\n    /**\n     * `onItemSelect` - свойство для полного контроля над изменением группировки при выборе опций.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    onItemSelect?: (props: {\n      item: DropdownItemOption;\n      setGroupedCols: React.Dispatch<React.SetStateAction<string[]>>;\n      columns: {\n        visible: string[];\n        hidden: string[];\n      };\n    }) => void;\n  };\n  /**\n   * `groupRowReplaceTo` - свойство для изменения данных сгруппированных строк. Может понадобиться в редких случаях.\n   *\n   * @param groupRow данные сгруппированной строки\n   * @returns измененная группировка или строка без группировки — строка, которые заменит groupRow\n   */\n  groupRowReplaceTo?: (\n    groupRow: GroupRow<RowType>,\n  ) => GroupRow<RowType> | RowType;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n\nexport type RenderGroupCellProps<\n  RowType extends ObjectForExtending,\n  ColumnConfig extends LocalColumnInstance = LocalColumnInstance,\n> = {\n  column: ColumnConfig;\n  tabIndex: number;\n  theme?: Theme;\n  // TODO isExpanded: boolean;\n  // TODO toggleGroup: () => void;\n} & GroupRow<RowType>;\n\nexport type ColumnRowsGrouping<\n  RowType extends ObjectForExtending,\n  ColumnConfig extends LocalColumnInstance,\n> = {\n  /**\n   * @default true - при наличии ColumnConfig.rowsGrouping\n   */\n  groupByColumn?: boolean;\n  /**\n   * @default ColumnConfig.key\n   */\n  columnGroupLabel?: string;\n  /**\n   * Свой контент ячейки строки-группы. Работает только в виде дерева: при\n   * view: 'merged' строк-групп нет (группы показаны объединёнными ячейками),\n   * поэтому этот рендер не вызывается.\n   */\n  renderGroupCell?: (\n    props: RenderGroupCellProps<RowType, ColumnConfig>,\n  ) => CanvasContent;\n};\n```\n\n## subRows (merged-вид)\n\nПоля subRows, относящиеся к merged-виду: `view: 'merged'` и `mergedColumns`\n(упорядоченный список колонок-предков, индекс = глубина уровня дерева).\n\n```typescript\ntype SubRows<RowType, RowIdType> = {\n  /**\n   * Возвращает дочерние строки узла (или undefined, если их нет).\n   *\n   * Функция должна быть стабильной — не менять поведение между рендерами.\n   * Если она зависит от чего-то меняющегося, оберните её в useCallback.\n   */\n  getSubRows: (row: RowType) => RowType[] | undefined;\n  /**\n   * Возвращает уникальный ключ строки.\n   *\n   * Функция должна быть стабильной — не менять поведение между рендерами.\n   * Если она зависит от чего-то меняющегося, оберните её в useCallback.\n   */\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * Внешний стейт развёрнутых строк.\n   * Если не задан — используется внутренний useState.\n   * При view: 'merged' не используется: сворачивания в этом виде нет.\n   */\n  expandedIdsState?: [\n    Set<string | number>,\n    (\n      newV:\n        | Set<string | number>\n        | ((prev: Set<string | number>) => Set<string | number>),\n    ) => void,\n  ];\n  /**\n   * Как показывать дерево.\n   * 'tree' (по умолчанию) — узлы с раскрытием (шевроны) и отступом по уровню.\n   * 'merged' — дерево разворачивается в листья, а колонки-предки показаны\n   * объединёнными ячейками. Структуру задаёт потребитель через getSubRows;\n   * данные (пагинация, сортировка, поиск) остаются на его стороне.\n   */\n  view?: 'tree' | 'merged';\n  /**\n   * Только для view: 'merged'. Колонки-предки по порядку уровней:\n   * mergedColumns[0] — верхний уровень, дальше глубже. Каждая такая колонка\n   * показывает значение своего узла-предка (узел должен нести поле с этим именем)\n   * и объединяется по его границам. Верхний уровень задаёт чекбокс и номер блока.\n   */\n  mergedColumns?: string[];\n};\n```",
      "api": [
        {
          "typeName": "MergedCellsRegion",
          "source": "type MergedCellsRegion = {\n  rowKeys: Array<string | number>;\n  colKeys: string[];\n  /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n  mergedCellsAlign?: MergedCellsAlign;\n};"
        },
        {
          "typeName": "MergedCellsAlign",
          "source": "type MergedCellsAlign = {\n  /** По горизонтали. @default из `contentFormat.alignContent` колонки, иначе 'left' */\n  horizontal?: 'left' | 'center' | 'right';\n  /** По вертикали. @default 'center' */\n  vertical?: 'top' | 'center' | 'bottom';\n};"
        },
        {
          "typeName": "RowsGrouping",
          "source": "type RowsGrouping<\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n  ColumnConfig extends LocalColumnInstance = LocalColumnInstance,\n> = {\n  /**\n   * массив группированных колонок и его setter\n   */\n  groupByState: [string[], React.Dispatch<React.SetStateAction<string[]>>];\n  /**\n   * Как показывать группировку.\n   * 'tree' (по умолчанию) — дерево с раскрытием (шевроны) и колонкой группировки.\n   * 'merged' — плоский вид: строки идут по группам, а группирующие колонки\n   * показаны объединёнными ячейками. Раскрытия нет; чекбокс и номер — на всю\n   * группу верхнего уровня.\n   * @default 'tree'\n   */\n  view?: 'tree' | 'merged';\n  /**\n   * Только для view: 'merged'. Выравнивание по умолчанию в объединённых ячейках\n   * группирующих колонок. Колоночный mergedCellsAlign важнее.\n   */\n  mergedCellsAlign?: MergedCellsAlign;\n  /**\n   * Только для view: 'merged'. Запретить сортировку по группирующим колонкам\n   * (как в дереве). По остальным колонкам сортировка остаётся.\n   * @default false\n   */\n  disableGroupColumnsSort?: boolean;\n  /**\n   * Функция определения уникального id строки\n   */\n  rowKeyGetter: (row: RowType) => string | number;\n  /**\n   * Показывать ли кнопку «Группировать» в controlBlock.\n   * При `false` кнопка скрыта и не участвует в компрессии,\n   * но группировка строк продолжает работать от внешнего `groupByState`.\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * Настройки колонки «Группировка» (имя, ширина, свои рендеры). Работает только\n   * в виде дерева: при view: 'merged' эта колонка не создаётся, а сгруппированные\n   * колонки остаются на своих местах.\n   * @default 'Группировка'\n   */\n  groupedColumnProps?: Partial<Pick<ColumnConfig, 'name' | 'width'>> & {\n    renderCell?: (\n      props: CellInfoGlideInstance<RowType, SummaryRowType> & {\n        parentGroupKey: string | undefined;\n        groupByArr: string[];\n      },\n    ) => CanvasContent;\n    rowsGrouping?: Pick<\n      ColumnRowsGrouping<RowType, ColumnConfig>,\n      'renderGroupCell'\n    >;\n  };\n  /** Кнопка «развернуть всё». Работает только в виде дерева: при view: 'merged' шевронов нет. */\n  expandAllBtn?: {\n    /**\n     * Функция для расчета состояния открытости всех раскрываемых строк. Функция должна быть чистой.\n     * @returns boolean\n     */\n    expandedAll: (p: {\n      /**\n       * allRowsIds - уникальные идентификаторы всех строк (группировок и обычных)\n       */\n      allRowsIds: Set<string | number> | null;\n      /**\n       * shownRows - представленные прямо сейчас строки (группировки и обычные). Или видимые строки - видимые не во viewport-е, а которые должны быть показаны из-за раскрытий)\n       */\n      shownRows: readonly RowType[];\n      expandedRowsIds: Set<string | number>;\n    }) => boolean;\n  };\n  /**\n   * `groupButton` - свойство для кастомизации кнопки с выпадающим списком\n   */\n  groupButton?: {\n    getGroupedCount?: (props: {\n      /**\n       * высчитанное автоматически количество активных группировок.\n       */\n      currCount: number;\n      /**\n       * активные группировки.\n       */\n      groupedCols: string[];\n      columns: {\n        /**\n         * `visible` - видимые в выпадающем списке колонки-группировки.\n         */\n        visible: string[];\n        /**\n         * `hidden` - невидимые  или не участвующие в группировке колонки\n         *\n         * (columnConfig.rowsGrouping=undefined ||\n         *  columnConfig.rowsGrouping.groupByColumn=false).\n         */\n        hidden: string[];\n      };\n    }) => number;\n    /**\n     * `defaultCustomItems` - свойство для добавления ключей группировки, которых нет в таблице.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    defaultCustomItems?: DropdownItemOption[];\n    /**\n     * `onItemSelect` - свойство для полного контроля над изменением группировки при выборе опций.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    onItemSelect?: (props: {\n      item: DropdownItemOption;\n      setGroupedCols: React.Dispatch<React.SetStateAction<string[]>>;\n      columns: {\n        visible: string[];\n        hidden: string[];\n      };\n    }) => void;\n  };\n  /**\n   * `groupRowReplaceTo` - свойство для изменения данных сгруппированных строк. Может понадобиться в редких случаях.\n   *\n   * @param groupRow данные сгруппированной строки\n   * @returns измененная группировка или строка без группировки — строка, которые заменит groupRow\n   */\n  groupRowReplaceTo?: (\n    groupRow: GroupRow<RowType>,\n  ) => GroupRow<RowType> | RowType;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n\nexport type RenderGroupCellProps<\n  RowType extends ObjectForExtending,\n  ColumnConfig extends LocalColumnInstance = LocalColumnInstance,\n> = {\n  column: ColumnConfig;\n  tabIndex: number;\n  theme?: Theme;\n  // TODO isExpanded: boolean;\n  // TODO toggleGroup: () => void;\n} & GroupRow<RowType>;\n\nexport type ColumnRowsGrouping<\n  RowType extends ObjectForExtending,\n  ColumnConfig extends LocalColumnInstance,\n> = {\n  /**\n   * @default true - при наличии ColumnConfig.rowsGrouping\n   */\n  groupByColumn?: boolean;\n  /**\n   * @default ColumnConfig.key\n   */\n  columnGroupLabel?: string;\n  /**\n   * Свой контент ячейки строки-группы. Работает только в виде дерева: при\n   * view: 'merged' строк-групп нет (группы показаны объединёнными ячейками),\n   * поэтому этот рендер не вызывается.\n   */\n  renderGroupCell?: (\n    props: RenderGroupCellProps<RowType, ColumnConfig>,\n  ) => CanvasContent;\n};"
        },
        {
          "typeName": "SubRows",
          "source": "type SubRows<RowType, RowIdType> = {\n  /**\n   * Возвращает дочерние строки узла (или undefined, если их нет).\n   *\n   * Функция должна быть стабильной — не менять поведение между рендерами.\n   * Если она зависит от чего-то меняющегося, оберните её в useCallback.\n   */\n  getSubRows: (row: RowType) => RowType[] | undefined;\n  /**\n   * Возвращает уникальный ключ строки.\n   *\n   * Функция должна быть стабильной — не менять поведение между рендерами.\n   * Если она зависит от чего-то меняющегося, оберните её в useCallback.\n   */\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * Внешний стейт развёрнутых строк.\n   * Если не задан — используется внутренний useState.\n   * При view: 'merged' не используется: сворачивания в этом виде нет.\n   */\n  expandedIdsState?: [\n    Set<string | number>,\n    (\n      newV:\n        | Set<string | number>\n        | ((prev: Set<string | number>) => Set<string | number>),\n    ) => void,\n  ];\n  /**\n   * Как показывать дерево.\n   * 'tree' (по умолчанию) — узлы с раскрытием (шевроны) и отступом по уровню.\n   * 'merged' — дерево разворачивается в листья, а колонки-предки показаны\n   * объединёнными ячейками. Структуру задаёт потребитель через getSubRows;\n   * данные (пагинация, сортировка, поиск) остаются на его стороне.\n   */\n  view?: 'tree' | 'merged';\n  /**\n   * Только для view: 'merged'. Колонки-предки по порядку уровней:\n   * mergedColumns[0] — верхний уровень, дальше глубже. Каждая такая колонка\n   * показывает значение своего узла-предка (узел должен нести поле с этим именем)\n   * и объединяется по его границам. Верхний уровень задаёт чекбокс и номер блока.\n   */\n  mergedColumns?: string[];\n};"
        }
      ],
      "stories": [
        {
          "exportName": "BigDataExample",
          "displayName": "Большой набор данных (строки × колонки)",
          "type": "full-code",
          "code": "() => {\n    const [cols, setCols] = useState(1000);\n    const [rowInput, setRowInput] = useState('50000');\n    const [rowTarget, setRowTarget] = useState(50000);\n    const [withMerge, setWithMerge] = useState(true);\n    const [heavyCells, setHeavyCells] = useState(true);\n    const [withEditing, setWithEditing] = useState(false);\n    // Правки пользователя поверх сгенерированных данных (режим редактирования).\n    const [editedRows, setEditedRows] = useState<Node[] | null>(null);\n\n    const commitsRef = useRef<number[]>([]);\n    const onRender = useCallback(\n      (_id: string, _phase: string, actualDuration: number) => {\n        commitsRef.current.push(actualDuration);\n      },\n      [],\n    );\n\n    const { rows: builtRows, leaves } = useMemo(\n      () => buildData(rowTarget, withMerge),\n      [rowTarget, withMerge],\n    );\n\n    useEffect(() => {\n      setEditedRows(null);\n    }, [builtRows]);\n\n    const dataRows = editedRows ?? builtRows;\n\n    const columns = useMemo(\n      () => buildColumns(cols, heavyCells, withEditing),\n      [cols, heavyCells, withEditing],\n    );\n\n    const tableConfig = useMemo(\n      () => ({\n        containerStyle: { height: '70vh' },\n        rowMarkers: { startIndex: 1 },\n        resizableColumn: true,\n        columnsControl: {\n          enable: true,\n          pinning: true,\n        },\n        ...(withMerge\n          ? {\n              subRows: {\n                getSubRows: (row: Node) => row?.subRows,\n                rowKeyGetter: (row: Node) => row.id,\n                view: 'merged' as const,\n                mergedColumns: ['division', 'unit', 'team'],\n              },\n            }\n          : {}),\n        ...(withEditing\n          ? {\n              editing: {\n                onRowsChange: (next: Node[]) => setEditedRows(next),\n                rowKeyGetter: (r: Node) => r.id,\n              },\n            }\n          : {}),\n      }),\n      [withMerge, withEditing],\n    );\n\n    return (\n      <div>\n        <StoryHint>\n          Пример на большом наборе данных: настройте число колонок и строк,\n          включите нужные режимы и проверяйте выделение, скролл, сайдбар и\n          редактирование. HUD справа показывает метрики производительности: FPS\n          — кадров в секунду (ниже 40 подсвечивается красным); «коммитов/с» —\n          сколько раз в секунду React перерендерил таблицу (при протяжке\n          выделения каждый шаг мыши даёт один коммит); «коммит сред/макс» —\n          среднее и максимальное время одного такого перерендера в\n          миллисекундах, то есть цена реакции таблицы на одно действие.\n        </StoryHint>\n\n        <div\n          style={{\n            display: 'flex',\n            gap: 24,\n            alignItems: 'center',\n            flexWrap: 'wrap',\n            padding: '8px 4px 12px',\n            fontSize: 13,\n          }}\n        >\n          <span style={{ display: 'flex', gap: 8, alignItems: 'center' }}>\n            Колонок: <b style={{ minWidth: 42 }}>{cols}</b>\n            <div style={{ width: 220 }}>\n              <Slider\n                value={cols}\n                min={1}\n                max={1500}\n                onChangeCommitted={(value) => setCols(value)}\n              />\n            </div>\n          </span>\n\n          <span style={{ display: 'flex', gap: 8, alignItems: 'center' }}>\n            Строк:\n            <div style={{ width: 130 }}>\n              <TextField\n                value={rowInput}\n                type=\"number\"\n                size=\"s\"\n                onChange={(e) => setRowInput(e.target.value)}\n              />\n            </div>\n            <Button\n              size=\"s\"\n              view=\"secondary\"\n              onClick={() => setRowTarget(Math.max(1, Number(rowInput) || 1))}\n            >\n              Построить\n            </Button>\n            <span style={{ opacity: 0.75 }}>\n              (листьев: <b>{fmt(leaves)}</b>)\n            </span>\n          </span>\n\n          <Checkbox\n            label=\"объединение (subRows merged)\"\n            checked={withMerge}\n            onChange={(e) => setWithMerge(e.target.checked)}\n          />\n\n          <Checkbox\n            label=\"тяжёлые ячейки (Canvas.Badge)\"\n            checked={heavyCells}\n            onChange={(e) => setHeavyCells(e.target.checked)}\n          />\n\n          <Checkbox\n            label=\"редактирование (error-ячейки)\"\n            checked={withEditing}\n            onChange={(e) => setWithEditing(e.target.checked)}\n          />\n\n          <PerfHudBadge commitsRef={commitsRef} />\n        </div>\n\n        <Profiler id=\"big-data-table\" onRender={onRender}>\n          <TableCanvas\n            tableConfig={tableConfig}\n            columnConfig={columns}\n            rows={dataRows as Node[]}\n          />\n        </Profiler>\n      </div>\n    );\n  }"
        },
        {
          "exportName": "RowSpanBasic",
          "displayName": "mergeByCellValues: объединение по значению",
          "type": "full-code",
          "code": "import { useMemo, useRef, useState } from 'react';\nimport { Select } from '@daisforge/ui';\nimport {\n  Canvas,\n  type CellsSelectionMode,\n  type ColumnConfig,\n  type HighlightActiveType,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\ntype Row = {\n  id: number;\n  role: string;\n  dept: string;\n  period: string;\n  plan: number;\n  fact: number;\n};\n\n// role/dept повторяются в данных блоками по 3 строки — объединение\n// выводится из повторяющихся значений, данные не мутируются.\nconst GROUPS = [\n  { role: 'Аналитик', dept: 'Отдел A' },\n  { role: 'Разработчик', dept: 'Отдел B' },\n  { role: 'Тестировщик', dept: 'Отдел C' },\n  { role: 'Менеджер', dept: 'Отдел D' },\n];\nconst PERIODS = ['Q1', 'Q2', 'Q3'];\nconst INITIAL_ROWS: Row[] = [];\nlet counter = 1;\nfor (const g of GROUPS) {\n  for (const p of PERIODS) {\n    INITIAL_ROWS.push({\n      id: counter,\n      role: g.role,\n      dept: g.dept,\n      period: p,\n      plan: counter * 10,\n      fact: counter * 8,\n    });\n    counter += 1;\n  }\n}\n\nconst SELECTION_MODE_OPTIONS: Array<{\n  label: string;\n  value: CellsSelectionMode;\n}> = [\n  { label: 'cell', value: 'cell' },\n  { label: 'range-cell', value: 'range-cell' },\n  { label: 'multi-range-cell', value: 'multi-range-cell' },\n  { label: 'disabled', value: 'disabled' },\n];\n\nconst HIGHLIGHT_ACTIVE_TYPE_OPTIONS: Array<{\n  label: string;\n  value: HighlightActiveType;\n}> = [\n  { label: 'row', value: 'row' },\n  { label: 'disabled', value: 'disabled' },\n];\n\nexport const Example = () => {\n  const [rows, setRows] = useState<Row[]>(INITIAL_ROWS);\n  const beforeEditRef = useRef(rows);\n  const [selectionMode, setSelectionMode] =\n    useState<CellsSelectionMode>('range-cell');\n  const [highlightActiveType, setHighlightActiveType] =\n    useState<HighlightActiveType>('disabled');\n\n  const columns = useMemo<readonly ColumnConfig<Row>[]>(\n    () => [\n      { key: 'role', name: 'Роль (merge ×3)', width: 220 },\n      {\n        key: 'dept',\n        name: 'Отдел (custom + merge ×3)',\n        width: 220,\n        renderCell: ({ row, theme }) => (\n          <Canvas.Container padding={8} alignItems=\"center\" justifyContent=\"center\">\n            <Canvas.Text color={theme.textDark}>{row.dept}</Canvas.Text>\n          </Canvas.Container>\n        ),\n        copyData: (row) => row.dept,\n        // У canvas-колонок превью по умолчанию выключено — включаем явно.\n        renderCellPreview: 'cellEditorAsPreview',\n      },\n      { key: 'period', name: 'Период', width: 120, editingCell: { component: 'inputString' } },\n      { key: 'plan', name: 'План', width: 120, editingCell: { component: 'inputNumber' } },\n      { key: 'fact', name: 'Факт', width: 120, editingCell: { component: 'inputNumber' } },\n    ],\n    [],\n  );\n\n  return (\n    <div>\n      <div style={{ display: 'flex', gap: 16, marginBottom: 12 }}>\n        <Select\n          target=\"textfield-like\"\n          label=\"Режим выделения\"\n          value={selectionMode}\n          onChange={(v) => setSelectionMode(v as CellsSelectionMode)}\n          items={SELECTION_MODE_OPTIONS}\n        />\n        <Select\n          target=\"textfield-like\"\n          label=\"Highlight active\"\n          value={highlightActiveType}\n          onChange={(v) => setHighlightActiveType(v as HighlightActiveType)}\n          items={HIGHLIGHT_ACTIVE_TYPE_OPTIONS}\n        />\n      </div>\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '600px' },\n          highlightActiveType,\n          rowMarkers: { startIndex: 1 },\n          columnsControl: { enable: true },\n          rowSize: { default: 'medium', showInControl: true },\n          fullScreenEnabled: true,\n          mergeCells: { mergeByCellValues: ['role', 'dept'] },\n          cellsSelection: { mode: selectionMode, enableColumnSelection: true },\n          cellTransfer: { fillHandle: true },\n          editing: {\n            onRowsChange: setRows,\n            rowKeyGetter: (r) => \\"
        },
        {
          "exportName": "DerivedGroupingSortFilter",
          "displayName": "mergeByCellValues: сортировка и фильтр",
          "type": "full-code",
          "code": "import { useState } from 'react';\nimport {\n  type ColumnConfig,\n  type SortColumn,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\ntype Row = {\n  id: number;\n  role: string;\n  dept: string;\n  person: string;\n  plan: number;\n};\n\nconst GROUPS = [\n  { role: 'Аналитик', dept: 'Отдел A' },\n  { role: 'Разработчик', dept: 'Отдел B' },\n  { role: 'Тестировщик', dept: 'Отдел C' },\n  { role: 'Менеджер', dept: 'Отдел D' },\n];\nconst ALL: Row[] = [];\nlet counter = 1;\nfor (const g of GROUPS) {\n  for (let p = 0; p < 3; p += 1) {\n    ALL.push({\n      id: counter,\n      role: g.role,\n      dept: g.dept,\n      person: \\"
        },
        {
          "exportName": "SpanByWithEditing",
          "displayName": "mergeByCellValues: редактирование",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport {\n  type ColumnConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\ntype Row = { id: number; region: string; team: string; person: string };\n\n// 6 регионов × 4 строки: регион слит блоками по 4, команда — по 2 (вложенно).\nconst REGIONS = ['Север', 'Юг', 'Запад', 'Восток', 'Центр', 'Урал'];\nconst INITIAL_ROWS: Row[] = [];\nlet c = 1;\nfor (const region of REGIONS) {\n  for (let t = 0; t < 4; t += 1) {\n    INITIAL_ROWS.push({\n      id: c,\n      region,\n      team: \\"
        },
        {
          "exportName": "MergedSelectEditing",
          "displayName": "Select в объединённой ячейке",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport {\n  type ColumnConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\ntype Row = {\n  id: number;\n  status: string;\n  owner: string;\n  priority: string;\n  stage: string;\n  task: string;\n};\n\nconst STATUSES = ['В работе', 'Готово', 'Отменено', 'На паузе'];\nconst OWNERS = ['Иванов', 'Петров', 'Сидоров'];\nconst PRIORITIES = ['Высокий', 'Средний', 'Низкий'];\n// Неслитый Select (per-row) — для проверки обычных ячеек рядом со слитыми.\nconst STAGES = ['Анализ', 'Разработка', 'Тест', 'Релиз'];\n\n// Блоки разной высоты: 4 строки, 3 строки, 2 строки. Все три select-колонки\n// слиты синхронно (одинаковые границы).\nconst INITIAL_ROWS: Row[] = [\n  { id: 1, status: 'В работе', owner: 'Иванов', priority: 'Высокий', stage: 'Анализ', task: 'Задача 1' },\n  { id: 2, status: 'В работе', owner: 'Иванов', priority: 'Высокий', stage: 'Разработка', task: 'Задача 2' },\n  { id: 3, status: 'В работе', owner: 'Иванов', priority: 'Высокий', stage: 'Тест', task: 'Задача 3' },\n  { id: 4, status: 'В работе', owner: 'Иванов', priority: 'Высокий', stage: 'Релиз', task: 'Задача 4' },\n  { id: 5, status: 'Готово', owner: 'Петров', priority: 'Средний', stage: 'Анализ', task: 'Задача 5' },\n  { id: 6, status: 'Готово', owner: 'Петров', priority: 'Средний', stage: 'Разработка', task: 'Задача 6' },\n  { id: 7, status: 'Готово', owner: 'Петров', priority: 'Средний', stage: 'Тест', task: 'Задача 7' },\n  { id: 8, status: 'Отменено', owner: 'Сидоров', priority: 'Низкий', stage: 'Анализ', task: 'Задача 8' },\n  { id: 9, status: 'Отменено', owner: 'Сидоров', priority: 'Низкий', stage: 'Релиз', task: 'Задача 9' },\n];\n\nconst columns: readonly ColumnConfig<Row>[] = [\n  {\n    key: 'status',\n    name: 'Статус — низ/лево',\n    width: 220,\n    // Выравнивание контента блока: вертикаль низ, горизонталь лево.\n    mergedCellsAlign: { vertical: 'bottom', horizontal: 'left' },\n    editingCell: {\n      component: 'select',\n      options: {\n        type: 'constant',\n        options: STATUSES.map((s) => ({ text: s, value: s })),\n      },\n    },\n  },\n  {\n    key: 'owner',\n    name: 'Ответственный — низ/право',\n    width: 220,\n    mergedCellsAlign: { vertical: 'bottom', horizontal: 'right' },\n    editingCell: {\n      component: 'select',\n      options: {\n        type: 'constant',\n        options: OWNERS.map((s) => ({ text: s, value: s })),\n      },\n    },\n  },\n  {\n    key: 'priority',\n    name: 'Приоритет — центр/центр',\n    width: 200,\n    mergedCellsAlign: { vertical: 'center', horizontal: 'center' },\n    editingCell: {\n      component: 'select',\n      options: {\n        type: 'constant',\n        options: PRIORITIES.map((s) => ({ text: s, value: s })),\n      },\n    },\n  },\n  {\n    key: 'stage',\n    name: 'Этап (Select, НЕ слит)',\n    width: 200,\n    editingCell: {\n      component: 'select',\n      options: {\n        type: 'constant',\n        options: STAGES.map((s) => ({ text: s, value: s })),\n      },\n    },\n  },\n  {\n    key: 'task',\n    name: 'Задача (текст, не слит)',\n    width: 180,\n    editingCell: { component: 'inputString' },\n  },\n];\n\nexport const Example = () => {\n  const [rows, setRows] = useState<Row[]>(INITIAL_ROWS);\n  const beforeEditRef = useRef(rows);\n\n  return (\n    <TableCanvas\n      tableConfig={{\n        containerStyle: { height: '560px' },\n        rowMarkers: { startIndex: 1 },\n        columnsControl: { enable: true },\n        rowSize: { default: 'medium', showInControl: true },\n        fullScreenEnabled: true,\n        mergeCells: {\n          mergeByCellValues: ['status', 'owner', 'priority'],\n        },\n        cellsSelection: { mode: 'range-cell' },\n        editing: {\n          onRowsChange: setRows,\n          rowKeyGetter: (r) => \\"
        },
        {
          "exportName": "Colspan",
          "displayName": "mergedCellsRegions: заголовки секций",
          "type": "full-code",
          "code": "import { useMemo, useRef, useState } from 'react';\nimport {\n  Canvas,\n  type ColumnConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\ntype Row = {\n  id: number;\n  kind: 'header' | 'data';\n  label: string;\n  a: string;\n  b: string;\n};\n\n// Правило блока: данные одинаковы во всех его ячейках. Блок показывает свою\n// левую верхнюю видимую ячейку, а после закрепления или перестановки колонок\n// ею может стать другая колонка — заголовок при этом останется видимым.\nconst buildRows = (): Row[] => {\n  const out: Row[] = [];\n  let id = 1;\n  for (let s = 0; s < 3; s += 1) {\n    out.push({\n      id: id++,\n      kind: 'header',\n      label: \\"
        },
        {
          "exportName": "Rectangular",
          "displayName": "mergedCellsRegions: прямоугольный блок",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport {\n  Canvas,\n  type ColumnConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\ntype Row = { id: number; a: string; b: string; c: string; d: string };\n\nconst INITIAL_ROWS: Row[] = Array.from({ length: 10 }, (_, i) => ({\n  id: i + 1,\n  a: \\"
        },
        {
          "exportName": "ControlledSpans",
          "displayName": "mergedCellsRegions: управление кнопками",
          "type": "full-code",
          "code": "import { useState } from 'react';\nimport { Button } from '@daisforge/ui';\nimport {\n  type ColumnConfig,\n  type MergedCellsRegion,\n  type SortColumn,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\ntype Row = {\n  id: number;\n  dept: string;\n  role: string;\n  person: string;\n  plan: number;\n};\n\nconst GROUPS = [\n  { dept: 'Отдел A', role: 'Аналитик', ids: [1, 2, 3] },\n  { dept: 'Отдел B', role: 'Разработчик', ids: [4, 5, 6] },\n  { dept: 'Отдел C', role: 'Тестировщик', ids: [7, 8, 9, 10] },\n];\nconst ROWS: Row[] = [];\nfor (const g of GROUPS) {\n  for (const id of g.ids) {\n    ROWS.push({\n      id,\n      dept: g.dept,\n      role: g.role,\n      person: \\"
        },
        {
          "exportName": "FormatInBlock",
          "displayName": "Форматирование и свой рендер в блоке",
          "type": "full-code",
          "code": "import { useState } from 'react';\nimport { Button } from '@daisforge/ui';\nimport {\n  Canvas,\n  type ColumnConfig,\n  type MergedCellsRegion,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\ntype Row = {\n  id: number;\n  dept: string;\n  role: string;\n  person: string;\n  plan: number;\n  fact: number;\n};\n\n// dept/role повторяются в данных: 3 отдела, в каждом 2 роли по 2 сотрудника.\nconst DEPTS = [\n  { dept: 'Отдел A', roles: ['Аналитик', 'Разработчик'] },\n  { dept: 'Отдел B', roles: ['Разработчик', 'Тестировщик'] },\n  { dept: 'Отдел C', roles: ['Менеджер', 'Аналитик'] },\n];\nconst ROWS: Row[] = [];\nlet id = 1;\nfor (const d of DEPTS) {\n  for (const role of d.roles) {\n    for (let i = 0; i < 2; i += 1) {\n      ROWS.push({\n        id,\n        dept: d.dept,\n        role,\n        person: \\"
        },
        {
          "exportName": "Showcase",
          "displayName": "mergeByCellValues: пример с серверными данными",
          "type": "full-code",
          "code": "import { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  type ColumnConfig,\n  type ColumnOrColumnGroupConfig,\n  type SortColumn,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\n// Строка-лист: сотрудник, показатели и путь предков, продублированный в строке.\n// Ключи пути (divPath/unitPath/teamPath) учитывают предков — по ним\n// объединяются колонки-предки, одинаковые имена в разных ветках не сливаются.\ntype Row = {\n  id: string;\n  division: string;\n  unit: string;\n  team: string;\n  employee: string;\n  plan: number;\n  fact: number;\n  divPath: string;\n  unitPath: string;\n  teamPath: string;\n};\n\n// Оргструктура «от бэка»: дивизион -> управление -> команда -> сотрудники.\nconst ORG = [\n  {\n    name: 'Розничный бизнес',\n    units: [\n      { name: 'Управление продаж', teams: ['Команда Север', 'Команда Юг'] },\n      { name: 'Управление сервиса', teams: ['Команда Онлайн'] },\n    ],\n  },\n  {\n    name: 'Корпоративный бизнес',\n    units: [\n      { name: 'Управление КИБ', teams: ['Команда Крупные', 'Команда СМБ'] },\n    ],\n  },\n];\nconst SURNAMES = ['Иванов', 'Петрова', 'Сидоров', 'Кузнецова', 'Смирнов'];\n\nconst buildRows = (): Row[] => {\n  const out: Row[] = [];\n  let g = 0;\n  for (const div of ORG) {\n    for (const unit of div.units) {\n      for (const team of unit.teams) {\n        // По 12 сотрудников в команде — крупные блоки под merge и пагинацию.\n        for (let i = 0; i < 12; i += 1) {\n          const plan = 600000 + ((g * 37) % 18) * 100000;\n          out.push({\n            id: \\"
        },
        {
          "exportName": "SubRowsMerged",
          "displayName": "subRows: дерево с пагинацией",
          "type": "full-code",
          "code": "import { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  type ColumnConfig,\n  type SortColumn,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\n// Узел дерева: узлы-предки несут своё поле (division/unit/team), листья — строки с показателями.\ntype Node = {\n  id: string;\n  division?: string;\n  unit?: string;\n  team?: string;\n  employee?: string;\n  plan?: number;\n  fact?: number;\n  subRows?: Node[];\n};\n\nconst ORG = [\n  {\n    name: 'Розничный бизнес',\n    units: [\n      { name: 'Управление продаж', teams: ['Команда Север', 'Команда Юг'] },\n      { name: 'Управление сервиса', teams: ['Команда Онлайн'] },\n    ],\n  },\n  {\n    name: 'Корпоративный бизнес',\n    units: [\n      { name: 'Управление КИБ', teams: ['Команда Крупные', 'Команда СМБ'] },\n    ],\n  },\n];\nconst SURNAMES = ['Иванов', 'Петрова', 'Сидоров', 'Кузнецова', 'Смирнов'];\n\n// Дерево «от бэка»: дивизион -> управление -> команда -> сотрудники (листья).\nlet g = 0;\nconst TREE: Node[] = ORG.map((div, di) => ({\n  id: \\"
        },
        {
          "exportName": "GroupingMerged",
          "displayName": "rowsGrouping: группировка пользователем",
          "type": "full-code",
          "code": "import { useRef, useState } from 'react';\nimport {\n  type ColumnConfig,\n  type SortColumn,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\n// Плоские листья на входе, дерево строит сама таблица по groupByState.\ntype Row = {\n  id: string;\n  division: string;\n  unit: string;\n  team: string;\n  employee: string;\n  plan: number;\n  fact: number;\n};\n\nconst ORG = [\n  {\n    name: 'Розничный бизнес',\n    units: [\n      { name: 'Управление продаж', teams: ['Команда Север', 'Команда Юг'] },\n      { name: 'Управление сервиса', teams: ['Команда Онлайн'] },\n    ],\n  },\n  {\n    name: 'Корпоративный бизнес',\n    units: [\n      { name: 'Управление КИБ', teams: ['Команда Крупные', 'Команда СМБ'] },\n    ],\n  },\n];\nconst SURNAMES = ['Иванов', 'Петрова', 'Сидоров', 'Кузнецова', 'Смирнов'];\n\nconst buildRows = (): Row[] => {\n  const out: Row[] = [];\n  let g = 0;\n  for (const div of ORG) {\n    for (const unit of div.units) {\n      for (const team of unit.teams) {\n        for (let i = 0; i < 12; i += 1) {\n          const plan = 600000 + ((g * 37) % 18) * 100000;\n          out.push({\n            id: \\"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "ColumnResize",
      "legacy": false,
      "summary": "Ограничения ширины колонок. Задаются на уровне колонки (`columnConfig`) или глобально в `tableConfig`.",
      "docs": "# Column Resize (minWidth / maxWidth / maxAutoWidth)\n\nОграничения ширины колонок. Задаются на уровне колонки (`columnConfig`) или глобально в `tableConfig`.\n\n## Быстрый старт\n\n```tsx\nconst columnConfig: ColumnConfig<Row>[] = [\n  {\n    key: 'name',\n    name: 'Название',\n    width: 250,\n    minWidth: 150,\n    maxWidth: 400,\n  },\n  {\n    key: 'description',\n    name: 'Описание',\n    maxAutoWidth: 500,\n  },\n];\n```\n\n## Поля колонки\n\n### minWidth\n\nМинимальная ширина колонки (px). Колонка не может стать уже этого значения — ни при ресайзе мышкой, ни при автоматическом расчёте ширины.\n\nЕсли не задан — берётся глобальный `minColumnWidth` из `tableConfig`.\n\n### maxWidth\n\nМаксимальная ширина колонки (px). **Жёсткий потолок** — ограничивает всё: и автоматический расчёт ширины, и ручной ресайз мышкой. Колонка никогда не станет шире `maxWidth`.\n\nЕсли не задан — берётся глобальный `maxColumnWidth` из `tableConfig`.\n\n### maxAutoWidth\n\nМаксимальная ширина колонки при **автоматическом расчёте** (px). **Мягкий потолок** — колонка стремится не превышать это значение при автоматическом распределении ширин, но **пользователь может растянуть её шире** вручную.\n\nЕсли не задан — берётся глобальный `maxColumnAutoWidth` из `tableConfig`.\n\n#### Отличие maxAutoWidth от maxWidth\n\n- `maxWidth` — жёсткий потолок. Ограничивает и автоматическую ширину, и ручной ресайз.\n- `maxAutoWidth` — мягкий потолок. Ограничивает только автоматическую ширину. Ручной ресайз не ограничен.\n\nЕсли заданы оба — при автоматическом расчёте берётся **меньшее** из двух значений. При ручном ресайзе действует только `maxWidth`.\n\n## Начальная ширина\n\nЕсли у колонки задан `width`, она рендерится с этой шириной (клампится в диапазон `minWidth`..`maxWidth`).\n\nЕсли `width` не задан — начальная ширина вычисляется автоматически. Колонки без фиксированной ширины заполняют свободное место в контейнере. При этом `maxAutoWidth` ограничивает, насколько широко колонка может автоматически растянуться.\n\n## Глобальные ограничения\n\nВ `tableConfig` можно задать ограничения по умолчанию для всех колонок:\n\n```tsx\n<TableCanvas\n  tableConfig={{\n    minColumnWidth: 80,\n    maxColumnWidth: 600,\n    maxColumnAutoWidth: 400,\n  }}\n  columnConfig={columnConfig}\n  rows={rows}\n/>\n```\n\nЕсли у конкретной колонки задано своё значение (`minWidth`, `maxWidth`, `maxAutoWidth`), оно перебивает глобальное.\n\n## Приоритеты\n\n- Колоночные значения (`minWidth`, `maxWidth`, `maxAutoWidth`) приоритетнее глобальных из `tableConfig`\n- Если `minWidth` больше `maxWidth`, приоритет у `minWidth`\n- `maxAutoWidth` не влияет на ручной ресайз — пользователь всегда может растянуть колонку шире\n\nПолная типизация колонок: [columnConfig API](?path=/docs/локальные-компоненты-tablecanvas-api-columnconfig--docs).",
      "apiDocs": "",
      "api": [],
      "stories": [
        {
          "exportName": "MinMaxWidth",
          "displayName": "minWidth / maxWidth",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          width: 80,\n        },\n        {\n          key: 'task',\n          name: 'Title (min 150, max 400)',\n          width: 250,\n          minWidth: 150,\n          maxWidth: 400,\n        },\n        {\n          key: 'priority',\n          name: 'Priority (min 120, max 300)',\n          width: 200,\n          minWidth: 120,\n          maxWidth: 300,\n        },\n        {\n          key: 'loremIpsum',\n          name: 'Issue Type (max 200)',\n          width: 150,\n          maxWidth: 200,\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n          width: 150,\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MaxAutoWidthBasic",
          "displayName": "maxAutoWidth — базовый",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID (maxAutoWidth: 120)',\n          maxAutoWidth: 120,\n        },\n        {\n          key: 'task',\n          name: 'Task (maxAutoWidth: 400)',\n          maxAutoWidth: 400,\n        },\n        {\n          key: 'priority',\n          name: 'Priority (без ограничений)',\n        },\n        {\n          key: 'loremIpsum',\n          name: 'Issue Type (maxAutoWidth: 200)',\n          maxAutoWidth: 200,\n        },\n        {\n          key: 'complete',\n          name: '% Complete (фикс 130px)',\n          width: 130,\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          resizableColumn: true,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MaxAutoWidthVsMaxWidth",
          "displayName": "maxAutoWidth + maxWidth (комбинация)",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID (maxAutoWidth: 150, maxWidth: 200)',\n          maxAutoWidth: 150,\n          maxWidth: 200,\n        },\n        {\n          key: 'task',\n          name: 'Task (maxAutoWidth: 400)',\n          maxAutoWidth: 400,\n        },\n        {\n          key: 'priority',\n          name: 'Priority (maxAutoWidth: 180, maxWidth: 180)',\n          maxAutoWidth: 180,\n          maxWidth: 180,\n        },\n        {\n          key: 'loremIpsum',\n          name: 'Issue (без ограничений)',\n        },\n        {\n          key: 'complete',\n          name: '% Complete (фикс 130px)',\n          width: 130,\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          resizableColumn: true,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MaxAutoWidthGlobal",
          "displayName": "maxColumnAutoWidth (глобальный)",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Task',\n        },\n        {\n          key: 'priority',\n          name: 'Priority (maxAutoWidth: 250 — перебивает глобальный)',\n          maxAutoWidth: 250,\n        },\n        {\n          key: 'loremIpsum',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          resizableColumn: true,\n          maxColumnAutoWidth: 300,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ManualResizeBypassesMaxAutoWidth",
          "displayName": "maxAutoWidth не ограничивает ручной ресайз",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID (maxAutoWidth: 100)',\n          maxAutoWidth: 100,\n        },\n        {\n          key: 'task',\n          name: 'Task (maxAutoWidth: 250, maxWidth: 500)',\n          maxAutoWidth: 250,\n          maxWidth: 500,\n        },\n        {\n          key: 'priority',\n          name: 'Priority (maxAutoWidth: 200)',\n          maxAutoWidth: 200,\n        },\n        {\n          key: 'loremIpsum',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete (фикс 150px)',\n          width: 150,\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          resizableColumn: true,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "Collapsing",
      "legacy": false,
      "summary": "*tableConfig.collapsing**",
      "docs": "# Collapsing (TableCanvas)\n\n**tableConfig.collapsing**\n\nСворачивание/разворачивание тела таблицы. Кнопка управления отображается в controlBlock.\n\n## Ключевые особенности\n\n- Активация через `enableCollapse: true`\n- Внешнее управление состоянием через `collapsedState`\n- Два варианта размещения кнопки: `'inside'` (в controlBlock, участвует в компрессии) и `'above'` (отдельный блок сверху)\n- Кастомный слот справа от кнопки при `collapseButtonPlacement: 'above'`\n\n## Конфигурация\n\n- **`enableCollapse`** `boolean` — активация фичи (default: `false`)\n- **`defaultCollapsed`** `boolean` — начальное состояние (default: `false`)\n- **`collapseText`** `string` — текст кнопки при раскрытом состоянии (default: `'Свернуть'`)\n- **`expandText`** `string` — текст кнопки при закрытом состоянии (default: `'Развернуть'`)\n- **`onToggleCollapse`** `(isCollapsed: boolean) => void` — callback при изменении состояния\n- **`collapsedState`** `[boolean, setState]` — внешний стейт\n- **`collapseButtonPlacement`** `'inside' | 'above'` — размещение кнопки (default: `'inside'`)\n- **`collapseButtonAboveRightSlot`** `ReactNode` — кастомный слот справа (только при `'above'`)\n\n> Подробнее о типах — [Collapsing API](?path=/docs/локальные-компоненты-tablecanvas-collapsing-api--docs)",
      "apiDocs": "# Collapsing API\n\n## TableCollapseConfig\n\n```typescript\ntype TableCollapseConfig = {\n  /**\n   * Обязательный флаг для активации\n   * @default false\n   */\n  enableCollapse?: boolean;\n  /**\n   * Начальное состояние (опционально)\n   *  @default false\n   */\n  defaultCollapsed?: boolean;\n  /**\n   * Текст для кнопки при раскрытом состоянии (опционально)\n   * @default \"Свернуть\"\n   */\n  collapseText?: string;\n  /**\n   * Текст для кнопки при закрытом состоянии (опционально)\n   * @default \"Развернуть\"\n   */\n  expandText?: string;\n  /**\n   * callback при изменении состояния\n   */\n  onToggleCollapse?: (isCollapsed: boolean) => void;\n  /** Внешнее состояние [isCollapsed, setIsCollapsed] */\n  collapsedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n  /**\n   * Размещение кнопки коллапсинга / заголовка\n   * - 'inside' - внутри контрол-блока (по умолчанию, участвует в компрессии)\n   * - 'above' - в отдельном блоке сверху контрол-блока (не участвует в компрессии)\n   * @default 'inside'\n   */\n  collapseButtonPlacement?: 'inside' | 'above';\n  /**\n   * Кастомный рендер правого слота кнопки коллапсинга, который используется при collapseButtonPlacement='above'\n   */\n  collapseButtonAboveRightSlot?: React.ReactNode;\n  /**\n   * Текст заголовка таблицы. Только строка, оформляется нашей типографикой.\n   * Рендерится в блоке above или inline в зависимости от collapseButtonPlacement.\n   * При 'above' — показывается вместе с кнопкой коллапсинга (или без неё если enableCollapse=false).\n   * При 'inline' — показывается внутри контрол-блока слева.\n   * Для произвольной разметки заголовка используйте titleRender.\n   */\n  titleText?: string;\n  /**\n   * Полностью кастомный рендер заголовка (заменяет titleText).\n   */\n  titleRender?: React.ReactNode;\n};\n```",
      "api": [
        {
          "typeName": "TableCollapseConfig",
          "source": "type TableCollapseConfig = {\n  /**\n   * Обязательный флаг для активации\n   * @default false\n   */\n  enableCollapse?: boolean;\n  /**\n   * Начальное состояние (опционально)\n   *  @default false\n   */\n  defaultCollapsed?: boolean;\n  /**\n   * Текст для кнопки при раскрытом состоянии (опционально)\n   * @default \"Свернуть\"\n   */\n  collapseText?: string;\n  /**\n   * Текст для кнопки при закрытом состоянии (опционально)\n   * @default \"Развернуть\"\n   */\n  expandText?: string;\n  /**\n   * callback при изменении состояния\n   */\n  onToggleCollapse?: (isCollapsed: boolean) => void;\n  /** Внешнее состояние [isCollapsed, setIsCollapsed] */\n  collapsedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n  /**\n   * Размещение кнопки коллапсинга / заголовка\n   * - 'inside' - внутри контрол-блока (по умолчанию, участвует в компрессии)\n   * - 'above' - в отдельном блоке сверху контрол-блока (не участвует в компрессии)\n   * @default 'inside'\n   */\n  collapseButtonPlacement?: 'inside' | 'above';\n  /**\n   * Кастомный рендер правого слота кнопки коллапсинга, который используется при collapseButtonPlacement='above'\n   */\n  collapseButtonAboveRightSlot?: React.ReactNode;\n  /**\n   * Текст заголовка таблицы. Только строка, оформляется нашей типографикой.\n   * Рендерится в блоке above или inline в зависимости от collapseButtonPlacement.\n   * При 'above' — показывается вместе с кнопкой коллапсинга (или без неё если enableCollapse=false).\n   * При 'inline' — показывается внутри контрол-блока слева.\n   * Для произвольной разметки заголовка используйте titleRender.\n   */\n  titleText?: string;\n  /**\n   * Полностью кастомный рендер заголовка (заменяет titleText).\n   */\n  titleRender?: React.ReactNode;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "InternalStateCollapsing",
          "displayName": "Collapse тела таблицы (внутреннее состояние)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          minWidth: 200,\n          width: 300,\n          maxWidth: 500,\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '400px' },\n          collapsing: {\n            enableCollapse: true,\n            defaultCollapsed: true,\n            expandText: 'Развернуть информацию',\n            collapseText: 'Свернуть информацию',\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ExternalStateCollapsing",
          "displayName": "Collapse тела таблицы (внешнее состояние)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n    const [externalCollapsed, setExternalCollapsed] = useState(true);\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          minWidth: 200,\n          width: 300,\n          maxWidth: 500,\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n        <Button onClick={() => setExternalCollapsed(!externalCollapsed)}>\n          {externalCollapsed ? 'Развернуть таблицу' : 'Свернуть таблицу'}\n        </Button>\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '300px' },\n            collapsing: {\n              enableCollapse: true,\n              collapsedState: [externalCollapsed, setExternalCollapsed],\n              domMetadata: {\n                className: 'testClassNameForCollapsing',\n                dataAttributes: {\n                  'data-test-collapsing': 'test-collapsing',\n                },\n              },\n              onToggleCollapse: (collapsed) =>\n                // eslint-disable-next-line no-console\n                console.debug('Table collapsed:', collapsed),\n            },\n          }}\n          columnConfig={columns}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "ColumnsControl",
      "legacy": false,
      "summary": "*tableConfig.columnsControl**",
      "docs": "# ColumnsControl (TableCanvas)\n\n**tableConfig.columnsControl**\n\nНастройка колонок таблицы: скрытие, закрепление, изменение порядка (через Aside-панель и drag в header).\n\n## Ключевые особенности\n\n- Активация через `enable: true` — включает все подфичи по умолчанию\n- Скрытие колонок через свитчи в Aside (`hiding`)\n- Закрепление колонок (`pinning`)\n- Перетаскивание колонок в Aside (`reorderingAside`) и через header (`reorderingHeader`)\n- Дефолтные состояния при первом рендере (`pinnedDefault`, `hiddenDefault`, `orderDefault`)\n- Переопределение названий колонок в Aside (`columnsLabel`)\n- Колбэк при применении настроек (`onConfirm`)\n- Синий индикатор скрытых столбцов в шапке (`hiddenColumnsIndicator`)\n\n## Подфичи\n\nКаждая подфича по умолчанию наследует значение `enable`. Можно отключить отдельно:\n\n- **`hiding`** — скрытие/показ колонок через свитчи. `disableHiding` исключает конкретные колонки\n- **`pinning`** — закрепление колонок слева. `disablePinning` исключает конкретные колонки\n- **`reorderingAside`** — drag-and-drop порядка колонок в Aside-панели\n- **`reorderingHeader`** — drag-and-drop заголовков колонок прямо в таблице. `onReorderingHeader` — callback с новым порядком\n\n## Дефолтные состояния\n\n- **`pinnedDefault`** — массив ключей колонок, закреплённых при первом рендере\n- **`hiddenDefault`** — массив ключей скрытых колонок при первом рендере\n- **`orderDefault`** — массив ключей, определяющий начальный порядок колонок\n\n## onConfirm\n\nCallback вызывается при нажатии «Применить» в Aside. Получает текущее состояние (`pinned`, `order`, `hidden`, `changed`) и сеттеры для программного управления состоянием.\n\n## Индикатор скрытых столбцов (hiddenColumnsIndicator)\n\nКогда между двумя видимыми колонками спрятаны столбцы, на границе в шапке вместо обычного бордера рисуется толстая синяя полосатая линия. Так пользователь видит, что тут есть скрытый промежуток, и может быстро его раскрыть.\n\n- Фича **нативная**: включается сама вместе с `hiding`. Отдельно управляется флагом `hiddenColumnsIndicator` (по умолчанию `true` при активном `hiding`). Отключается `hiddenColumnsIndicator: false`.\n- **Одна полоса на весь промежуток**: сколько бы столбцов ни было скрыто подряд, линия одна. Двойной клик раскрывает сразу весь промежуток.\n- **Наведение** на линию показывает тултип «Дважды нажмите, чтобы развернуть».\n- **Ресайз** соседней колонки за эту же границу работает как обычно (тянем перетаскиванием), меняется только двойной клик: он раскрывает промежуток вместо автосайза. Если полоса высокая, тянуть за ресайз можно по всей её высоте, а не только в листовом ряду.\n- **Края таблицы**: если скрыт первый или последний столбец, линия прижимается к левому или правому краю.\n- **Сгруппированная шапка**: фича относится только к колонкам, сами группы не скрываются, а высота полосы подстраивается под то, что скрыто. Если спрятаны только листья внутри групп, полоса низкая (в листовом ряду). Если среди скрытых есть большая колонка верхнего уровня, полоса тянется вверх на всю высоту шапки. Высоту дополнительно ограничивает общая группа видимых соседей: пока они под одной группой, полоса не поднимается выше её низа.\n\n### onHiddenColumnsIndicatorExpand\n\nКолбэк-уведомление о раскрытии промежутка двойным кликом. Само раскрытие (снятие скрытия) делает обёртка; колбэк нужен, чтобы продукт мог подписаться на это событие. В него приходит объект с полями: `keys` (ключи раскрываемых столбцов), `leftKey` и `rightKey` (видимые соседи слева и справа от линии, `undefined` на краю таблицы).\n\nСрабатывает **только** на двойной клик по линии индикатора. Обычное изменение видимости через панель настройки колонок (Aside) или контекстное меню продукта его не вызывает: для этих сценариев есть общий стейт скрытых колонок и `onConfirm`.\n\nПримеры: стори «ColumnsControl: индикатор скрытых столбцов» и рядом (по бокам, выключен, в группе, в скваш-колонках).\n\n## Меню закрепления в контрл-блоке (pinningMenu)\n\nКогда включено `pinning`, в правой зоне иконок контрл-блока автоматически появляется нативная кнопка-иконка (пин + шеврон) — быстрый доступ к закреплению выбранных колонок, дополняющий Aside-панель. Задаётся через `controlBlock.pinningMenu`.\n\n- Фича **нативная**: появляется сама при активном `pinning`, отдельно включать не нужно. Отключается `controlBlock.pinningMenu.enable: false`.\n- **Размеры** завязаны на размер контрл-блока (`controlBlock.size`) — в компактном (`xs`) ужимается вместе с остальными иконками.\n- Участвует в **компрессии**: при нехватке места уезжает в overflow-меню `…` вложенным подменю.\n\nПункты меню:\n\n- **Стандартные (из коробки):** «Открепить всё» и «Закрепить столбцы».\n- **Свои пункты** — через `pinningMenu.items` (напр. «Закрепить строки», «Закрепить шапку»). Порядок задаётся `order` (у нативных: `Открепить всё` = 100, `Закрепить столбцы` = 200), разделитель после пункта — `dividerAfter`. Совпадение `value` с нативным = переопределение.\n- Состояние и иконку продуктовых пунктов **контролирует продукт** (иконка — `ReactNode` или функция от `rowSize`, может отражать состояние).\n\nЛевая иконка (кнопка-действие):\n\n- Синеет, когда среди **видимых** колонок есть хотя бы одна закреплённая (скрыли видимость закреплённой — снова обычный цвет).\n- Tooltip и действие зависят от выделения: нет выделения — подсказка выбрать колонки; выбраны незакреплённые — «Закрепить»; выбраны только закреплённые — «Открепить».\n- После закрепления выделение **переезжает** за колонками (закреплённые уезжают влево), соседние сливаются без разделителей.\n- Клик по действию закрепления **без выделенных колонок** шлёт событие в `tableConfig.notifications` (`type: 'pin'`, `code: 'no-selection'`) — продукт показывает свою подсказку. Подробнее — в разделе [Notifications](?path=/docs/локальные-компоненты-tablecanvas-notifications--docs).\n\nПример добавления своих пунктов — в стори «ColumnsControl: доп. пункты меню закрепления».\n\n> Подробнее о типах и пропсах — [ColumnsControl API](?path=/docs/локальные-компоненты-tablecanvas-columnscontrol-api--docs)",
      "apiDocs": "# ColumnsControl API\n\n## ColumnsControlConfig\n\n```typescript\ntype ColumnsControlConfig = {\n  enable: boolean;\n  /**\n   * @default enable\n   */\n  hiding?: boolean;\n  /**\n   * @default enable\n   */\n  pinning?: boolean;\n  /**\n   * @default enable\n   */\n  reorderingAside?: boolean;\n  /**\n   * reorderingHeader  - активация изменения порядка колонок  посредством перемещения шапок колонок таблицы\n   */\n  /**\n   * @default enable\n   */\n  reorderingHeader?: boolean;\n  onReorderingHeader?: (params: {\n    newOrder: string[];\n    sourceKey: string;\n    targetKey: string;\n  }) => void;\n\n  columnsLabel?: Record<\n    string,\n    ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n  >;\n\n  /**\n   * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n   * видимые строки списка. false — отключить полностью; { minCount } —\n   * включать, когда строк в списке не меньше порога.\n   * @default { minCount: 30 }\n   */\n  virtualization?: boolean | { minCount?: number };\n\n  orderDefault?: string[];\n\n  pinnedDefault?: string[];\n  disablePinning?: string[];\n\n  hiddenDefault?: string[];\n  disableHiding?: string[];\n  /**\n   * Индикатор скрытых столбцов: синяя полосатая линия в шапке на границе, за\n   * которой скрыты столбцы. Двойной клик по линии раскрывает весь промежуток,\n   * ресайз на этой границе работает как обычно.\n   * @default hiding\n   */\n  hiddenColumnsIndicator?: boolean;\n  /**\n   * Уведомление о раскрытии промежутка двойным кликом по индикатору скрытых\n   * столбцов. Само раскрытие (снятие скрытия) обёртка делает сама; колбэк нужен,\n   * чтобы внешний потребитель мог подписаться на это событие и узнать, какие\n   * столбцы раскрылись и между какими видимыми колонками стояла линия.\n   */\n  onHiddenColumnsIndicatorExpand?: (\n    info: HiddenColumnsIndicatorExpandInfo,\n  ) => void;\n\n  onConfirm?: (\n    params: {\n      pinned: string[];\n      order: string[];\n      hidden: string[];\n      changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n    },\n    setters: {\n      setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n      setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n      setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n    },\n  ) => void;\n  /**\n   * DomMetadata для кнопок закрепления столбцов\n   */\n  pinDomMetadata?: DomMetadata;\n  /**\n   * DomMetadata для свитчеров скрытия/показа столбцов\n   */\n  switchDomMetadata?: DomMetadata;\n};\n```\n\n## HiddenColumnsIndicatorExpandInfo\n\nДанные, которые приходят в колбэк `onHiddenColumnsIndicatorExpand` при раскрытии промежутка двойным кликом по индикатору скрытых столбцов.\n\n```typescript\ntype HiddenColumnsIndicatorExpandInfo = {\n  /** Ключи скрытых столбцов, которые раскрываются (весь промежуток за линией). */\n  keys: string[];\n  /** Видимый сосед слева от линии. undefined, если линия у левого края таблицы. */\n  leftKey?: string;\n  /** Видимый сосед справа от линии. undefined, если линия у правого края таблицы. */\n  rightKey?: string;\n};\n```\n\n## PinningMenuConfig\n\nМеню закрепления в контрл-блоке (`controlBlock.pinningMenu`). Появляется, когда включено `columnsControl.pinning`.\n\n```typescript\ntype PinningMenuConfig = {\n  /**\n   * Явное вкл/выкл фичи.\n   * @default columnsControl.pinning\n   */\n  enable?: boolean;\n  /**\n   * Продуктовые пункты меню — мёржатся с нативными (override по value,\n   * сортировка по order).\n   */\n  items?: PinningMenuItem[];\n  /**\n   * DomMetadata левой кнопки-иконки закрепления. Её `dataAttributes`\n   * навешиваются на кнопку-иконку (data-атрибуты для e2e-тестов, аналитики и\n   * онбординга — поиск элемента в DOM). Пример:\n   * `{ dataAttributes: { 'data-testid': 'pinning-icon' } }`.\n   */\n  iconDomMetadata?: DomMetadata;\n};\n```\n\n## PinningMenuItem\n\nПункт меню закрепления — нативный или добавленный продуктом.\n\n```typescript\ntype PinningMenuItem = {\n  /**\n   * Уникальный ключ пункта. Совпадение с value нативного пункта = override\n   * (продуктовые поля перекрывают нативные).\n   */\n  value: string;\n  label: string;\n  /**\n   * Иконка слева в пункте. Узел рендерится как есть, либо функция (ctx),\n   * чтобы подстроить размер под rowSize (в т.ч. внутри overflow-дропдауна\n   * при компрессии). Стейт/иконку продуктовых пунктов контролирует продукт.\n   */\n  icon?: FeatureIconRender;\n  /**\n   * Действие пункта. У нативных пунктов задаётся таблицей; продукт может\n   * переопределить.\n   */\n  onClick?: () => void;\n  /**\n   * Порядок в списке (по возрастанию). Нативные: reset=100, pin-columns=200.\n   * Пункты без order идут в конец, сохраняя исходный порядок.\n   */\n  order?: number;\n  /**\n   * Нарисовать разделитель после пункта.\n   * @default false\n   */\n  dividerAfter?: boolean;\n  disabled?: boolean;\n};\n```",
      "api": [
        {
          "typeName": "ColumnsControlConfig",
          "source": "type ColumnsControlConfig = {\n  enable: boolean;\n  /**\n   * @default enable\n   */\n  hiding?: boolean;\n  /**\n   * @default enable\n   */\n  pinning?: boolean;\n  /**\n   * @default enable\n   */\n  reorderingAside?: boolean;\n  /**\n   * reorderingHeader  - активация изменения порядка колонок  посредством перемещения шапок колонок таблицы\n   */\n  /**\n   * @default enable\n   */\n  reorderingHeader?: boolean;\n  onReorderingHeader?: (params: {\n    newOrder: string[];\n    sourceKey: string;\n    targetKey: string;\n  }) => void;\n\n  columnsLabel?: Record<\n    string,\n    ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n  >;\n\n  /**\n   * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n   * видимые строки списка. false — отключить полностью; { minCount } —\n   * включать, когда строк в списке не меньше порога.\n   * @default { minCount: 30 }\n   */\n  virtualization?: boolean | { minCount?: number };\n\n  orderDefault?: string[];\n\n  pinnedDefault?: string[];\n  disablePinning?: string[];\n\n  hiddenDefault?: string[];\n  disableHiding?: string[];\n  /**\n   * Индикатор скрытых столбцов: синяя полосатая линия в шапке на границе, за\n   * которой скрыты столбцы. Двойной клик по линии раскрывает весь промежуток,\n   * ресайз на этой границе работает как обычно.\n   * @default hiding\n   */\n  hiddenColumnsIndicator?: boolean;\n  /**\n   * Уведомление о раскрытии промежутка двойным кликом по индикатору скрытых\n   * столбцов. Само раскрытие (снятие скрытия) обёртка делает сама; колбэк нужен,\n   * чтобы внешний потребитель мог подписаться на это событие и узнать, какие\n   * столбцы раскрылись и между какими видимыми колонками стояла линия.\n   */\n  onHiddenColumnsIndicatorExpand?: (\n    info: HiddenColumnsIndicatorExpandInfo,\n  ) => void;\n\n  onConfirm?: (\n    params: {\n      pinned: string[];\n      order: string[];\n      hidden: string[];\n      changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n    },\n    setters: {\n      setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n      setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n      setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n    },\n  ) => void;\n  /**\n   * DomMetadata для кнопок закрепления столбцов\n   */\n  pinDomMetadata?: DomMetadata;\n  /**\n   * DomMetadata для свитчеров скрытия/показа столбцов\n   */\n  switchDomMetadata?: DomMetadata;\n};"
        },
        {
          "typeName": "HiddenColumnsIndicatorExpandInfo",
          "source": "type HiddenColumnsIndicatorExpandInfo = {\n  /** Ключи скрытых столбцов, которые раскрываются (весь промежуток за линией). */\n  keys: string[];\n  /** Видимый сосед слева от линии. undefined, если линия у левого края таблицы. */\n  leftKey?: string;\n  /** Видимый сосед справа от линии. undefined, если линия у правого края таблицы. */\n  rightKey?: string;\n};"
        },
        {
          "typeName": "PinningMenuConfig",
          "source": "type PinningMenuConfig = {\n  /**\n   * Явное вкл/выкл фичи.\n   * @default columnsControl.pinning\n   */\n  enable?: boolean;\n  /**\n   * Продуктовые пункты меню — мёржатся с нативными (override по value,\n   * сортировка по order).\n   */\n  items?: PinningMenuItem[];\n  /**\n   * DomMetadata левой кнопки-иконки закрепления. Её `dataAttributes`\n   * навешиваются на кнопку-иконку (data-атрибуты для e2e-тестов, аналитики и\n   * онбординга — поиск элемента в DOM). Пример:\n   * `{ dataAttributes: { 'data-testid': 'pinning-icon' } }`.\n   */\n  iconDomMetadata?: DomMetadata;\n};"
        },
        {
          "typeName": "PinningMenuItem",
          "source": "type PinningMenuItem = {\n  /**\n   * Уникальный ключ пункта. Совпадение с value нативного пункта = override\n   * (продуктовые поля перекрывают нативные).\n   */\n  value: string;\n  label: string;\n  /**\n   * Иконка слева в пункте. Узел рендерится как есть, либо функция (ctx),\n   * чтобы подстроить размер под rowSize (в т.ч. внутри overflow-дропдауна\n   * при компрессии). Стейт/иконку продуктовых пунктов контролирует продукт.\n   */\n  icon?: FeatureIconRender;\n  /**\n   * Действие пункта. У нативных пунктов задаётся таблицей; продукт может\n   * переопределить.\n   */\n  onClick?: () => void;\n  /**\n   * Порядок в списке (по возрастанию). Нативные: reset=100, pin-columns=200.\n   * Пункты без order идут в конец, сохраняя исходный порядок.\n   */\n  order?: number;\n  /**\n   * Нарисовать разделитель после пункта.\n   * @default false\n   */\n  dividerAfter?: boolean;\n  disabled?: boolean;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "ColumnsControl",
          "displayName": "ID",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          // eslint-disable-next-line @typescript-eslint/no-unused-vars\n          renderCell(cellInfo) {\n            return (\n              <Canvas.Button\n                id=\"header-tooltip-drag\"\n                portalHoverEnabled\n                onClick={() => {}}\n              >\n                123\n              </Canvas.Button>\n            );\n          },\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          columnsControl: {\n            enable: true,\n            hiding: true,\n            disableHiding: ['id'],\n            pinning: true,\n            disablePinning: ['developer'],\n            reorderingAside: true,\n            reorderingHeader: true,\n            columnsLabel: {\n              task: 'Задачи',\n            },\n            orderDefault: ['id', 'issueType', 'task'],\n            hiddenDefault: ['tr1'],\n            pinnedDefault: ['complete'],\n            onConfirm: ({ order, hidden, pinned }, _setters) => {\n              // eslint-disable-next-line no-alert\n              alert(`\n                                    order: ${order.join(', ')}\n                                    pinned: ${pinned.join(', ')}\n                                    hidden: ${hidden.join(', ')}\n                                `);\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ColumnsControlDynamicColumn",
          "displayName": "ColumnsControl: динамическое добавление колонки",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n    const [developerIsShown, setDeveloperIsShown] = useState(false);\n\n    const filteringStateAndSetter = useState({\n      id: '',\n      task: '',\n      priority: 'All',\n      issueType: [],\n      complete: '',\n      date: '',\n      globalFilter: '',\n    });\n    const sortingStateAndSetter = useState<readonly SortColumn[]>([]);\n\n    const themeOverride = useCallback<\n      NonNullable<ColumnConfig<Row>['themeOverride']>\n    >((cellInfo) => {\n      if (cellInfo.hovered.rowHover) {\n        return { bgCell: cellInfo.theme.bgHeader };\n      }\n      return {};\n    }, []);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          themeOverride,\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          themeOverride,\n          minWidth: 200,\n          width: 250,\n        },\n        ...(developerIsShown\n          ? [\n              {\n                key: 'developer',\n                name: 'Developer',\n                themeOverride,\n              } satisfies ColumnConfig<Row>,\n            ]\n          : []),\n        {\n          key: 'priority',\n          name: 'Priority',\n          sortingType: 'stringSort',\n          themeOverride,\n          filtering: {\n            component: 'select',\n            selectOptions: {\n              type: 'constant',\n              options: [\n                { value: 'All', text: 'All' },\n                { value: 'High', text: 'High' },\n                { value: 'Critical', text: 'Critical' },\n                { value: 'Medium', text: 'Medium' },\n                { value: 'Low', text: 'Low' },\n              ],\n            },\n            keyInFilterState: 'priority',\n            valueInRow: (r) => r.priority,\n            filter: {\n              typeOfValue: 'single',\n              filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n            },\n          },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          themeOverride,\n          filtering: {\n            component: 'input',\n            filter: 'includes',\n            valueInRow: (r) => `${r.task} ${r.id}`,\n            keyInFilterState: 'task',\n          },\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n          themeOverride,\n        },\n      ],\n      [developerIsShown, themeOverride],\n    );\n\n    return (\n      <Box $css={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n        <Box>\n          <Button\n            size=\"s\"\n            view=\"secondary\"\n            onClick={() => setDeveloperIsShown((prev) => !prev)}\n          >\n            {developerIsShown\n              ? 'Удалить колонку Developer'\n              : 'Добавить колонку Developer'}\n          </Button>\n        </Box>\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '60vh' },\n            highlightActiveType: 'row',\n            columnsControl: {\n              enable: true,\n              hiding: true,\n              pinning: true,\n              reorderingAside: true,\n              reorderingHeader: true,\n            },\n            filtering: {\n              state: filteringStateAndSetter,\n              filtersInfo: {\n                id: { label: 'id', clearedValue: '' },\n                task: { label: 'task', clearedValue: '' },\n                priority: { label: 'Some Label', clearedValue: 'All' },\n                issueType: { label: 'issueType', clearedValue: [] },\n                complete: { label: 'complete', clearedValue: '' },\n                date: { label: 'Дата', clearedValue: '' },\n                globalFilter: { label: 'Global filter', clearedValue: '' },\n              },\n            },\n            sorting: {\n              state: sortingStateAndSetter,\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </Box>\n    );\n  }"
        },
        {
          "exportName": "SimpleTableDynamicColumn",
          "displayName": "SimpleTable: динамическое добавление колонки",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n    const [isFavorite, setIsFavorite] = useState(true);\n    const [developerIsShown, setDeveloperIsShown] = useState(false);\n\n    const filteringStateAndSetter = useState({\n      id: '',\n      task: '',\n      priority: 'All',\n      issueType: [],\n      complete: '',\n      date: '',\n      globalFilter: '',\n    });\n    const themeOverride = useCallback<\n      NonNullable<ColumnConfig<Row>['themeOverride']>\n    >((cellInfo) => {\n      if (cellInfo.hovered.rowHover) {\n        return { bgCell: cellInfo.theme.bgHeader };\n      }\n      return {};\n    }, []);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'id',\n          themeOverride,\n          renderHeaderCell: ({ theme }) => (\n            <Canvas.Container\n              direction=\"row\"\n              alignItems=\"center\"\n              gap={8}\n              padding={{\n                left: theme.cellHorizontalPadding,\n                right: theme.cellHorizontalPadding,\n              }}\n            >\n              <Canvas.Container position=\"relative\">\n                <Canvas.Icon icon={<IconChevronCircleDownFill />} />\n                <Canvas.Icon\n                  position=\"absolute\"\n                  top={-5}\n                  right={-5}\n                  icon={<IconBrightness0Fill color=\"#d70101\" size=\"xs\" />}\n                />\n              </Canvas.Container>\n              <Canvas.Container position=\"relative\">\n                <Canvas.Icon icon={<IconAddOutline />} />\n                <Canvas.Icon\n                  position=\"absolute\"\n                  top={-5}\n                  right={-5}\n                  icon={<IconBrightness0Fill color=\"#d70101\" size=\"xs\" />}\n                />\n              </Canvas.Container>\n            </Canvas.Container>\n          ),\n          renderCell: ({ theme }) => (\n            <Canvas.Container\n              direction=\"row\"\n              alignItems=\"center\"\n              justifyContent=\"space-between\"\n              gap={8}\n              padding={{\n                left: theme.cellHorizontalPadding,\n                right: theme.cellHorizontalPadding,\n              }}\n            >\n              <Canvas.Container position=\"relative\">\n                <Canvas.Icon icon={<IconChevronCircleDownFill />} />\n                <Canvas.Icon\n                  position=\"absolute\"\n                  top={-5}\n                  right={-5}\n                  icon={<IconBrightness0Fill color=\"#d70101\" size=\"xs\" />}\n                />\n              </Canvas.Container>\n              <Canvas.Container position=\"relative\">\n                <Canvas.Icon icon={<IconAddOutline />} />\n                <Canvas.Icon\n                  position=\"absolute\"\n                  top={-5}\n                  right={-5}\n                  icon={<IconBrightness0Fill color=\"#d70101\" size=\"xs\" />}\n                />\n              </Canvas.Container>\n            </Canvas.Container>\n          ),\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          themeOverride,\n          minWidth: 200,\n          width: 250,\n          renderCell: ({ row, theme }) => (\n            <Canvas.Container\n              direction=\"row\"\n              alignItems=\"center\"\n              justifyContent=\"space-between\"\n              gap={8}\n              wrap=\"wrap\"\n              padding={{\n                left: theme.cellHorizontalPadding,\n                right: theme.cellHorizontalPadding,\n              }}\n              style={{ width: '100%' }}\n            >\n              <Canvas.Container direction=\"column\" gap={2}>\n                <Canvas.Text\n                  font={theme.baseFontStyle}\n                  color={theme.accentFg}\n                  style={{ flexGrow: 1 }}\n                >\n                  {row.task ?? '—'}\n                </Canvas.Text>\n                <Canvas.Text\n                  font={theme.baseFontStyle}\n                  color={theme.textHeader}\n                  style={{ flexGrow: 1 }}\n                >\n                  {row.priority ?? '—'}\n                </Canvas.Text>\n              </Canvas.Container>\n              <Canvas.Button\n                portalHoverEnabled\n                variant=\"secondary\"\n                onClick={() =>\n                  // eslint-disable-next-line no-console\n                  console.log('Подробнее по сотруднику', row.complete)\n                }\n              >\n                Подробнее\n              </Canvas.Button>\n            </Canvas.Container>\n          ),\n        },\n        ...(developerIsShown\n          ? [\n              {\n                key: 'developer',\n                name: 'Developer',\n                themeOverride,\n              } satisfies ColumnConfig<Row>,\n            ]\n          : []),\n        {\n          key: 'priority',\n          name: 'Priority',\n          sortingType: 'stringSort',\n          themeOverride,\n          filtering: {\n            component: 'select',\n            selectOptions: {\n              type: 'constant',\n              options: [\n                { value: 'All', text: 'All' },\n                { value: 'High', text: 'High' },\n                { value: 'Critical', text: 'Critical' },\n                { value: 'Medium', text: 'Medium' },\n                { value: 'Low', text: 'Low' },\n              ],\n            },\n\n            keyInFilterState: 'priority',\n            valueInRow: (r) => r.priority,\n            filter: {\n              typeOfValue: 'single',\n              filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n            },\n          },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          themeOverride,\n          filtering: {\n            component: 'input',\n            filter: 'includes',\n\n            valueInRow: (r) => `${r.task} ${r.id}`,\n\n            keyInFilterState: 'task',\n          },\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n          themeOverride,\n        },\n      ],\n      [developerIsShown, themeOverride],\n    );\n\n    const sortingStateAndSetter = useState<readonly SortColumn[]>([]);\n\n    return (\n      <Box $css={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n        <Box>\n          <Button\n            size=\"s\"\n            view=\"secondary\"\n            onClick={() => setDeveloperIsShown((prev) => !prev)}\n          >\n            {developerIsShown\n              ? 'Удалить колонку Developer'\n              : 'Добавить колонку Developer'}\n          </Button>\n        </Box>\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '60vh' },\n            rowSize: {\n              default: 'big',\n              showInControl: true,\n            },\n            highlightActiveType: 'row',\n\n            fullScreenEnabled: true,\n            controlBlock: {\n              customFeatures: [\n                // Обязательная кастомная фича\n                {\n                  value: 'favorite',\n                  label: 'Удалить из избранного',\n                  Icon: IconStar,\n                  onClick: () => {},\n                  mandatory: true,\n                  details: {\n                    type: 'switch',\n                    label: 'В избранном',\n                    checked: isFavorite,\n                    onChange: (e) => setIsFavorite(e.target.checked),\n                  },\n                },\n              ],\n            },\n            filtering: {\n              state: filteringStateAndSetter,\n              filtersInfo: {\n                id: {\n                  label: 'id',\n                  clearedValue: '',\n                },\n                task: {\n                  label: 'task',\n                  clearedValue: '',\n                },\n                priority: {\n                  label: 'Some Label',\n                  clearedValue: 'All',\n                },\n                issueType: {\n                  label: 'issueType',\n                  clearedValue: [],\n                },\n                complete: {\n                  label: 'complete',\n                  clearedValue: '',\n                },\n                date: {\n                  label: 'Дата',\n                  clearedValue: '',\n                },\n                globalFilter: {\n                  label: 'Global filter',\n                  clearedValue: '',\n                },\n              },\n            },\n            sorting: {\n              state: sortingStateAndSetter,\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </Box>\n    );\n  }"
        },
        {
          "exportName": "ColumnsControlPinningMenu",
          "displayName": "ColumnsControl: доп. пункты меню закрепления",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n    // Шапка по умолчанию закреплена (unstickyHeader=false) → галочка есть.\n    const [isHeaderPinned, setIsHeaderPinned] = useState(true);\n    const [isRowsPinned, setIsRowsPinned] = useState(false);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'developer', name: 'Developer' },\n        { key: 'complete', name: '% Complete' },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          // Реальное залипание шапки — «Закрепить шапку» переключает его.\n          unstickyHeader: !isHeaderPinned,\n          // Клик «Закрепить столбцы» без выделения → событие pin/no-selection.\n          notifications: {\n            onNotification: (e) => {\n              // eslint-disable-next-line no-alert\n              alert(e.message);\n            },\n          },\n          columnsControl: {\n            enable: true,\n            pinning: true,\n            disablePinning: ['developer'],\n            pinnedDefault: ['complete'],\n          },\n          controlBlock: {\n            pinningMenu: {\n              // Мёржатся с нативными (Открепить всё order=100, Закрепить\n              // столбцы order=200). Итог: … → Закрепить строки → divider →\n              // Закрепить шапку.\n              items: [\n                {\n                  value: 'pin-rows',\n                  label: 'Закрепить строки',\n                  order: 300,\n                  dividerAfter: true,\n                  icon: (ctx) => (\n                    <IconPinListOutline\n                      size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                      color={isRowsPinned ? textInfo : 'inherit'}\n                    />\n                  ),\n                  onClick: () => setIsRowsPinned((prev) => !prev),\n                },\n                {\n                  value: 'pin-header',\n                  label: 'Закрепить шапку',\n                  order: 400,\n                  icon: (ctx) => (\n                    <Box\n                      $css={{\n                        display: 'inline-flex',\n                        alignItems: 'center',\n                        justifyContent: 'center',\n                        visibility: isHeaderPinned ? 'visible' : 'hidden',\n                      }}\n                    >\n                      <IconDone\n                        size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                        color={textInfo}\n                      />\n                    </Box>\n                  ),\n                  onClick: () => setIsHeaderPinned((prev) => !prev),\n                },\n              ],\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ColumnsControlWithServiceColumnsForTest",
          "displayName": "ID",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          selecting: {\n            rowCheckboxDisabled: (row) => row.id === 2,\n            rowShowCheckbox: (row) => row.id !== 3,\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id + r.issueType,\n            showDefault: false,\n          },\n          containerStyle: { height: 700 },\n          columnsControl: {\n            enable: true,\n            hiding: true,\n            disableHiding: ['id'],\n            pinning: true,\n            disablePinning: ['developer'],\n            reorderingAside: true,\n            reorderingHeader: true,\n            columnsLabel: {\n              task: 'Задачи',\n            },\n            orderDefault: ['id', 'issueType', 'task'],\n            hiddenDefault: ['tr1'],\n            pinnedDefault: ['complete'],\n            onConfirm: ({ order, hidden, pinned }, _setters) => {\n              // eslint-disable-next-line no-alert\n              alert(`\n                                    order: ${order.join(', ')}\n                                    pinned: ${pinned.join(', ')}\n                                    hidden: ${hidden.join(', ')}\n                                `);\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "HiddenColumnsIndicator",
          "displayName": "ColumnsControl: индикатор скрытых столбцов",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 420 },\n          rowMarkers: { startIndex: 1 },\n          columnsControl: {\n            enable: true,\n            hiding: true,\n            hiddenDefault: ['priority', 'developer', 'tr1'],\n          },\n        }}\n        columnConfig={INDICATOR_COLS}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "HiddenColumnsIndicatorEdges",
          "displayName": "ColumnsControl: индикатор скрытых столбцов по бокам",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 420 },\n          rowMarkers: { startIndex: 1 },\n          columnsControl: {\n            enable: true,\n            hiding: true,\n            pinning: true,\n            pinnedDefault: ['task'],\n            hiddenDefault: ['id', 'complete'],\n          },\n        }}\n        columnConfig={INDICATOR_COLS}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "HiddenColumnsIndicatorDisabled",
          "displayName": "ColumnsControl: индикатор скрытых столбцов выключен",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 420 },\n          rowMarkers: { startIndex: 1 },\n          columnsControl: {\n            enable: true,\n            hiding: true,\n            hiddenColumnsIndicator: false,\n            hiddenDefault: ['priority'],\n          },\n        }}\n        columnConfig={INDICATOR_COLS}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "HiddenColumnsIndicatorGrouped",
          "displayName": "ColumnsControl: индикатор скрытых столбцов в группе",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig: ColumnOrColumnGroupConfig<Row>[] = [\n      { key: 'id', name: 'ID', width: 120 },\n      {\n        key: 'metrics',\n        name: 'Показатели',\n        children: [\n          { key: 'task', name: 'План', width: 130 },\n          { key: 'priority', name: 'Факт', width: 130 },\n          { key: 'issueType', name: 'Прогноз', width: 130 },\n        ],\n      },\n      {\n        key: 'grade',\n        name: 'Оценка',\n        children: [\n          { key: 'developer', name: 'Инд', width: 130 },\n          { key: 'complete', name: 'Итог', width: 130 },\n        ],\n      },\n    ];\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 420 },\n          rowMarkers: { startIndex: 1 },\n          columnsControl: {\n            enable: true,\n            hiding: true,\n            hiddenDefault: ['priority', 'developer'],\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "HiddenColumnsIndicatorSquashed",
          "displayName": "ColumnsControl: индикатор скрытых столбцов в скваш-колонках",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig: ColumnOrColumnGroupConfig<Row>[] = [\n      { key: 'id', name: 'ID', width: 100 },\n      {\n        key: 'deep',\n        name: 'Глубокая',\n        children: [\n          {\n            key: 'sub',\n            name: 'Подгруппа',\n            children: [\n              { key: 'task', name: 'A', width: 110 },\n              { key: 'priority', name: 'B', width: 110 },\n              { key: 'issueType', name: 'B1', width: 110 },\n            ],\n          },\n        ],\n      },\n      { key: 'developer', name: 'Ср', width: 130 },\n      {\n        key: 'shallow',\n        name: 'Мелкая',\n        children: [{ key: 'complete', name: 'C', width: 160 }],\n      },\n    ];\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 420 },\n          rowMarkers: { startIndex: 1 },\n          columnsGrouping: { squashEmptyCells: true },\n          columnsControl: {\n            enable: true,\n            hiding: true,\n            hiddenDefault: ['issueType', 'developer'],\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "ColumnsGrouping",
      "legacy": false,
      "summary": "*columnConfig.children**",
      "docs": "# ColumnsGrouping (TableCanvas)\n\n**columnConfig.children**\n\nГруппировка колонок — вложенная структура шапки таблицы. Позволяет объединять несколько колонок под одним общим заголовком, создавая иерархию в шапке.\n\n## Ключевые особенности\n\n- Поддержка многоуровневой вложенности (2, 3+ уровня)\n- Совместимость с `columnsControl`, `resizableColumn`\n- Кастомизация `name` через `ReactNode`\n\n## Как работает\n\nДля создания группы колонок используется `ColumnGroupConfig` вместо обычного `ColumnConfig`. Группа определяется наличием ключа `children`, в котором перечисляются дочерние колонки или вложенные группы.\n\n```tsx\nconst columnConfig = [\n  {\n    name: 'Основные данные',\n    children: [\n      { key: 'name', name: 'Имя' },\n      { key: 'age', name: 'Возраст' },\n    ],\n  },\n  {\n    name: 'Статистика',\n    children: [\n      { key: 'score', name: 'Баллы' },\n      { key: 'rank', name: 'Ранг' },\n    ],\n  },\n];\n```\n\n## Особенности\n\n- Группа не имеет собственного `key` — это чисто визуальный элемент шапки\n- `name` группы может быть строкой или `ReactNode` для кастомного рендера\n- При использовании с `columnsControl` скрытие/показ работает на уровне дочерних колонок, не на уровне группы\n- При `resizableColumn` ресайз работает на уровне дочерних колонок\n\n## Слияние ячеек шапки (squashEmptyCells)\n\nВ многоуровневой шапке рядом с группами остаются пустые ячейки: у одиночной колонки без группы — пустая полоса СВЕРХУ, у «мелкой» группы (под которой нет более глубоких подгрупп) — пустая полоса СНИЗУ. `tableConfig.columnsGrouping.squashEmptyCells` схлопывает их: одиночная колонка тянется вверх, мелкая группа — вниз, всё одной ячейкой без пустых полос. **Включено по умолчанию**; выключить — `squashEmptyCells: false`.\n\n```tsx\ntableConfig={{ columnsGrouping: { squashEmptyCells: true } }}\n```\n\nОдин переключатель на всю таблицу — не нужно решать по каждой колонке/группе. Пример с тумблером — стори «Группировка (squash)».\n\n### Выравнивание заголовка в слитой ячейке\n\n`squashedHeaderAlign: { horizontal, vertical }` задаёт положение текста в слитой ячейке:\n\n- дефолт на таблице — `tableConfig.columnsGrouping.squashedHeaderAlign`;\n- точечно на колонке (лист) — `columnConfig[].squashedHeaderAlign`;\n- точечно на группе — `ColumnGroupConfig.squashedHeaderAlign`.\n\nЗначение на колонке или группе перекрывает табличный дефолт.\n\n`horizontal` — `left | center | right`; `vertical` — `top | center | bottom`. Дефолт — `left` / по центру по высоте. Действует только на слитой шапке. Пример — стори «Выравнивание заголовка».\n\n### Кастомный контент в слитой шапке\n\nЕсли `name` колонки или группы — canvas-элемент (`Canvas.Text` / `Canvas.Container`), в слитой шапке он центрируется по всей высоте объединённой ячейки. Пример — группа с кастомным `name` в стори «Группировка (squash)».\n\n### Реордер и группы\n\nСлияние совместимо с реордером колонок за шапку (`columnsControl.reorderingHeader`, включён по умолчанию при `columnsControl.enable`). Drag-иконка показывается на листовых колонках, у групп своей нет — перетаскиваются листья.\n\n## Ограничения / edge-кейсы\n\n- Слияние имеет смысл при наличии групп в шапке (иначе групп-рядов нет и сливать нечего).\n- `squashedHeaderAlign` действует только на слитой шапке (при `squashEmptyCells`).\n\n> Подробнее о типах и пропсах — [ColumnsGrouping API](?path=/docs/локальные-компоненты-tablecanvas-columnsgrouping-api--docs)",
      "apiDocs": "# ColumnsGrouping API\n\n## ColumnsGroupingConfig\n\nКонфиг группировки на уровне таблицы — `tableConfig.columnsGrouping`.\n\n```typescript\ntype ColumnsGroupingConfig = {\n  /**\n   * Объединять пустые ячейки шапки: колонка без группы (конечная, без вложенных\n   * подколонок) растягивается вверх на всю высоту шапки, а «мелкая» группа (без более\n   * глубоких подгрупп) — вниз. Убирает пустые полосы в многоуровневой шапке.\n   * Включает/выключает поведение сразу для всей таблицы.\n   * @default true\n   */\n  squashEmptyCells?: boolean;\n  /**\n   * Дефолт выравнивания текста в объединённых ячейках шапки. Влияет только на\n   * объединённые ячейки, обычные (не объединённые) ячейки не затрагивает. Точечно\n   * перекрывается на колонке или группе через их собственный `squashedHeaderAlign`.\n   */\n  squashedHeaderAlign?: HeaderAlignment;\n};\n```\n\n## HeaderAlignment\n\n`squashedHeaderAlign` задаёт выравнивание текста в слитой ячейке шапки. Доступно на трёх уровнях: `tableConfig.columnsGrouping.squashedHeaderAlign` (дефолт для таблицы), на колонке `columnConfig[].squashedHeaderAlign` (лист) и на группе `ColumnGroupConfig.squashedHeaderAlign`.\n\n```typescript\ntype HeaderAlignment = {\n  /** По горизонтали. @default 'left' */\n  horizontal?: 'left' | 'center' | 'right';\n  /** По вертикали. @default 'center' */\n  vertical?: 'top' | 'center' | 'bottom';\n};\n```\n\n## ColumnGroupConfig\n\n```typescript\ninterface ColumnGroupConfig<\n  R extends ObjectForExtending,\n  SR = unknown,\n> {\n  /** Уникальный ключ группы. */\n  readonly key: string;\n  /** Название группы, отображается в ячейке шапки. Строка или JSX. */\n  readonly name: string | ReactElement;\n  // readonly headerCellClass?: Maybe<string>;\n  /** Вложенные колонки и подгруппы этой группы. */\n  readonly children: readonly ColumnOrColumnGroupConfig<R, SR>[];\n  /** Выравнивание текста в объединённой шапке группы. Действует при squashEmptyCells. */\n  readonly squashedHeaderAlign?: HeaderAlignment;\n}\n```\n\n## ColumnOrColumnGroupConfig\n\n```typescript\ntype ColumnOrColumnGroupConfig<\n  R extends ObjectForExtending,\n  SR = unknown,\n> = ColumnConfig<R, SR> | ColumnGroupConfig<R, SR>;\n```",
      "api": [
        {
          "typeName": "ColumnsGroupingConfig",
          "source": "type ColumnsGroupingConfig = {\n  /**\n   * Объединять пустые ячейки шапки: колонка без группы (конечная, без вложенных\n   * подколонок) растягивается вверх на всю высоту шапки, а «мелкая» группа (без более\n   * глубоких подгрупп) — вниз. Убирает пустые полосы в многоуровневой шапке.\n   * Включает/выключает поведение сразу для всей таблицы.\n   * @default true\n   */\n  squashEmptyCells?: boolean;\n  /**\n   * Дефолт выравнивания текста в объединённых ячейках шапки. Влияет только на\n   * объединённые ячейки, обычные (не объединённые) ячейки не затрагивает. Точечно\n   * перекрывается на колонке или группе через их собственный `squashedHeaderAlign`.\n   */\n  squashedHeaderAlign?: HeaderAlignment;\n};"
        },
        {
          "typeName": "HeaderAlignment",
          "source": "type HeaderAlignment = {\n  /** По горизонтали. @default 'left' */\n  horizontal?: 'left' | 'center' | 'right';\n  /** По вертикали. @default 'center' */\n  vertical?: 'top' | 'center' | 'bottom';\n};"
        },
        {
          "typeName": "ColumnGroupConfig",
          "source": "interface ColumnGroupConfig<\n  R extends ObjectForExtending,\n  SR = unknown,\n> {\n  /** Уникальный ключ группы. */\n  readonly key: string;\n  /** Название группы, отображается в ячейке шапки. Строка или JSX. */\n  readonly name: string | ReactElement;\n  // readonly headerCellClass?: Maybe<string>;\n  /** Вложенные колонки и подгруппы этой группы. */\n  readonly children: readonly ColumnOrColumnGroupConfig<R, SR>[];\n  /** Выравнивание текста в объединённой шапке группы. Действует при squashEmptyCells. */\n  readonly squashedHeaderAlign?: HeaderAlignment;\n}"
        },
        {
          "typeName": "ColumnOrColumnGroupConfig",
          "source": "type ColumnOrColumnGroupConfig<\n  R extends ObjectForExtending,\n  SR = unknown,\n> = ColumnConfig<R, SR> | ColumnGroupConfig<R, SR>;"
        }
      ],
      "stories": [
        {
          "exportName": "Playground",
          "displayName": "Группировка (squash)",
          "type": "full-code",
          "code": "import {\n  Canvas,\n  ColumnOrColumnGroupConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n    const [squash, setSquash] = useState(true);\n\n    const columnConfig = useMemo<ColumnOrColumnGroupConfig<Row>[]>(\n      () => [\n        // Одиночная колонка без группы: при squash её шапка тянется вверх.\n        { key: 'id', name: 'ID', width: 90, resizable: true },\n        // Глубокая группа (3 уровня) для реордера.\n        {\n          key: 'metrics',\n          name: 'Показатели',\n          children: [\n            {\n              key: 'sales',\n              name: 'Продажи',\n              children: [\n                { key: 'task', name: 'План', width: 150, resizable: true },\n                { key: 'priority', name: 'Факт', width: 130, resizable: true },\n              ],\n            },\n            {\n              key: 'grade',\n              name: 'Оценка',\n              children: [\n                { key: 'issueType', name: 'Инд', width: 120, resizable: true },\n                { key: 'developer', name: 'Кол', width: 120, resizable: true },\n                { key: 'complete', name: 'Итог', width: 120, resizable: true },\n              ],\n            },\n          ],\n        },\n        // «Мелкая» группа с кастомным canvas-name: при squash тянется вниз\n        // (под шапкой нет подгрупп, иначе была бы пустая полоса).\n        {\n          key: 'pppp',\n          name: (\n            <Canvas.Container padding={{ left: 8, right: 8 }}>\n              <Canvas.Text\n                color={tableCanvasTheme.accentColor}\n                font={tableCanvasFonts.bodyXSBold}\n              >\n                кастомный name\n              </Canvas.Text>\n            </Canvas.Container>\n          ),\n          children: [{ key: 'tr', name: 'TR', width: 130, resizable: true }],\n        },\n      ],\n      [],\n    );\n\n    return (\n      <div>\n        <div\n          style={{\n            display: 'flex',\n            alignItems: 'center',\n            gap: 8,\n            marginBottom: 12,\n          }}\n        >\n          <Switch\n            checked={squash}\n            onChange={(e) => setSquash(e.target.checked)}\n            label=\"columnsGrouping.squashEmptyCells\"\n          />\n        </div>\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: 340 },\n            columnsGrouping: { squashEmptyCells: squash },\n            columnsControl: { enable: true },\n            resizableColumn: true,\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "HeaderAlign",
          "displayName": "Выравнивание заголовка",
          "type": "full-code",
          "code": "import {\n  Canvas,\n  ColumnOrColumnGroupConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const columnConfig: ColumnOrColumnGroupConfig<Row>[] = [\n      // Лист без группы: выравнивание на колонке. Имя короткое, колонка широкая,\n      // чтобы было видно позицию текста.\n      {\n        key: 'id',\n        name: 'top-left',\n        width: 200,\n        squashedHeaderAlign: { horizontal: 'left', vertical: 'top' },\n      },\n      // Глубокая группа задаёт третий уровень, чтобы соседняя группа стала «мелкой».\n      {\n        key: 'deep',\n        name: 'Глубокая',\n        children: [\n          {\n            key: 'sub',\n            name: 'Подгруппа',\n            children: [\n              { key: 'task', name: 'A', width: 110 },\n              { key: 'priority', name: 'B', width: 110 },\n            ],\n          },\n        ],\n      },\n      // Мелкая группа (сливается вниз): выравнивание на группе. Колонка широкая,\n      // чтобы короткое имя было видно прижатым вниз-вправо.\n      {\n        key: 'shallow',\n        name: 'bottom-right',\n        squashedHeaderAlign: { horizontal: 'right', vertical: 'bottom' },\n        children: [{ key: 'complete', name: 'C', width: 240 }],\n      },\n    ];\n\n    return (\n      <TableCanvas\n        tableConfig={{ containerStyle: { height: 320 } }}\n        columnConfig={columnConfig}\n        rows={spanRows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "ContextMenu",
      "legacy": false,
      "summary": "*tableConfig.onHeaderContextMenu / onCellContextMenu / onHeaderContextMenuDropdown / onCellContextMenuDropdown**",
      "docs": "# Context Menu\n\n**tableConfig.onHeaderContextMenu / onCellContextMenu / onHeaderContextMenuDropdown / onCellContextMenuDropdown**\n\nКонтекстное меню для заголовков колонок и ячеек.\n\n## Основные возможности\n\n- Правый клик по заголовку колонки или ячейке открывает контекстное меню\n- Поддержка многоуровневых dropdown-меню (на основе компонента Dropdown)\n- Кастомизация пунктов меню в зависимости от контекста (колонка/ячейка)\n- Обработка выбора пунктов меню с передачей соответствующего контекста\n\n## Варианты использования\n\n### 1. Простой обработчик клика (без меню)\n\n- `onHeaderContextMenu` — для заголовков колонок\n- `onCellContextMenu` — для ячеек таблицы\n\n### 2. Dropdown-меню (расширенный вариант)\n\n- `onHeaderContextMenuDropdown` — для заголовков\n- `onCellContextMenuDropdown` — для ячеек\n\n## Приоритет вызова\n\nЕсли определены оба варианта (и обработчик, и dropdown):\n\n1. Сначала вызывается `onHeaderContextMenu` / `onCellContextMenu`\n2. Затем происходит обработка dropdown-меню\n\n## Конфигурация Dropdown\n\nДля конфигурации dropdown-меню используются специальные пропсы, исключающие некоторые параметры стандартного Dropdown, которые управляются таблицей (например, позиционирование, триггеры и т.д.).\n\n## Асинхронная подгрузка пунктов\n\nКогда пункты меню неизвестны заранее и подгружаются по правому клику. Запросом и его состоянием (загрузка / данные / ошибка) владеет потребитель — таблица только открывает меню и реактивно перечитывает пункты.\n\n- `onOpen` — вызывается при открытии меню; здесь потребитель стартует запрос и хранит своё состояние. Если задан, меню открывается даже при пустом результате `getDropdownItems`.\n- `getDropdownItems` — читается реактивно, пока меню открыто: во время загрузки верните скелетон-пункты, после — реальные. Меню обновляется само, без переоткрытия.\n- Индикатор загрузки — скелетон-пункты (через `renderItem`) или произвольный узел в `beforeList`.\n- Ошибка — узел в `beforeList` (например `EmptyState` с кнопкой повтора, вызывающей повторную загрузку).\n\nПример со скелетонами, успешной загрузкой и ошибкой — в стори ниже.\n\nПодробное описание API и типов доступно в разделе [API](/docs/локальные-компоненты-tablecanvas-contextmenu-api--docs).",
      "apiDocs": "# Context Menu API\n\n## ContextMenuDropdownProps\n\nПропсы Dropdown, доступные для проброса в контекстное меню.\nМожно передать `size`, `listWidth`, `closeOnSelect`, `offset` и другие свойства Dropdown.\n\n```typescript\ntype ContextMenuDropdownProps = Omit<\n  DropdownProps,\n  | 'children'\n  | 'items'\n  | 'placement'\n  | 'closeOnOverlayClick'\n  | 'portal'\n  | 'openByRightClick'\n  | 'onItemClick'\n  | 'hoverIndex'\n  | 'alwaysOpened'\n  | 'trigger'\n  | 'hasArrow'\n  | 'onItemSelect'\n>;\n```\n\n## HeaderContextMenuDropdownProps\n\n```typescript\ntype HeaderContextMenuDropdownProps<\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n  CustomCtxs extends ObjectForExtending = ObjectForExtending,\n> = ContextMenuDropdownProps & {\n  /** Тип конфигурации (всегда 'dropdown') */\n  type: 'dropdown';\n  /**\n   * Функция, возвращающая массив пунктов меню для конкретного заголовка.\n   * В асинхронном режиме (задан onOpen) перечитывается реактивно, пока меню\n   * открыто: верните скелетон-пункты во время загрузки и реальные — после.\n   */\n  getDropdownItems: (\n    params: TableInfoBase<RowType, SummaryRowType, CustomCtxs>,\n  ) => DropdownProps['items'];\n  /**\n   * Колбэк открытия меню для асинхронной подгрузки. Если getDropdownItems\n   * вернул пусто, но onOpen задан — меню всё равно открывается, а потребитель\n   * здесь стартует запрос и хранит своё состояние (loading/error/items).\n   */\n  onOpen?: (params: TableInfoBase<RowType, SummaryRowType, CustomCtxs>) => void;\n  /** Обработчик выбора пункта меню */\n  onItemSelect?: (\n    item: ContextMenuDropdownItem,\n    context: TableInfoBase<RowType, SummaryRowType, CustomCtxs>,\n    event?: React.SyntheticEvent,\n  ) => void;\n};\n```\n\n## CellContextMenuDropdownProps\n\n```typescript\ntype CellContextMenuDropdownProps<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  CustomCtxs extends ObjectForExtending = ObjectForExtending,\n> = ContextMenuDropdownProps & {\n  /** Тип конфигурации (всегда 'dropdown') */\n  type: 'dropdown';\n  /**\n   * Функция, возвращающая массив пунктов меню для конкретной ячейки.\n   * В асинхронном режиме (задан onOpen) перечитывается реактивно, пока меню\n   * открыто: верните скелетон-пункты во время загрузки и реальные — после.\n   */\n  getDropdownItems: (\n    params: TableInfoWithRow<RowType, SummaryRowType, CustomCtxs>,\n  ) => DropdownProps['items'];\n  /**\n   * Колбэк открытия меню для асинхронной подгрузки. Если getDropdownItems\n   * вернул пусто, но onOpen задан — меню всё равно открывается, а потребитель\n   * здесь стартует запрос и хранит своё состояние (loading/error/items).\n   */\n  onOpen?: (\n    params: TableInfoWithRow<RowType, SummaryRowType, CustomCtxs>,\n  ) => void;\n  /** Обработчик выбора пункта меню */\n  onItemSelect?: (\n    item: ContextMenuDropdownItem,\n    context: TableInfoWithRow<RowType, SummaryRowType, CustomCtxs>,\n    event?: React.SyntheticEvent,\n  ) => void;\n};\n```\n\n## DropdownContextMenu\n\n```typescript\ntype DropdownContextMenu = {\n  type: 'Dropdown';\n  getDropdownItems: (params: { columnLabel: string }) => DropdownProps['items'];\n} & ContextMenuDropdownProps;\n```\n\n## ContextMenuDropdownItem\n\n```typescript\ntype ContextMenuDropdownItem = NonNullable<\n  DropdownProps['items']\n>[number];\n```",
      "api": [
        {
          "typeName": "ContextMenuDropdownProps",
          "source": "type ContextMenuDropdownProps = Omit<\n  DropdownProps,\n  | 'children'\n  | 'items'\n  | 'placement'\n  | 'closeOnOverlayClick'\n  | 'portal'\n  | 'openByRightClick'\n  | 'onItemClick'\n  | 'hoverIndex'\n  | 'alwaysOpened'\n  | 'trigger'\n  | 'hasArrow'\n  | 'onItemSelect'\n>;"
        },
        {
          "typeName": "HeaderContextMenuDropdownProps",
          "source": "type HeaderContextMenuDropdownProps<\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n  CustomCtxs extends ObjectForExtending = ObjectForExtending,\n> = ContextMenuDropdownProps & {\n  /** Тип конфигурации (всегда 'dropdown') */\n  type: 'dropdown';\n  /**\n   * Функция, возвращающая массив пунктов меню для конкретного заголовка.\n   * В асинхронном режиме (задан onOpen) перечитывается реактивно, пока меню\n   * открыто: верните скелетон-пункты во время загрузки и реальные — после.\n   */\n  getDropdownItems: (\n    params: TableInfoBase<RowType, SummaryRowType, CustomCtxs>,\n  ) => DropdownProps['items'];\n  /**\n   * Колбэк открытия меню для асинхронной подгрузки. Если getDropdownItems\n   * вернул пусто, но onOpen задан — меню всё равно открывается, а потребитель\n   * здесь стартует запрос и хранит своё состояние (loading/error/items).\n   */\n  onOpen?: (params: TableInfoBase<RowType, SummaryRowType, CustomCtxs>) => void;\n  /** Обработчик выбора пункта меню */\n  onItemSelect?: (\n    item: ContextMenuDropdownItem,\n    context: TableInfoBase<RowType, SummaryRowType, CustomCtxs>,\n    event?: React.SyntheticEvent,\n  ) => void;\n};"
        },
        {
          "typeName": "CellContextMenuDropdownProps",
          "source": "type CellContextMenuDropdownProps<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  CustomCtxs extends ObjectForExtending = ObjectForExtending,\n> = ContextMenuDropdownProps & {\n  /** Тип конфигурации (всегда 'dropdown') */\n  type: 'dropdown';\n  /**\n   * Функция, возвращающая массив пунктов меню для конкретной ячейки.\n   * В асинхронном режиме (задан onOpen) перечитывается реактивно, пока меню\n   * открыто: верните скелетон-пункты во время загрузки и реальные — после.\n   */\n  getDropdownItems: (\n    params: TableInfoWithRow<RowType, SummaryRowType, CustomCtxs>,\n  ) => DropdownProps['items'];\n  /**\n   * Колбэк открытия меню для асинхронной подгрузки. Если getDropdownItems\n   * вернул пусто, но onOpen задан — меню всё равно открывается, а потребитель\n   * здесь стартует запрос и хранит своё состояние (loading/error/items).\n   */\n  onOpen?: (\n    params: TableInfoWithRow<RowType, SummaryRowType, CustomCtxs>,\n  ) => void;\n  /** Обработчик выбора пункта меню */\n  onItemSelect?: (\n    item: ContextMenuDropdownItem,\n    context: TableInfoWithRow<RowType, SummaryRowType, CustomCtxs>,\n    event?: React.SyntheticEvent,\n  ) => void;\n};"
        },
        {
          "typeName": "DropdownContextMenu",
          "source": "type DropdownContextMenu = {\n  type: 'Dropdown';\n  getDropdownItems: (params: { columnLabel: string }) => DropdownProps['items'];\n} & ContextMenuDropdownProps;"
        },
        {
          "typeName": "ContextMenuDropdownItem",
          "source": "type ContextMenuDropdownItem = NonNullable<\n  DropdownProps['items']\n>[number];"
        }
      ],
      "stories": [
        {
          "exportName": "ContextOnHeaderMenuDropdownStory",
          "displayName": "Контекстное меню Dropdown (шапка таблицы)",
          "type": "full-code",
          "code": "import { createRows, type Row } from './data/tableData';\nimport { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.ContextMenu/TableCanvasContextMenu.stories.tsx',\n  'ExampleHeaderDropdown',\n)}"
        },
        {
          "exportName": "ContextOnHeaderMenuStory",
          "displayName": "Контекстное меню, функция обработчик (шапка таблицы)",
          "type": "full-code",
          "code": "import { createRows, type Row } from './data/tableData';\nimport { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.ContextMenu/TableCanvasContextMenu.stories.tsx',\n  'ExampleHeaderHandler',\n)}"
        },
        {
          "exportName": "ContextOnCellMenuDropdownStory",
          "displayName": "Контекстное меню Dropdown (cell таблицы)",
          "type": "full-code",
          "code": "import { createRows, type Row } from './data/tableData';\nimport { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.ContextMenu/TableCanvasContextMenu.stories.tsx',\n  'ExampleCellDropdown',\n)}"
        },
        {
          "exportName": "ContextOnCellMenuStory",
          "displayName": "Контекстное меню, функция обработчик (cell таблицы)",
          "type": "full-code",
          "code": "import { createRows, type Row } from './data/tableData';\nimport { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.ContextMenu/TableCanvasContextMenu.stories.tsx',\n  'ExampleCellHandler',\n)}"
        },
        {
          "exportName": "ContextMenuCustomDropdownPropsStory",
          "displayName": "Кастомные свойства Dropdown (size, listWidth, closeOnSelect)",
          "type": "full-code",
          "code": "import { createRows, type Row } from './data/tableData';\nimport { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.ContextMenu/TableCanvasContextMenu.stories.tsx',\n  'ExampleCustomDropdownProps',\n)}"
        },
        {
          "exportName": "ContextOnCellAndOnHeaderMenuStory",
          "displayName": "Контекстное меню (все возможности)",
          "type": "full-code",
          "code": "function ExampleAllFeatures() {\n  const [rows] = useState(createRows);\n\n  const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n    () => [\n      { key: 'id', name: 'ID' },\n      { key: 'task', name: 'Title' },\n      { key: 'priority', name: 'Priority' },\n      { key: 'issueType', name: 'Issue Type' },\n      { key: 'developer', name: 'Developer' },\n      { key: 'tr1', name: 'TR' },\n      { key: 'complete', name: '% Complete' },\n    ],\n    [],\n  );\n\n  return (\n    <TableCanvas\n      tableConfig={{\n        onCellContextMenu: (args, event, context) => {\n          console.debug(args, event, context, 'onCellContextMenu');\n        },\n        onCellContextMenuDropdown: {\n          type: 'dropdown',\n          getDropdownItems: ({ column }) => [\n            {\n              value: `lvl1 ${column.name}`,\n              label: `${column.name} lvl1`,\n              items: [\n                {\n                  value: `lvl1_inside ${column.name}`,\n                  label: `${column.name} lvl1 inside`,\n                },\n              ],\n            },\n            {\n              value: `lvl2 ${column.name}`,\n              label: `${column.name} lvl2`,\n            },\n          ],\n          onItemSelect: (item, context, event) => {\n            console.group('onItemSelect for onCellContextMenuDropdown');\n            console.debug(item, 'item');\n            console.debug(context, 'context');\n            console.debug(event, 'event');\n            console.groupEnd();\n          },\n        },\n        onHeaderContextMenu: (colIndex, event, context) =>\n          console.debug(colIndex, event, context),\n        onHeaderContextMenuDropdown: {\n          type: 'dropdown',\n          getDropdownItems: ({ column }) => [\n            {\n              value: `lvl1 ${column.name}`,\n              label: `${column.name} lvl1`,\n              items: [\n                {\n                  value: `lvl1_inside ${column.name}`,\n                  label: `${column.name} lvl1 inside`,\n                },\n              ],\n            },\n            {\n              value: `lvl2 ${column.name}`,\n              label: `${column.name} lvl2`,\n            },\n          ],\n          onItemSelect: (item, context, event) => {\n            console.group('onItemSelect for onHeaderContextMenuDropdown');\n            console.debug(item, 'item');\n            console.debug(context, 'context');\n            console.debug(event, 'event');\n            console.groupEnd();\n          },\n        },\n      }}\n      columnConfig={columnConfig}\n      rows={rows}\n    />\n  );\n}"
        },
        {
          "exportName": "ContextOnCellMenuAsyncSuccessStory",
          "displayName": "Async-подгрузка пунктов (успех)",
          "type": "full-code",
          "code": "() => <AsyncCellDropdownExample shouldFail={false} />"
        },
        {
          "exportName": "ContextOnCellMenuAsyncErrorStory",
          "displayName": "Async-подгрузка пунктов (ошибка + ретрай)",
          "type": "full-code",
          "code": "() => <AsyncCellDropdownExample shouldFail />"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "ControlBlock",
      "legacy": false,
      "summary": "*tableConfig.controlBlock**",
      "docs": "# ControlBlock (TableCanvas)\n\n**tableConfig.controlBlock**\n\nПанель управления таблицы (верхний блок с кнопками).\n\n## Ключевые особенности\n\n- Поиск по таблице\n- Кнопки действий (`rightSideInner`) и кастомные фичи с иконками (`customFeatures`)\n- Встроенные фичи: ключ-текст, группировка строк, размер строк, полноэкранный режим\n- Режим редактирования с кастомным слотом слева (`editModeLeftSlot`)\n- Заголовок таблицы и сворачивание, внутри панели или над таблицей\n- Три размера панели: `m`, `s`, `xs`. `m` и `s` одинаковы и подходят всем продуктам, `xs` использует команда APE\n- Компрессия по ширине: лишние фичи уезжают в overflow-дропдаун, его ширина, размер и иконки внутри подстраиваются под `rowSize`\n\n## Размеры\n\nРазмер панели задаётся в `tableConfig.controlBlock.size`: `m`, `s` или `xs`. Размер каскадно применяется к кнопкам, поиску, заголовку и кнопке сворачивания. Высота панели: `m` и `s` дают 40px, `xs` дает 32px.\n\n`m` и `s` дают одинаковый размер и предназначены для всех продуктов. `xs` это компактный режим, его использует команда APE. Примеры `xs` смотрите в разделе ControlBlock APE.\n\n## Заголовок и сворачивание\n\nЗаголовок и сворачивание настраиваются в `tableConfig.collapsing` (на уровне всей таблицы, рядом с `controlBlock`, а не внутри него).\n\n- `titleText` показывает заголовок таблицы (для своего узла есть `titleRender`).\n- `enableCollapse` добавляет кнопку сворачивания таблицы.\n- `collapseButtonPlacement` задаёт, где живут заголовок и кнопка: `inside` (по умолчанию) рисует их внутри самой панели, `above` выносит в отдельную полосу над таблицей. Для режима `above` есть `collapseButtonAboveRightSlot` под свой контент справа.\n\n## Фичи и details\n\nКастомные фичи задаются в `tableConfig.controlBlock.customFeatures` (массив). Каждая фича рисуется в панели как иконка, а при компрессии может уехать в overflow-дропдаун.\n\nИконку в самой панели задают на фиче через `Icon` (компонент иконки) или `CustomIconRender` (свой рендер).\n\nПоле `details` (на той же фиче) описывает, как фича выглядит, когда уезжает в дропдаун. Раньше `details` отвечал за правый сайдбар, теперь за дропдаун. Имя оставили, чтобы не ломать существующий код.\n\nТипы `details`:\n\n- `button` — пункт с иконкой и действием\n- `switch` — переключатель\n- `select` — выпадающий список\n- `custom` — свой рендер пункта\n\nТочные типы фич и `details` смотрите в [ControlBlock API](?path=/docs/локальные-компоненты-tablecanvas-controlblock-api--docs), готовые примеры — в stories ниже.\n\n## Поведение при компрессии\n\nКогда таблице не хватает ширины, фичи по одной уезжают в overflow-дропдаун (троеточие). В дропдауне фича показывается по своему `details`; фича без `details` при нехватке места просто скрывается.\n\nОба флага ниже задаются на самой фиче (элемент массива `customFeatures`):\n\n- `canBeCompressedInToolsMenu` управляет уходом фичи в дропдаун. По умолчанию `true`, при нехватке места фича может уехать в overflow-дропдаун. Поставьте `false`, чтобы фича всегда оставалась видимой в панели и никогда не пряталась.\n- `mandatory: true` ставит фичу в начало панели и закрепляет её там. Влияет на порядок и присутствие фичи в панели (наследие старого распределения панель и сайдбар), а уходом в дропдаун управляет именно `canBeCompressedInToolsMenu`.\n\n## Размер иконок в дропдауне\n\nСам дропдаун подстраивается под `rowSize`: на маленьком `rowSize` он уже и компактнее. Поэтому и иконки внутри берутся на ступень меньше, чем в самой панели.\n\n- Наши штатные фичи мы размеряем сами по дизайн-макетам. Иконки-компоненты (`Icon`), а также ключ-текст, группировка и вид отображения мельчают в дропдауне автоматически, ничего делать не нужно.\n- Свои кастомные фичи в правой части размеряете вы. Готовый JSX размер сам не знает, поэтому кастомные рендеры получают контекст `{ rowSize, isInDropdown }` и подбирают размер сами. `isInDropdown` отличает панель (`false`, иконка обычная) от дропдауна (`true`, мельче при маленьком `rowSize`):\n\n```tsx\n// кастомная иконка фичи в панели и в дропдауне (поле CustomIconRender фичи)\nCustomIconRender: ({ rowSize, isInDropdown }) => (\n  <IconStar size={isInDropdown && rowSize === 'small' ? 'xs' : 's'} />\n),\n\n// иконка фичи в details, задаём функцией вместо готового узла\ndetails: {\n  type: 'button',\n  label: 'Экспорт',\n  icon: ({ rowSize, isInDropdown }) => (\n    <IconExport size={isInDropdown && rowSize === 'small' ? 'xs' : 's'} />\n  ),\n  onClick: handleExport,\n},\n\n// иконка кнопки rightSideInner, когда она уезжает в дропдаун\n{\n  text: 'Сохранить',\n  contentLeft: <IconSave />,\n  dropdownIconRender: ({ rowSize }) => (\n    <IconSave size={rowSize === 'small' ? 'xs' : 's'} />\n  ),\n},\n```\n\nЕсли оставить статичный узел (`icon: <IconExport />`, `CustomIconRender: () => <Icon />`), он работает как раньше, просто размер в дропдауне не меняется.\n\nПодробнее смотрите примеры в сториях ниже: там кастомные фичи получают `rowSize` и `isInDropdown` и сами выбирают размер иконки для дропдауна.\n\n## Кнопки с дропдауном\n\nУ кнопок правой части (`rightSideInner`) с `dropdown` шеврон раскрытия рисуется автоматически. Если `contentRight` не задан, кнопка сама показывает справа `IconChevronDown` с анимацией флипа при открытии дропдауна. Размер шеврона берётся из той же размерной сетки, что и иконки кнопок, отдельно его задавать не нужно.\n\nЕсли `contentRight` задан (например счётчик у группировки), используется он, авто-шеврон не добавляется. Анимацию флипа панель навешивает только на свой авто-шеврон, ваш `contentRight` рендерится как есть, контроль за анимация остается на вашей стороне в этом случае.\n\nРазмер иконки кнопки (`contentLeft`) панель задаёт сама под свой размер, отдельно его указывать не нужно. Но если вы явно проставили `size` на иконке своей кнопки, он сохраняется, панель его не перезаписывает.\n\n## Разделители\n\nНа фиче в `customFeatures` можно включить разделитель слева через `dividerLeft: true`. Если по дизайн-макету ваша кастомная фича отделена разделителем, задайте `dividerLeft`. Разделители сохраняются и в overflow-дропдауне, в той же последовательности, что и в панели.\n\n## Устаревшее\n\n- `controlBlock.leftSideInner` (кнопки в левой части панели, блок «Действия»). Используйте `controlBlock.rightSideInner` или `controlBlock.customFeatures`.\n- Link-стили у кнопок панели (`view: 'linkDefault'`, `'linkAccent'` и подобные на `ControlBlockButtonProps`) и `controlButtonDefaultProps`. Кнопки панели теперь рисуются как обычные, link-стиль маппится автоматически.\n- Старый `dropdown` на фиче заменён на `details`, `customDropdownItem` больше не поддерживается.\n- Свойство `view` в `tableConfig` не используется.\n\n## Пример конфигурации\n\n```tsx\nconst tableConfig = {\n  // заголовок и сворачивание — на уровне таблицы, рядом с controlBlock\n  collapsing: {\n    enableCollapse: true,\n    titleText: 'Реестр задач',\n    collapseButtonPlacement: 'above',\n  },\n  controlBlock: {\n    size: 's',\n    customFeatures: [\n      {\n        value: 'customPin',\n        label: pinIsActive ? 'Открепить' : 'Закрепить',\n        Icon: pinIsActive ? IconPinOutline : IconPinFill,\n        onClick: () => setPinIsActive(!pinIsActive),\n        // по умолчанию true; поставьте false, чтобы фича не пряталась в дропдаун\n        canBeCompressedInToolsMenu: true,\n        details: {\n          type: 'switch',\n          label: 'Закрепление колонок',\n          checked: pinIsActive,\n          onChange: () => setPinIsActive(!pinIsActive),\n        },\n      },\n    ],\n  },\n};\n```\n\n> Подробнее о типах — [ControlBlock API](?path=/docs/локальные-компоненты-tablecanvas-controlblock-api--docs)\n\n# SplitIconButton (TableCanvas)\n\nПереиспользуемый компонент для кастомных слотов ControlBlock. Это пара кнопок-иконок рядом: основное действие слева и кнопка-шеврон справа, открывающая дропдаун (паттерн split button). Реэкспортируется из TableCanvas, импорт: `import { SplitIconButton } from '@daisforge/ui/components/TableCanvas'`.\n\n## Ключевые особенности\n\n- Две независимые кнопки: основная иконка (`onIconClick`) и кнопка-шеврон, открывающая дропдаун\n- Шеврон и анимация раскрытия идут от компонента, левую иконку и размеры задаёт разработчик\n- Дропдаун под капотом это TableDropdown, поэтому ширина и размер списка подхватывают `rowSize` таблицы автоматически\n- Пункты дропдауна (`items`) полностью на стороне разработчика: галочки, иконки или ничего, библиотека их только прокидывает\n- Если `items` не заданы, шеврон работает как обычная кнопка (`onChevronClick`)\n\n## Где использовать\n\n- `editing.editModeLeftSlot` это кастомный слот слева в режиме редактирования\n- `controlBlock.customFeatures[].CustomIconRender` это кастомная фича в правой части панели\n\n## Особенности\n\n- Работает только внутри контекста TableCanvas, потому что дропдаун использует контекст таблицы (`rowSize`, контейнер). Вне таблицы не используется.\n- Размеры задаёт потребитель: `size` для кнопок, `chevronSize` для иконки шеврона, размер своей иконки слева.\n- При компрессии фича уезжает в overflow-дропдаун. Её свёрнутый вид описывается через `details` самой фичи, а не через сам компонент. Например `details: { type: 'select' }` с галочкой активного пункта в `contentLeft` опций.\n\nОписание типов в разделе [SplitIconButton API](?path=/docs/локальные-компоненты-tablecanvas-controlblock-spliticonbutton-api--docs).",
      "apiDocs": "# ControlBlock API\n\n## ControlBlockConfig\n\n```typescript\ntype ControlBlockConfig = {\n  /**\n   * show - наличие controlBlock-а\n   * @default true\n   */\n  show?: boolean;\n  /**\n   * Размер controlBlock и его элементов (кнопки, иконки, поиск, отступы).\n   * 'm' и 's' — стандартные стили, 'xs' — компактный режим.\n   * Не влияет на customFeatures и кастомные слоты — они контролируются разработчиком.\n   * @default 'm'\n   */\n  size?: ControlBlockSize;\n  /**\n   * @deprecated Используйте кастомные кнопки через rightSideInner или customFeatures.\n   * leftSideInner - пропс для добавления кнопок в левую часть контролблока.\n   * Продолжает работать для обратной совместимости.\n   */\n  leftSideInner?: ControlBlockButtonProps[];\n  /**\n   * rightSideInner - пропс для добавления кнопок в правую часть контролблока\n   */\n  rightSideInner?: ControlBlockButtonProps[];\n  /**\n   * customFeatures - пропс для добавления кастомных фичей (кнопки-иконки)\n   */\n  customFeatures?: FeatureItem[];\n  /**\n   * pinningMenu - нативная фича закрепления столбцов (SplitIconButton с\n   * дропдауном) в правой зоне иконок. Появляется, когда активировано\n   * закрепление колонок (columnsControl.pinning). Продукт может донастроить\n   * и дополнить пункты меню (см. PinningMenuConfig).\n   */\n  pinningMenu?: PinningMenuConfig;\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n   */\n  leftSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n   */\n  rightSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n   * @default true\n   */\n  enableAdaptiveCompress?: boolean;\n  /**\n   * Панель массовых действий\n   */\n  massActionPanel?: {\n    /**\n     * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n     * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n     */\n    buttons: MassActionButtonProps[];\n    /**\n     * Пропсы для Dropdown, в который сжались кнопки\n     */\n    collapsedDropdownProps?: TableDropdownConfigProps;\n    /**\n     * Отступ панели снизу от контейнера (px)\n     * @default 24\n     */\n    bottom?: number;\n    /**\n     * Управление отображением панели массовых действий.\n     * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n     * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n     * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n     */\n    show?: boolean;\n    /**\n     * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n     * Viewport-логика (1280) в таблице не используется.\n     * @default 's'\n     */\n    size?: MassActionsSize;\n  };\n};\n```\n\n## ControlBlockButtonProps\n\n```ts\nexport const controlButtonDefaultProps = {\n  size: 's',\n  view: 'linkDefault',\n} as const;\n```\n\n```typescript\ntype ButtonProps = ComponentProps<typeof Button>;\n```\n\n## FeatureItem (v2.0)\n\nКастомная фича в `tableConfig.controlBlock.customFeatures`. Иконку в панели задают через `Icon` или `CustomIconRender`, поведение в дропдауне — через `details`. Флаги `mandatory` и `canBeCompressedInToolsMenu` ставятся здесь же, на фиче.\n\n```typescript\ntype FeatureItemWithIcon = FeatureDetailsBase & {\n  /**\n   * Свойства ниже - сохранение старой реализации фичей, до переезда их в sidebar.\n   * Используются для отображения фичи в верхнем controlBlock\n   */\n  value: string;\n  label: string;\n  onClick: () => void;\n  Icon: FC<IconProps>;\n  /**\n   * Добавляет разделитель слева от элемента\n   * @default false\n   */\n  dividerLeft?: boolean;\n  modal?: ReactNode;\n  className?: string;\n} & DataAttributes;\n```\n\n## FeatureDetails\n\nПоле `details` у фичи (`customFeatures[].details`). Описывает, как фича выглядит в overflow-дропдауне (троеточие), куда она уезжает при компрессии. Раньше отвечал за правый сайдбар, имя сохранено для обратной совместимости.\n\n```typescript\ntype FeatureDetailsBase = {\n  /**\n   * Если true, фича будет всегда отображаться в controlBlock и не может быть перенесена в sidebar\n   * @default false\n   */\n  mandatory?: boolean;\n  /**\n   * Если true, фича может быть сжата в блок ... внутри ToolsMenu\n   * @default false\n   */\n  canBeCompressedInToolsMenu?: boolean;\n  /**\n   * Дополнительные детали/настройки для фичи для отображения в RightSidebar таблицы\n   */\n  details?: FeatureDetails;\n};\n```\n\n## FeatureIconRender\n\nТип иконки в `details.icon` (для `details` типа `button` и `select`). Либо готовый узел, либо функция от контекста рендера. Функция нужна, чтобы подстроить размер иконки в дропдауне.\n\n```typescript\ntype FeatureIconRender =\n  | ReactNode\n  | ((ctx: DropdownRenderCtx) => ReactNode);\n```\n\n## DropdownRenderCtx\n\nКонтекст, который получают кастомные рендеры иконок (`CustomIconRender`, `details.icon` как функция, `dropdownIconRender` у кнопок). По нему потребитель сам подбирает размер иконки.\n\n```typescript\ntype DropdownRenderCtx = {\n  /** Текущая высота строк таблицы (big | medium | small) */\n  rowSize: SIZE;\n  /** true - иконка рисуется в overflow дропдауне, false - в контрл-блоке */\n  isInDropdown: boolean;\n};\n```\n\n# SplitIconButton API\n\n## SplitIconButtonProps\n\n```typescript\ntype SplitIconButtonProps = {\n  /** Иконка основной (левой) кнопки-действия */\n  icon: ReactNode;\n  /** Клик по основной кнопке-иконке */\n  onIconClick?: () => void;\n  /** Tooltip на левой кнопке-иконке (если задан — оборачиваем в TableTooltip). */\n  iconTooltip?: ReactNode;\n  /**\n   * Полная замена иконки шеврона своим узлом. Обычно не нужна — шеврон наш\n   * (IconChevronDown), а размер задаётся через chevronSize. Если задан, имеет\n   * приоритет над chevronSize.\n   */\n  chevronIcon?: ReactNode;\n  /** Размер нашей иконки-шеврона. Игнорируется, если задан chevronIcon. */\n  chevronSize?: 'xs' | 's' | 'm';\n  /** Размер обеих кнопок (EmbedIconButton) */\n  size?: ComponentProps<typeof EmbedIconButton>['size'];\n  /**\n   * Пункты дропдауна. Если заданы — кнопка-шеврон открывает TableDropdown.\n   * Если не заданы — шеврон работает как обычная кнопка (onChevronClick).\n   */\n  items?: TableDropdownProps['items'];\n  /** Выбор пункта дропдауна */\n  onItemSelect?: TableDropdownProps['onItemSelect'];\n  /** Клик по шеврону в режиме без дропдауна (items не заданы) */\n  onChevronClick?: () => void;\n  /** Колбэк открытия/закрытия дропдауна */\n  onToggle?: (isOpen: boolean) => void;\n  /** Доп. конфиг TableDropdown (placement, listWidth и т.п.) */\n  dropdownProps?: TableDropdownConfigProps;\n  /** data-атрибуты на контейнер */\n  domMetadata?: DataAttributes;\n  /** data-атрибуты на основную кнопку */\n  iconDomMetadata?: DataAttributes;\n  /** data-атрибуты на кнопку-шеврон */\n  chevronDomMetadata?: DataAttributes;\n};\n```",
      "api": [
        {
          "typeName": "ControlBlockConfig",
          "source": "type ControlBlockConfig = {\n  /**\n   * show - наличие controlBlock-а\n   * @default true\n   */\n  show?: boolean;\n  /**\n   * Размер controlBlock и его элементов (кнопки, иконки, поиск, отступы).\n   * 'm' и 's' — стандартные стили, 'xs' — компактный режим.\n   * Не влияет на customFeatures и кастомные слоты — они контролируются разработчиком.\n   * @default 'm'\n   */\n  size?: ControlBlockSize;\n  /**\n   * @deprecated Используйте кастомные кнопки через rightSideInner или customFeatures.\n   * leftSideInner - пропс для добавления кнопок в левую часть контролблока.\n   * Продолжает работать для обратной совместимости.\n   */\n  leftSideInner?: ControlBlockButtonProps[];\n  /**\n   * rightSideInner - пропс для добавления кнопок в правую часть контролблока\n   */\n  rightSideInner?: ControlBlockButtonProps[];\n  /**\n   * customFeatures - пропс для добавления кастомных фичей (кнопки-иконки)\n   */\n  customFeatures?: FeatureItem[];\n  /**\n   * pinningMenu - нативная фича закрепления столбцов (SplitIconButton с\n   * дропдауном) в правой зоне иконок. Появляется, когда активировано\n   * закрепление колонок (columnsControl.pinning). Продукт может донастроить\n   * и дополнить пункты меню (см. PinningMenuConfig).\n   */\n  pinningMenu?: PinningMenuConfig;\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n   */\n  leftSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n   */\n  rightSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n   * @default true\n   */\n  enableAdaptiveCompress?: boolean;\n  /**\n   * Панель массовых действий\n   */\n  massActionPanel?: {\n    /**\n     * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n     * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n     */\n    buttons: MassActionButtonProps[];\n    /**\n     * Пропсы для Dropdown, в который сжались кнопки\n     */\n    collapsedDropdownProps?: TableDropdownConfigProps;\n    /**\n     * Отступ панели снизу от контейнера (px)\n     * @default 24\n     */\n    bottom?: number;\n    /**\n     * Управление отображением панели массовых действий.\n     * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n     * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n     * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n     */\n    show?: boolean;\n    /**\n     * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n     * Viewport-логика (1280) в таблице не используется.\n     * @default 's'\n     */\n    size?: MassActionsSize;\n  };\n};"
        },
        {
          "typeName": "ButtonProps",
          "source": "type ButtonProps = ComponentProps<typeof Button>;"
        },
        {
          "typeName": "FeatureItemWithIcon",
          "source": "type FeatureItemWithIcon = FeatureDetailsBase & {\n  /**\n   * Свойства ниже - сохранение старой реализации фичей, до переезда их в sidebar.\n   * Используются для отображения фичи в верхнем controlBlock\n   */\n  value: string;\n  label: string;\n  onClick: () => void;\n  Icon: FC<IconProps>;\n  /**\n   * Добавляет разделитель слева от элемента\n   * @default false\n   */\n  dividerLeft?: boolean;\n  modal?: ReactNode;\n  className?: string;\n} & DataAttributes;"
        },
        {
          "typeName": "FeatureDetailsBase",
          "source": "type FeatureDetailsBase = {\n  /**\n   * Если true, фича будет всегда отображаться в controlBlock и не может быть перенесена в sidebar\n   * @default false\n   */\n  mandatory?: boolean;\n  /**\n   * Если true, фича может быть сжата в блок ... внутри ToolsMenu\n   * @default false\n   */\n  canBeCompressedInToolsMenu?: boolean;\n  /**\n   * Дополнительные детали/настройки для фичи для отображения в RightSidebar таблицы\n   */\n  details?: FeatureDetails;\n};"
        },
        {
          "typeName": "FeatureIconRender",
          "source": "type FeatureIconRender =\n  | ReactNode\n  | ((ctx: DropdownRenderCtx) => ReactNode);"
        },
        {
          "typeName": "DropdownRenderCtx",
          "source": "type DropdownRenderCtx = {\n  /** Текущая высота строк таблицы (big | medium | small) */\n  rowSize: SIZE;\n  /** true - иконка рисуется в overflow дропдауне, false - в контрл-блоке */\n  isInDropdown: boolean;\n};"
        },
        {
          "typeName": "SplitIconButtonProps",
          "source": "type SplitIconButtonProps = {\n  /** Иконка основной (левой) кнопки-действия */\n  icon: ReactNode;\n  /** Клик по основной кнопке-иконке */\n  onIconClick?: () => void;\n  /** Tooltip на левой кнопке-иконке (если задан — оборачиваем в TableTooltip). */\n  iconTooltip?: ReactNode;\n  /**\n   * Полная замена иконки шеврона своим узлом. Обычно не нужна — шеврон наш\n   * (IconChevronDown), а размер задаётся через chevronSize. Если задан, имеет\n   * приоритет над chevronSize.\n   */\n  chevronIcon?: ReactNode;\n  /** Размер нашей иконки-шеврона. Игнорируется, если задан chevronIcon. */\n  chevronSize?: 'xs' | 's' | 'm';\n  /** Размер обеих кнопок (EmbedIconButton) */\n  size?: ComponentProps<typeof EmbedIconButton>['size'];\n  /**\n   * Пункты дропдауна. Если заданы — кнопка-шеврон открывает TableDropdown.\n   * Если не заданы — шеврон работает как обычная кнопка (onChevronClick).\n   */\n  items?: TableDropdownProps['items'];\n  /** Выбор пункта дропдауна */\n  onItemSelect?: TableDropdownProps['onItemSelect'];\n  /** Клик по шеврону в режиме без дропдауна (items не заданы) */\n  onChevronClick?: () => void;\n  /** Колбэк открытия/закрытия дропдауна */\n  onToggle?: (isOpen: boolean) => void;\n  /** Доп. конфиг TableDropdown (placement, listWidth и т.п.) */\n  dropdownProps?: TableDropdownConfigProps;\n  /** data-атрибуты на контейнер */\n  domMetadata?: DataAttributes;\n  /** data-атрибуты на основную кнопку */\n  iconDomMetadata?: DataAttributes;\n  /** data-атрибуты на кнопку-шеврон */\n  chevronDomMetadata?: DataAttributes;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "AllFeaturesWithTabs",
          "displayName": "1. Все фичи: Collapsing + TableTabs + ControlBlock",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\nimport { TableTabs } from '@daisforge/ui';\n\n() => {\n    const { rows, setRows, rowKeyGetter, columnConfig } = useBaseSetup();\n    const [groupByArr, setGroupByArr] = useState<string[]>([]);\n    const selectingState = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n    const editingEnabled = useState(false);\n    const activeTabState = useState<string | number>('tab1');\n    const [isFavorite, setIsFavorite] = useState(false);\n    const starFeature = useStarFeature();\n\n    return (\n      <TableTabs\n        tabs={[\n          { tabId: 'tab1', label: 'Основная' },\n          { tabId: 'tab2', label: 'Архив' },\n          { tabId: 'tab3', label: 'Аналитика' },\n        ]}\n        activeTabIdState={activeTabState}\n        rightSlot={<CustomRightSlot />}\n        collapsing={{\n          enabled: true,\n          collapseText: 'Свернуть таблицу',\n          expandText: 'Развернуть таблицу',\n          rightSlot: <CustomRightSlot />,\n        }}\n      >\n        <TableTabs.TabPanel tabId=\"tab1\">\n          <TableCanvas\n            tableConfig={{\n              containerStyle: { height: '60vh' },\n              fullScreenEnabled: true,\n              resizableColumn: true,\n              rowSize: { default: 'big', showInControl: true },\n              searching: { enabled: true },\n              keyText: { showInControl: true, controlBlock: {}, sidebar: {} },\n              rowsGrouping: {\n                rowKeyGetter,\n                groupByState: [groupByArr, setGroupByArr],\n              },\n              selecting: {\n                state: selectingState,\n                rowKeyGetter,\n              },\n              editing: {\n                onRowsChange: (newRows) => setRows(newRows as Row[]),\n                rowKeyGetter,\n                enabled: editingEnabled,\n                showButtons: true,\n                editModeLeftSlot: <EditModeLeftPanel />,\n              },\n              controlBlock: {\n                show: true,\n                size: 'm',\n                rightSideInner: [\n                  {\n                    text: 'Загрузить',\n                    contentLeft: <IconSb color=\"inherit\" />,\n                    // Пользовательская кнопка сама подгоняет иконку под\n                    // дропдаун: мельче на маленьком rowSize. Готовый\n                    // contentLeft мы не трогаем, размер задаёт автор кнопки.\n                    dropdownIconRender: (ctx) => (\n                      <IconSb\n                        color=\"inherit\"\n                        size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                      />\n                    ),\n                  },\n                  {\n                    text: 'Выгрузить',\n                    contentLeft: <IconSb color=\"inherit\" />,\n                    dropdownIconRender: (ctx) => (\n                      <IconSb\n                        color=\"inherit\"\n                        size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                      />\n                    ),\n                  },\n                  {\n                    text: 'Экспорт',\n                    contentLeft: <IconSb color=\"inherit\" />,\n                    dropdownIconRender: (ctx) => (\n                      <IconSb\n                        color=\"inherit\"\n                        size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                      />\n                    ),\n                    dropdown: {\n                      items: [\n                        { value: 'csv', label: 'CSV' },\n                        { value: 'xlsx', label: 'Excel' },\n                        { value: 'pdf', label: 'PDF' },\n                      ],\n                      onItemSelect: (item: any) =>\n                        alert(`Экспорт: ${item.label}`),\n                    },\n                  },\n                ],\n                customFeatures: [\n                  {\n                    value: 'refresh',\n                    label: 'Обновить',\n                    Icon: IconRefresh,\n                    onClick: () => alert('Обновить'),\n                    dividerLeft: true,\n                  },\n                  {\n                    value: 'favorite',\n                    label: 'Избранное',\n                    Icon: IconStar,\n                    onClick: () => alert('Избранное'),\n                    mandatory: true,\n                    details: {\n                      type: 'switch',\n                      label: 'В избранном',\n                      checked: isFavorite,\n                      onChange: (e) => setIsFavorite(e.target.checked),\n                    },\n                  },\n                  {\n                    value: 'add-row',\n                    label: 'Добавить строку',\n                    Icon: IconPlus,\n                    onClick: () => alert('Добавить строку'),\n                    dividerLeft: true,\n                    // Pinned-фича: НЕ уходит в overflow-дропдаун при сжатии,\n                    // всегда остаётся видимой в правой части\n                    canBeCompressedInToolsMenu: false,\n                  },\n                  starFeature,\n                ],\n              },\n            }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"tab2\">\n          <div style={{ padding: 24 }}>Архивные данные</div>\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"tab3\">\n          <div style={{ padding: 24 }}>Аналитика</div>\n        </TableTabs.TabPanel>\n      </TableTabs>\n    );\n  }"
        },
        {
          "exportName": "TabsWithoutCollapsing",
          "displayName": "2. TableTabs + ControlBlock (без коллапсинга)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\nimport { TableTabs } from '@daisforge/ui';\n\n() => {\n    const { rows, columnConfig } = useBaseSetup();\n    const activeTabState = useState<string | number>('tab1');\n    const starFeature = useStarFeature();\n\n    return (\n      <TableTabs\n        tabs={[\n          { tabId: 'tab1', label: 'Данные' },\n          { tabId: 'tab2', label: 'Настройки' },\n        ]}\n        activeTabIdState={activeTabState}\n        rightSlot={<CustomRightSlot />}\n      >\n        <TableTabs.TabPanel tabId=\"tab1\">\n          <TableCanvas\n            tableConfig={{\n              containerStyle: { height: '60vh' },\n              fullScreenEnabled: true,\n              rowSize: { default: 'big', showInControl: true },\n              searching: { enabled: true },\n              keyText: { showInControl: true, controlBlock: {}, sidebar: {} },\n              controlBlock: {\n                show: true,\n                size: 'm',\n                rightSideInner: [\n                  {\n                    text: 'Экспорт',\n                    contentLeft: <IconSb color=\"inherit\" />,\n                    dropdownIconRender: (ctx) => (\n                      <IconSb\n                        color=\"inherit\"\n                        size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                      />\n                    ),\n                    dropdown: {\n                      items: [\n                        { value: 'csv', label: 'CSV' },\n                        { value: 'xlsx', label: 'Excel' },\n                        { value: 'pdf', label: 'PDF' },\n                      ],\n                      onItemSelect: (item: any) =>\n                        alert(`Экспорт: ${item.label}`),\n                    },\n                  },\n                ],\n                customFeatures: [\n                  {\n                    value: 'refresh',\n                    label: 'Обновить',\n                    Icon: IconRefresh,\n                    onClick: () => alert('Обновить'),\n                  },\n                  starFeature,\n                ],\n              },\n            }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"tab2\">\n          <div style={{ padding: 24 }}>Настройки</div>\n        </TableTabs.TabPanel>\n      </TableTabs>\n    );\n  }"
        },
        {
          "exportName": "CollapsingAboveNoTabs",
          "displayName": "3. Collapsing above + ControlBlock (без табов)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\nimport { TableTabs } from '@daisforge/ui';\n\n() => {\n    const { rows, columnConfig } = useBaseSetup();\n    const starFeature = useStarFeature();\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          fullScreenEnabled: true,\n          rowSize: { default: 'big', showInControl: true },\n          searching: { enabled: true },\n          keyText: { showInControl: true, controlBlock: {}, sidebar: {} },\n          controlBlock: {\n            show: true,\n            size: 'm',\n            rightSideInner: [\n              {\n                text: 'Загрузить',\n                contentLeft: <IconSb color=\"inherit\" />,\n                dropdownIconRender: (ctx) => (\n                  <IconSb\n                    color=\"inherit\"\n                    size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                  />\n                ),\n              },\n              {\n                text: 'Экспорт',\n                contentLeft: <IconSb color=\"inherit\" />,\n                dropdownIconRender: (ctx) => (\n                  <IconSb\n                    color=\"inherit\"\n                    size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                  />\n                ),\n                dropdown: {\n                  items: [\n                    { value: 'csv', label: 'CSV' },\n                    { value: 'xlsx', label: 'Excel' },\n                    { value: 'pdf', label: 'PDF' },\n                  ],\n                  onItemSelect: (item: any) => alert(`Экспорт: ${item.label}`),\n                },\n              },\n            ],\n            customFeatures: [starFeature],\n          },\n          collapsing: {\n            enableCollapse: true,\n            collapseButtonPlacement: 'above',\n            collapseButtonAboveRightSlot: <CustomRightSlot />,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "InlineCollapsing",
          "displayName": "4. ControlBlock с inline collapsing",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\nimport { TableTabs } from '@daisforge/ui';\n\n() => {\n    const { rows, rowKeyGetter, columnConfig } = useBaseSetup();\n    const [groupByArr, setGroupByArr] = useState<string[]>([]);\n    const starFeature = useStarFeature();\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          fullScreenEnabled: true,\n          rowSize: { default: 'big', showInControl: true },\n          searching: { enabled: true },\n          keyText: { showInControl: true, controlBlock: {}, sidebar: {} },\n          rowsGrouping: {\n            rowKeyGetter,\n            groupByState: [groupByArr, setGroupByArr],\n          },\n          controlBlock: {\n            show: true,\n            size: 'm',\n            rightSideInner: [\n              {\n                text: 'Обновить',\n                contentLeft: <IconRefresh color=\"inherit\" />,\n                dropdownIconRender: (ctx) => (\n                  <IconRefresh\n                    color=\"inherit\"\n                    size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                  />\n                ),\n              },\n              {\n                text: 'Экспорт',\n                contentLeft: <IconSb color=\"inherit\" />,\n                dropdownIconRender: (ctx) => (\n                  <IconSb\n                    color=\"inherit\"\n                    size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                  />\n                ),\n                dropdown: {\n                  items: [\n                    { value: 'csv', label: 'CSV' },\n                    { value: 'xlsx', label: 'Excel' },\n                    { value: 'pdf', label: 'PDF' },\n                  ],\n                  onItemSelect: (item: any) => alert(`Экспорт: ${item.label}`),\n                },\n              },\n            ],\n            customFeatures: [starFeature],\n          },\n          collapsing: {\n            enableCollapse: true,\n            collapseButtonPlacement: 'inside',\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "TitleBlockStory",
          "displayName": "5. Title above (заголовок без коллапсинга)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\nimport { TableTabs } from '@daisforge/ui';\n\n() => {\n    const { rows, columnConfig } = useBaseSetup();\n    const starFeature = useStarFeature();\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          fullScreenEnabled: true,\n          rowSize: { default: 'big', showInControl: true },\n          searching: { enabled: true },\n          collapsing: {\n            collapseButtonPlacement: 'above',\n            titleText: 'Реестр задач',\n            collapseButtonAboveRightSlot: <CustomRightSlot />,\n          },\n          controlBlock: {\n            show: true,\n            size: 'm',\n            rightSideInner: [\n              {\n                text: 'Экспорт',\n                contentLeft: <IconSb color=\"inherit\" />,\n                dropdownIconRender: (ctx) => (\n                  <IconSb\n                    color=\"inherit\"\n                    size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                  />\n                ),\n                dropdown: {\n                  items: [\n                    { value: 'csv', label: 'CSV' },\n                    { value: 'xlsx', label: 'Excel' },\n                    { value: 'pdf', label: 'PDF' },\n                  ],\n                  onItemSelect: (item: any) => alert(`Экспорт: ${item.label}`),\n                },\n              },\n            ],\n            customFeatures: [starFeature],\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "TitleBlockInline",
          "displayName": "5b. Title inline (заголовок внутри controlBlock)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\nimport { TableTabs } from '@daisforge/ui';\n\n() => {\n    const { rows, columnConfig } = useBaseSetup();\n    const starFeature = useStarFeature();\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          fullScreenEnabled: true,\n          rowSize: { default: 'big', showInControl: true },\n          searching: { enabled: true },\n          collapsing: {\n            titleText: 'Реестр задач',\n          },\n          controlBlock: {\n            show: true,\n            size: 'm',\n            rightSideInner: [\n              {\n                text: 'Экспорт',\n                contentLeft: <IconSb color=\"inherit\" />,\n                dropdownIconRender: (ctx) => (\n                  <IconSb\n                    color=\"inherit\"\n                    size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                  />\n                ),\n                dropdown: {\n                  items: [\n                    { value: 'csv', label: 'CSV' },\n                    { value: 'xlsx', label: 'Excel' },\n                    { value: 'pdf', label: 'PDF' },\n                  ],\n                  onItemSelect: (item: any) => alert(`Экспорт: ${item.label}`),\n                },\n              },\n            ],\n            customFeatures: [starFeature],\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "AsCustomFeatures",
          "displayName": "SplitIconButton как кастомные фичи ControlBlock",
          "type": "full-code",
          "code": "import {\n  ColumnConfig,\n  SplitIconButton,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID', resizable: true },\n        { key: 'task', name: 'Task', resizable: true },\n        { key: 'priority', name: 'Priority', resizable: true },\n        { key: 'developer', name: 'Developer', resizable: true },\n      ],\n      [],\n    );\n\n    // Фича \"Метка\": один и тот же контент пунктов и в панели (items), и в\n    // свёрнутом виде (details.options). Синюю галочку активного пункта рисует\n    // сам разработчик через contentLeft — библиотека её не навязывает.\n    const [label, setLabel] = useState('important');\n    const LABELS = [\n      { value: 'important', label: 'Важное' },\n      { value: 'urgent', label: 'Срочное' },\n      { value: 'later', label: 'На потом' },\n    ];\n    const withCheck = (value: string) => ({\n      contentLeft: (\n        <span\n          style={{\n            display: 'inline-flex',\n            visibility: label === value ? 'visible' : 'hidden',\n          }}\n        >\n          <IconDone size=\"s\" color={textInfo} />\n        </span>\n      ),\n    });\n    const labelItems = LABELS.map((o) => ({ ...o, ...withCheck(o.value) }));\n\n    // Фича \"Экспорт\": пункты без галочек — просто список форматов.\n    const [fmt, setFmt] = useState('csv');\n    const FORMATS = [\n      { value: 'csv', label: 'CSV' },\n      { value: 'xlsx', label: 'Excel' },\n      { value: 'pdf', label: 'PDF' },\n    ];\n\n    // Фича \"Копирование\": шеврон без дропдауна (items не заданы) —\n    // обе кнопки работают как обычные действия.\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          // Поиск + rowSize + fullScreen, чтобы можно было сузить окно и\n          // увидеть компрессию фич в overflow-дропдаун.\n          fullScreenEnabled: true,\n          rowSize: { default: 'big', showInControl: true },\n          searching: { enabled: true },\n          controlBlock: {\n            show: true,\n            size: 'm',\n            customFeatures: [\n              {\n                value: 'label',\n                // Панель: SplitIconButton с выбором метки и галочкой.\n                CustomIconRender: () => (\n                  <SplitIconButton\n                    icon={<IconStar size=\"s\" />}\n                    chevronSize=\"xs\"\n                    size=\"m\"\n                    items={labelItems}\n                    onItemSelect={(item) => setLabel(String(item.value))}\n                    onIconClick={() => alert('Клик по иконке метки')}\n                  />\n                ),\n                canBeCompressedInToolsMenu: true,\n                // Свёрнутый вид: тот же выбор как select с галочкой в contentLeft.\n                details: {\n                  type: 'select',\n                  label: 'Метка',\n                  value: label,\n                  options: labelItems,\n                  onChange: setLabel,\n                  icon: () => <IconStar size=\"s\" />,\n                },\n              },\n              {\n                value: 'export',\n                CustomIconRender: () => (\n                  <SplitIconButton\n                    icon={<IconSb size=\"s\" />}\n                    chevronSize=\"xs\"\n                    size=\"m\"\n                    items={FORMATS}\n                    onItemSelect={(item) => setFmt(String(item.value))}\n                    onIconClick={() => alert('Клик по иконке экспорта')}\n                  />\n                ),\n                canBeCompressedInToolsMenu: true,\n                details: {\n                  type: 'select',\n                  label: 'Экспорт',\n                  value: fmt,\n                  options: FORMATS,\n                  onChange: setFmt,\n                  icon: () => <IconSb size=\"s\" />,\n                },\n              },\n              {\n                value: 'copy',\n                // Без items: шеврон становится обычной кнопкой (onChevronClick).\n                CustomIconRender: () => (\n                  <SplitIconButton\n                    icon={<IconSb size=\"s\" />}\n                    chevronSize=\"xs\"\n                    size=\"m\"\n                    onIconClick={() => alert('Скопировать')}\n                    onChevronClick={() => alert('Дополнительно')}\n                  />\n                ),\n              },\n            ],\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "controlBlockApe",
      "legacy": false,
      "summary": "Примеры ControlBlock в размере `xs` для команды APE. Это компактный режим панели: контрл-блок, табы и заголовок в уменьшенном размере.",
      "docs": "# ControlBlock APE\n\nПримеры ControlBlock в размере `xs` для команды APE. Это компактный режим панели: контрл-блок, табы и заголовок в уменьшенном размере.\n\nAPI и поведение те же, что у обычного ControlBlock, отличается только `tableConfig.controlBlock.size: 'xs'`. Полное описание фич, компрессии и кастомизации иконок смотрите в разделе [ControlBlock](?path=/docs/локальные-компоненты-tablecanvas-controlblock--docs).",
      "apiDocs": "# ControlBlock APE API\n\nAPE это тот же ControlBlock в компактном размере (`tableConfig.controlBlock.size: 'xs'`). Отдельного API у него нет: типы, фичи и поведение те же, что у обычного ControlBlock. Полное описание типов в разделе [ControlBlock API](?path=/docs/локальные-компоненты-tablecanvas-controlblock-api--docs).",
      "api": [],
      "stories": [
        {
          "exportName": "XSAllFeaturesWithTabs",
          "displayName": "1. XS: Все фичи: Collapsing + TableTabs + ControlBlock",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\nimport { TableTabs } from '@daisforge/ui';\n\n() => {\n    const { rows, setRows, rowKeyGetter, columnConfig } = useBaseSetup();\n    const [groupByArr, setGroupByArr] = useState<string[]>([]);\n    const selectingState = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n    const editingEnabled = useState(false);\n    const activeTabState = useState<string | number>('tab1');\n    const [isFavorite, setIsFavorite] = useState(false);\n    const starFeature = useStarFeature({ embedSize: 's', panelStarSize: 'xs' });\n\n    return (\n      <TableTabs\n        size=\"xs\"\n        tabs={[\n          { tabId: 'tab1', label: 'Основная' },\n          { tabId: 'tab2', label: 'Архив' },\n          { tabId: 'tab3', label: 'Аналитика' },\n        ]}\n        activeTabIdState={activeTabState}\n        rightSlot={<CustomRightSlot />}\n        collapsing={{\n          enabled: true,\n          collapseText: 'Свернуть таблицу',\n          expandText: 'Развернуть таблицу',\n          rightSlot: <CustomRightSlot />,\n        }}\n      >\n        <TableTabs.TabPanel tabId=\"tab1\">\n          <TableCanvas\n            tableConfig={{\n              containerStyle: { height: '60vh' },\n              fullScreenEnabled: true,\n              columnsControl: { enable: true },\n              notifications: { onNotification: (e) => alert(e.message) },\n              resizableColumn: true,\n              rowSize: { default: 'small', showInControl: true },\n              searching: { enabled: true },\n              keyText: { showInControl: true, controlBlock: {}, sidebar: {} },\n              rowsGrouping: {\n                rowKeyGetter,\n                groupByState: [groupByArr, setGroupByArr],\n              },\n              selecting: {\n                state: selectingState,\n                rowKeyGetter,\n              },\n              editing: {\n                onRowsChange: (newRows) => setRows(newRows as Row[]),\n                rowKeyGetter,\n                enabled: editingEnabled,\n                showButtons: true,\n                editModeLeftSlot: <EditModeLeftPanel />,\n              },\n              controlBlock: {\n                show: true,\n                size: 'xs',\n                rightSideInner: [\n                  {\n                    text: 'Загрузить',\n                    contentLeft: <IconSb color=\"inherit\" />,\n                    dropdownIconRender: (ctx) => (\n                      <IconSb\n                        color=\"inherit\"\n                        size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                      />\n                    ),\n                  },\n                  {\n                    text: 'Выгрузить',\n                    contentLeft: <IconSb color=\"inherit\" />,\n                    dropdownIconRender: (ctx) => (\n                      <IconSb\n                        color=\"inherit\"\n                        size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                      />\n                    ),\n                  },\n                  {\n                    text: 'Экспорт',\n                    contentLeft: <IconSb color=\"inherit\" />,\n                    dropdownIconRender: (ctx) => (\n                      <IconSb\n                        color=\"inherit\"\n                        size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                      />\n                    ),\n                    dropdown: {\n                      items: [\n                        { value: 'csv', label: 'CSV' },\n                        { value: 'xlsx', label: 'Excel' },\n                        { value: 'pdf', label: 'PDF' },\n                      ],\n                      onItemSelect: (item: any) =>\n                        alert(`Экспорт: ${item.label}`),\n                    },\n                  },\n                ],\n                customFeatures: [\n                  {\n                    value: 'refresh',\n                    label: 'Обновить',\n                    Icon: IconRefresh,\n                    onClick: () => alert('Обновить'),\n                    dividerLeft: true,\n                  },\n                  {\n                    value: 'favorite',\n                    label: 'Избранное',\n                    Icon: IconStar,\n                    onClick: () => alert('Избранное'),\n                    mandatory: true,\n                    details: {\n                      type: 'switch',\n                      label: 'В избранном',\n                      checked: isFavorite,\n                      onChange: (e) => setIsFavorite(e.target.checked),\n                    },\n                  },\n                  {\n                    value: 'add-row',\n                    label: 'Добавить строку',\n                    Icon: IconPlus,\n                    onClick: () => alert('Добавить строку'),\n                    dividerLeft: true,\n                  },\n                  starFeature,\n                ],\n              },\n            }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"tab2\">\n          <div style={{ padding: 24 }}>Архивные данные</div>\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"tab3\">\n          <div style={{ padding: 24 }}>Аналитика</div>\n        </TableTabs.TabPanel>\n      </TableTabs>\n    );\n  }"
        },
        {
          "exportName": "XSTabsWithoutCollapsing",
          "displayName": "2. XS: TableTabs + ControlBlock (без коллапсинга)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\nimport { TableTabs } from '@daisforge/ui';\n\n() => {\n    const { rows, columnConfig } = useBaseSetup();\n    const activeTabState = useState<string | number>('tab1');\n    const starFeature = useStarFeature({ embedSize: 's', panelStarSize: 'xs' });\n\n    return (\n      <TableTabs\n        size=\"xs\"\n        tabs={[\n          { tabId: 'tab1', label: 'Данные' },\n          { tabId: 'tab2', label: 'Настройки' },\n        ]}\n        activeTabIdState={activeTabState}\n        rightSlot={<CustomRightSlot />}\n      >\n        <TableTabs.TabPanel tabId=\"tab1\">\n          <TableCanvas\n            tableConfig={{\n              containerStyle: { height: '60vh' },\n              fullScreenEnabled: true,\n              columnsControl: { enable: true },\n              notifications: { onNotification: (e) => alert(e.message) },\n              rowSize: { default: 'small', showInControl: true },\n              searching: { enabled: true },\n              keyText: { showInControl: true, controlBlock: {}, sidebar: {} },\n              controlBlock: {\n                show: true,\n                size: 'xs',\n                rightSideInner: [\n                  {\n                    text: 'Экспорт',\n                    contentLeft: <IconSb color=\"inherit\" />,\n                    dropdownIconRender: (ctx) => (\n                      <IconSb\n                        color=\"inherit\"\n                        size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                      />\n                    ),\n                    dropdown: {\n                      items: [\n                        { value: 'csv', label: 'CSV' },\n                        { value: 'xlsx', label: 'Excel' },\n                        { value: 'pdf', label: 'PDF' },\n                      ],\n                      onItemSelect: (item: any) =>\n                        alert(`Экспорт: ${item.label}`),\n                    },\n                  },\n                ],\n                customFeatures: [\n                  {\n                    value: 'refresh',\n                    label: 'Обновить',\n                    Icon: IconRefresh,\n                    onClick: () => alert('Обновить'),\n                  },\n                  starFeature,\n                ],\n              },\n            }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </TableTabs.TabPanel>\n        <TableTabs.TabPanel tabId=\"tab2\">\n          <div style={{ padding: 24 }}>Настройки</div>\n        </TableTabs.TabPanel>\n      </TableTabs>\n    );\n  }"
        },
        {
          "exportName": "XSCollapsingAboveNoTabs",
          "displayName": "3. XS: Collapsing above + ControlBlock (без табов)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\nimport { TableTabs } from '@daisforge/ui';\n\n() => {\n    const { rows, columnConfig } = useBaseSetup();\n    const starFeature = useStarFeature({ embedSize: 's', panelStarSize: 'xs' });\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          fullScreenEnabled: true,\n          columnsControl: { enable: true },\n          notifications: { onNotification: (e) => alert(e.message) },\n          rowSize: { default: 'small', showInControl: true },\n          searching: { enabled: true },\n          keyText: { showInControl: true, controlBlock: {}, sidebar: {} },\n          controlBlock: {\n            show: true,\n            size: 'xs',\n            rightSideInner: [\n              {\n                text: 'Загрузить',\n                contentLeft: <IconSb color=\"inherit\" />,\n                dropdownIconRender: (ctx) => (\n                  <IconSb\n                    color=\"inherit\"\n                    size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                  />\n                ),\n              },\n              {\n                text: 'Экспорт',\n                contentLeft: <IconSb color=\"inherit\" />,\n                dropdownIconRender: (ctx) => (\n                  <IconSb\n                    color=\"inherit\"\n                    size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                  />\n                ),\n                dropdown: {\n                  items: [\n                    { value: 'csv', label: 'CSV' },\n                    { value: 'xlsx', label: 'Excel' },\n                    { value: 'pdf', label: 'PDF' },\n                  ],\n                  onItemSelect: (item: any) => alert(`Экспорт: ${item.label}`),\n                },\n              },\n            ],\n            customFeatures: [starFeature],\n          },\n          collapsing: {\n            enableCollapse: true,\n            collapseButtonPlacement: 'above',\n            collapseButtonAboveRightSlot: <CustomRightSlot />,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "XSInlineCollapsing",
          "displayName": "4. XS: ControlBlock с inline collapsing",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\nimport { TableTabs } from '@daisforge/ui';\n\n() => {\n    const { rows, rowKeyGetter, columnConfig } = useBaseSetup();\n    const [groupByArr, setGroupByArr] = useState<string[]>([]);\n    const starFeature = useStarFeature({ embedSize: 's', panelStarSize: 'xs' });\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          fullScreenEnabled: true,\n          columnsControl: { enable: true },\n          notifications: { onNotification: (e) => alert(e.message) },\n          rowSize: { default: 'small', showInControl: true },\n          searching: { enabled: true },\n          keyText: { showInControl: true, controlBlock: {}, sidebar: {} },\n          rowsGrouping: {\n            rowKeyGetter,\n            groupByState: [groupByArr, setGroupByArr],\n          },\n          controlBlock: {\n            show: true,\n            size: 'xs',\n            rightSideInner: [\n              {\n                text: 'Обновить',\n                contentLeft: <IconRefresh color=\"inherit\" />,\n                dropdownIconRender: (ctx) => (\n                  <IconRefresh\n                    color=\"inherit\"\n                    size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                  />\n                ),\n              },\n              {\n                text: 'Экспорт',\n                contentLeft: <IconSb color=\"inherit\" />,\n                dropdownIconRender: (ctx) => (\n                  <IconSb\n                    color=\"inherit\"\n                    size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                  />\n                ),\n                dropdown: {\n                  items: [\n                    { value: 'csv', label: 'CSV' },\n                    { value: 'xlsx', label: 'Excel' },\n                    { value: 'pdf', label: 'PDF' },\n                  ],\n                  onItemSelect: (item: any) => alert(`Экспорт: ${item.label}`),\n                },\n              },\n            ],\n            customFeatures: [starFeature],\n          },\n          collapsing: {\n            enableCollapse: true,\n            collapseButtonPlacement: 'inside',\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "XSTitleBlockStory",
          "displayName": "5. XS: Title above (заголовок без коллапсинга)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\nimport { TableTabs } from '@daisforge/ui';\n\n() => {\n    const { rows, columnConfig } = useBaseSetup();\n    const starFeature = useStarFeature({ embedSize: 's', panelStarSize: 'xs' });\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          fullScreenEnabled: true,\n          columnsControl: { enable: true },\n          notifications: { onNotification: (e) => alert(e.message) },\n          rowSize: { default: 'small', showInControl: true },\n          searching: { enabled: true },\n          collapsing: {\n            collapseButtonPlacement: 'above',\n            titleText: 'Реестр задач',\n            collapseButtonAboveRightSlot: <CustomRightSlot />,\n          },\n          controlBlock: {\n            show: true,\n            size: 'xs',\n            rightSideInner: [\n              {\n                text: 'Экспорт',\n                contentLeft: <IconSb color=\"inherit\" />,\n                dropdownIconRender: (ctx) => (\n                  <IconSb\n                    color=\"inherit\"\n                    size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                  />\n                ),\n                dropdown: {\n                  items: [\n                    { value: 'csv', label: 'CSV' },\n                    { value: 'xlsx', label: 'Excel' },\n                    { value: 'pdf', label: 'PDF' },\n                  ],\n                  onItemSelect: (item: any) => alert(`Экспорт: ${item.label}`),\n                },\n              },\n            ],\n            customFeatures: [starFeature],\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "XSTitleBlockInline",
          "displayName": "5b. XS: Title inline (заголовок внутри controlBlock)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\nimport { TableTabs } from '@daisforge/ui';\n\n() => {\n    const { rows, columnConfig } = useBaseSetup();\n    const starFeature = useStarFeature({ embedSize: 's', panelStarSize: 'xs' });\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          fullScreenEnabled: true,\n          columnsControl: { enable: true },\n          notifications: { onNotification: (e) => alert(e.message) },\n          rowSize: { default: 'small', showInControl: true },\n          searching: { enabled: true },\n          collapsing: {\n            titleText: 'Реестр задач',\n          },\n          controlBlock: {\n            show: true,\n            size: 'xs',\n            rightSideInner: [\n              {\n                text: 'Экспорт',\n                contentLeft: <IconSb color=\"inherit\" />,\n                dropdownIconRender: (ctx) => (\n                  <IconSb\n                    color=\"inherit\"\n                    size={ctx.rowSize === 'small' ? 'xs' : 's'}\n                  />\n                ),\n                dropdown: {\n                  items: [\n                    { value: 'csv', label: 'CSV' },\n                    { value: 'xlsx', label: 'Excel' },\n                    { value: 'pdf', label: 'PDF' },\n                  ],\n                  onItemSelect: (item: any) => alert(`Экспорт: ${item.label}`),\n                },\n              },\n            ],\n            customFeatures: [starFeature],\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "massPanelAction",
      "legacy": false,
      "summary": "Панель действий для выбранных строк",
      "docs": "# TableCanvas MassPanelAction\n\n## Ключевые особенности\n\n- Панель действий для выбранных строк\n- Автоматическое появление при активном selecting\n- Компрессия кнопок и отдельное поведение accent-кнопок\n\n**tableConfig.controlBlock.massActionPanel**\n\nПанель массовых действий (MassPanelAction) - это компонент, который отображается внизу таблицы и позволяет применять действия к выбранным строкам. Панель появляется автоматически, когда в таблице выбраны строки.\n\n## Когда открывается панель\n\nПанель массовых действий появляется автоматически, когда:\n\n- Включена функция выбора строк (`selecting` в `tableConfig`)\n- Выбрана хотя бы одна строка в таблице\n- `selectingRowsIsActive` равен `true`\n\nПанель скрывается автоматически, когда все строки сняты с выбора.\n\n## Управление видимостью\n\nПо умолчанию панель показывается автоматически при активном `selecting` и хотя бы одной выбранной строке. Это поведение переопределяется через `massActionPanel.show`:\n\n- `undefined` (по умолчанию) — штатное поведение (selecting + выбранные строки)\n- `false` — панель не рендерится, действиями вы управляете сами\n- `true` — панель показывается всегда, даже без активного selecting и выбранных строк (см. стори «Панель без selecting»)\n\n## Замена leftSideInner\n\n**Важно:** Панель массовых действий (`massActionPanel`) была создана как **замена** для `leftSideInner` в `controlBlock`.\n\n### ⚠️ Не рекомендуется использовать вместе\n\n**НЕ ЖЕЛАТЕЛЬНО** использовать `leftSideInner` и `massActionPanel` одновременно, так как:\n\n- Это создает дублирование функциональности\n- `massActionPanel` специально разработан для работы с выбранными строками\n- `massActionPanel` имеет адаптивную компрессию и автоматическое позиционирование\n- `massActionPanel` лучше интегрирован с функцией выбора строк\n\n### Рекомендация\n\nИспользуйте `massActionPanel` вместо `leftSideInner` для кнопок, которые должны работать с выбранными строками. Кнопки, которые не зависят от выбора строк, можно оставить в `leftSideInner` или `rightSideInner`.\n\n## Особенности работы\n\n### Accent кнопки всегда видимы\n\nКнопки с `view: 'accent'` **никогда не скрываются** в дропдауне скрытых действий, даже если панель не помещается по ширине. Они всегда остаются видимыми и сохраняют свой оригинальный порядок относительно других кнопок.\n\n### Адаптивная компрессия\n\nПри нехватке места панель автоматически:\n\n- Скрывает обычные кнопки в дропдаун скрытых действий\n- Оставляет accent кнопки всегда видимыми\n- Сохраняет порядок кнопок (accent кнопки остаются на своих позициях)\n- Автоматически центрируется с учетом открытого сайдбара\n\n### Взаимодействие с сайдбаром\n\nПри открытии сайдбара:\n\n- Панель автоматически сворачивается (если была развернута)\n- Позиция корректируется с учетом ширины сайдбара\n- При закрытии сайдбара панель автоматически разворачивается\n\n### Размеры кнопок\n\nРазмеры кнопок и дропдаунов панель подбирает сама — по размеру панели (`massActionPanel.size`: `m`/`s`/`xs`) и компактности. Передавать `size` кнопкам отдельно **не нужно**. Если `size` всё же задан — он используется как есть.\n\n## Конфигурация\n\nПанель массовых действий настраивается через `tableConfig.controlBlock.massActionPanel`:\n\n```tsx\ntableConfig={{\n  selecting: {\n    state: selectingRowState,\n    rowKeyGetter: (row) => row.id,\n  },\n  controlBlock: {\n    massActionPanel: {\n      buttons: [\n        {\n          type: 'button',\n          text: 'Действие',\n          view: 'secondary', // или 'accent', 'critical', 'primary' и т.д.\n          onClick: () => {\n            // Обработчик клика\n          },\n        },\n      ],\n    },\n  },\n}}\n```\n\nПомимо `buttons`, у панели есть необязательные пропсы: `size` (размер панели, см. «Размеры кнопок»), `show` (управление видимостью), `bottom` (отступ панели снизу от контейнера, по умолчанию 24px) и `collapsedDropdownProps` (пропсы дропдауна скрытых действий). Полное описание типов — в разделе API.\n\n## Типы кнопок\n\n### Button\n\nИспользуется компонент `Button` с `type: 'button'`:\n\n- Доступны view: `'accent'`, `'secondary'`, `'critical'`, `'primary'` и т.д.\n- `view: 'accent'` - accent кнопки, которые всегда остаются видимыми\n\n### LinkButton\n\nКнопка-ссылка с `type: 'linkButton'` (компонент `LinkButton`). View задаётся в link-нотации:\n\n```tsx\n{\n  type: 'linkButton',\n  text: 'Ссылка-действие',\n  view: 'linkSecondary', // 'linkAccent' / 'linkDefault' и т.д.\n  onClick: () => {},\n}\n```\n\n## Disabled состояние\n\nЕсли кнопка имеет `disabled: true`, можно передать `disabledTooltipProps` для отображения подсказки при наведении на disabled кнопку:\n\n```tsx\n{\n  type: 'button',\n  text: 'Действие',\n  view: 'secondary',\n  disabled: true,\n  disabledTooltipProps: {\n    text: 'Выберите строки для выполнения действия',\n  },\n  onClick: () => {},\n}\n```\n\n**Важно:** disabled кнопка остаётся неактивной и после перемещения в дропдаун скрытых действий — `disabled` пробрасывается на пункт меню. Подсказка `disabledTooltipProps` при этом показывается только у кнопок на самой панели, в меню её нет.\n\n## Dropdown в кнопках\n\nКнопки могут иметь вложенный dropdown:\n\n```tsx\n{\n  type: 'button',\n  text: 'Действие с меню',\n  view: 'secondary',\n  dropdown: {\n    items: [\n      { label: 'Опция 1', value: '1' },\n      { label: 'Опция 2', value: '2' },\n    ],\n    onItemSelect: (item) => {\n      // Обработчик выбора\n    },\n  },\n}\n```\n\n> Подробнее о типах — [MassPanelAction API](?path=/docs/локальные-компоненты-tablecanvas-controlblock-masspanelaction-api--docs)",
      "apiDocs": "# MassPanelAction API\n\n## MassActionsButtonProps\n\n```typescript\ntype MassActionsButtonPropsButton = DataAttributes &\n  Partial<ButtonCompProps> & {\n    type: 'button';\n    view?: ButtonCompProps['view'];\n    /**\n     * Dropdown для кнопки.\n     * Используется универсальный DropdownProps, который работает и с обычным Dropdown, и с TableDropdown\n     */\n    dropdown?: DropdownProps & { $css?: CSSObject };\n    disabledTooltipProps?: TooltipProps;\n  };\n```\n\n## MassActionsButtonPropsLinkButton\n\n```typescript\ntype MassActionsButtonPropsLinkButton = DataAttributes &\n  Partial<LinkButtonProps> & {\n    type?: 'linkButton';\n    view?: LinkView<LinkButtonView>;\n    /**\n     * Dropdown для кнопки.\n     * Используется универсальный DropdownProps, который работает и с обычным Dropdown, и с TableDropdown\n     */\n    dropdown?: DropdownProps & { $css?: CSSObject };\n    disabledTooltipProps?: TooltipProps;\n  };\n```",
      "api": [
        {
          "typeName": "MassActionsButtonPropsButton",
          "source": "type MassActionsButtonPropsButton = DataAttributes &\n  Partial<ButtonCompProps> & {\n    type: 'button';\n    view?: ButtonCompProps['view'];\n    /**\n     * Dropdown для кнопки.\n     * Используется универсальный DropdownProps, который работает и с обычным Dropdown, и с TableDropdown\n     */\n    dropdown?: DropdownProps & { $css?: CSSObject };\n    disabledTooltipProps?: TooltipProps;\n  };"
        },
        {
          "typeName": "MassActionsButtonPropsLinkButton",
          "source": "type MassActionsButtonPropsLinkButton = DataAttributes &\n  Partial<LinkButtonProps> & {\n    type?: 'linkButton';\n    view?: LinkView<LinkButtonView>;\n    /**\n     * Dropdown для кнопки.\n     * Используется универсальный DropdownProps, который работает и с обычным Dropdown, и с TableDropdown\n     */\n    dropdown?: DropdownProps & { $css?: CSSObject };\n    disabledTooltipProps?: TooltipProps;\n  };"
        }
      ],
      "stories": [
        {
          "exportName": "MassPanelActionBasic",
          "displayName": "Базовая панель массовых действий",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n() => {\n    const [rows] = useState(createRows);\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (row) => row.id,\n          },\n          controlBlock: {\n            massActionPanel: {\n              buttons: [\n                {\n                  type: 'button',\n                  text: 'Экспорт',\n                  view: 'secondary',\n                  onClick: () => {\n                    alert('Экспорт выбранных строк');\n                  },\n                },\n\n                {\n                  type: 'button',\n                  text: 'Архивировать',\n                  view: 'secondary',\n                  onClick: () => {\n                    alert('Архивирование выбранных строк');\n                  },\n                },\n                {\n                  type: 'button',\n                  text: 'Дублировать',\n                  view: 'secondary',\n                  onClick: () => {\n                    alert('Дублирование выбранных строк');\n                  },\n                },\n                {\n                  type: 'button',\n                  text: 'Accent',\n                  view: 'accent',\n                  onClick: () => {\n                    alert('Accent click');\n                  },\n                },\n              ],\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MassPanelActionWithAccent",
          "displayName": "Панель с accent кнопками",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n() => {\n    const [rows] = useState(createRows);\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (row) => row.id,\n          },\n          controlBlock: {\n            massActionPanel: {\n              buttons: [\n                {\n                  type: 'button',\n                  text: 'Обычная кнопка 1',\n                  view: 'secondary',\n                  onClick: () => alert('Кнопка 1'),\n                },\n\n                {\n                  type: 'button',\n                  text: 'Обычная кнопка 2',\n                  view: 'secondary',\n                  onClick: () => alert('Кнопка 2'),\n                },\n                {\n                  type: 'button',\n                  text: 'Еще одна кнопка',\n                  view: 'secondary',\n                  onClick: () => alert('Accent Button'),\n                },\n                {\n                  type: 'button',\n                  text: 'Обычная кнопка 3',\n                  view: 'secondary',\n                  onClick: () => alert('Кнопка 3'),\n                },\n                {\n                  type: 'button',\n                  text: 'Accent кнопка (всегда видима)',\n                  view: 'accent',\n                  onClick: () => alert('Accent кнопка'),\n                },\n              ],\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MassPanelActionWithButton",
          "displayName": "Панель с кнопками типа Button",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n() => {\n    const [rows] = useState(createRows);\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (row) => row.id,\n          },\n          controlBlock: {\n            massActionPanel: {\n              buttons: [\n                {\n                  type: 'button',\n                  text: 'Отменить',\n                  view: 'secondary',\n                  onClick: () => alert('Отменить'),\n                },\n                {\n                  type: 'button',\n                  text: 'Действие',\n                  view: 'secondary',\n                  onClick: () => alert('Действие'),\n                },\n                {\n                  type: 'button',\n                  text: 'Сохранить',\n                  view: 'accent',\n                  onClick: () => alert('Сохранить'),\n                },\n              ],\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MassPanelActionWithDisabled",
          "displayName": "Панель с disabled кнопками",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n() => {\n    const [rows] = useState(createRows);\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n    const [selectedCount] = selectingRowStateAndSetter;\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (row) => row.id,\n          },\n          controlBlock: {\n            massActionPanel: {\n              buttons: [\n                {\n                  type: 'button',\n                  text: 'Экспорт',\n                  view: 'secondary',\n                  disabled: selectedCount.size === 0,\n                  disabledTooltipProps: {\n                    text: 'Выберите хотя бы одну строку для экспорта',\n                  },\n                  onClick: () => alert('Экспорт'),\n                },\n\n                {\n                  type: 'button',\n                  text: 'Архивировать',\n                  view: 'secondary',\n                  disabled: selectedCount.size < 2,\n                  disabledTooltipProps: {\n                    text: 'Выберите минимум 2 строки для архивирования',\n                  },\n                  onClick: () => alert('Архивировать'),\n                },\n                {\n                  type: 'button',\n                  text: 'Accent',\n                  view: 'accent',\n                  disabled: selectedCount.size === 0,\n                  disabledTooltipProps: {\n                    text: 'Выберите строки для удаления',\n                  },\n                  onClick: () => alert('Accent'),\n                },\n              ],\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MassPanelActionForceShow",
          "displayName": "Панель без selecting (show: true)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          controlBlock: {\n            massActionPanel: {\n              show: true,\n              buttons: [\n                {\n                  type: 'button',\n                  text: 'Отменить',\n                  view: 'secondary',\n                  onClick: () => {\n                    alert('Отменить');\n                  },\n                },\n                {\n                  type: 'button',\n                  text: 'Сохранить',\n                  view: 'accent',\n                  onClick: () => {\n                    alert('Сохранить');\n                  },\n                },\n              ],\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MassPanelActionSizeXS",
          "displayName": "Уменьшенная панель (size XS)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n() => {\n    const [rows] = useState(createRows);\n    // Предвыбираем несколько строк, чтобы панель сразу была видна (со счётчиком и «Сбросить всё»).\n    const selectingRowStateAndSetter = useState<ReadonlySet<string | number>>(\n      () => new Set(rows.slice(0, 3).map((r) => r.id)),\n    );\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'developer', name: 'Developer' },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (row) => row.id,\n          },\n          controlBlock: {\n            massActionPanel: {\n              // Размер панели задаётся извне, независимо от вьюпорта.\n              size: 'xs',\n              buttons: [\n                {\n                  type: 'button',\n                  text: 'Экспорт',\n                  view: 'secondary',\n                  onClick: () => alert('Экспорт'),\n                },\n                {\n                  type: 'button',\n                  text: 'Архивировать',\n                  view: 'secondary',\n                  onClick: () => alert('Архивировать'),\n                },\n                {\n                  type: 'button',\n                  text: 'Дублировать',\n                  view: 'secondary',\n                  onClick: () => alert('Дублировать'),\n                },\n                {\n                  type: 'button',\n                  text: 'Accent',\n                  view: 'accent',\n                  onClick: () => alert('Accent'),\n                },\n              ],\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "CopyPasteFill",
      "legacy": false,
      "summary": "*tableConfig.cellTransfer**",
      "docs": "# Clipboard — копирование, вставка, fill handle\n\n**tableConfig.cellTransfer**\n\nФича реализует Copy (Ctrl+C), Paste (Ctrl+V) и Fill Handle (drag-to-fill) для TableCanvas.\n\n---\n\n## Формат данных\n\nДанные копируются и вставляются в формате **TSV (Tab-Separated Values)** — тот же\nформат, который использует Excel и Google Sheets. Значения разделяются `\\t` (tab)\nмежду колонками и `\\n` между строками.\n\nБлагодаря этому:\n\n- Скопированное из TableCanvas можно вставить в Excel / Google Sheets\n- Скопированное из Excel можно вставить в TableCanvas\n\n---\n\n## Copy (Ctrl+C / Cmd+C)\n\nКопирование работает всегда — и в режиме редактирования, и без него.\nОтключить можно только явно через `cellTransfer: { enabled: false }`.\n\nКопируется ровно то, что сейчас выделено в таблице (`selection.current.range`).\nФича не привязана к `highlightActiveType` — она работает с фактическим\nвыделением, а не с тем, как оно визуально подсвечивается.\n\n### Что копируется из ячейки\n\nДля обычной ячейки: `row[column.key]?.toString()`.\n\nДля кастомной canvas-ячейки (Canvas.Badge, Canvas.Text и т.д.) текст из canvas\nавтоматически извлечь нельзя. Поэтому используется `copyData` в конфиге\nколонки:\n\n```tsx\n{\n  key: 'status',\n  renderCell: ({ row }) => (\n    <Canvas.Badge text={row.status} view=\"positive\" size=\"s\" />\n  ),\n  // Указываем, что копировать — текстовое значение из row\n  copyData: (row) => row.status ?? '',\n}\n```\n\nЕсли `copyData` не указан, используется fallback на `row[column.key]?.toString()`.\nДля canvas-ячеек это может дать пустую строку или `[object Object]`, поэтому\n`copyData` рекомендуется всегда указывать для кастомных рендеров.\n\n### SubRows при копировании\n\nДля колонок с `subRow.keyOfColumnInSubRow` данные subrow-ячеек автоматически\nизвлекаются из нужного поля:\n\n```tsx\n{\n  key: 'block',\n  subRow: {\n    keyOfColumnInSubRow: (lvl) => {\n      switch (lvl) {\n        case 1: return 'tribe';\n        case 2: return 'product';\n        default: return 'block';\n      }\n    },\n  },\n}\n// Для parent (lvl=0): копирует row.block\n// Для subrow lvl=1: копирует row.tribe\n// Для subrow lvl=2: копирует row.product\n```\n\n---\n\n## Paste (Ctrl+V / Cmd+V)\n\nВставка работает только в режиме редактирования (`editing` активен).\n\nПорядок действий при вставке:\n\n1. Чтение TSV из clipboard (`navigator.clipboard.readText`)\n2. Парсинг в 2D-массив строк\n3. Определение целевой ячейки (из текущего selection)\n4. Применение значений начиная от целевой ячейки вправо и вниз\n\n### Валидация типов при вставке (type-check)\n\nПо умолчанию включена проверка `paste.validation: 'type-check'`:\n\n- **`inputNumber` / `contentFormat: 'number'`** — значение должно парситься в число. Если нет, ячейка пропускается.\n- **`select` (ComboBox)** — значение должно совпадать с одной из `options` (по `value` или `text`). Если нет, ячейка пропускается.\n- **`inputString`** — всегда валидно, строка вставляется как есть.\n\nНевалидные ячейки пропускаются, остальные вставляются нормально.\n\nОтключить: `paste: { validation: 'none' }`.\n\nРазделители для парсинга чисел берутся из `column.contentFormat`\n(`decimalSeparator`, `thousandSeparator`), а не из локали.\n\n### Readonly-ячейки\n\nПо умолчанию (`readonlyBehavior: 'skip'`) readonly-ячейки пропускаются,\nостальные вставляются нормально.\n\nПри `readonlyBehavior: 'abort'` любая readonly-ячейка в зоне вставки отменяет\nвсю вставку целиком (поведение Excel).\n\n### Выход за границы\n\nПо умолчанию (`overflowBehavior: 'truncate'`) данные обрезаются по границе\nтаблицы. То, что не влезло, теряется.\n\nПри `overflowBehavior: 'abort'` вставка отменяется, если данные не влезают.\n\n### Вставка в кастомные ячейки (Canvas.Badge и т.д.)\n\n`writeCellValue` пишет строку в `row[column.key]`. Кастомный рендер на следующем\nцикле получает обновлённый `row` и отрисовывает новое значение.\n\nЕсли `renderCell` ожидает в `row[key]` не строку, а объект, вставка строки\nсломает рендер. В этом случае используйте `onBeforePaste` для трансформации:\n\n```tsx\ncellTransfer: {\n  onBeforePaste: (data, meta) => {\n    // Трансформировать строки в нужные объекты\n    return data.map((row, y) =>\n      row.map((value, x) => {\n        const cell = meta.targetCells[y]?.[x];\n        if (cell?.column.key === 'complexField') {\n          return JSON.stringify({ label: value, color: 'default' });\n        }\n        return value;\n      })\n    );\n  },\n}\n```\n\n### SubRows при вставке\n\nРаботает аналогично копированию — через `keyOfColumnInSubRow`. Если у subrow\nданные в другом поле, `writeCellValue` запишет в правильный ключ.\n\nОтключить вставку в subrows: `paste: { allowSubRows: false }`.\n\n### Поток данных при вставке (pipeline)\n\nПри Ctrl+V значения проходят через цепочку проверок. Каждый шаг может отменить\nоперацию или пропустить отдельную ячейку:\n\n```\nCtrl+V\n  │\n  ▼\n1. editModeEnabled?\n   └─ нет → СТОП (вставка только в editing)\n  │\n  ▼\n2. navigator.clipboard.readText() → parseTsv() → string[][]\n   └─ пустой clipboard → СТОП\n  │\n  ▼\n3. onBeforePaste(data, meta)?\n   └─ вернул false -> СТОП (пользователь отменил)\n   └─ вернул модифицированный data → используем его\n  │\n  ▼\n4. overflowBehavior: данные выходят за границы?\n   └─ 'abort' → СТОП\n   └─ 'truncate' → обрезаем (default)\n  │\n  ▼\n5. readonlyBehavior: есть readonly-ячейки в зоне вставки?\n   └─ 'abort' → СТОП (первый проход, до записи)\n   └─ 'skip' → пропускаем эти ячейки (default)\n  │\n  ▼\n6. Для каждой ячейки:\n   │\n   ├─ shouldSkipCell?\n   │  ├─ no-row / нет колонки → skip\n   │  ├─ service-column → skip\n   │  ├─ subrow + !allowSubRows → skip\n   │  └─ not-editable → skip\n   │\n   ├─ validation: 'type-check'?\n   │  ├─ inputNumber: не парсится в число → skip\n   │  ├─ select: значения нет в options → skip\n   │  └─ inputString: OK\n   │\n   └─ writeCellValue(row, column, lvl, value) → запись\n  │\n  ▼\n7. onRowsChange(newRows, { column, indexes })\n   tree update → setRows → re-render\n```\n\nFill handle проходит ту же цепочку начиная с шага 6 (без clipboard и без\noverflow — зону протяжки таблица ограничивает сама). Перед записью вызывается\n`onBeforeFill(data, meta)` — аналог `onBeforePaste` для fill handle.\n\n---\n\n## Нотификации об ошибках\n\nОшибки copy / paste / fill дополнительно сообщаются во внешний модуль\n[Notifications](?path=/docs/локальные-компоненты-tablecanvas-notifications--docs)\nчерез `tableConfig.notifications.onNotification` — таблица UI не рисует, тост\nпоказывает потребитель (`type` = операция):\n\n- `paste` / `readonly-abort` — при `readonlyBehavior: 'abort'` в зоне вставки\n  есть readonly-ячейка;\n- `paste` / `overflow-abort` — при `overflowBehavior: 'abort'` данные не влезли;\n- `paste` / `validation-skipped` (`warning`) — часть значений пропущена\n  type-check валидацией;\n- `fill` / `readonly-abort` и `fill` / `validation-skipped` — то же для\n  автозаполнения (fill handle);\n- `copy` / `paste` с code `multi-range-scattered` — 2D-разброс в\n  `multi-range-cell`.\n\n## Перехват данных — onBeforeCopy / onBeforePaste\n\nКолбэки вызываются перед операцией. Получают:\n\n- Первый аргумент: `data: string[][]` — 2D-массив значений (TSV-формат)\n- Второй аргумент: `meta` — информация о ячейках\n\n### onBeforeCopy\n\n```tsx\ncellTransfer: {\n  onBeforeCopy: (data, meta) => {\n    // data — string[][] (что будет в clipboard)\n    // meta.range — Rectangle выделения\n    // meta.cells — CellTransferCellInfo[][] (row, column, lvl, rawValue, formattedValue)\n\n    console.log('Копируем:', data);\n    console.log('Колонки:', meta.cells[0]?.map(c => c.column.key));\n\n    // Модифицировать данные:\n    return data.map(row => row.map(val => val.toUpperCase()));\n\n    // Или отменить копирование:\n    return false;\n  },\n}\n```\n\n### onBeforePaste\n\n```tsx\ncellTransfer: {\n  onBeforePaste: (data, meta) => {\n    // data — string[][] (что из clipboard)\n    // meta.target — { col, row } верхний-левый угол вставки\n    // meta.targetCells — CellTransferCellInfo[][] (инфа о ЦЕЛЕВЫХ ячейках)\n    // meta.selection — GridSelection\n\n    // Пример: ограничить кол-во строк\n    if (data.length > 100) {\n      alert('Слишком много строк для вставки');\n      return false;\n    }\n\n    // Пример: трансформировать данные\n    return data;\n  },\n}\n```\n\n---\n\n## Fill Handle (drag-to-fill)\n\nВ правом-нижнем углу выделения появляется квадратик. Перетаскивая его мышью,\nможно размножить значения (как в Excel / Google Sheets).\n\nКвадратик и preview-рамку таблица рисует нативно — фича только применяет\nзначения source range в destination range.\n\n### Поведение\n\n- **Одна ячейка** — значение дублируется во все target-ячейки\n- **Диапазон N×M** — значения повторяются циклически\n- **Type-check валидация** — та же, что при paste (числа, select-опции)\n- **Readonly-ячейки** в destination пропускаются\n- **Квадратик скрывается**, если source-ячейка non-editable\n\n### Направления\n\nПо умолчанию `allowedDirections: 'orthogonal'` — snap к ближайшей оси\n(только строки или только колонки, не диагональ).\n\nВарианты: `'horizontal'`, `'vertical'`, `'orthogonal'`, `'any'`.\n\n### Перехват — onBeforeFill\n\nКолбэк `onBeforeFill` вызывается перед применением значений при fill handle.\nПолучает `data: string[][]` и `meta: FillMeta` (см. API — структура meta\nотличается от `CopyMeta` / `PasteMeta`).\n\n```tsx\ncellTransfer: {\n  fillHandle: true,\n  onBeforeFill: (data, meta) => {\n    // data — string[][] (значения, которые будут вставлены)\n    // meta.sourceRange — Rectangle источника\n    // meta.destinationRange — Rectangle назначения\n    // meta.sourceCells — CellTransferCellInfo[][] (исходные ячейки, включая row)\n    // meta.targetCells — CellTransferCellInfo[][] (целевые ячейки до заполнения)\n\n    const sourceRow = meta.sourceCells[0]?.[0]?.row;\n    console.log('Исходная строка:', sourceRow);\n\n    // Модифицировать данные:\n    return data;\n\n    // Или отменить:\n    return false;\n  },\n}\n```\n\n**Типичный сценарий:** при перетаскивании одной колонки нужно скопировать\nи соседние колонки из исходной строки. Source row доступен через\n`meta.sourceCells[rowIndex][colIndex].row`.\n\n### type в onRowsChange\n\nВторой аргумент `onRowsChange` содержит поле `type` (`'edit'` | `'paste'` | `'fill'`),\nуказывающее источник изменения строк. При `type === 'fill'` дополнительно\nпередаются `fillMeta` (FillMeta) и `fillResult` (результат `onBeforeFill`,\nесли он задан).\n\n---\n\n## Кастомные хоткеи\n\nПо умолчанию: Ctrl+C (copy), Ctrl+V (paste). На Mac — Cmd вместо Ctrl.\n\nХоткеи работают независимо от раскладки (RU/EN) — используется `event.code`\n(`'KeyC'`, `'KeyV'`), а не `event.key` (`'c'`, `'с'`).\n\n```tsx\ncellTransfer: {\n  hotkeys: {\n    copy: { code: 'KeyC', ctrl: true, alt: true },   // Ctrl+Alt+C\n    paste: [\n      { code: 'KeyV', ctrl: true },                   // Ctrl+V (дефолт сохраняем)\n      { code: 'Insert', shift: true },                // Shift+Insert (альтернатива)\n    ],\n  },\n}\n```\n\nЕсли задать только кастомный хоткей (без массива), дефолтный Ctrl+C / Ctrl+V\nперестаёт работать (replace-семантика). Чтобы сохранить оба варианта,\nпередавайте массив, как в примере для `paste` выше.\n\n---\n\n## Конфигурация\n\n```tsx\ntableConfig={{\n  cellTransfer: {\n    // Явно включить/выключить (copy работает всегда по умолчанию)\n    enabled: true,\n\n    // Хоткеи\n    hotkeys: { copy: ..., paste: ... },\n\n    // Настройки paste\n    paste: {\n      readonlyBehavior: 'skip' | 'abort',     // default: 'skip'\n      allowSubRows: true | false,             // default: true\n      overflowBehavior: 'truncate' | 'abort', // default: 'truncate'\n      broadcast: true | false,                // default: false\n      validation: 'none' | 'type-check',      // default: 'type-check'\n    },\n\n    // Fill handle\n    fillHandle: true | false | {\n      shape: 'square' | 'circle',\n      size: number,\n      allowedDirections: 'horizontal' | 'vertical' | 'orthogonal' | 'any',\n      readonlyBehavior: 'skip' | 'abort',\n      allowSubRows: boolean,\n    },\n\n    // Перехваты\n    onBeforeCopy: (data, meta) => data | false,\n    onBeforePaste: (data, meta) => data | false,\n    onBeforeFill: (data, meta) => data | false,\n  },\n}}\n```\n\n---\n\n## Debug\n\n```js\nwindow.__TABLE_CANVAS_CLIPBOARD_DEBUG__ = true;\n```\n\nВключите уровень \"Verbose\" в DevTools. Префиксы логов:\n\n- `[TableCanvas/cellTransfer]` — перехват хоткеев\n- `[TableCanvas/copy]` — копирование\n- `[TableCanvas/paste]` — вставка (включая skipped by validation)\n- `[TableCanvas/fillHandle]` — fill handle (source, dest, affected rows)\n\nПолное описание API типов см. на странице **Clipboard / API**.",
      "apiDocs": "# Cell Transfer API (Copy / Paste / Fill)\n\n## CellTransferConfig (в TableConfig)\n\n```typescript\ntype CellTransferConfig = {\n  /**\n   * Явное включение/выключение всей фичи.\n   * По умолчанию copy работает всегда, а paste и fill handle следуют\n   * за `editModeEnabled`. При `false` отключается всё.\n   */\n  enabled?: boolean;\n  /**\n   * Переопределение хоткеев.\n   * Можно передать один `HotkeyConfig` или массив альтернативных комбинаций.\n   * По умолчанию: copy = Ctrl+C / Cmd+C, paste = Ctrl+V / Cmd+V.\n   */\n  hotkeys?: {\n    /** Хоткей(и) для копирования */\n    copy?: HotkeyConfig | HotkeyConfig[];\n    /** Хоткей(и) для вставки */\n    paste?: HotkeyConfig | HotkeyConfig[];\n  };\n  /** Настройки paste (readonly, overflow, broadcast, validation) */\n  paste?: PasteConfig;\n  /** Настройки fill handle. `true/false` — быстрое вкл/выкл без деталей */\n  fillHandle?: boolean | FillHandleConfig;\n  /**\n   * Колбэк перед копированием.\n   * Можно модифицировать данные (вернуть новый `string[][]`) или отменить\n   * операцию (вернуть `false`).\n   * Если onBeforeCopy нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n   */\n  onBeforeCopy?: (data: string[][], meta: CopyMeta) => string[][] | false;\n  /**\n   * Колбэк перед вставкой.\n   * Можно модифицировать данные (вернуть новый `string[][]`) или отменить\n   * операцию (вернуть `false`).\n   * Если onBeforePaste нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n   */\n  onBeforePaste?: (data: string[][], meta: PasteMeta) => string[][] | false;\n  /**\n   * Колбэк перед fill handle (drag-to-fill).\n   * Вызывается перед применением значений. Можно модифицировать данные\n   * (вернуть новый `string[][]`) или отменить операцию (вернуть `false`).\n   *\n   * `meta.sourceCells` содержит полную информацию об исходных ячейках,\n   * включая объекты строк (`row`) — позволяет получить source row\n   * и использовать данные из соседних колонок.\n   * Если onBeforeFill нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n   */\n  onBeforeFill?: (data: string[][], meta: FillMeta) => string[][] | false;\n};\n```\n\n## HotkeyConfig\n\n```typescript\ntype HotkeyConfig = {\n  /** Физический код клавиши: `'KeyC'`, `'KeyV'`, `'Insert'` и т.д. */\n  code: string;\n  /** Нужно ли нажатие Ctrl (на Mac учитывается и Cmd). По умолчанию `true` */\n  ctrl?: boolean;\n  /** Нужно ли нажатие Shift. По умолчанию `false` */\n  shift?: boolean;\n  /** Нужно ли нажатие Alt. По умолчанию `false` */\n  alt?: boolean;\n  /** Нужно ли нажатие Meta (Cmd на Mac, Win на Windows). По умолчанию `false` */\n  meta?: boolean;\n};\n```\n\nМожно передать массив — сработает любая из комбинаций:\n\n```tsx\nhotkeys: {\n  copy: [\n    { code: 'KeyC', ctrl: true },\n    { code: 'Insert', ctrl: true },  // альтернативный хоткей\n  ],\n}\n```\n\n## PasteConfig\n\n```typescript\ntype PasteConfig = {\n  /**\n   * Что делать с readonly-ячейками в зоне вставки.\n   * `'skip'` пропускает их, `'abort'` отменяет всю вставку целиком.\n   * По умолчанию `'skip'`.\n   */\n  readonlyBehavior?: ReadonlyBehavior;\n  /** Разрешать ли вставку в subrow-ячейки. По умолчанию `true` */\n  allowSubRows?: boolean;\n  /**\n   * Что делать при выходе данных за границы таблицы.\n   * `'truncate'` обрезает лишнее, `'abort'` отменяет вставку.\n   * По умолчанию `'truncate'`.\n   */\n  overflowBehavior?: OverflowBehavior;\n  /**\n   * Тиражирование источника на всё выделение (как в Excel).\n   * Если `true` и в буфере одна строка/колонка, а выделение больше,\n   * буфер повторится по соответствующей оси.\n   * По умолчанию `false`.\n   */\n  broadcast?: boolean;\n  /**\n   * Режим валидации значений при вставке.\n   * - `'none'` вставляет строку как есть без проверок\n   * - `'type-check'` (по умолчанию) проверяет соответствие типу ячейки:\n   *   числовые поля должны парситься в число, select-поля должны содержать\n   *   значение из `options`. Невалидные ячейки пропускаются.\n   */\n  validation?: ValidationMode;\n};\n```\n\nПоле `validation: 'type-check'` (default) автоматически проверяет:\n\n- **inputNumber / contentFormat.type='number'** — значение должно парситься в число через разделители из `contentFormat`. Невалидные ячейки пропускаются.\n- **select** — значение должно совпадать с одной из options (value или text). Невалидные пропускаются.\n- **inputString / остальное** — всегда валидно.\n\nУстановите `validation: 'none'` чтобы вставлять сырые строки без проверок.\n\n## CellTransferCellInfo\n\nИнформация об одной ячейке. Используется как элемент двумерного массива `cells` внутри\nвсех meta-типов ниже (`CopyMeta`, `PasteMeta`, `FillMeta`).\n\n```typescript\ntype CellTransferCellInfo = {\n  /** Объект строки, в которой находится ячейка */\n  row: ObjectForExtending;\n  /** Конфиг колонки (срез важных полей) */\n  column: TransferColumnConfig;\n  /** Индекс колонки в массиве columns */\n  colIndex: number;\n  /** Индекс строки в массиве flattenedRows */\n  rowIndex: number;\n  /** Уровень вложенности subrow: 0 — parent, 1+ — subrow */\n  lvl: number;\n  /** Сырое значение из `row[key]` или `row[subKey]` (без форматирования) */\n  rawValue: unknown;\n  /** Текстовое представление ячейки (то что попадает в TSV) */\n  formattedValue: string;\n};\n```\n\n## Метаданные колбэков (Meta-типы)\n\nКаждый колбэк (`onBeforeCopy`, `onBeforePaste`, `onBeforeFill`) получает вторым\nаргументом свой meta-объект с контекстом операции.\n\n### CopyMeta (`onBeforeCopy`)\n\n```typescript\ntype CopyMeta = {\n  /** Прямоугольный диапазон выделения в координатах таблицы */\n  range: Rectangle;\n  /** Двумерный массив информации о каждой ячейке, той же формы что data */\n  cells: CellTransferCellInfo[][];\n};\n```\n\n### PasteMeta (`onBeforePaste`)\n\n```typescript\ntype PasteMeta = {\n  /** Верхний-левый угол целевой области (куда начинается вставка) */\n  target: { col: number; row: number };\n  /** Двумерный массив информации о целевых ячейках, той же формы что data */\n  targetCells: CellTransferCellInfo[][];\n  /** Текущее выделение в таблице */\n  selection: GridSelection;\n};\n```\n\n### FillMeta (`onBeforeFill`)\n\n```typescript\ntype FillMeta = {\n  /** Исходный диапазон (откуда тянули) */\n  sourceRange: Rectangle;\n  /** Целевой диапазон (куда заполнили) */\n  destinationRange: Rectangle;\n  /** Двумерный массив информации об исходных ячейках */\n  sourceCells: CellTransferCellInfo[][];\n  /** Двумерный массив информации о целевых ячейках (до заполнения) */\n  targetCells: CellTransferCellInfo[][];\n};\n```\n\n## RowsChangeType\n\nПоле `type` в `onRowsChange` указывает источник изменения строк.\n\n```typescript\ntype RowsChangeType = 'edit' | 'paste' | 'fill';\n```\n\n## FillHandleConfig\n\n```typescript\ntype FillHandleConfig = {\n  /** Включён ли fill handle. По умолчанию включён если включён cellTransfer */\n  enabled?: boolean;\n  /** Форма квадратика. По умолчанию `'square'` */\n  shape?: 'square' | 'circle';\n  /** Размер квадратика в пикселях */\n  size?: number;\n  /** Толщина обводки квадратика в пикселях */\n  outline?: number;\n  /**\n   * Разрешённые направления перетаскивания.\n   * `'orthogonal'` (по умолчанию) разрешает только вдоль одной оси за раз.\n   */\n  allowedDirections?: AllowedFillDirections;\n  /**\n   * Поведение при попадании readonly-ячеек в destination.\n   * См. `PasteConfig.readonlyBehavior`. По умолчанию `'skip'`.\n   */\n  readonlyBehavior?: ReadonlyBehavior;\n  /** Разрешать ли fill в subrow-ячейки. По умолчанию `true` */\n  allowSubRows?: boolean;\n};\n```\n\n## AllowedFillDirections / FillPatternEvent\n\n```typescript\ntype AllowedFillDirections =\n  | 'horizontal'\n  | 'vertical'\n  | 'orthogonal'\n  | 'any';\n```\n\n```typescript\ntype FillPatternEvent = {\n  /** Исходный диапазон (откуда берутся значения) */\n  patternSource: Rectangle;\n  /** Целевой диапазон (куда тиражируются значения) */\n  fillDestination: Rectangle;\n  /** Вызов отменяет fill (данные не записываются) */\n  preventDefault: () => void;\n};\n```\n\n## columnConfig.copyData\n\nТекстовое представление ячейки для копирования в буфер.\n\n```ts\ncopyData?: string | ((row: Row) => string);\n```\n\nЕсли `copyData` не задан, используется `row[column.key]?.toString()`.\n\n## Примеры\n\n### Базовое использование (работает из коробки)\n\n```tsx\n<TableCanvas\n  tableConfig={{\n    editing: {\n      onRowsChange: setRows,\n      rowKeyGetter: (r) => r.id,\n      defaultEnabled: true,\n    },\n  }}\n  columnConfig={columnConfig}\n  rows={rows}\n/>\n```\n\nCopy (Ctrl+C) и Paste (Ctrl+V) работают автоматически в режиме редактирования.\n\n### Excel-like поведение paste\n\n```tsx\ntableConfig={{\n  cellTransfer: {\n    paste: {\n      readonlyBehavior: 'abort',  // как в Excel\n      broadcast: true,\n    },\n  },\n}}\n```\n\n### Кастомные хоткеи + перехват\n\n```tsx\ntableConfig={{\n  cellTransfer: {\n    hotkeys: {\n      copy: { code: 'KeyC', ctrl: true, alt: true },\n      paste: { code: 'KeyV', ctrl: true, alt: true },\n    },\n    onBeforeCopy: (data) => {\n      // логируем или модифицируем данные\n      console.log('Copying:', data);\n      return data;\n    },\n    onBeforePaste: (data) => {\n      if (data.length > 100) {\n        alert('Слишком много строк');\n        return false;\n      }\n      return data;\n    },\n  },\n}}\n```\n\n### Кастомный copyData для canvas-ячейки\n\n```tsx\ncolumnConfig={[\n  {\n    key: 'status',\n    name: 'Статус',\n    renderCell: ({ row }) => (\n      <Canvas.Badge\n        text={row.status}\n        view={row.status === 'Активный' ? 'positive' : 'warning'}\n      />\n    ),\n    copyData: (row) => row.status ?? '',  // копируем только текст\n  },\n]}\n```",
      "api": [
        {
          "typeName": "CellTransferConfig",
          "source": "type CellTransferConfig = {\n  /**\n   * Явное включение/выключение всей фичи.\n   * По умолчанию copy работает всегда, а paste и fill handle следуют\n   * за `editModeEnabled`. При `false` отключается всё.\n   */\n  enabled?: boolean;\n  /**\n   * Переопределение хоткеев.\n   * Можно передать один `HotkeyConfig` или массив альтернативных комбинаций.\n   * По умолчанию: copy = Ctrl+C / Cmd+C, paste = Ctrl+V / Cmd+V.\n   */\n  hotkeys?: {\n    /** Хоткей(и) для копирования */\n    copy?: HotkeyConfig | HotkeyConfig[];\n    /** Хоткей(и) для вставки */\n    paste?: HotkeyConfig | HotkeyConfig[];\n  };\n  /** Настройки paste (readonly, overflow, broadcast, validation) */\n  paste?: PasteConfig;\n  /** Настройки fill handle. `true/false` — быстрое вкл/выкл без деталей */\n  fillHandle?: boolean | FillHandleConfig;\n  /**\n   * Колбэк перед копированием.\n   * Можно модифицировать данные (вернуть новый `string[][]`) или отменить\n   * операцию (вернуть `false`).\n   * Если onBeforeCopy нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n   */\n  onBeforeCopy?: (data: string[][], meta: CopyMeta) => string[][] | false;\n  /**\n   * Колбэк перед вставкой.\n   * Можно модифицировать данные (вернуть новый `string[][]`) или отменить\n   * операцию (вернуть `false`).\n   * Если onBeforePaste нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n   */\n  onBeforePaste?: (data: string[][], meta: PasteMeta) => string[][] | false;\n  /**\n   * Колбэк перед fill handle (drag-to-fill).\n   * Вызывается перед применением значений. Можно модифицировать данные\n   * (вернуть новый `string[][]`) или отменить операцию (вернуть `false`).\n   *\n   * `meta.sourceCells` содержит полную информацию об исходных ячейках,\n   * включая объекты строк (`row`) — позволяет получить source row\n   * и использовать данные из соседних колонок.\n   * Если onBeforeFill нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n   */\n  onBeforeFill?: (data: string[][], meta: FillMeta) => string[][] | false;\n};"
        },
        {
          "typeName": "HotkeyConfig",
          "source": "type HotkeyConfig = {\n  /** Физический код клавиши: `'KeyC'`, `'KeyV'`, `'Insert'` и т.д. */\n  code: string;\n  /** Нужно ли нажатие Ctrl (на Mac учитывается и Cmd). По умолчанию `true` */\n  ctrl?: boolean;\n  /** Нужно ли нажатие Shift. По умолчанию `false` */\n  shift?: boolean;\n  /** Нужно ли нажатие Alt. По умолчанию `false` */\n  alt?: boolean;\n  /** Нужно ли нажатие Meta (Cmd на Mac, Win на Windows). По умолчанию `false` */\n  meta?: boolean;\n};"
        },
        {
          "typeName": "PasteConfig",
          "source": "type PasteConfig = {\n  /**\n   * Что делать с readonly-ячейками в зоне вставки.\n   * `'skip'` пропускает их, `'abort'` отменяет всю вставку целиком.\n   * По умолчанию `'skip'`.\n   */\n  readonlyBehavior?: ReadonlyBehavior;\n  /** Разрешать ли вставку в subrow-ячейки. По умолчанию `true` */\n  allowSubRows?: boolean;\n  /**\n   * Что делать при выходе данных за границы таблицы.\n   * `'truncate'` обрезает лишнее, `'abort'` отменяет вставку.\n   * По умолчанию `'truncate'`.\n   */\n  overflowBehavior?: OverflowBehavior;\n  /**\n   * Тиражирование источника на всё выделение (как в Excel).\n   * Если `true` и в буфере одна строка/колонка, а выделение больше,\n   * буфер повторится по соответствующей оси.\n   * По умолчанию `false`.\n   */\n  broadcast?: boolean;\n  /**\n   * Режим валидации значений при вставке.\n   * - `'none'` вставляет строку как есть без проверок\n   * - `'type-check'` (по умолчанию) проверяет соответствие типу ячейки:\n   *   числовые поля должны парситься в число, select-поля должны содержать\n   *   значение из `options`. Невалидные ячейки пропускаются.\n   */\n  validation?: ValidationMode;\n};"
        },
        {
          "typeName": "CellTransferCellInfo",
          "source": "type CellTransferCellInfo = {\n  /** Объект строки, в которой находится ячейка */\n  row: ObjectForExtending;\n  /** Конфиг колонки (срез важных полей) */\n  column: TransferColumnConfig;\n  /** Индекс колонки в массиве columns */\n  colIndex: number;\n  /** Индекс строки в массиве flattenedRows */\n  rowIndex: number;\n  /** Уровень вложенности subrow: 0 — parent, 1+ — subrow */\n  lvl: number;\n  /** Сырое значение из `row[key]` или `row[subKey]` (без форматирования) */\n  rawValue: unknown;\n  /** Текстовое представление ячейки (то что попадает в TSV) */\n  formattedValue: string;\n};"
        },
        {
          "typeName": "CopyMeta",
          "source": "type CopyMeta = {\n  /** Прямоугольный диапазон выделения в координатах таблицы */\n  range: Rectangle;\n  /** Двумерный массив информации о каждой ячейке, той же формы что data */\n  cells: CellTransferCellInfo[][];\n};"
        },
        {
          "typeName": "PasteMeta",
          "source": "type PasteMeta = {\n  /** Верхний-левый угол целевой области (куда начинается вставка) */\n  target: { col: number; row: number };\n  /** Двумерный массив информации о целевых ячейках, той же формы что data */\n  targetCells: CellTransferCellInfo[][];\n  /** Текущее выделение в таблице */\n  selection: GridSelection;\n};"
        },
        {
          "typeName": "FillMeta",
          "source": "type FillMeta = {\n  /** Исходный диапазон (откуда тянули) */\n  sourceRange: Rectangle;\n  /** Целевой диапазон (куда заполнили) */\n  destinationRange: Rectangle;\n  /** Двумерный массив информации об исходных ячейках */\n  sourceCells: CellTransferCellInfo[][];\n  /** Двумерный массив информации о целевых ячейках (до заполнения) */\n  targetCells: CellTransferCellInfo[][];\n};"
        },
        {
          "typeName": "RowsChangeType",
          "source": "type RowsChangeType = 'edit' | 'paste' | 'fill';"
        },
        {
          "typeName": "FillHandleConfig",
          "source": "type FillHandleConfig = {\n  /** Включён ли fill handle. По умолчанию включён если включён cellTransfer */\n  enabled?: boolean;\n  /** Форма квадратика. По умолчанию `'square'` */\n  shape?: 'square' | 'circle';\n  /** Размер квадратика в пикселях */\n  size?: number;\n  /** Толщина обводки квадратика в пикселях */\n  outline?: number;\n  /**\n   * Разрешённые направления перетаскивания.\n   * `'orthogonal'` (по умолчанию) разрешает только вдоль одной оси за раз.\n   */\n  allowedDirections?: AllowedFillDirections;\n  /**\n   * Поведение при попадании readonly-ячеек в destination.\n   * См. `PasteConfig.readonlyBehavior`. По умолчанию `'skip'`.\n   */\n  readonlyBehavior?: ReadonlyBehavior;\n  /** Разрешать ли fill в subrow-ячейки. По умолчанию `true` */\n  allowSubRows?: boolean;\n};"
        },
        {
          "typeName": "AllowedFillDirections",
          "source": "type AllowedFillDirections =\n  | 'horizontal'\n  | 'vertical'\n  | 'orthogonal'\n  | 'any';"
        },
        {
          "typeName": "FillPatternEvent",
          "source": "type FillPatternEvent = {\n  /** Исходный диапазон (откуда берутся значения) */\n  patternSource: Rectangle;\n  /** Целевой диапазон (куда тиражируются значения) */\n  fillDestination: Rectangle;\n  /** Вызов отменяет fill (данные не записываются) */\n  preventDefault: () => void;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "ClipboardFullDemo",
          "displayName": "Полный пример (все возможности)",
          "type": "full-code",
          "code": "() => {\n    useEffect(() => {\n      (\n        window as unknown as Record<string, boolean>\n      ).__TABLE_CANVAS_CLIPBOARD_DEBUG__ = true;\n    }, []);\n\n    const [rows, setRows] = useState(() => createRowsTree());\n    const [highlightActiveType, setHighlightActiveType] =\n      useState<HighlightActiveType>('row');\n    const [selectionMode, setSelectionMode] =\n      useState<CellsSelectionMode>('range-cell');\n\n    const columns = useMemo(\n      (): readonly ColumnConfig<TreeRow>[] => [\n        {\n          key: 'block',\n          name: 'Блок',\n          editingCell: {\n            editable: (r) => r.block === BLOCKS[1],\n            component: 'select',\n            options: {\n              type: 'constant',\n              options: BLOCKS.map((i) => ({ text: i, value: i })),\n            },\n          },\n          subRow: {\n            keyOfColumnInSubRow: (lvl) => {\n              switch (lvl) {\n                case 0:\n                  return 'block';\n                case 1:\n                  return 'tribe';\n                case 2:\n                  return 'product';\n                default:\n                  return 'block';\n              }\n            },\n            editingCell: {\n              component: 'inputString',\n              inputProps: { placeholder: 'Введите значение' },\n            },\n            isColumnWithArrow: true,\n          },\n        },\n        {\n          key: 'blockActivity',\n          name: 'Активность блока',\n          editingCell: { component: 'inputString' },\n          renderCell: ({ row }) => (\n            <Canvas.Container direction=\"row\" alignItems=\"center\" padding={8}>\n              <Canvas.Badge\n                text={row.blockActivity}\n                view={row.blockActivity === 'Активный' ? 'positive' : 'warning'}\n                size=\"s\"\n              />\n            </Canvas.Container>\n          ),\n          copyData: (row: TreeRow) => row.blockActivity ?? '',\n          subRow: {\n            keyOfColumnInSubRow: 'blockActivity',\n            editingCell: { component: 'inputString' },\n          },\n        },\n        {\n          key: 'tribe',\n          name: 'Трайб',\n          editingCell: {\n            component: 'select',\n            options: {\n              type: 'stateInRowContext',\n              optionsKeyInRowContext: 'tribeOptions',\n            },\n          },\n          renderCell: ({ row, theme }) => (\n            <Canvas.Container padding={8}>\n              <Canvas.Text color={theme.textDark}>{row.tribe}</Canvas.Text>\n            </Canvas.Container>\n          ),\n          copyData: (row: TreeRow) => row.tribe ?? '',\n          subRow: {\n            keyOfColumnInSubRow: 'tribe',\n            editingCell: { component: 'inputString' },\n          },\n        },\n        {\n          key: 'product',\n          name: 'Продукт',\n          editingCell: {\n            component: 'select',\n            options: {\n              type: 'stateInRowContext',\n              optionsKeyInRowContext: 'productOptions',\n            },\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'product',\n            editingCell: { component: 'inputString' },\n          },\n        },\n        {\n          key: 'q1',\n          name: 'Q1',\n          editingCell: { component: 'inputNumber' },\n          contentFormat: {\n            type: 'number',\n            decimalSeparator: ',',\n            thousandSeparator: ' ',\n            minimumFractionDigits: 2,\n            maximumFractionDigits: 2,\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n        {\n          key: 'q2',\n          name: 'Q2',\n          contentFormat: 'number',\n          editingCell: { component: 'inputNumber' },\n          subRow: {\n            keyOfColumnInSubRow: 'q2',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n        {\n          key: 'q3',\n          name: 'Q3',\n          contentFormat: 'number',\n          editingCell: { component: 'inputNumber' },\n          subRow: {\n            keyOfColumnInSubRow: 'q3',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n        {\n          key: 'q4',\n          name: 'Q4',\n          contentFormat: 'number',\n          editingCell: { component: 'inputNumber' },\n          subRow: {\n            keyOfColumnInSubRow: 'q4',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n      ],\n      [],\n    );\n\n    const rowContextValue = useMemo(\n      () => ({\n        tribeOptions: TRIBES.map((i) => ({ text: i, value: i })),\n        productOptions: PRODUCTS.map((i) => ({ text: i, value: i })),\n      }),\n      [],\n    );\n\n    const savedRowsRef = useRef<null | typeof rows>(null);\n\n    return (\n      <div>\n        <div\n          style={{ display: 'flex', gap: 12, maxWidth: 760, marginBottom: 12 }}\n        >\n          <Select\n            label=\"Режим выделения\"\n            value={selectionMode}\n            onChange={(value) => setSelectionMode(value as CellsSelectionMode)}\n            items={SELECTION_MODE_OPTIONS}\n          />\n          <Select\n            label=\"highlightActiveType (подсветка)\"\n            value={highlightActiveType}\n            onChange={(value) =>\n              setHighlightActiveType(value as HighlightActiveType)\n            }\n            items={HIGHLIGHT_ACTIVE_TYPE_OPTIONS}\n          />\n        </div>\n\n        <StoryHint>\n          <b>Copy:</b> работает всегда (Ctrl+C). <b>Paste/Fill:</b> только в\n          режиме редактирования.\n          <br />\n          <b>Выделение строк:</b> клик/драг по колонке нумерации — строка(и);{' '}\n          <b>Ctrl/Cmd+клик</b> по номерам — набор отдельных строк (группа).\n          Скопированное (Ctrl+C) можно вставить (Ctrl+V) на выделенные строки.\n          <br />\n          <b>Выделение колонок:</b> клик по шапке (Ctrl/Shift — мультивыбор),\n          copy/paste по колонкам.\n          <br />\n          <b>Колонки:</b> Блок (select, readonly часть), Активность\n          (Canvas.Badge + copyData), Трайб (Canvas.Text + copyData + select),\n          Продукт (select), Q1 (число + contentFormat), Q2-Q4 (число).\n          <br />\n          <b>Debug:</b> логи включены (DevTools → Verbose).\n        </StoryHint>\n\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '700px' },\n            // Подсветка строки — отдельная визуальная ось (Фаза 2+).\n            highlightActiveType,\n            // Нумерация строк: клик/драг по ней выделяет строку(и); Ctrl/Meta —\n            // накопительный выбор отдельных строк. Copy/Paste работают по строкам.\n            rowMarkers: { startIndex: 1 },\n            // Режим выделения ячеек: по нему работают copy/paste и рамка.\n            // Выделение колонок по клику на шапку (по умолчанию включено).\n            cellsSelection: {\n              mode: selectionMode,\n              enableColumnSelection: true,\n            },\n            rowSize: { showInControl: true, default: 'big' },\n            editing: {\n              onEnableEditing(enableEditorMode) {\n                savedRowsRef.current = JSON.parse(JSON.stringify(rows));\n                enableEditorMode();\n              },\n              onCancel(disableEditorMode) {\n                if (savedRowsRef.current) setRows(savedRowsRef.current);\n                disableEditorMode();\n              },\n              onSave(disableEditorMode) {\n                savedRowsRef.current = null;\n                disableEditorMode();\n              },\n              onRowsChange: setRows,\n              rowKeyGetter: (r) => `${r.id}`,\n              rowEditable: (r) => r.block !== BLOCKS[1],\n            },\n            subRows: {\n              getSubRows: (row) => row?.subRows,\n              rowKeyGetter: (row) => row.id,\n            },\n            resizableColumn: true,\n          }}\n          columnConfig={columns}\n          rows={rows}\n          rowContextValue={rowContextValue}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "InterceptCopyPaste",
          "displayName": "Перехват onBeforeCopy / onBeforePaste",
          "type": "full-code",
          "code": "() => {\n    const [rows, setRows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          width: 90,\n          editingCell: { component: 'inputNumber' },\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          width: 260,\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          width: 180,\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          width: 180,\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n          width: 160,\n          editingCell: { component: 'inputNumber' },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <div>\n        <StoryHint>\n          <b>onBeforeCopy:</b> при Ctrl+C в консоль выводятся скопированные\n          данные, колонки и rawValue каждой ячейки.\n          <br />\n          <b>onBeforePaste:</b> при Ctrl+V выводятся вставляемые данные и info о\n          target-ячейках. Если вставляется больше 5 строк, вставка блокируется\n          (return false).\n        </StoryHint>\n\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '500px' },\n            rowSize: { default: 'medium', showInControl: true },\n            cellTransfer: {\n              onBeforeCopy: (data, meta) => {\n                console.log('[onBeforeCopy] data:', data);\n                console.log(\n                  '[onBeforeCopy] колонки:',\n                  meta.cells[0]?.map((c) => c.column.key),\n                );\n                console.log(\n                  '[onBeforeCopy] rawValues:',\n                  meta.cells.map((row) => row.map((c) => c.rawValue)),\n                );\n                return data;\n              },\n              onBeforePaste: (data, meta) => {\n                console.log('[onBeforePaste] data:', data);\n                console.log('[onBeforePaste] target:', meta.target);\n                console.log(\n                  '[onBeforePaste] targetCells:',\n                  meta.targetCells.map((row) =>\n                    row.map(\n                      (c) =>\n                        `${c.column.key} (${\n                          c.column.editingCell ? 'editable' : 'readonly'\n                        })`,\n                    ),\n                  ),\n                );\n                if (data.length > 5) {\n                  console.warn('[onBeforePaste] Блокировка: больше 5 строк');\n                  return false;\n                }\n                return data;\n              },\n            },\n            editing: {\n              onRowsChange: setRows,\n              rowKeyGetter: (r) => `${r.id}`,\n              defaultEnabled: true,\n            },\n            resizableColumn: true,\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "CopyDataExample",
          "displayName": "copyData для кастомных ячеек",
          "type": "full-code",
          "code": "() => {\n    const [rows, setRows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          width: 80,\n          editingCell: { component: 'inputNumber' },\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          width: 240,\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'priority',\n          name: 'Priority (Badge + copyData)',\n          width: 220,\n          editingCell: { component: 'inputString' },\n          renderCell: ({ row }) => (\n            <Canvas.Container direction=\"row\" alignItems=\"center\" padding={8}>\n              <Canvas.Badge\n                text={row.priority}\n                view={row.priority === 'Critical' ? 'negative' : 'default'}\n                size=\"s\"\n              />\n            </Canvas.Container>\n          ),\n          copyData: (row: Row) => row.priority ?? '',\n        },\n        {\n          key: 'issueType',\n          name: 'Type (Text + copyData)',\n          width: 200,\n          editingCell: { component: 'inputString' },\n          renderCell: ({ row, theme }) => (\n            <Canvas.Container padding={8}>\n              <Canvas.Text color={theme.textDark}>{row.issueType}</Canvas.Text>\n            </Canvas.Container>\n          ),\n          copyData: (row: Row) => row.issueType ?? '',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n          width: 140,\n          editingCell: { component: 'inputNumber' },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <div>\n        <StoryHint>\n          <b>Priority</b> — Canvas.Badge с <code>copyData</code>. <b>Type</b> —\n          Canvas.Text с <code>copyData</code>.\n          <br />\n          Выделите ячейку Priority → Ctrl+C → вставьте в блокнот: скопируется\n          текст бейджа (например &quot;Critical&quot;), а не пустая строка.\n        </StoryHint>\n\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '400px' },\n            rowSize: { default: 'medium', showInControl: true },\n            editing: {\n              onRowsChange: setRows,\n              rowKeyGetter: (r) => `${r.id}`,\n              defaultEnabled: true,\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "TypeCheckValidation",
          "displayName": "Валидация типов при вставке",
          "type": "full-code",
          "code": "() => {\n    useEffect(() => {\n      (\n        window as unknown as Record<string, boolean>\n      ).__TABLE_CANVAS_CLIPBOARD_DEBUG__ = true;\n    }, []);\n\n    const [rows, setRows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID', width: 80 },\n        {\n          key: 'task',\n          name: 'Title (строка)',\n          width: 240,\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'priority',\n          name: 'Priority (select)',\n          width: 180,\n          editingCell: {\n            component: 'select',\n            options: {\n              type: 'constant',\n              options: [\n                { value: 'Critical', text: 'Critical' },\n                { value: 'High', text: 'High' },\n                { value: 'Medium', text: 'Medium' },\n                { value: 'Low', text: 'Low' },\n              ],\n            },\n          },\n        },\n        {\n          key: 'complete',\n          name: '% Complete (число)',\n          width: 180,\n          editingCell: { component: 'inputNumber' },\n          contentFormat: {\n            type: 'number',\n            decimalSeparator: ',',\n            thousandSeparator: ' ',\n          },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <div>\n        <StoryHint>\n          <b>Priority</b> — select (Critical / High / Medium / Low). Вставка\n          &quot;Unknown&quot; пропустится.\n          <br />\n          <b>% Complete</b> — число. Вставка &quot;hello&quot; пропустится.\n          <br />\n          <b>Title</b> — строка, принимает всё.\n          <br />\n          Debug логи включены — смотрите{' '}\n          <code>[TableCanvas/paste] skipped by validation</code> в консоли.\n        </StoryHint>\n\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '400px' },\n            rowSize: { default: 'medium', showInControl: true },\n            editing: {\n              onRowsChange: setRows,\n              rowKeyGetter: (r) => `${r.id}`,\n              defaultEnabled: true,\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "FillHandleWithSourceRow",
          "displayName": "Fill Handle — доступ к source row (onBeforeFill)",
          "type": "full-code",
          "code": "() => {\n    const [rows, setRows] = useState(createRows);\n    const savedRowsRef = useRef<Row[] | null>(null);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          width: 80,\n          editingCell: { component: 'inputNumber' },\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          width: 260,\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          width: 180,\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          width: 180,\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n          width: 160,\n          editingCell: { component: 'inputNumber' },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <div>\n        <StoryHint>\n          Выделите ячейку в колонке <b>% Complete</b> и перетащите fill handle\n          вниз.\n          <br />\n          <b>onRowsChange</b> получает <code>type: &apos;fill&apos;</code> и{' '}\n          <code>fillMeta</code> с source row, что позволяет дополнительно\n          скопировать <b>priority</b> из исходной строки.\n        </StoryHint>\n\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '500px' },\n            highlightActiveType: 'range-cell',\n            rowSize: { default: 'medium', showInControl: true },\n            cellTransfer: {\n              fillHandle: true,\n              onBeforeFill: (data, meta) => {\n                console.log(\n                  '[onBeforeFill] source row:',\n                  meta.sourceCells[0]?.[0]?.row,\n                );\n                console.log('[onBeforeFill] data:', data);\n                return data;\n              },\n            },\n            editing: {\n              onEnableEditing(enableEditorMode) {\n                savedRowsRef.current = JSON.parse(JSON.stringify(rows));\n                enableEditorMode();\n              },\n              onCancel(disableEditorMode) {\n                if (savedRowsRef.current) {\n                  setRows(savedRowsRef.current);\n                  savedRowsRef.current = null;\n                }\n                disableEditorMode();\n              },\n              onRowsChange: (newRows, { indexes, column, type, fillMeta }) => {\n                if (type === 'fill' && fillMeta && column.key === 'complete') {\n                  const sourceRow = fillMeta.sourceCells[0]?.[0]?.row as\n                    | Row\n                    | undefined;\n\n                  if (sourceRow) {\n                    const updated = newRows.map((row, i) =>\n                      indexes.includes(i)\n                        ? { ...row, priority: sourceRow.priority }\n                        : row,\n                    );\n                    setRows(updated);\n                    return;\n                  }\n                }\n\n                setRows(newRows);\n              },\n              rowKeyGetter: (r) => `${r.id}`,\n              defaultEnabled: false,\n            },\n            resizableColumn: true,\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "CustomHotkeys",
          "displayName": "Кастомные хоткеи",
          "type": "full-code",
          "code": "() => {\n    const [rows, setRows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          width: 80,\n          editingCell: { component: 'inputNumber' },\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          width: 260,\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          width: 180,\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n          width: 160,\n          editingCell: { component: 'inputNumber' },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <div>\n        <StoryHint>\n          Copy: <b>Ctrl+Alt+C</b>. Paste: <b>Ctrl+Alt+V</b>.\n          <br />\n          Обычные Ctrl+C / Ctrl+V для этой таблицы не работают — хук блокирует\n          дефолт, когда задан кастомный хоткей.\n        </StoryHint>\n\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '400px' },\n            rowSize: { default: 'medium', showInControl: true },\n            cellTransfer: {\n              hotkeys: {\n                copy: { code: 'KeyC', ctrl: true, alt: true },\n                paste: { code: 'KeyV', ctrl: true, alt: true },\n              },\n            },\n            editing: {\n              onRowsChange: setRows,\n              rowKeyGetter: (r) => `${r.id}`,\n              defaultEnabled: true,\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "CustomRender",
      "legacy": false,
      "summary": "*columnConfig.renderCell / renderHeaderCell / renderSummaryCell**",
      "docs": "# Custom Render\n\n**columnConfig.renderCell / renderHeaderCell / renderSummaryCell**\n\nКастомный рендеринг ячеек таблицы через Canvas-компоненты.\n\n## Ключевые особенности\n\n- `renderCell` — кастомный рендер ячеек данных\n- `renderHeaderCell` — кастомный рендер заголовков колонок\n- `renderSummaryCell` — кастомный рендер итоговых строк\n- Доступ к `theme`, `column`, `row` и `ctxs` внутри рендер-функций\n\n## Особенности\n\n- Каждая ячейка должна учитывать `theme.cellHorizontalPadding` для корректных отступов\n- В качестве `name` колонки можно передать `Canvas.Element` для кастомного заголовка\n- Доступны все Canvas-компоненты: Badge, Button, Text, Container и др.\n\n> Подробнее о типах и пропсах — [Custom Render API](?path=/docs/локальные-компоненты-tablecanvas-customrender-api--docs)",
      "apiDocs": "# Custom Render API\n\nКастомный рендеринг настраивается через свойства `columnConfig`.\n\n## CellInfo (renderCell)\n\n```typescript\ntype CellInfo<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<\n  CellInfoGlideInstance<R, SR, CustomCtxs>,\n  'column' | 'ctxs' | 'hovered' | 'active'\n> & {\n  column: ColumnConfig<R, SR, CustomCtxs>;\n  ctxs: CtxsType<CustomCtxs>;\n  /**\n   * Состояние наведения для текущей ячейки, которую рендерит renderCell.\n   * `cellHover` равно true только у ячейки под курсором, `rowHover` — у всех ячеек ее строки.\n   */\n  hovered: CellHoverState;\n  /**\n   * Состояние активного выделения для текущей ячейки, которую рендерит renderCell.\n   * `cellActive` равно true у активной ячейки или диапазона, `rowActive` — у строк с активной ячейкой или диапазоном.\n   */\n  active: CellActiveState;\n};\n```\n\n## HeaderCellInfo (renderHeaderCell)\n\n```typescript\ntype HeaderCellInfo<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<HeaderCellInfoGlideInstance<R, SR, CustomCtxs>, 'column' | 'ctxs'> & {\n  column: ColumnConfig<R, SR, CustomCtxs>;\n  ctxs: CtxsType<CustomCtxs>;\n};\n```\n\n## name\n\nСвойство `name` в `columnConfig` принимает `string | ReactElement`. Для кастомного заголовка можно передать `Canvas.Element`.",
      "api": [
        {
          "typeName": "CellInfo",
          "source": "type CellInfo<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<\n  CellInfoGlideInstance<R, SR, CustomCtxs>,\n  'column' | 'ctxs' | 'hovered' | 'active'\n> & {\n  column: ColumnConfig<R, SR, CustomCtxs>;\n  ctxs: CtxsType<CustomCtxs>;\n  /**\n   * Состояние наведения для текущей ячейки, которую рендерит renderCell.\n   * `cellHover` равно true только у ячейки под курсором, `rowHover` — у всех ячеек ее строки.\n   */\n  hovered: CellHoverState;\n  /**\n   * Состояние активного выделения для текущей ячейки, которую рендерит renderCell.\n   * `cellActive` равно true у активной ячейки или диапазона, `rowActive` — у строк с активной ячейкой или диапазоном.\n   */\n  active: CellActiveState;\n};"
        },
        {
          "typeName": "HeaderCellInfo",
          "source": "type HeaderCellInfo<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<HeaderCellInfoGlideInstance<R, SR, CustomCtxs>, 'column' | 'ctxs'> & {\n  column: ColumnConfig<R, SR, CustomCtxs>;\n  ctxs: CtxsType<CustomCtxs>;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "CustomRenderCell",
          "displayName": "Кастомизация рендера ячеек шапки, данных, итоговых данных",
          "type": "full-code",
          "code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport {\n  Canvas,\n  ColumnConfig,\n  TableCanvas,\n  tableCanvasTheme,\n} from '@daisforge/ui/components/TableCanvas';\nimport { Badge } from '@daisforge/ui';\nimport React, { ComponentProps, useMemo, useState } from 'react';\n\n() => {\n    const [rows] = useState<Row[]>(createRows(0, 20));\n    const columnConfig = useMemo(\n      (): ColumnConfig<Row>[] => [\n        {\n          key: 'id',\n          name: 'ID',\n          renderHeaderCell({ theme, column }) {\n            return (\n              <Canvas.Container\n                padding={{\n                  left: theme.cellHorizontalPadding,\n                  right: theme.cellHorizontalPadding,\n                }}\n                alignItems=\"center\"\n              >\n                <Canvas.Text\n                  color={theme.textHeader}\n                  font={theme.headerFontStyle}\n                >\n                  {column.name} - кастомный renderHeaderCell\n                </Canvas.Text>\n              </Canvas.Container>\n            );\n          },\n          renderCell: ({ column, row, theme }) => (\n            <Canvas.Container\n              padding={{\n                left: theme.cellHorizontalPadding,\n                right: theme.cellHorizontalPadding,\n              }}\n              alignItems=\"center\"\n            >\n              <Canvas.Badge\n                view=\"accent\"\n                text={row[column.key as keyof Row]?.toString() ?? ''}\n              />\n            </Canvas.Container>\n          ),\n          renderSummaryCell: ({ row: summ, theme }) => (\n            <Canvas.Container\n              padding={{\n                left: theme.cellHorizontalPadding,\n                right: theme.cellHorizontalPadding,\n              }}\n              alignItems=\"center\"\n            >\n              <Canvas.Text font={theme.baseFontStyle}>\n                Итого {summ?.toString() ?? ''} - кастомный renderSummaryCell\n              </Canvas.Text>\n            </Canvas.Container>\n          ),\n        },\n        {\n          key: 'task',\n          name: (\n            <Canvas.Container\n              padding={{ left: tableCanvasTheme.cellHorizontalPadding }}\n              alignItems=\"center\"\n            >\n              <Canvas.Text\n                font={tableCanvasTheme.headerFontStyle}\n                color={tableCanvasTheme.textHeader}\n              >\n                Task - кастомный canvas-name\n              </Canvas.Text>\n            </Canvas.Container>\n          ),\n          width: 200,\n          renderCell: ({ row, rowInd, theme }) => (\n            <Canvas.Container\n              padding={{\n                left: theme.cellHorizontalPadding,\n                right: theme.cellHorizontalPadding,\n              }}\n              alignItems=\"center\"\n            >\n              <Canvas.Button\n                view=\"secondary\"\n                onClick={() =>\n                  // Для примера\n                  // eslint-disable-next-line no-alert\n                  alert(`Строка ${rowInd}. Клик по кнопке кастомной ячейки`)\n                }\n              >\n                {`${row?.task} кликните`}\n              </Canvas.Button>\n            </Canvas.Container>\n          ),\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          renderCell: ({ row, theme }) => {\n            const viewMap: Record<\n              Row['priority'],\n              ComponentProps<typeof Badge>['view']\n            > = {\n              High: 'accent',\n              Medium: 'warning',\n              Low: 'dark',\n              Critical: 'negative',\n            };\n            return (\n              <Canvas.Container\n                padding={{\n                  left: theme.cellHorizontalPadding,\n                  right: theme.cellHorizontalPadding,\n                }}\n                alignItems=\"center\"\n              >\n                <Canvas.Badge\n                  text={row.priority}\n                  view={viewMap[row.priority] || 'default'}\n                  pilled\n                />\n              </Canvas.Container>\n            );\n          },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          summaryRows: {\n            showDefault: true,\n            showInControl: false,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n        bottomSummaryRows={[rows.length]}\n      />\n    );\n  }"
        },
        {
          "exportName": "HoveredCellIcon",
          "displayName": "Иконка при наведении на ячейку",
          "type": "full-code",
          "code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport {\n  Canvas,\n  ColumnConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\nimport { IconSearch } from '@daisforge/ui/icons';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.CustomRender/TableCanvas.customRenderCell.stories.tsx',\n  'renderCellWithHoverIcon',\n)}\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.CustomRender/TableCanvas.customRenderCell.stories.tsx',\n  'HoveredCellIconExample',\n)}"
        },
        {
          "exportName": "ActiveCellIcon",
          "displayName": "Иконка активной ячейки",
          "type": "full-code",
          "code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport {\n  Canvas,\n  ColumnConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\nimport { IconSearch } from '@daisforge/ui/icons';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.CustomRender/TableCanvas.customRenderCell.stories.tsx',\n  'renderCellWithActiveIcon',\n)}\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.CustomRender/TableCanvas.customRenderCell.stories.tsx',\n  'ActiveCellIconExample',\n)}"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "DomMetadata",
      "legacy": false,
      "summary": "*tableConfig.\\*.domMetadata**",
      "docs": "# DomMetadata\n\n**tableConfig.\\*.domMetadata**\n\nМетки для автоматизированного тестирования, аналитики и онбординга.\n\n`DomMetadata` позволяет навешивать CSS-классы, data-атрибуты и обработчики кликов на интерактивные элементы таблицы.\nЭто нужно для:\n\n- **Аналитики** — трекинг кликов по кнопкам таблицы\n- **Автотестов** — поиск элементов по `data-testid`\n- **Онбординга** — привязка подсказок к конкретным элементам\n\n## Поддерживаемые элементы (className, dataAttributes)\n\nСледующие элементы поддерживают `className` и `dataAttributes` через `domMetadata`:\n\n**Control Block (панель управления):**\n\n- **Редактирование** — `tableConfig.editing.domMetadata`\n- **Полноэкранный режим** — `tableConfig.fullScreenEnabled.domMetadata`\n- **Размер строки** — `tableConfig.rowSize.domMetadata`\n- **Переключение вида** (строки/карточки) — `tableConfig.view.domMetadata`\n- **Группировка строк** — `tableConfig.rowsGrouping.domMetadata`\n- **Поиск** — `tableConfig.searching.domMetadata`\n- **Итоговые строки** — `tableConfig.summaryRows.domMetadata`\n- **KeyText** (controlBlock) — `tableConfig.keyText.controlBlock.domMetadata`\n- **KeyText** (sidebar) — `tableConfig.keyText.sidebar.domMetadata`\n\n**Selecting (выбор строк):**\n\n- **Чекбокс \"Выбрать все\"** (controlBlock) — `tableConfig.selecting.controlBlock.domMetadata`\n- **Свитч в сайдбаре** — `tableConfig.selecting.sidebar.domMetadata`\n\n**Sidebar (правая панель):**\n\n- **Табы сайдбара** — `tableConfig.sidebarConfig.defaultTabs[].domMetadata`\n- **Подтабы настроек** (Фильтры, Столбцы) — `tableConfig.sidebarConfig.defaultTabs[{id:'filtering'|'columns'}].domMetadata`\n\n**Другие:**\n\n- **Кнопка сворачивания таблицы** — `tableConfig.collapse.domMetadata`\n\n## Элементы с расширенным onClick (className, dataAttributes, onClick + detail)\n\nВ дополнение к `className` и `dataAttributes`, следующие элементы поддерживают `onClick` с контекстом `detail`:\n\n- **Группировать** (чекбоксы, сброс) — `tableConfig.rowsGrouping.domMetadata` — actions: `toggle-group`, `reset-groups`, `custom-item-select`\n- **Кнопка размера строки** — `tableConfig.rowSize.domMetadata` — action: `change-row-size`\n- **Шестеренка настроек** — `tableConfig.sidebarConfig.defaultTabs[{id:'tableSettings'}].domMetadata` — action: `toggle-sidebar-tab`\n- **Крестик закрыть сайдбар** — тот же `domMetadata` таба — action: `close-sidebar`\n- **Закрепить столбец** — `tableConfig.columnsControl.pinDomMetadata` — actions: `pin-column`, `unpin-column`\n- **Свитчер видимости столбца** — `tableConfig.columnsControl.switchDomMetadata` — actions: `show-column`, `hide-column`\n\n## onClick\n\nОбработчик `onClick` вызывается **после** основной логики элемента. Он не мешает работе кнопки и не вызывает `stopPropagation`.\n\n```tsx\nonClick?: (\n  e?: React.MouseEvent<HTMLElement>,  // MouseEvent (undefined для элементов внутри Dropdown)\n  detail?: Record<string, unknown>     // контекст: action, columnKey, size и др.\n) => void;\n```\n\n### Примеры detail\n\n```ts\n// Группировка\n{ action: 'toggle-group', columnKey: 'status' }\n{ action: 'reset-groups' }\n\n// Размер строки\n{ action: 'change-row-size', size: 'medium' }\n\n// Сайдбар\n{ action: 'toggle-sidebar-tab', tabId: 'tableSettings' }\n{ action: 'close-sidebar' }\n\n// Столбцы\n{ action: 'pin-column', columnKey: 'name' }\n{ action: 'unpin-column', columnKey: 'name' }\n{ action: 'hide-column', columnKey: 'name' }\n{ action: 'show-column', columnKey: 'name' }\n```\n\nПодробнее о типах — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-dommetadata-api--docs).",
      "apiDocs": "# DomMetadata API\n\n## DomMetadata\n\n```typescript\ntype DomMetadata = {\n  /**\n   * CSS класс для стилизации и поиска элемента\n   *\n   * @example 'user-profile-card'\n   * @example 'onboarding-step-1'\n   */\n  className?: string;\n  /**\n   * Data-атрибуты для тестирования, аналитики и онбординга\n   *\n   * @example { 'data-testid': 'submit-button', 'data-analytics': 'click-event' }\n   */\n  dataAttributes?: DataAttributes;\n  /**\n   * Обработчик клика для аналитики и трекинга\n   *\n   * Вызывается вместе с основным обработчиком элемента (не заменяет его).\n   * Не вызывает stopPropagation — оригинальная логика кнопки сохраняется.\n   *\n   * @param e - MouseEvent (может быть undefined для элементов внутри Dropdown)\n   * @param detail - контекст действия: action, columnKey, size и др.\n   *\n   * @example onClick: (e, detail) => analytics.track(detail?.action, detail)\n   */\n  onClick?: (\n    e?: React.MouseEvent<HTMLElement>,\n    detail?: Record<string, unknown>,\n  ) => void;\n};\n```\n\n## DOM_METADATA_ACTIONS\n\n```typescript\nexport const DOM_METADATA_ACTIONS = {\n  /** Включение/выключение группировки по столбцу. detail.columnKey — ключ столбца */\n  TOGGLE_GROUP: 'toggle-group',\n  /** Сброс всех группировок */\n  RESET_GROUPS: 'reset-groups',\n  /** Выбор пункта в кастомном onItemSelect группировки. detail.columnKey — ключ */\n  CUSTOM_ITEM_SELECT: 'custom-item-select',\n  /** Переключение размера строки. detail.size — новый размер ('small' | 'medium' | 'big') */\n  CHANGE_ROW_SIZE: 'change-row-size',\n  /** Клик по табу сайдбара (шестерёнка и др.). detail.tabId — id таба */\n  TOGGLE_SIDEBAR_TAB: 'toggle-sidebar-tab',\n  /** Закрытие сайдбара (крестик) */\n  CLOSE_SIDEBAR: 'close-sidebar',\n  /** Закрепление столбца. detail.columnKey — ключ столбца */\n  PIN_COLUMN: 'pin-column',\n  /** Открепление столбца. detail.columnKey — ключ столбца */\n  UNPIN_COLUMN: 'unpin-column',\n  /** Скрытие столбца. detail.columnKey — ключ столбца */\n  HIDE_COLUMN: 'hide-column',\n  /** Показ столбца. detail.columnKey — ключ столбца */\n  SHOW_COLUMN: 'show-column',\n} as const;\n```\n\n## DomMetadataAction\n\n```typescript\ntype DomMetadataAction =\n  (typeof DOM_METADATA_ACTIONS)[keyof typeof DOM_METADATA_ACTIONS];\n```\n\n## ColumnsControlConfig\n\n```typescript\ntype ColumnsControlConfig = {\n  enable: boolean;\n  /**\n   * @default enable\n   */\n  hiding?: boolean;\n  /**\n   * @default enable\n   */\n  pinning?: boolean;\n  /**\n   * @default enable\n   */\n  reorderingAside?: boolean;\n  /**\n   * reorderingHeader  - активация изменения порядка колонок  посредством перемещения шапок колонок таблицы\n   */\n  /**\n   * @default enable\n   */\n  reorderingHeader?: boolean;\n  onReorderingHeader?: (params: {\n    newOrder: string[];\n    sourceKey: string;\n    targetKey: string;\n  }) => void;\n\n  columnsLabel?: Record<\n    string,\n    ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n  >;\n\n  /**\n   * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n   * видимые строки списка. false — отключить полностью; { minCount } —\n   * включать, когда строк в списке не меньше порога.\n   * @default { minCount: 30 }\n   */\n  virtualization?: boolean | { minCount?: number };\n\n  orderDefault?: string[];\n\n  pinnedDefault?: string[];\n  disablePinning?: string[];\n\n  hiddenDefault?: string[];\n  disableHiding?: string[];\n  /**\n   * Индикатор скрытых столбцов: синяя полосатая линия в шапке на границе, за\n   * которой скрыты столбцы. Двойной клик по линии раскрывает весь промежуток,\n   * ресайз на этой границе работает как обычно.\n   * @default hiding\n   */\n  hiddenColumnsIndicator?: boolean;\n  /**\n   * Уведомление о раскрытии промежутка двойным кликом по индикатору скрытых\n   * столбцов. Само раскрытие (снятие скрытия) обёртка делает сама; колбэк нужен,\n   * чтобы внешний потребитель мог подписаться на это событие и узнать, какие\n   * столбцы раскрылись и между какими видимыми колонками стояла линия.\n   */\n  onHiddenColumnsIndicatorExpand?: (\n    info: HiddenColumnsIndicatorExpandInfo,\n  ) => void;\n\n  onConfirm?: (\n    params: {\n      pinned: string[];\n      order: string[];\n      hidden: string[];\n      changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n    },\n    setters: {\n      setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n      setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n      setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n    },\n  ) => void;\n  /**\n   * DomMetadata для кнопок закрепления столбцов\n   */\n  pinDomMetadata?: DomMetadata;\n  /**\n   * DomMetadata для свитчеров скрытия/показа столбцов\n   */\n  switchDomMetadata?: DomMetadata;\n};\n```",
      "api": [
        {
          "typeName": "DomMetadata",
          "source": "type DomMetadata = {\n  /**\n   * CSS класс для стилизации и поиска элемента\n   *\n   * @example 'user-profile-card'\n   * @example 'onboarding-step-1'\n   */\n  className?: string;\n  /**\n   * Data-атрибуты для тестирования, аналитики и онбординга\n   *\n   * @example { 'data-testid': 'submit-button', 'data-analytics': 'click-event' }\n   */\n  dataAttributes?: DataAttributes;\n  /**\n   * Обработчик клика для аналитики и трекинга\n   *\n   * Вызывается вместе с основным обработчиком элемента (не заменяет его).\n   * Не вызывает stopPropagation — оригинальная логика кнопки сохраняется.\n   *\n   * @param e - MouseEvent (может быть undefined для элементов внутри Dropdown)\n   * @param detail - контекст действия: action, columnKey, size и др.\n   *\n   * @example onClick: (e, detail) => analytics.track(detail?.action, detail)\n   */\n  onClick?: (\n    e?: React.MouseEvent<HTMLElement>,\n    detail?: Record<string, unknown>,\n  ) => void;\n};"
        },
        {
          "typeName": "Unknown",
          "source": "export const DOM_METADATA_ACTIONS = {\n  /** Включение/выключение группировки по столбцу. detail.columnKey — ключ столбца */\n  TOGGLE_GROUP: 'toggle-group',\n  /** Сброс всех группировок */\n  RESET_GROUPS: 'reset-groups',\n  /** Выбор пункта в кастомном onItemSelect группировки. detail.columnKey — ключ */\n  CUSTOM_ITEM_SELECT: 'custom-item-select',\n  /** Переключение размера строки. detail.size — новый размер ('small' | 'medium' | 'big') */\n  CHANGE_ROW_SIZE: 'change-row-size',\n  /** Клик по табу сайдбара (шестерёнка и др.). detail.tabId — id таба */\n  TOGGLE_SIDEBAR_TAB: 'toggle-sidebar-tab',\n  /** Закрытие сайдбара (крестик) */\n  CLOSE_SIDEBAR: 'close-sidebar',\n  /** Закрепление столбца. detail.columnKey — ключ столбца */\n  PIN_COLUMN: 'pin-column',\n  /** Открепление столбца. detail.columnKey — ключ столбца */\n  UNPIN_COLUMN: 'unpin-column',\n  /** Скрытие столбца. detail.columnKey — ключ столбца */\n  HIDE_COLUMN: 'hide-column',\n  /** Показ столбца. detail.columnKey — ключ столбца */\n  SHOW_COLUMN: 'show-column',\n} as const;"
        },
        {
          "typeName": "DomMetadataAction",
          "source": "type DomMetadataAction =\n  (typeof DOM_METADATA_ACTIONS)[keyof typeof DOM_METADATA_ACTIONS];"
        },
        {
          "typeName": "ColumnsControlConfig",
          "source": "type ColumnsControlConfig = {\n  enable: boolean;\n  /**\n   * @default enable\n   */\n  hiding?: boolean;\n  /**\n   * @default enable\n   */\n  pinning?: boolean;\n  /**\n   * @default enable\n   */\n  reorderingAside?: boolean;\n  /**\n   * reorderingHeader  - активация изменения порядка колонок  посредством перемещения шапок колонок таблицы\n   */\n  /**\n   * @default enable\n   */\n  reorderingHeader?: boolean;\n  onReorderingHeader?: (params: {\n    newOrder: string[];\n    sourceKey: string;\n    targetKey: string;\n  }) => void;\n\n  columnsLabel?: Record<\n    string,\n    ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n  >;\n\n  /**\n   * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n   * видимые строки списка. false — отключить полностью; { minCount } —\n   * включать, когда строк в списке не меньше порога.\n   * @default { minCount: 30 }\n   */\n  virtualization?: boolean | { minCount?: number };\n\n  orderDefault?: string[];\n\n  pinnedDefault?: string[];\n  disablePinning?: string[];\n\n  hiddenDefault?: string[];\n  disableHiding?: string[];\n  /**\n   * Индикатор скрытых столбцов: синяя полосатая линия в шапке на границе, за\n   * которой скрыты столбцы. Двойной клик по линии раскрывает весь промежуток,\n   * ресайз на этой границе работает как обычно.\n   * @default hiding\n   */\n  hiddenColumnsIndicator?: boolean;\n  /**\n   * Уведомление о раскрытии промежутка двойным кликом по индикатору скрытых\n   * столбцов. Само раскрытие (снятие скрытия) обёртка делает сама; колбэк нужен,\n   * чтобы внешний потребитель мог подписаться на это событие и узнать, какие\n   * столбцы раскрылись и между какими видимыми колонками стояла линия.\n   */\n  onHiddenColumnsIndicatorExpand?: (\n    info: HiddenColumnsIndicatorExpandInfo,\n  ) => void;\n\n  onConfirm?: (\n    params: {\n      pinned: string[];\n      order: string[];\n      hidden: string[];\n      changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n    },\n    setters: {\n      setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n      setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n      setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n    },\n  ) => void;\n  /**\n   * DomMetadata для кнопок закрепления столбцов\n   */\n  pinDomMetadata?: DomMetadata;\n  /**\n   * DomMetadata для свитчеров скрытия/показа столбцов\n   */\n  switchDomMetadata?: DomMetadata;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "DomMetadataOnClick",
          "displayName": "onClick для аналитики",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n    const [groupedCols, setGroupedCols] = useState<string[]>([]);\n    const [filters, setFilters] = useState({});\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          rowsGrouping: { columnGroupLabel: 'ID' },\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          rowsGrouping: { columnGroupLabel: 'Title' },\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          rowsGrouping: { columnGroupLabel: 'Priority' },\n        },\n      ],\n      [],\n    );\n\n    // Общий обработчик для аналитики.\n    // e — MouseEvent (undefined для элементов внутри Dropdown).\n    // detail — контекст: action, columnKey, size и др.\n    // detail.action — одна из констант DOM_METADATA_ACTIONS\n    const handleDomMetadataClick = (\n      source: string,\n      e?: React.MouseEvent<HTMLElement>,\n      detail?: Record<string, unknown>,\n    ) => {\n      // Пример: проверка конкретного действия через константу\n      if (detail?.action === DOM_METADATA_ACTIONS.TOGGLE_GROUP) {\n        console.debug(\n          `[DomMetadata] Группировка по столбцу: ${detail.columnKey}`,\n        );\n      }\n      console.debug(`[DomMetadata] ${source}:`, {\n        detail,\n        target: e?.currentTarget,\n      });\n    };\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '700px' },\n\n          // 1. Группировка строк\n          // detail.action: 'toggle-group' | 'reset-groups' | 'custom-item-select'\n          // detail.columnKey: ключ столбца (для toggle-group и custom-item-select)\n          rowsGrouping: {\n            groupByState: [groupedCols, setGroupedCols],\n            rowKeyGetter: (row) => row.id.toString(),\n            domMetadata: {\n              className: 'analytics-grouping',\n              dataAttributes: { 'data-feature': 'grouping' },\n              onClick: (e, detail) =>\n                handleDomMetadataClick('rowsGrouping', e, detail),\n            },\n          },\n\n          // 2. Кнопка размера строки\n          // detail.action: 'change-row-size'\n          // detail.size: новый размер ('small' | 'medium' | 'big')\n          rowSize: {\n            showInControl: true,\n            default: 'small',\n            available: ['small', 'medium', 'big'],\n            domMetadata: {\n              className: 'analytics-row-size',\n              dataAttributes: { 'data-feature': 'row-size' },\n              onClick: (e, detail) =>\n                handleDomMetadataClick('rowSize', e, detail),\n            },\n          },\n\n          // 3. Настройки столбцов: закрепление и видимость\n          // pinDomMetadata — detail.action: 'pin-column' | 'unpin-column', detail.columnKey\n          // switchDomMetadata — detail.action: 'show-column' | 'hide-column', detail.columnKey\n          columnsControl: {\n            enable: true,\n            pinDomMetadata: {\n              className: 'analytics-pin',\n              dataAttributes: { 'data-feature': 'pin-column' },\n              onClick: (e, detail) =>\n                handleDomMetadataClick('pinColumn', e, detail),\n            },\n            switchDomMetadata: {\n              className: 'analytics-switch',\n              dataAttributes: { 'data-feature': 'column-visibility' },\n              onClick: (e, detail) =>\n                handleDomMetadataClick('columnVisibility', e, detail),\n            },\n          },\n\n          // 4. Таб настроек сайдбара (шестерёнка + крестик закрыть)\n          // detail.action: 'toggle-sidebar-tab' (шестерёнка) | 'close-sidebar' (крестик)\n          // detail.tabId: id таба (для toggle-sidebar-tab)\n          sidebarConfig: {\n            defaultTabs: [\n              {\n                id: 'tableSettings',\n                domMetadata: {\n                  className: 'analytics-settings',\n                  dataAttributes: { 'data-feature': 'settings' },\n                  onClick: (e, detail) =>\n                    handleDomMetadataClick('settings', e, detail),\n                },\n              },\n            ],\n          },\n\n          filtering: {\n            state: [filters, setFilters],\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "Editing",
      "legacy": false,
      "summary": "*tableConfig.editing + columnConfig.editingCell**",
      "docs": "# Editing (TableCanvas)\n\n**tableConfig.editing + columnConfig.editingCell**\n\nРежим редактирования данных в ячейках таблицы. Условие активации — наличие свойства `editing` в `tableConfig`. Также необходимо сконфигурировать колонки через `editingCell`.\n\n## Ключевые особенности\n\n- Управление режимом редактирования через `enabled` / `defaultEnabled`\n- Callback-и при включении, сохранении и отмене (`onEnableEditing`, `onSave`, `onCancel`)\n- Контроль редактируемости строк через `rowEditable`\n- Поддержка дочерних строк через `subRowsKey`\n- Кнопки управления в controlBlock (`showButtons`)\n- `editingCell.component` рендерит React-компонент поверх таблицы; `Canvas.*` элементы используйте только в `renderCell`, `renderHeaderCell` и `renderSummaryCell`\n\n## Жизненный цикл\n\n1. Пользователь нажимает кнопку «Редактирование» → вызывается `onEnableEditing`\n2. При изменении ячейки → вызывается `onRowsChange` с данными об изменённых строках\n3. При нажатии «Сохранить» → вызывается `onSave`\n4. При нажатии «Отменить» → вызывается `onCancel`\n\n## Управление состоянием\n\n- **`defaultEnabled`** — начальное состояние (внутренний стейт)\n- **`enabled: boolean`** — полностью внешнее управление (без переключения в таблице)\n- **`enabled: [boolean, setState]`** — внешний стейт с возможностью переключения в таблице\n\n## Особенности\n\n- `onRowsChange` — обязательный callback, получает обновлённые строки и метаданные (индексы, колонка, before/after)\n- `subRowsKey` — обязателен, если дочерние строки хранятся не под ключом `subRows`. Поддерживает вложенность через точку (например, `'data.children'`)\n- `showButtons` — по умолчанию `true`, управляет видимостью кнопок в controlBlock\n\n## Управление кнопками (buttons)\n\nЧерез `editing.buttons` можно передать пропсы кнопкам `save`, `cancel` и `edit`. `onClick` исключён — обработчики задаются через `onSave` / `onCancel` / `onEnableEditing`.\n\n```tsx\nediting: {\n  buttons: {\n    save: { disabled: isSaving, isLoading: isSaving },\n    cancel: { disabled: isSaving },\n  },\n  onSave(disableEditorMode) {\n    setIsSaving(true);\n    api.save(rows).finally(() => {\n      setIsSaving(false);\n      disableEditorMode();\n    });\n  },\n}\n```",
      "apiDocs": "# Editing API\n\n## EditingConfig\n\n```typescript\ntype EditingConfig<\n  RowType extends ObjectForExtending,\n  RowIdType,\n  SummaryRowType,\n> = {\n  /**\n   * Функция обработки изменений в редактируемой строке\n   */\n  onRowsChange: Maybe<\n    (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n  >;\n  /**\n   * свойство, необходимое для корректного изменения дочерних строк.\n   * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n   *\n   * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n   * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n   *\n   * @example \"child\" или \"uvh367.children\"\n   */\n  subRowsKey?: string;\n  /**\n   * Глубокое копирование строк перед применением правки в режиме редактирования.\n   *\n   * Включите, если строки, передаваемые в таблицу, иммутабельны/заморожены\n   * (напр. стейт под управлением Redux Toolkit или Immer — они вызывают\n   * Object.freeze в dev). При редактировании дочерней строки таблица записывает\n   * изменение ВНУТРЬ объекта родителя; на замороженном объекте это падает с\n   * `TypeError: Cannot assign to read only property`.\n   *\n   * Когда флаг включён, таблица сама делает structuredClone редактируемой строки\n   * перед записью — ваш иммутабельный стейт не мутируется, и редактирование\n   * дочерних строк работает без действий с вашей стороны.\n   *\n   * ⚠️ Данные строки должны быть сериализуемыми. Где доступен structuredClone —\n   * Date/Map/Set и вложенные структуры копируются корректно; на старых средах\n   * без structuredClone используется JSON-фоллбэк (теряет Date/Map/Set, undefined\n   * и функции). Не включайте без необходимости — глубокое копирование добавляет\n   * накладные расходы.\n   *\n   * @default false\n   */\n  deepCloneRows?: boolean;\n  /**\n   * Функция определения уникального id строки\n   * @param row\n   * @returns\n   */\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * Функция определения возможности редактирования строки\n   * @param row\n   * @returns\n   */\n  rowEditable?: (row: RowType) => boolean;\n  /**\n   * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n   * @default false\n   */\n  defaultEnabled?: boolean;\n  /**\n   * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n   * По умолчанию, управление происходит в компоненте.\n   * Приоритетнее, чем defaultEnabled.\n   *\n   * @type boolean - если НЕ нужно переключение в самой таблице\n   * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n   *\n   */\n  enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n   * @default true\n   */\n  showButtons?: boolean;\n  /**\n   * Функция, вызывающаяся при включении фичи.\n   * @param enableEditorMode - функция включающая режим редактирования\n   */\n  onEnableEditing?: (enableEditorMode: () => void) => void;\n  /**\n   * Функция, вызывающаяся при сохранении отредактированного.\n   * @param disableEditorMode - функция выключающая режим редактирования\n   */\n  onSave?: (disableEditorMode: () => void) => void;\n  /**\n   * Функция, вызывающаяся при отмене отредактированного.\n   * @param disableEditorMode - функция выключающая режим редактирования\n   */\n  onCancel?: (disableEditorMode: () => void) => void;\n  /** Пропсы кнопок в controlBlock. */\n  buttons?: {\n    save?: EditingButtonProps;\n    cancel?: EditingButtonProps;\n    edit?: EditingButtonProps;\n  };\n  /**\n   * Кастомный слот, отображаемый левее кнопок «Отменить» / «Сохранить».\n   * Виден только когда режим редактирования активен (editMode = true).\n   * Зона ответственности разработчика — размерная сетка controlBlock не влияет на этот слот.\n   */\n  editModeLeftSlot?: React.ReactNode;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: {\n    enableButton?: DomMetadata;\n    saveButton?: DomMetadata;\n    cancelButton?: DomMetadata;\n  };\n};\n```\n\n## EditingButtonProps\n\n```typescript\ntype EditingButtonProps = Omit<\n  Partial<ControlBlockButtonProps>,\n  | 'onClick'\n  | 'size'\n  | 'dropdown'\n  | 'isTargetAction'\n  | 'skipRightDivider'\n  | 'tooltipText'\n>;\n```\n\n## Editing\n\n```typescript\ntype EditingCellInfo<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = ObjectForExtending,\n> = Omit<EditingCellInfoGlideInstance<R, SR, CustomCtxs>, 'column'> & {\n  column: ColumnConfig<R, SR, CustomCtxs>;\n};\n```",
      "api": [
        {
          "typeName": "EditingConfig",
          "source": "type EditingConfig<\n  RowType extends ObjectForExtending,\n  RowIdType,\n  SummaryRowType,\n> = {\n  /**\n   * Функция обработки изменений в редактируемой строке\n   */\n  onRowsChange: Maybe<\n    (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n  >;\n  /**\n   * свойство, необходимое для корректного изменения дочерних строк.\n   * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n   *\n   * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n   * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n   *\n   * @example \"child\" или \"uvh367.children\"\n   */\n  subRowsKey?: string;\n  /**\n   * Глубокое копирование строк перед применением правки в режиме редактирования.\n   *\n   * Включите, если строки, передаваемые в таблицу, иммутабельны/заморожены\n   * (напр. стейт под управлением Redux Toolkit или Immer — они вызывают\n   * Object.freeze в dev). При редактировании дочерней строки таблица записывает\n   * изменение ВНУТРЬ объекта родителя; на замороженном объекте это падает с\n   * `TypeError: Cannot assign to read only property`.\n   *\n   * Когда флаг включён, таблица сама делает structuredClone редактируемой строки\n   * перед записью — ваш иммутабельный стейт не мутируется, и редактирование\n   * дочерних строк работает без действий с вашей стороны.\n   *\n   * ⚠️ Данные строки должны быть сериализуемыми. Где доступен structuredClone —\n   * Date/Map/Set и вложенные структуры копируются корректно; на старых средах\n   * без structuredClone используется JSON-фоллбэк (теряет Date/Map/Set, undefined\n   * и функции). Не включайте без необходимости — глубокое копирование добавляет\n   * накладные расходы.\n   *\n   * @default false\n   */\n  deepCloneRows?: boolean;\n  /**\n   * Функция определения уникального id строки\n   * @param row\n   * @returns\n   */\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * Функция определения возможности редактирования строки\n   * @param row\n   * @returns\n   */\n  rowEditable?: (row: RowType) => boolean;\n  /**\n   * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n   * @default false\n   */\n  defaultEnabled?: boolean;\n  /**\n   * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n   * По умолчанию, управление происходит в компоненте.\n   * Приоритетнее, чем defaultEnabled.\n   *\n   * @type boolean - если НЕ нужно переключение в самой таблице\n   * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n   *\n   */\n  enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n   * @default true\n   */\n  showButtons?: boolean;\n  /**\n   * Функция, вызывающаяся при включении фичи.\n   * @param enableEditorMode - функция включающая режим редактирования\n   */\n  onEnableEditing?: (enableEditorMode: () => void) => void;\n  /**\n   * Функция, вызывающаяся при сохранении отредактированного.\n   * @param disableEditorMode - функция выключающая режим редактирования\n   */\n  onSave?: (disableEditorMode: () => void) => void;\n  /**\n   * Функция, вызывающаяся при отмене отредактированного.\n   * @param disableEditorMode - функция выключающая режим редактирования\n   */\n  onCancel?: (disableEditorMode: () => void) => void;\n  /** Пропсы кнопок в controlBlock. */\n  buttons?: {\n    save?: EditingButtonProps;\n    cancel?: EditingButtonProps;\n    edit?: EditingButtonProps;\n  };\n  /**\n   * Кастомный слот, отображаемый левее кнопок «Отменить» / «Сохранить».\n   * Виден только когда режим редактирования активен (editMode = true).\n   * Зона ответственности разработчика — размерная сетка controlBlock не влияет на этот слот.\n   */\n  editModeLeftSlot?: React.ReactNode;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: {\n    enableButton?: DomMetadata;\n    saveButton?: DomMetadata;\n    cancelButton?: DomMetadata;\n  };\n};"
        },
        {
          "typeName": "EditingButtonProps",
          "source": "type EditingButtonProps = Omit<\n  Partial<ControlBlockButtonProps>,\n  | 'onClick'\n  | 'size'\n  | 'dropdown'\n  | 'isTargetAction'\n  | 'skipRightDivider'\n  | 'tooltipText'\n>;"
        },
        {
          "typeName": "EditingCellInfo",
          "source": "type EditingCellInfo<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = ObjectForExtending,\n> = Omit<EditingCellInfoGlideInstance<R, SR, CustomCtxs>, 'column'> & {\n  column: ColumnConfig<R, SR, CustomCtxs>;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "Editing",
          "displayName": "Блок",
          "type": "full-code",
          "code": "() => {\n    const [rows, setRows] = useState(() => createRowsTree());\n    const columns = useMemo(\n      (): readonly ColumnConfig<TreeRow>[] => [\n        {\n          key: 'block',\n          name: 'Блок',\n          editingCell: {\n            editable: (r) => r.block === BLOCKS[1],\n            error: {\n              value: (r) => r.block === BLOCKS[0],\n            },\n            component: 'select',\n            options: {\n              type: 'constant',\n              options: BLOCKS.map((i) => ({ text: i, value: i })),\n            },\n          },\n          subRow: {\n            keyOfColumnInSubRow: (lvl) => {\n              switch (lvl) {\n                case 0:\n                  return 'block';\n                case 1:\n                  return 'tribe';\n                case 2:\n                  return 'product';\n                default:\n                  return 'block';\n              }\n            },\n            editingCell: {\n              component: 'inputString',\n              inputProps: {\n                placeholder: 'Введите значение',\n              },\n            },\n\n            isColumnWithArrow: true,\n            hideHeaderExpandAllArrow: false,\n          },\n        },\n        {\n          key: 'blockActivity',\n          name: 'Активность блока',\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'tribe',\n          name: 'Трайб',\n          editingCell: {\n            component: 'select',\n            options: {\n              type: 'stateInRowContext',\n              optionsKeyInRowContext: 'tribeOptions',\n            },\n            selectProps: {\n              listMaxHeight: '210px',\n            },\n          },\n        },\n        {\n          key: 'product',\n          name: 'Продукт',\n          editingCell: {\n            component: 'select',\n            options: {\n              type: 'stateInRowContext',\n              optionsKeyInRowContext: 'productOptions',\n            },\n          },\n        },\n        {\n          key: 'q1',\n          name: 'Q1',\n\n          editingCell: {\n            component: 'inputNumber',\n            inputProps: {\n              placeholder: 'Введите значение',\n            },\n          },\n          contentFormat: {\n            type: 'number',\n            decimalSeparator: ',',\n            thousandSeparator: ' ',\n            alignContent: 'right',\n            minimumFractionDigits: 2,\n            maximumFractionDigits: 2,\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n        {\n          key: 'q2',\n          name: 'Q2',\n          contentFormat: 'number',\n          editingCell: {\n            component: ({\n              row,\n              onRowChange,\n              column,\n              cellHeight,\n              cellWidth,\n              initialValue,\n            }) => {\n              const initialValueAsNumber =\n                initialValue && !Number.isNaN(+initialValue)\n                  ? +initialValue\n                  : null;\n\n              const [v, setV] = useState<string | number>(\n                initialValueAsNumber ??\n                  (row?.[column.key as keyof typeof row] as unknown as number),\n              );\n\n              const handleChange = (\n                _event?: React.ChangeEvent<HTMLInputElement>,\n                values?: {\n                  floatValue: number | undefined;\n                  formattedValue: string;\n                  value: string;\n                },\n              ) => {\n                if (values) {\n                  const resultValue =\n                    values.floatValue ?? values.formattedValue;\n                  setV(resultValue);\n                  onRowChange({\n                    ...row,\n                    [column.key]: resultValue,\n                  });\n                }\n              };\n              return (\n                <CellEditorNumberFormat\n                  cellHeight={cellHeight}\n                  cellWidth={cellWidth}\n                  autoFocusType={\n                    initialValueAsNumber === null\n                      ? 'autoFocusAndSelect'\n                      : 'autoFocus'\n                  }\n                  value={v}\n                  onChange={handleChange}\n                />\n              );\n            },\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'q2',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n        {\n          key: 'q3',\n          name: 'Q3',\n          contentFormat: 'number',\n\n          editingCell: { component: 'inputNumber' },\n          subRow: {\n            keyOfColumnInSubRow: 'q3',\n\n            editingCell: {\n              component: 'inputNumber',\n              error: {\n                value(_row, _treeLvl) {\n                  return true;\n                },\n              },\n            },\n          },\n        },\n        {\n          key: 'q4',\n          name: 'Q4',\n          contentFormat: 'number',\n\n          editingCell: { component: 'inputNumber' },\n          subRow: {\n            keyOfColumnInSubRow: 'q4',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n      ],\n      [],\n    );\n\n    const rowContextValue = useMemo(\n      () => ({\n        tribeOptions: TRIBES.map((i) => ({ text: i, value: i })),\n        productOptions: PRODUCTS.map((i) => ({ text: i, value: i })),\n      }),\n      [],\n    );\n    const savedRowsRef = useRef<null | typeof rows>(null);\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          enableLowDprHairline: true,\n          containerStyle: { height: '700px' },\n          rowSize: {\n            showInControl: true,\n            default: 'big',\n          },\n          editing: {\n            onEnableEditing(enableEditorMode) {\n              savedRowsRef.current = JSON.parse(JSON.stringify(rows));\n              enableEditorMode();\n            },\n            onCancel(disableEditorMode) {\n              if (savedRowsRef.current) {\n                setRows(savedRowsRef.current);\n              }\n              disableEditorMode();\n            },\n            onSave(disableEditorMode) {\n              savedRowsRef.current = null;\n              disableEditorMode();\n            },\n            onRowsChange: setRows,\n            rowKeyGetter: (r) => `${r.id}`,\n            rowEditable: (r) => r.block !== BLOCKS[1],\n          },\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          resizableColumn: true,\n        }}\n        columnConfig={columns}\n        rows={rows}\n        rowContextValue={rowContextValue}\n      />\n    );\n  }"
        },
        {
          "exportName": "EditingButtonsControl",
          "displayName": "Buttons Control (disabled, isLoading)",
          "type": "full-code",
          "code": "() => {\n    const [rows, setRows] = useState<SimpleRow[]>([\n      { id: '1', name: 'Альфа', value: 100 },\n      { id: '2', name: 'Бета', value: 200 },\n      { id: '3', name: 'Гамма', value: 300 },\n    ]);\n    const [isSaving, setIsSaving] = useState(false);\n    const savedRowsRef = useRef<SimpleRow[] | null>(null);\n\n    const columnConfig = useMemo(\n      (): ColumnConfig<SimpleRow>[] => [\n        {\n          key: 'name',\n          name: 'Название',\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'value',\n          name: 'Значение',\n          contentFormat: 'number',\n          editingCell: { component: 'inputNumber' },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '400px' },\n          editing: {\n            onRowsChange: setRows,\n            rowKeyGetter: (r) => r.id,\n            buttons: {\n              save: {\n                disabled: isSaving,\n                isLoading: isSaving,\n              },\n              cancel: {\n                disabled: isSaving,\n              },\n            },\n            onEnableEditing(enableEditorMode) {\n              savedRowsRef.current = [...rows];\n              enableEditorMode();\n            },\n            onSave(disableEditorMode) {\n              setIsSaving(true);\n              setTimeout(() => {\n                setIsSaving(false);\n                savedRowsRef.current = null;\n                disableEditorMode();\n              }, 2000);\n            },\n            onCancel(disableEditorMode) {\n              if (savedRowsRef.current) {\n                setRows(savedRowsRef.current);\n              }\n              disableEditorMode();\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "EditingInModal",
          "displayName": "Блок",
          "type": "full-code",
          "code": "() => {\n    const [rows, setRows] = useState(() => createRowsTree());\n    const columns = useMemo(\n      (): readonly ColumnConfig<TreeRow>[] => [\n        {\n          key: 'block',\n          name: 'Блок',\n          editingCell: {\n            editable: (r) => r.block === BLOCKS[1],\n            error: {\n              value: (r) => r.block === BLOCKS[0],\n            },\n            component: 'select',\n            options: {\n              type: 'constant',\n              options: BLOCKS.map((i) => ({ text: i, value: i })),\n            },\n          },\n          subRow: {\n            keyOfColumnInSubRow: (lvl) => {\n              switch (lvl) {\n                case 0:\n                  return 'block';\n                case 1:\n                  return 'tribe';\n                case 2:\n                  return 'product';\n                default:\n                  return 'block';\n              }\n            },\n            editingCell: {\n              component: 'inputString',\n              inputProps: {\n                placeholder: 'Введите значение',\n              },\n            },\n\n            isColumnWithArrow: true,\n            hideHeaderExpandAllArrow: false,\n          },\n        },\n        {\n          key: 'blockActivity',\n          name: 'Активность блока',\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'tribe',\n          name: 'Трайб',\n          editingCell: {\n            component: 'select',\n            options: {\n              type: 'stateInRowContext',\n              optionsKeyInRowContext: 'tribeOptions',\n            },\n            selectProps: {\n              listMaxHeight: '210px',\n            },\n          },\n        },\n        {\n          key: 'product',\n          name: 'Продукт',\n          editingCell: {\n            component: 'select',\n            options: {\n              type: 'stateInRowContext',\n              optionsKeyInRowContext: 'productOptions',\n            },\n          },\n        },\n        {\n          key: 'q1',\n          name: 'Q1',\n\n          editingCell: {\n            component: 'inputNumber',\n            inputProps: {\n              placeholder: 'Введите значение',\n            },\n          },\n          contentFormat: {\n            type: 'number',\n            decimalSeparator: ',',\n            thousandSeparator: ' ',\n            alignContent: 'right',\n            minimumFractionDigits: 2,\n            maximumFractionDigits: 2,\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n        {\n          key: 'q2',\n          name: 'Q2',\n          contentFormat: 'number',\n          editingCell: {\n            component: ({\n              row,\n              onRowChange,\n              column,\n              cellHeight,\n              cellWidth,\n              initialValue,\n            }) => {\n              const initialValueAsNumber =\n                initialValue && !Number.isNaN(+initialValue)\n                  ? +initialValue\n                  : null;\n\n              const [v, setV] = useState<string | number>(\n                initialValueAsNumber ??\n                  (row?.[column.key as keyof typeof row] as unknown as number),\n              );\n\n              const handleChange = (\n                _event?: React.ChangeEvent<HTMLInputElement>,\n                values?: {\n                  floatValue: number | undefined;\n                  formattedValue: string;\n                  value: string;\n                },\n              ) => {\n                if (values) {\n                  const resultValue =\n                    values.floatValue ?? values.formattedValue;\n                  setV(resultValue);\n                  onRowChange({\n                    ...row,\n                    [column.key]: resultValue,\n                  });\n                }\n              };\n              return (\n                <CellEditorNumberFormat\n                  cellHeight={cellHeight}\n                  cellWidth={cellWidth}\n                  autoFocusType={\n                    initialValueAsNumber === null\n                      ? 'autoFocusAndSelect'\n                      : 'autoFocus'\n                  }\n                  value={v}\n                  onChange={handleChange}\n                />\n              );\n            },\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'q2',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n        {\n          key: 'q3',\n          name: 'Q3',\n          contentFormat: 'number',\n\n          editingCell: { component: 'inputNumber' },\n          subRow: {\n            keyOfColumnInSubRow: 'q3',\n\n            editingCell: {\n              component: 'inputNumber',\n              error: {\n                value(_row, _treeLvl) {\n                  return true;\n                },\n              },\n            },\n          },\n        },\n        {\n          key: 'q4',\n          name: 'Q4',\n          contentFormat: 'number',\n\n          editingCell: { component: 'inputNumber' },\n          subRow: {\n            keyOfColumnInSubRow: 'q4',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n      ],\n      [],\n    );\n\n    const rowContextValue = useMemo(\n      () => ({\n        tribeOptions: TRIBES.map((i) => ({ text: i, value: i })),\n        productOptions: PRODUCTS.map((i) => ({ text: i, value: i })),\n      }),\n      [],\n    );\n    const savedRowsRef = useRef<null | typeof rows>(null);\n    const [opened, setOpened] = useState(false);\n    return (\n      <>\n        <Button type=\"button\" onClick={() => setOpened((prev) => !prev)}>\n          Toggle Modal\n        </Button>\n        <ModalDF opened={opened} onClose={() => setOpened(false)}>\n          <ModalDF.Main>\n            <ModalDF.Header\n              title=\"Режим редактирования внутри модальных окон\"\n              badge={{ text: `tableConfig.editorOverlayPortal: 'inside'` }}\n            />\n            <ModalDF.Content>\n              <TableCanvas\n                tableConfig={{\n                  // КЛЮЧЕВОЕ СВОЙСТВО ДЛЯ КОРРЕКТНОЙ РАБОТЫ РЕЖИМА РЕДАКТИРОВАНИЯ ВНУТРИ МОДАЛЬНЫХ ОКОН\n                  editorOverlayPortal: 'inside',\n                  //\n                  containerStyle: {\n                    height: '60vh',\n                    width: '80vw',\n                  },\n                  rowSize: {\n                    showInControl: true,\n                    default: 'big',\n                  },\n                  editing: {\n                    defaultEnabled: true,\n                    onEnableEditing(enableEditorMode) {\n                      savedRowsRef.current = JSON.parse(JSON.stringify(rows));\n                      enableEditorMode();\n                    },\n                    onCancel(disableEditorMode) {\n                      if (savedRowsRef.current) {\n                        setRows(savedRowsRef.current);\n                      }\n                      disableEditorMode();\n                    },\n                    onSave(disableEditorMode) {\n                      savedRowsRef.current = null;\n                      disableEditorMode();\n                    },\n                    onRowsChange: setRows,\n                    rowKeyGetter: (r) => `${r.id}`,\n                    rowEditable: (r) => r.block !== BLOCKS[1],\n                  },\n                  subRows: {\n                    getSubRows: (row) => row?.subRows,\n                    rowKeyGetter: (row) => row.id,\n                  },\n                  resizableColumn: true,\n                }}\n                columnConfig={columns}\n                rows={rows}\n                rowContextValue={rowContextValue}\n              />\n            </ModalDF.Content>\n          </ModalDF.Main>\n        </ModalDF>\n      </>\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "EmptyState",
      "legacy": false,
      "summary": "*tableConfig.emptyState**",
      "docs": "# TableCanvas Empty State\n\n**tableConfig.emptyState**\n\nПустое состояние таблицы. Показывается после завершения загрузки, когда для текущих фильтров, поиска или ответа бэкенда нет строк для отображения.\n\n## Что показывают сценарии\n\n- `Default Empty State` показывает дефолтное состояние таблицы после загрузки.\n- `Custom Empty State` показывает, как переопределять `title`, `subtitle`, `variant` и `buttons`.\n- `Grouped Columns Empty State` демонстрирует, что grouped headers остаются видимыми.\n- `Full Content Empty State Without Headers` имитирует сценарий, когда схема колонок не пришла с бэкенда и state занимает всю content-область.\n- `Empty State With Control Block And Pagination` проверяет совместимость состояния с control block, pagination и настройкой размера строк.",
      "apiDocs": "# TableCanvas Empty State API\n\nКонфиг пустого состояния (`tableConfig.emptyState`). Показывается внутри\ncontent-области; control block, шапка колонок и pagination остаются видимыми.\nОбъект с обязательным флагом `enabled`.\n\n## TableCanvasEmptyStateConfig\n\n```typescript\ntype TableCanvasEmptyStateConfig = TableCanvasContentStateBase &\n  Partial<EmptyStateProps>;\n```\n\n## TableCanvasContentStateBase\n\n```typescript\ntype TableCanvasContentStateBase = {\n  /**\n   * Включено ли состояние.\n   */\n  enabled: boolean;\n  /**\n   * Полностью кастомный контент состояния вместо дефолтного EmptyState.\n   */\n  custom?: ReactNode;\n};\n```\n\n## EmptyStateProps\n\n```typescript\ntype EmptyStateProps = {\n  /**\n   * Размер компонента (small, medium, large)\n   *   */\n  size: 's' | 'm' | 'l';\n  /**\n   * Основной заголовок состояния\n   *   */\n  title?: ReactNode;\n  /**\n   * Дополнительный поясняющий текст\n   *   */\n  subtitle?: ReactNode;\n  /**\n   * Вариант изображения для отображения\n   * Поддерживаются варианты EmptyState (loading, life-circle, need-access, no-access, no-content, not-found, not-result)\n   * и варианты ErrorPage (400, 401, 403, 404, 500, 502, 503, unidentified)\n   */\n  variant?: EmptyStateImageVariant;\n  /**\n   * @deprecated Используйте prop `variant` для отображения изображений.\n   * Компонент иконки (только для size='m' или для size='s')\n   * Оставлено для обратной совместимости.\n   */\n  icon?: React.FC<IconProps>;\n  /**\n   * @deprecated Используйте prop `variant` для отображения изображений.\n   * Дополнительные пропсы для иконки\n   * Оставлено для обратной совместимости.\n   */\n  iconProps?: Omit<IconProps, 'size'>;\n  /**\n   * Массив кнопок (до 2 для size='l', до 1 для других размеров)\n   */\n  buttons?: EmptyStateButtonProps[];\n  /**\n   * Дополнительная кнопка (только для size='l')\n   */\n  extraButton?: EmptyStateButtonProps;\n  /**\n   * Дополнительный класс для корневого элемента\n   */\n  className?: string;\n  /**\n   * Объект с классами для внутренних элементов\n   */\n  classes?: EmptyStateClasses;\n  /**\n   * Центрировать контент по вертикали и горизонтали\n   */\n  centered?: boolean;\n  /**\n   * Кастомные CSS-стили для контейнера\n   */\n  $css?: string | CSSObject | FlattenSimpleInterpolation;\n};\n```\n\n## EmptyStateButtonProps\n\n```typescript\ntype EmptyStateButtonProps = ButtonVariant | LinkButtonVariant;\n```\n\n## EmptyStateImageVariant\n\n```typescript\ntype EmptyStateImageVariant = EmptyStateVariant | ErrorPageVariant;\n```\n\n## EmptyStateVariant\n\n```typescript\ntype EmptyStateVariant =\n  | 'loading'\n  | 'life-circle'\n  | 'need-access'\n  | 'no-access'\n  | 'no-content'\n  | 'not-found'\n  /** @deprecated Используйте `'not-found'` */\n  | 'not-result'\n  | 'success';\n```\n\n## ErrorPageVariant\n\n```typescript\ntype ErrorPageVariant =\n  | '400'\n  | '401'\n  | '403'\n  | '404'\n  | '409'\n  | '500'\n  | '502'\n  | '503'\n  | 'unidentified';\n```",
      "api": [
        {
          "typeName": "TableCanvasEmptyStateConfig",
          "source": "type TableCanvasEmptyStateConfig = TableCanvasContentStateBase &\n  Partial<EmptyStateProps>;"
        },
        {
          "typeName": "TableCanvasContentStateBase",
          "source": "type TableCanvasContentStateBase = {\n  /**\n   * Включено ли состояние.\n   */\n  enabled: boolean;\n  /**\n   * Полностью кастомный контент состояния вместо дефолтного EmptyState.\n   */\n  custom?: ReactNode;\n};"
        },
        {
          "typeName": "EmptyStateProps",
          "source": "type EmptyStateProps = {\n  /**\n   * Размер компонента (small, medium, large)\n   *   */\n  size: 's' | 'm' | 'l';\n  /**\n   * Основной заголовок состояния\n   *   */\n  title?: ReactNode;\n  /**\n   * Дополнительный поясняющий текст\n   *   */\n  subtitle?: ReactNode;\n  /**\n   * Вариант изображения для отображения\n   * Поддерживаются варианты EmptyState (loading, life-circle, need-access, no-access, no-content, not-found, not-result)\n   * и варианты ErrorPage (400, 401, 403, 404, 500, 502, 503, unidentified)\n   */\n  variant?: EmptyStateImageVariant;\n  /**\n   * @deprecated Используйте prop `variant` для отображения изображений.\n   * Компонент иконки (только для size='m' или для size='s')\n   * Оставлено для обратной совместимости.\n   */\n  icon?: React.FC<IconProps>;\n  /**\n   * @deprecated Используйте prop `variant` для отображения изображений.\n   * Дополнительные пропсы для иконки\n   * Оставлено для обратной совместимости.\n   */\n  iconProps?: Omit<IconProps, 'size'>;\n  /**\n   * Массив кнопок (до 2 для size='l', до 1 для других размеров)\n   */\n  buttons?: EmptyStateButtonProps[];\n  /**\n   * Дополнительная кнопка (только для size='l')\n   */\n  extraButton?: EmptyStateButtonProps;\n  /**\n   * Дополнительный класс для корневого элемента\n   */\n  className?: string;\n  /**\n   * Объект с классами для внутренних элементов\n   */\n  classes?: EmptyStateClasses;\n  /**\n   * Центрировать контент по вертикали и горизонтали\n   */\n  centered?: boolean;\n  /**\n   * Кастомные CSS-стили для контейнера\n   */\n  $css?: string | CSSObject | FlattenSimpleInterpolation;\n};"
        },
        {
          "typeName": "EmptyStateButtonProps",
          "source": "type EmptyStateButtonProps = ButtonVariant | LinkButtonVariant;"
        },
        {
          "typeName": "EmptyStateImageVariant",
          "source": "type EmptyStateImageVariant = EmptyStateVariant | ErrorPageVariant;"
        },
        {
          "typeName": "EmptyStateVariant",
          "source": "type EmptyStateVariant =\n  | 'loading'\n  | 'life-circle'\n  | 'need-access'\n  | 'no-access'\n  | 'no-content'\n  | 'not-found'\n  /** @deprecated Используйте `'not-found'` */\n  | 'not-result'\n  | 'success';"
        },
        {
          "typeName": "ErrorPageVariant",
          "source": "type ErrorPageVariant =\n  | '400'\n  | '401'\n  | '403'\n  | '404'\n  | '409'\n  | '500'\n  | '502'\n  | '503'\n  | 'unidentified';"
        }
      ],
      "stories": [
        {
          "exportName": "DefaultEmptyState",
          "displayName": "Default Empty State",
          "type": "full-code",
          "code": "import type { EmptyStateProps } from '@daisforge/ui';\nimport {\n  ColumnOrColumnGroupConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\nimport React, { ReactNode, useEffect, useState } from 'react';\n\ntype Row = {\n  id: string;\n  name: string;\n  status: string;\n  team: string;\n};\n\ntype EmptyStateStoryConfig =\n  {\n    enabled: boolean;\n    custom?: ReactNode;\n  } & Partial<EmptyStateProps>;\n\nconst TABLE_HEIGHT = 480;\nconst LOADING_DELAY_MS = 1200;\nconst EMPTY_ROWS: Row[] = [];\n\nconst flatColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  { key: 'id', name: 'ID' },\n  { key: 'name', name: 'Сотрудник' },\n  { key: 'status', name: 'Статус' },\n  { key: 'team', name: 'Команда' },\n];\n\nconst groupedColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  {\n    key: 'employee-group',\n    name: 'Сотрудник',\n    children: [\n      { key: 'id', name: 'ID' },\n      { key: 'name', name: 'ФИО' },\n    ],\n  },\n  {\n    key: 'meta-group',\n    name: 'Статус и команда',\n    children: [\n      { key: 'status', name: 'Статус' },\n      { key: 'team', name: 'Команда' },\n    ],\n  },\n];\n\nconst emptyColumns: readonly ColumnOrColumnGroupConfig<Row>[] = [];\n\nfunction useLoadingColumns(\n  initialColumns: readonly ColumnOrColumnGroupConfig<Row>[],\n  finalColumns: readonly ColumnOrColumnGroupConfig<Row>[]\n) {\n  const [isLoading, setIsLoading] = useState(true);\n  const [columnConfig, setColumnConfig] = useState(initialColumns);\n\n  useEffect(() => {\n    setIsLoading(true);\n    setColumnConfig(initialColumns);\n\n    const timeoutId = setTimeout(() => {\n      setColumnConfig(finalColumns);\n      setIsLoading(false);\n    }, LOADING_DELAY_MS);\n\n    return () => clearTimeout(timeoutId);\n  }, [finalColumns, initialColumns]);\n\n  return { columnConfig, isLoading };\n}\n\n() => {\n    const { columnConfig, isLoading } = useLoadingColumns(\n      flatColumnConfig,\n      flatColumnConfig,\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: TABLE_HEIGHT },\n          isLoading: {\n            boolean: isLoading,\n            skeletonRowsCount: 5,\n          },\n          loadingOverlay: {\n            active: isLoading,\n            subtitle: 'Имитируем загрузку перед переходом к emptyState.',\n          },\n          emptyState: isLoading ? undefined : { enabled: true },\n        }}\n        columnConfig={columnConfig}\n        rows={EMPTY_ROWS}\n      />\n    );\n  }"
        },
        {
          "exportName": "CustomEmptyState",
          "displayName": "Custom Empty State",
          "type": "full-code",
          "code": "import type { EmptyStateProps } from '@daisforge/ui';\nimport {\n  ColumnOrColumnGroupConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\nimport React, { ReactNode, useEffect, useState } from 'react';\n\ntype Row = {\n  id: string;\n  name: string;\n  status: string;\n  team: string;\n};\n\ntype EmptyStateStoryConfig =\n  {\n    enabled: boolean;\n    custom?: ReactNode;\n  } & Partial<EmptyStateProps>;\n\nconst TABLE_HEIGHT = 480;\nconst LOADING_DELAY_MS = 1200;\nconst EMPTY_ROWS: Row[] = [];\n\nconst flatColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  { key: 'id', name: 'ID' },\n  { key: 'name', name: 'Сотрудник' },\n  { key: 'status', name: 'Статус' },\n  { key: 'team', name: 'Команда' },\n];\n\nconst groupedColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  {\n    key: 'employee-group',\n    name: 'Сотрудник',\n    children: [\n      { key: 'id', name: 'ID' },\n      { key: 'name', name: 'ФИО' },\n    ],\n  },\n  {\n    key: 'meta-group',\n    name: 'Статус и команда',\n    children: [\n      { key: 'status', name: 'Статус' },\n      { key: 'team', name: 'Команда' },\n    ],\n  },\n];\n\nconst emptyColumns: readonly ColumnOrColumnGroupConfig<Row>[] = [];\n\nfunction useLoadingColumns(\n  initialColumns: readonly ColumnOrColumnGroupConfig<Row>[],\n  finalColumns: readonly ColumnOrColumnGroupConfig<Row>[]\n) {\n  const [isLoading, setIsLoading] = useState(true);\n  const [columnConfig, setColumnConfig] = useState(initialColumns);\n\n  useEffect(() => {\n    setIsLoading(true);\n    setColumnConfig(initialColumns);\n\n    const timeoutId = setTimeout(() => {\n      setColumnConfig(finalColumns);\n      setIsLoading(false);\n    }, LOADING_DELAY_MS);\n\n    return () => clearTimeout(timeoutId);\n  }, [finalColumns, initialColumns]);\n\n  return { columnConfig, isLoading };\n}\n\n() => {\n    const { columnConfig, isLoading } = useLoadingColumns(\n      flatColumnConfig,\n      flatColumnConfig,\n    );\n\n    const emptyState: EmptyStateStoryConfig = {\n      enabled: true,\n      title: 'Нет заявок для выбранного периода',\n      subtitle: 'Измените фильтры или создайте новую заявку.',\n      variant: 'no-content',\n      buttons: [\n        {\n          type: 'button',\n          props: {\n            children: 'Создать заявку',\n            view: 'accent',\n            onClick: () => undefined,\n          },\n        },\n      ],\n    };\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: TABLE_HEIGHT },\n          isLoading: {\n            boolean: isLoading,\n            skeletonRowsCount: 5,\n          },\n          loadingOverlay: {\n            active: isLoading,\n            subtitle: 'Сначала показываем loading, затем кастомный emptyState.',\n          },\n          emptyState: isLoading ? undefined : emptyState,\n        }}\n        columnConfig={columnConfig}\n        rows={EMPTY_ROWS}\n      />\n    );\n  }"
        },
        {
          "exportName": "GroupedColumnsEmptyState",
          "displayName": "Grouped Columns Empty State",
          "type": "full-code",
          "code": "import type { EmptyStateProps } from '@daisforge/ui';\nimport {\n  ColumnOrColumnGroupConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\nimport React, { ReactNode, useEffect, useState } from 'react';\n\ntype Row = {\n  id: string;\n  name: string;\n  status: string;\n  team: string;\n};\n\ntype EmptyStateStoryConfig =\n  {\n    enabled: boolean;\n    custom?: ReactNode;\n  } & Partial<EmptyStateProps>;\n\nconst TABLE_HEIGHT = 480;\nconst LOADING_DELAY_MS = 1200;\nconst EMPTY_ROWS: Row[] = [];\n\nconst flatColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  { key: 'id', name: 'ID' },\n  { key: 'name', name: 'Сотрудник' },\n  { key: 'status', name: 'Статус' },\n  { key: 'team', name: 'Команда' },\n];\n\nconst groupedColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  {\n    key: 'employee-group',\n    name: 'Сотрудник',\n    children: [\n      { key: 'id', name: 'ID' },\n      { key: 'name', name: 'ФИО' },\n    ],\n  },\n  {\n    key: 'meta-group',\n    name: 'Статус и команда',\n    children: [\n      { key: 'status', name: 'Статус' },\n      { key: 'team', name: 'Команда' },\n    ],\n  },\n];\n\nconst emptyColumns: readonly ColumnOrColumnGroupConfig<Row>[] = [];\n\nfunction useLoadingColumns(\n  initialColumns: readonly ColumnOrColumnGroupConfig<Row>[],\n  finalColumns: readonly ColumnOrColumnGroupConfig<Row>[]\n) {\n  const [isLoading, setIsLoading] = useState(true);\n  const [columnConfig, setColumnConfig] = useState(initialColumns);\n\n  useEffect(() => {\n    setIsLoading(true);\n    setColumnConfig(initialColumns);\n\n    const timeoutId = setTimeout(() => {\n      setColumnConfig(finalColumns);\n      setIsLoading(false);\n    }, LOADING_DELAY_MS);\n\n    return () => clearTimeout(timeoutId);\n  }, [finalColumns, initialColumns]);\n\n  return { columnConfig, isLoading };\n}\n\n() => {\n    const { columnConfig, isLoading } = useLoadingColumns(\n      groupedColumnConfig,\n      groupedColumnConfig,\n    );\n\n    const emptyState: EmptyStateStoryConfig = {\n      enabled: true,\n      title: 'Нет результатов по выбранным фильтрам',\n      subtitle:\n        'Grouped headers остаются видимыми, а empty state отображается ниже шапки таблицы.',\n      variant: 'not-result',\n    };\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: TABLE_HEIGHT },\n          isLoading: {\n            boolean: isLoading,\n            skeletonRowsCount: 5,\n          },\n          loadingOverlay: {\n            active: isLoading,\n            subtitle:\n              'Проверяем переход loading -> emptyState при группировке колонок.',\n          },\n          emptyState: isLoading ? undefined : emptyState,\n        }}\n        columnConfig={columnConfig}\n        rows={EMPTY_ROWS}\n      />\n    );\n  }"
        },
        {
          "exportName": "FullContentEmptyStateWithoutHeaders",
          "displayName": "Full Content Empty State Without Headers",
          "type": "full-code",
          "code": "import type { EmptyStateProps } from '@daisforge/ui';\nimport {\n  ColumnOrColumnGroupConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\nimport React, { ReactNode, useEffect, useState } from 'react';\n\ntype Row = {\n  id: string;\n  name: string;\n  status: string;\n  team: string;\n};\n\ntype EmptyStateStoryConfig =\n  {\n    enabled: boolean;\n    custom?: ReactNode;\n  } & Partial<EmptyStateProps>;\n\nconst TABLE_HEIGHT = 480;\nconst LOADING_DELAY_MS = 1200;\nconst EMPTY_ROWS: Row[] = [];\n\nconst flatColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  { key: 'id', name: 'ID' },\n  { key: 'name', name: 'Сотрудник' },\n  { key: 'status', name: 'Статус' },\n  { key: 'team', name: 'Команда' },\n];\n\nconst groupedColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  {\n    key: 'employee-group',\n    name: 'Сотрудник',\n    children: [\n      { key: 'id', name: 'ID' },\n      { key: 'name', name: 'ФИО' },\n    ],\n  },\n  {\n    key: 'meta-group',\n    name: 'Статус и команда',\n    children: [\n      { key: 'status', name: 'Статус' },\n      { key: 'team', name: 'Команда' },\n    ],\n  },\n];\n\nconst emptyColumns: readonly ColumnOrColumnGroupConfig<Row>[] = [];\n\nfunction useLoadingColumns(\n  initialColumns: readonly ColumnOrColumnGroupConfig<Row>[],\n  finalColumns: readonly ColumnOrColumnGroupConfig<Row>[]\n) {\n  const [isLoading, setIsLoading] = useState(true);\n  const [columnConfig, setColumnConfig] = useState(initialColumns);\n\n  useEffect(() => {\n    setIsLoading(true);\n    setColumnConfig(initialColumns);\n\n    const timeoutId = setTimeout(() => {\n      setColumnConfig(finalColumns);\n      setIsLoading(false);\n    }, LOADING_DELAY_MS);\n\n    return () => clearTimeout(timeoutId);\n  }, [finalColumns, initialColumns]);\n\n  return { columnConfig, isLoading };\n}\n\n() => {\n    const { columnConfig, isLoading } = useLoadingColumns(\n      emptyColumns,\n      emptyColumns,\n    );\n\n    const emptyState: EmptyStateStoryConfig = {\n      enabled: true,\n      title: 'Не удалось получить схему таблицы',\n      subtitle:\n        'Колонки не пришли с бэкенда, поэтому после loading emptyState занимает всю content-область без заголовков.',\n      variant: 'not-result',\n    };\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: TABLE_HEIGHT },\n          isLoading: {\n            boolean: isLoading,\n            skeletonRowsCount: 5,\n          },\n          loadingOverlay: {\n            active: isLoading,\n            subtitle:\n              'Сначала ждём схему колонок с бэкенда, затем показываем full-content emptyState.',\n          },\n          emptyState: isLoading ? undefined : emptyState,\n        }}\n        columnConfig={columnConfig}\n        rows={EMPTY_ROWS}\n      />\n    );\n  }"
        },
        {
          "exportName": "EmptyStateWithControlBlockAndPagination",
          "displayName": "Empty State With Control Block And Pagination",
          "type": "full-code",
          "code": "import type { EmptyStateProps } from '@daisforge/ui';\nimport {\n  ColumnOrColumnGroupConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\nimport React, { ReactNode, useEffect, useState } from 'react';\n\ntype Row = {\n  id: string;\n  name: string;\n  status: string;\n  team: string;\n};\n\ntype EmptyStateStoryConfig =\n  {\n    enabled: boolean;\n    custom?: ReactNode;\n  } & Partial<EmptyStateProps>;\n\nconst TABLE_HEIGHT = 480;\nconst LOADING_DELAY_MS = 1200;\nconst EMPTY_ROWS: Row[] = [];\n\nconst flatColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  { key: 'id', name: 'ID' },\n  { key: 'name', name: 'Сотрудник' },\n  { key: 'status', name: 'Статус' },\n  { key: 'team', name: 'Команда' },\n];\n\nconst groupedColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  {\n    key: 'employee-group',\n    name: 'Сотрудник',\n    children: [\n      { key: 'id', name: 'ID' },\n      { key: 'name', name: 'ФИО' },\n    ],\n  },\n  {\n    key: 'meta-group',\n    name: 'Статус и команда',\n    children: [\n      { key: 'status', name: 'Статус' },\n      { key: 'team', name: 'Команда' },\n    ],\n  },\n];\n\nconst emptyColumns: readonly ColumnOrColumnGroupConfig<Row>[] = [];\n\nfunction useLoadingColumns(\n  initialColumns: readonly ColumnOrColumnGroupConfig<Row>[],\n  finalColumns: readonly ColumnOrColumnGroupConfig<Row>[]\n) {\n  const [isLoading, setIsLoading] = useState(true);\n  const [columnConfig, setColumnConfig] = useState(initialColumns);\n\n  useEffect(() => {\n    setIsLoading(true);\n    setColumnConfig(initialColumns);\n\n    const timeoutId = setTimeout(() => {\n      setColumnConfig(finalColumns);\n      setIsLoading(false);\n    }, LOADING_DELAY_MS);\n\n    return () => clearTimeout(timeoutId);\n  }, [finalColumns, initialColumns]);\n\n  return { columnConfig, isLoading };\n}\n\n() => {\n    const { columnConfig, isLoading } = useLoadingColumns(\n      flatColumnConfig,\n      flatColumnConfig,\n    );\n    const [currentPage, setCurrentPage] = useState(1);\n    const [perPage, setPerPage] = useState(20);\n\n    const emptyState: EmptyStateStoryConfig = {\n      enabled: true,\n      title: 'Нет записей на текущей странице',\n      subtitle:\n        'Проверяем, что состояние не ломает control block, пагинацию и настройку размера строк.',\n      variant: 'not-result',\n    };\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: TABLE_HEIGHT },\n          rowSize: {\n            default: 'big',\n            showInControl: true,\n          },\n          controlBlock: {\n            rightSideInner: [\n              {\n                text: 'Экспорт',\n                view: 'linkAccent',\n                onClick: () => undefined,\n              },\n            ],\n          },\n          pagination: {\n            count: 48,\n            perPage,\n            value: currentPage,\n            responsiveSlots: true,\n            onChangePageValue(page, scrollToTop) {\n              if (typeof page === 'number') {\n                setCurrentPage(page);\n                scrollToTop();\n              }\n            },\n            async onChange(page, nextPerPage, scrollToTop) {\n              if (typeof page === 'number' && typeof nextPerPage === 'number') {\n                setCurrentPage(page);\n                setPerPage(nextPerPage);\n                scrollToTop();\n              }\n            },\n          },\n          isLoading: {\n            boolean: isLoading,\n            skeletonRowsCount: 5,\n          },\n          loadingOverlay: {\n            active: isLoading,\n            subtitle:\n              'Сначала показываем loading, затем проверяем emptyState в окружении control block и pagination.',\n          },\n          emptyState: isLoading ? undefined : emptyState,\n        }}\n        columnConfig={columnConfig}\n        rows={EMPTY_ROWS}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "ErrorState",
      "legacy": false,
      "summary": "*tableConfig.errorState**",
      "docs": "# TableCanvas Error State\n\n**tableConfig.errorState**\n\nСостояние ошибки таблицы. Показывается после завершения загрузки, если данные или схема таблицы не были получены корректно.\n\n## Что показывают сценарии\n\n- `Default Error State` показывает дефолтный `ErrorPage` после завершения loading.\n- `Custom Error State` показывает настройку через `statusCode`, `customStatuses` и `buttonHandler`.\n- `Grouped Columns Error State` демонстрирует overlay ниже grouped headers.\n- `Full Content Error State Without Headers` имитирует сценарий, когда схема колонок не пришла с бэкенда и error state занимает всю content-область.\n- `Error State With Control Block And Pagination` проверяет совместимость состояния с control block, pagination и настройкой размера строк.",
      "apiDocs": "# TableCanvas Error State API\n\nКонфиг состояния задаётся объектом с обязательным флагом `enabled`.\n\n## TableCanvasErrorStateConfig\n\n<!-- TypeSourceViewer: TableCanvasErrorStateConfig из packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts (не найден в types.string.json) -->\n\n## ErrorPageProps\n\n```typescript\ntype ErrorPageProps = {\n  /**\n   * `statusCode` - статус-код ошибки. Поддерживаются по умолчанию: 400 | 403 | 404 | 409 | 500 | 502 | 503\n   */\n  statusCode?: StatusCode;\n  /**\n   * `buttonHandler` - обработка клика по кнопке при разных ошибках\n   */\n  buttonHandler?: (\n    statusCode: StatusCode,\n    statusObj: CustomStatusObj,\n    e: React.MouseEvent<HTMLElement, MouseEvent>,\n  ) => void;\n  /**\n   * `customStatuses` - кастомные статусы и содержимое для их отображения.\n   * Если переданы статусы, которые компонентом по умолчанию поддерживаются, то кастомный перезапишет дефолтный.\n   */\n  customStatuses?: Record<number, CustomStatusObj>;\n  /**\n   * `unknownStatus` - содержимое для отображения, если статус не передан или статуса нет среди известных.\n   *\n   * Если данное свойство не передано, то при неизвестных статусах будет выбрано отображение по умолчанию.\n   */\n  unknownStatus?: CustomStatusObj;\n  /**\n   * `containerProps` - Пропсы для контейнера компонента. Например, `$css`, `style`.\n   */\n  containerProps?: BoxProps;\n  /**\n   * Показывать код ошибки перед заголовком. Например, \"503: Сервис временно недоступен\"\n   * @default false\n   */\n  showStatusCode?: boolean;\n  /**\n   * Идентификатор ошибки. Отображается под кнопками (или под subtitle, если кнопок нет).\n   * Формат отображения: \"Идентификатор ошибки: {значение}\"\n   */\n  errorId?: string;\n  /**\n   * Размер страницы ошибки. Влияет на изображение, типографику и отступы\n   * (размерная сетка та же, что у `EmptyState`).\n   * @default 'l'\n   */\n  size?: 's' | 'm' | 'l';\n};\n```\n\n## CustomStatusObj\n\n```typescript\ntype CustomStatusObj = {\n  title: ReactNode;\n  description: ReactNode;\n  button?: StatusButton;\n  buttons?: StatusButton[];\n};\n```",
      "api": [
        {
          "typeName": "ErrorPageProps",
          "source": "type ErrorPageProps = {\n  /**\n   * `statusCode` - статус-код ошибки. Поддерживаются по умолчанию: 400 | 403 | 404 | 409 | 500 | 502 | 503\n   */\n  statusCode?: StatusCode;\n  /**\n   * `buttonHandler` - обработка клика по кнопке при разных ошибках\n   */\n  buttonHandler?: (\n    statusCode: StatusCode,\n    statusObj: CustomStatusObj,\n    e: React.MouseEvent<HTMLElement, MouseEvent>,\n  ) => void;\n  /**\n   * `customStatuses` - кастомные статусы и содержимое для их отображения.\n   * Если переданы статусы, которые компонентом по умолчанию поддерживаются, то кастомный перезапишет дефолтный.\n   */\n  customStatuses?: Record<number, CustomStatusObj>;\n  /**\n   * `unknownStatus` - содержимое для отображения, если статус не передан или статуса нет среди известных.\n   *\n   * Если данное свойство не передано, то при неизвестных статусах будет выбрано отображение по умолчанию.\n   */\n  unknownStatus?: CustomStatusObj;\n  /**\n   * `containerProps` - Пропсы для контейнера компонента. Например, `$css`, `style`.\n   */\n  containerProps?: BoxProps;\n  /**\n   * Показывать код ошибки перед заголовком. Например, \"503: Сервис временно недоступен\"\n   * @default false\n   */\n  showStatusCode?: boolean;\n  /**\n   * Идентификатор ошибки. Отображается под кнопками (или под subtitle, если кнопок нет).\n   * Формат отображения: \"Идентификатор ошибки: {значение}\"\n   */\n  errorId?: string;\n  /**\n   * Размер страницы ошибки. Влияет на изображение, типографику и отступы\n   * (размерная сетка та же, что у `EmptyState`).\n   * @default 'l'\n   */\n  size?: 's' | 'm' | 'l';\n};"
        },
        {
          "typeName": "CustomStatusObj",
          "source": "type CustomStatusObj = {\n  title: ReactNode;\n  description: ReactNode;\n  button?: StatusButton;\n  buttons?: StatusButton[];\n};"
        }
      ],
      "stories": [
        {
          "exportName": "DefaultErrorState",
          "displayName": "Default Error State",
          "type": "full-code",
          "code": "import type { ErrorPageProps } from '@daisforge/ui';\nimport {\n  ColumnOrColumnGroupConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\nimport React, { ReactNode, useEffect, useState } from 'react';\n\ntype Row = {\n  id: string;\n  name: string;\n  status: string;\n  team: string;\n};\n\ntype ErrorStateStoryConfig =\n  {\n    enabled: boolean;\n    custom?: ReactNode;\n  } & Partial<ErrorPageProps>;\n\nconst TABLE_HEIGHT = 480;\nconst LOADING_DELAY_MS = 1200;\nconst EMPTY_ROWS: Row[] = [];\n\nconst flatColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  { key: 'id', name: 'ID' },\n  { key: 'name', name: 'Сотрудник' },\n  { key: 'status', name: 'Статус' },\n  { key: 'team', name: 'Команда' },\n];\n\nconst groupedColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  {\n    key: 'employee-group',\n    name: 'Сотрудник',\n    children: [\n      { key: 'id', name: 'ID' },\n      { key: 'name', name: 'ФИО' },\n    ],\n  },\n  {\n    key: 'meta-group',\n    name: 'Статус и команда',\n    children: [\n      { key: 'status', name: 'Статус' },\n      { key: 'team', name: 'Команда' },\n    ],\n  },\n];\n\nconst emptyColumns: readonly ColumnOrColumnGroupConfig<Row>[] = [];\n\nfunction useLoadingColumns(\n  initialColumns: readonly ColumnOrColumnGroupConfig<Row>[],\n  finalColumns: readonly ColumnOrColumnGroupConfig<Row>[]\n) {\n  const [isLoading, setIsLoading] = useState(true);\n  const [columnConfig, setColumnConfig] = useState(initialColumns);\n\n  useEffect(() => {\n    setIsLoading(true);\n    setColumnConfig(initialColumns);\n\n    const timeoutId = setTimeout(() => {\n      setColumnConfig(finalColumns);\n      setIsLoading(false);\n    }, LOADING_DELAY_MS);\n\n    return () => clearTimeout(timeoutId);\n  }, [finalColumns, initialColumns]);\n\n  return { columnConfig, isLoading };\n}\n\n() => {\n    const { columnConfig, isLoading } = useLoadingColumns(\n      flatColumnConfig,\n      flatColumnConfig,\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: TABLE_HEIGHT },\n          isLoading: {\n            boolean: isLoading,\n            skeletonRowsCount: 5,\n          },\n          loadingOverlay: {\n            active: isLoading,\n            subtitle: 'Имитируем запрос перед переходом к errorState.',\n          },\n          errorState: isLoading ? undefined : { enabled: true },\n        }}\n        columnConfig={columnConfig}\n        rows={EMPTY_ROWS}\n      />\n    );\n  }"
        },
        {
          "exportName": "CustomErrorState",
          "displayName": "Custom Error State",
          "type": "full-code",
          "code": "import type { ErrorPageProps } from '@daisforge/ui';\nimport {\n  ColumnOrColumnGroupConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\nimport React, { ReactNode, useEffect, useState } from 'react';\n\ntype Row = {\n  id: string;\n  name: string;\n  status: string;\n  team: string;\n};\n\ntype ErrorStateStoryConfig =\n  {\n    enabled: boolean;\n    custom?: ReactNode;\n  } & Partial<ErrorPageProps>;\n\nconst TABLE_HEIGHT = 480;\nconst LOADING_DELAY_MS = 1200;\nconst EMPTY_ROWS: Row[] = [];\n\nconst flatColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  { key: 'id', name: 'ID' },\n  { key: 'name', name: 'Сотрудник' },\n  { key: 'status', name: 'Статус' },\n  { key: 'team', name: 'Команда' },\n];\n\nconst groupedColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  {\n    key: 'employee-group',\n    name: 'Сотрудник',\n    children: [\n      { key: 'id', name: 'ID' },\n      { key: 'name', name: 'ФИО' },\n    ],\n  },\n  {\n    key: 'meta-group',\n    name: 'Статус и команда',\n    children: [\n      { key: 'status', name: 'Статус' },\n      { key: 'team', name: 'Команда' },\n    ],\n  },\n];\n\nconst emptyColumns: readonly ColumnOrColumnGroupConfig<Row>[] = [];\n\nfunction useLoadingColumns(\n  initialColumns: readonly ColumnOrColumnGroupConfig<Row>[],\n  finalColumns: readonly ColumnOrColumnGroupConfig<Row>[]\n) {\n  const [isLoading, setIsLoading] = useState(true);\n  const [columnConfig, setColumnConfig] = useState(initialColumns);\n\n  useEffect(() => {\n    setIsLoading(true);\n    setColumnConfig(initialColumns);\n\n    const timeoutId = setTimeout(() => {\n      setColumnConfig(finalColumns);\n      setIsLoading(false);\n    }, LOADING_DELAY_MS);\n\n    return () => clearTimeout(timeoutId);\n  }, [finalColumns, initialColumns]);\n\n  return { columnConfig, isLoading };\n}\n\n() => {\n    const { columnConfig, isLoading } = useLoadingColumns(\n      flatColumnConfig,\n      flatColumnConfig,\n    );\n\n    const errorState: ErrorStateStoryConfig = {\n      enabled: true,\n      statusCode: 503,\n      customStatuses: {\n        503: {\n          title: 'Не удалось получить актуальные данные',\n          description: 'Проверьте подключение или повторите попытку позже.',\n          button: {\n            label: 'Повторить',\n            view: 'accent',\n          },\n        },\n      },\n      buttonHandler: () => undefined,\n    };\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: TABLE_HEIGHT },\n          isLoading: {\n            boolean: isLoading,\n            skeletonRowsCount: 5,\n          },\n          loadingOverlay: {\n            active: isLoading,\n            subtitle: 'Сначала показываем loading, затем кастомный errorState.',\n          },\n          errorState: isLoading ? undefined : errorState,\n        }}\n        columnConfig={columnConfig}\n        rows={EMPTY_ROWS}\n      />\n    );\n  }"
        },
        {
          "exportName": "GroupedColumnsErrorState",
          "displayName": "Grouped Columns Error State",
          "type": "full-code",
          "code": "import type { ErrorPageProps } from '@daisforge/ui';\nimport {\n  ColumnOrColumnGroupConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\nimport React, { ReactNode, useEffect, useState } from 'react';\n\ntype Row = {\n  id: string;\n  name: string;\n  status: string;\n  team: string;\n};\n\ntype ErrorStateStoryConfig =\n  {\n    enabled: boolean;\n    custom?: ReactNode;\n  } & Partial<ErrorPageProps>;\n\nconst TABLE_HEIGHT = 480;\nconst LOADING_DELAY_MS = 1200;\nconst EMPTY_ROWS: Row[] = [];\n\nconst flatColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  { key: 'id', name: 'ID' },\n  { key: 'name', name: 'Сотрудник' },\n  { key: 'status', name: 'Статус' },\n  { key: 'team', name: 'Команда' },\n];\n\nconst groupedColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  {\n    key: 'employee-group',\n    name: 'Сотрудник',\n    children: [\n      { key: 'id', name: 'ID' },\n      { key: 'name', name: 'ФИО' },\n    ],\n  },\n  {\n    key: 'meta-group',\n    name: 'Статус и команда',\n    children: [\n      { key: 'status', name: 'Статус' },\n      { key: 'team', name: 'Команда' },\n    ],\n  },\n];\n\nconst emptyColumns: readonly ColumnOrColumnGroupConfig<Row>[] = [];\n\nfunction useLoadingColumns(\n  initialColumns: readonly ColumnOrColumnGroupConfig<Row>[],\n  finalColumns: readonly ColumnOrColumnGroupConfig<Row>[]\n) {\n  const [isLoading, setIsLoading] = useState(true);\n  const [columnConfig, setColumnConfig] = useState(initialColumns);\n\n  useEffect(() => {\n    setIsLoading(true);\n    setColumnConfig(initialColumns);\n\n    const timeoutId = setTimeout(() => {\n      setColumnConfig(finalColumns);\n      setIsLoading(false);\n    }, LOADING_DELAY_MS);\n\n    return () => clearTimeout(timeoutId);\n  }, [finalColumns, initialColumns]);\n\n  return { columnConfig, isLoading };\n}\n\n() => {\n    const { columnConfig, isLoading } = useLoadingColumns(\n      groupedColumnConfig,\n      groupedColumnConfig,\n    );\n\n    const errorState: ErrorStateStoryConfig = {\n      enabled: true,\n      statusCode: 502,\n      customStatuses: {\n        502: {\n          title: 'Сервис временно недоступен',\n          description:\n            'Grouped headers остаются на месте, а ошибка показывается только в контентной области.',\n        },\n      },\n    };\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: TABLE_HEIGHT },\n          isLoading: {\n            boolean: isLoading,\n            skeletonRowsCount: 5,\n          },\n          loadingOverlay: {\n            active: isLoading,\n            subtitle:\n              'Проверяем переход loading -> errorState при группировке колонок.',\n          },\n          errorState: isLoading ? undefined : errorState,\n        }}\n        columnConfig={columnConfig}\n        rows={EMPTY_ROWS}\n      />\n    );\n  }"
        },
        {
          "exportName": "FullContentErrorStateWithoutHeaders",
          "displayName": "Full Content Error State Without Headers",
          "type": "full-code",
          "code": "import type { ErrorPageProps } from '@daisforge/ui';\nimport {\n  ColumnOrColumnGroupConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\nimport React, { ReactNode, useEffect, useState } from 'react';\n\ntype Row = {\n  id: string;\n  name: string;\n  status: string;\n  team: string;\n};\n\ntype ErrorStateStoryConfig =\n  {\n    enabled: boolean;\n    custom?: ReactNode;\n  } & Partial<ErrorPageProps>;\n\nconst TABLE_HEIGHT = 480;\nconst LOADING_DELAY_MS = 1200;\nconst EMPTY_ROWS: Row[] = [];\n\nconst flatColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  { key: 'id', name: 'ID' },\n  { key: 'name', name: 'Сотрудник' },\n  { key: 'status', name: 'Статус' },\n  { key: 'team', name: 'Команда' },\n];\n\nconst groupedColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  {\n    key: 'employee-group',\n    name: 'Сотрудник',\n    children: [\n      { key: 'id', name: 'ID' },\n      { key: 'name', name: 'ФИО' },\n    ],\n  },\n  {\n    key: 'meta-group',\n    name: 'Статус и команда',\n    children: [\n      { key: 'status', name: 'Статус' },\n      { key: 'team', name: 'Команда' },\n    ],\n  },\n];\n\nconst emptyColumns: readonly ColumnOrColumnGroupConfig<Row>[] = [];\n\nfunction useLoadingColumns(\n  initialColumns: readonly ColumnOrColumnGroupConfig<Row>[],\n  finalColumns: readonly ColumnOrColumnGroupConfig<Row>[]\n) {\n  const [isLoading, setIsLoading] = useState(true);\n  const [columnConfig, setColumnConfig] = useState(initialColumns);\n\n  useEffect(() => {\n    setIsLoading(true);\n    setColumnConfig(initialColumns);\n\n    const timeoutId = setTimeout(() => {\n      setColumnConfig(finalColumns);\n      setIsLoading(false);\n    }, LOADING_DELAY_MS);\n\n    return () => clearTimeout(timeoutId);\n  }, [finalColumns, initialColumns]);\n\n  return { columnConfig, isLoading };\n}\n\n() => {\n    const { columnConfig, isLoading } = useLoadingColumns(\n      emptyColumns,\n      emptyColumns,\n    );\n\n    const errorState: ErrorStateStoryConfig = {\n      enabled: true,\n      unknownStatus: {\n        title: 'Не удалось получить схему таблицы',\n        description:\n          'Колонки не пришли с бэкенда, поэтому после loading errorState занимает всю content-область без заголовков.',\n      },\n    };\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: TABLE_HEIGHT },\n          isLoading: {\n            boolean: isLoading,\n            skeletonRowsCount: 5,\n          },\n          loadingOverlay: {\n            active: isLoading,\n            subtitle:\n              'Сначала ждём схему колонок с бэкенда, затем показываем full-content errorState.',\n          },\n          errorState: isLoading ? undefined : errorState,\n        }}\n        columnConfig={columnConfig}\n        rows={EMPTY_ROWS}\n      />\n    );\n  }"
        },
        {
          "exportName": "ErrorStateWithControlBlockAndPagination",
          "displayName": "Error State With Control Block And Pagination",
          "type": "full-code",
          "code": "import type { ErrorPageProps } from '@daisforge/ui';\nimport {\n  ColumnOrColumnGroupConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\nimport React, { ReactNode, useEffect, useState } from 'react';\n\ntype Row = {\n  id: string;\n  name: string;\n  status: string;\n  team: string;\n};\n\ntype ErrorStateStoryConfig =\n  {\n    enabled: boolean;\n    custom?: ReactNode;\n  } & Partial<ErrorPageProps>;\n\nconst TABLE_HEIGHT = 480;\nconst LOADING_DELAY_MS = 1200;\nconst EMPTY_ROWS: Row[] = [];\n\nconst flatColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  { key: 'id', name: 'ID' },\n  { key: 'name', name: 'Сотрудник' },\n  { key: 'status', name: 'Статус' },\n  { key: 'team', name: 'Команда' },\n];\n\nconst groupedColumnConfig: readonly ColumnOrColumnGroupConfig<Row>[] = [\n  {\n    key: 'employee-group',\n    name: 'Сотрудник',\n    children: [\n      { key: 'id', name: 'ID' },\n      { key: 'name', name: 'ФИО' },\n    ],\n  },\n  {\n    key: 'meta-group',\n    name: 'Статус и команда',\n    children: [\n      { key: 'status', name: 'Статус' },\n      { key: 'team', name: 'Команда' },\n    ],\n  },\n];\n\nconst emptyColumns: readonly ColumnOrColumnGroupConfig<Row>[] = [];\n\nfunction useLoadingColumns(\n  initialColumns: readonly ColumnOrColumnGroupConfig<Row>[],\n  finalColumns: readonly ColumnOrColumnGroupConfig<Row>[]\n) {\n  const [isLoading, setIsLoading] = useState(true);\n  const [columnConfig, setColumnConfig] = useState(initialColumns);\n\n  useEffect(() => {\n    setIsLoading(true);\n    setColumnConfig(initialColumns);\n\n    const timeoutId = setTimeout(() => {\n      setColumnConfig(finalColumns);\n      setIsLoading(false);\n    }, LOADING_DELAY_MS);\n\n    return () => clearTimeout(timeoutId);\n  }, [finalColumns, initialColumns]);\n\n  return { columnConfig, isLoading };\n}\n\n() => {\n    const { columnConfig, isLoading } = useLoadingColumns(\n      flatColumnConfig,\n      flatColumnConfig,\n    );\n    const [currentPage, setCurrentPage] = useState(1);\n    const [perPage, setPerPage] = useState(20);\n\n    const errorState: ErrorStateStoryConfig = {\n      enabled: true,\n      statusCode: 503,\n      customStatuses: {\n        503: {\n          title: 'Не удалось получить список сотрудников',\n          description:\n            'Проверяем, что errorState не ломает control block, пагинацию и настройку размера строк.',\n          button: {\n            label: 'Повторить',\n            view: 'accent',\n          },\n        },\n      },\n      buttonHandler: () => undefined,\n    };\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: TABLE_HEIGHT },\n          rowSize: {\n            default: 'big',\n            showInControl: true,\n          },\n          controlBlock: {\n            rightSideInner: [\n              {\n                text: 'Экспорт',\n                view: 'linkAccent',\n                onClick: () => undefined,\n              },\n            ],\n          },\n          pagination: {\n            count: 48,\n            perPage,\n            value: currentPage,\n            responsiveSlots: true,\n            onChangePageValue(page, scrollToTop) {\n              if (typeof page === 'number') {\n                setCurrentPage(page);\n                scrollToTop();\n              }\n            },\n            async onChange(page, nextPerPage, scrollToTop) {\n              if (typeof page === 'number' && typeof nextPerPage === 'number') {\n                setCurrentPage(page);\n                setPerPage(nextPerPage);\n                scrollToTop();\n              }\n            },\n          },\n          isLoading: {\n            boolean: isLoading,\n            skeletonRowsCount: 5,\n          },\n          loadingOverlay: {\n            active: isLoading,\n            subtitle:\n              'Сначала показываем loading, затем проверяем errorState в окружении control block и pagination.',\n          },\n          errorState: isLoading ? undefined : errorState,\n        }}\n        columnConfig={columnConfig}\n        rows={EMPTY_ROWS}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "Filtering",
      "legacy": false,
      "summary": "*tableConfig.filtering**",
      "docs": "# Filtering\n\n**tableConfig.filtering**\n\nФильтрация данных таблицы с поддержкой автоматического и ручного режимов.\n\n## Ключевые особенности\n\n- Три типа фильтров: `input`, `select`, `custom`\n- Автоматическая фильтрация по умолчанию, ручная через `manualFiltering: true`\n- Отображение активных фильтров в виде chip-элементов\n- Поддержка фильтрации через sidebar с настройкой порядка и глобальных фильтров\n- Кастомизация chip-стилей и лейблов\n\n## Типы фильтров\n\n### Input\n\nТекстовый фильтр с режимами: `'includes'`, `'startWith'`, `'equal'` или кастомная функция.\n\n### Select\n\nФильтр выбором из списка. Поддержка одиночного (`'single'`) и множественного (`'multiple'`) выбора.\n\n### Custom\n\nПолностью кастомный компонент фильтра через `customRender`.\n\n## Конфигурация FilteringConfig\n\n- **`state`** `[T, setState]` — стейт фильтров (обязательный)\n- **`manualFiltering`** `boolean` — ручная фильтрация (данные не фильтруются таблицей)\n- **`filtersInfo`** `Record<keyof T, { label, clearedValue }>` — метки и дефолтные значения фильтров\n- **`sidebarConfig`** `{ order?, items }` — конфигурация sidebar с фильтрами\n- **`chipStyle`** `(itemOrGroup, item) => CSSObject` — кастомные стили для chip-элементов\n- **`renderGroupLabel`** `(group) => string` — кастомный заголовок группы чипсов\n- **`renderChipLabel`** `(group, item) => string` — кастомный текст чипса\n\n## Кастомизация чипсов\n\n### chipStyle\n\nПозволяет динамически задавать стили для каждого чипа фильтра в зависимости от его типа и содержимого.\n\n### renderGroupLabel\n\nФорматтер заголовка группы чипсов. Полезен для i18n или добавления счётчика выбранных элементов.\n\n### renderChipLabel\n\nФорматтер текста внутри чипса. Полезен при серверной пагинации, когда в стейте хранится только `value`, а `label` подставляется из кэша.\n\n## Особенности\n\n- При `manualFiltering: true` таблица не фильтрует данные — ожидается внешняя логика (серверная)\n- `sidebarConfig` позволяет добавлять глобальные фильтры, не привязанные к колонкам\n- `filtersInfo` задаёт лейблы и значения по умолчанию для каждого фильтра\n\n> Подробнее о типах — [Filtering API](?path=/docs/локальные-компоненты-tablecanvas-filtering-api--docs)",
      "apiDocs": "# Filtering API\n\n## FilteringConfig\n\n```typescript\ntype FilteringConfig<T> = {\n  state: [T, React.Dispatch<React.SetStateAction<T>>];\n  /**\n   * @deprecated Использовать filtersInfo\n   *\n   * clearedValue - состояние фильтров после очистки. Используется для сравнения:\n   * Например, был ли фильтр конкретной колонки изменен рассчитывается посредством сравнения текущего значения фильтра и значения фильтра в clearedValue.\n   * Если они равны, то фильтр считается не измененным.\n   */\n  clearedValue?: T;\n  /**\n   * Информация о фильтрах для каждой колонки.\n   * Используется для:\n   * 1. Хранения меток (label) фильтров для отображения в UI\n   * 2. Хранения значений по умолчанию (clearedValue) для каждого фильтра\n   * 3. Определения, был ли фильтр изменен (сравнение текущего значения с clearedValue)\n   */\n  filtersInfo?: Record<\n    keyof T,\n    {\n      label: string;\n      clearedValue: T[keyof T];\n    }\n  >;\n  /**\n   * manualFiltering - пропс, активирующий ручную-кастомную (или на стороне бэка) фильтрацию.\n   * @remarks\n   * Для автоматической фильтрации (когда не используется manualFiltering в tableConfig):\n   * - Для всех типов фильтров обязательно должен быть указан `valueInRow`\n   * - Для component: 'select' дополнительно должен быть указан `filteringType`\n   * - Для component: 'input' с кастомным фильтром (когда filter - функция)\n   *   функция фильтрации должна быть передана явно\n   *\n   * Если используется manualFiltering, эти параметры не обязательны,\n   * так как вся логика фильтрации реализуется извне.\n   */\n  manualFiltering?: boolean;\n  /**\n   * Конфигурация для отображения фильтров в правом сайдбаре.\n   *\n   * Позволяет:\n   * 1. Добавлять глобальные фильтры (не привязанные к конкретной колонке)\n   * 2. Управлять порядком отображения фильтров\n   * 3. Переопределять рендер и заголовки колоночных фильтров\n   *\n   * Логика работы:\n   * - По умолчанию в сайдбаре отображаются все колоночные фильтры (из columnConfig)\n   * - Ключом фильтра считается `key` колонки, если его нет, то пытаемся взять `keyInFilterState` (если указан), иначе это не будет работать\n   * - Заголовком фильтра по умолчанию является `name` колонки или ключ фильтра (name || key)\n   * - Глобальные фильтры добавляются через `items` с уникальными ключами\n   *\n   * Особенности:\n   * 1. Порядок отображения:\n   *    - Сначала фильтры из `order` (в указанной последовательности)\n   *    - Затем остальные колоночные фильтры (в порядке columnConfig)\n   *    - В конце - глобальные фильтры (в алфавитном порядке ключей)\n   *\n   * 2. Переопределение колоночных фильтров:\n   *    - Чтобы изменить заголовок: укажите ключ колонки в `items` с новым `label`\n   *    - Чтобы заменить рендер: укажите ключ колонки с `customRenderFn`\n   *    - Оригинальный фильтр из колонки будет проигнорирован\n   *\n   * 3. Глобальные фильтры:\n   *    - Ключ не должен совпадать с ключами колонок\n   *    - Обязательно указать `label` и `customRenderFn`\n   *    - Отображаются после всех колоночных фильтров, если не переопределены в order\n   *\n   * @example\n   * // Добавление глобального фильтра и изменение порядка\n   * sidebarConfig: {\n   *   order: ['status', 'tasks', 'type'], // Сначала статус, затем глобальный поиск\n   *   items: {\n   *     tasks: { // Уникальный ключ\n   *       label: 'Поиск по всем полям',\n   *       customRenderFn: () => <TaskComponent />\n   *     },\n   *     status: { // Переопределение колоночного фильтра\n   *       label: 'Статус заявки', // Новый заголовок\n   *       customRenderFn: () => <CustomStatusFilter /> // Кастомный рендер\n   *     }\n   *     type: { // Переопределение только Label колоночного фильтра\n   *       label: 'Тип', // Новый заголовок\n   *     }\n   *   }\n   * }\n   */\n  sidebarConfig?: {\n    /**\n     * Определяет порядок отображения фильтров.\n     * - Указываются ключи фильтров (колоночных или глобальных)\n     * - Не указанные в order фильтры отображаются после\n     * - Если order пуст, сохраняется порядок: глобальные фильтры + columnConfig фильтры в конце\n     */\n    order?: string[];\n    /**\n     * Конфигурация фильтров для сайдбара.\n     * Ключом может быть:\n     * - Ключ колонки (для переопределения колоночного фильтра)\n     * - Уникальный ключ (для добавления глобального фильтра)\n     */\n    items: Partial<\n      Record<\n        keyof T,\n        {\n          /** Заголовок фильтра (обязателен для глобальных фильтров), можно использовать для переопределения для локальных фильтров */\n          label: string;\n          /**\n           * Функция рендера компонента фильтра.\n           * Для колоночных фильтров переопределяет оригинальный рендер.\n           * Для глобальных фильтров обязательна.\n           */\n          customRenderFn?: (\n            filters: T,\n            setFilters: React.Dispatch<React.SetStateAction<T>>,\n          ) => React.ReactNode;\n        }\n      >\n    >;\n  };\n  /**\n   * Callback для кастомизации стилей чипсов (фильтров) в списке\n   *\n   * @param {ItemOrGroup} itemOrGroup - Текущий элемент или группа фильтров\n   * @param {Item | undefined} item - Конкретный элемент фильтра (если есть)\n   * @returns {CSSObject} Объект стилей, который будет применен к чипсу\n   *\n   * @description\n   * Позволяет динамически задавать стили для каждого чипса в зависимости от его типа и содержимого.\n   * Вызывается для каждого отображаемого чипса (как для отдельных элементов, так и для элементов внутри групп).\n   *\n   * @example\n   * // Пример 1: Стилизация чипсов по типу\n   * chipStyle: (itemOrGroup, item) => {\n   *   if (isGroup(itemOrGroup)) {\n   *     return { backgroundColor: '#f0f0f0' };\n   *   }\n   *   return { backgroundColor: '#e0e0e0' };\n   * }\n   *\n   * @example\n   * // Пример 2: Стилизация по значению фильтра\n   * chipStyle: (itemOrGroup, item) => {\n   *   if (item?.label === 'Высокий приоритет') {\n   *     return {\n   *       backgroundColor: '#ffebee',\n   *       color: '#d32f2f'\n   *     };\n   *   }\n   *   return {};\n   * }\n   *\n   * @example\n   * // Пример 3: Разные стили для элементов в группе и одиночных\n   * chipStyle: (itemOrGroup, item) => {\n   *   if (item) {\n   *     // Стиль для элемента внутри группы\n   *     return { maxWidth: 180 };\n   *   }\n   *   // Стиль для одиночного чипа\n   *   return { maxWidth: 150 };\n   * }\n   */\n  chipStyle?: (itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject;\n  /**\n   * Пользовательский форматтер заголовка группы чипсов.\n   *\n   * Используется в блоке активных фильтров для подмены текста заголовка\n   * группы (например, “Статус”, “Тип”, “Автор”). Полезно, когда нужно\n   * динамически менять подпись (добавить счётчик, i18n и т.п.).\n   *\n   * @param {ItemOrGroup} itemOrGroup Объект группы (тип Group). Вызов происходит только для групп,\n   *                                   поэтому безопасно кастовать к Group.\n   * @returns {string} Текст заголовка группы чипсов.\n   *\n   * @default Возвращается `group.groupLabel`.\n   *\n   * @remarks\n   * - Функция должна быть чистой и быстрой (без сетевых запросов и побочных эффектов).\n   * - Возвращайте ТОЛЬКО строку — чипы отображают текстовое значение.\n   * - Для длинных строк применяется усечение (overflow с многоточием) на уровне компонента.\n   *\n   * @example\n   * // Добавить двоеточие и количество выбранных элементов\n   * renderGroupLabel: (group) => `${group.groupLabel}: ${group.items.length}`\n   *\n   * @example\n   * // Локализация заголовка группы\n   * const i18n = { status: 'Статус', type: 'Тип' };\n   * renderGroupLabel: (group) => i18n[group.groupId] ?? group.groupLabel\n   */\n  renderGroupLabel?: (group: Group) => string;\n\n  /**\n   * Пользовательский форматтер текста чипса (элемента внутри группы или одиночного фильтра).\n   *\n   * Позволяет управлять тем, что именно отображается внутри каждого чипса. Особенно полезен\n   * при серверной пагинации/ленивой загрузке, когда в состоянии фильтра хранится только value,\n   * а label необходимо подставить из локального кэша.\n   *\n   * @param {Group | null } group  Группа, внутри которой рендерится чип (или null).\n   * @param {Item} item   Сам элемент чипса. В группах передаётся конкретный `Item`,\n   *                                  для одиночного чипа может быть `undefined`.\n   * @returns {string} Текст, который будет показан в чипсе.\n   *\n   * @default Используется `item?.label.toString()` (или строковое представление value).\n   *\n   * @remarks\n   * - Функция должна быть чистой и быстрой;\n   * - Возвращайте ТОЛЬКО строку.\n   *\n   * @example\n   * // 1) Отображение label из кэша при серверной пагинации\n   * const labelsCacheRef = useRef(new Map<string, string>());\n   * renderChipLabel: (group, item) => {\n   *   if (item?.id != null) {\n   *     const key = String(item.id);\n   *     const fromCache = labelsCacheRef.current.get(key);\n   *     if (fromCache) return fromCache;     // красивый label, если уже загрузили\n   *     return String(item.label ?? key);    // фоллбэк: временно показываем value/label из item\n   *   }\n   *   return ''; // безопасный фоллбэк для одиночных случаев\n   * }\n   *\n   * @example\n   * // 2) Нормализация отображения числовых значений\n   * renderChipLabel: (_group, item) => {\n   *   const v = Number(item?.label);\n   *   return Number.isFinite(v) ? v.toLocaleString('ru-RU') : String(item?.label ?? '');\n   * }\n   *\n   * @example\n   * // 3) Префикс по типу группы\n   * renderChipLabel: (group, item) => {\n   *   const prefix = group.groupId === 'status' ? '' : '#';\n   *   return `${prefix}${item?.label ?? item?.id ?? ''}`;\n   * }\n   */\n  renderChipLabel?: (group: Group | null, item: Item) => string;\n};\n\nexport type DefaultSidebarTabIds = 'columns' | 'tableSettings' | 'filtering';\n\n/**\n * Конфигурация sidebar\n */\nexport type SidebarConfig = {\n  /**\n   * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n   * @default true\n   */\n  enabled?: boolean;\n  /**\n   * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n   * Игнорируется, если передан openState.\n   * @default false\n   */\n  defaultOpen?: boolean;\n  /**\n   * Внешний контроль открытия/закрытия sidebar.\n   * Если передан — источник истины, defaultOpen игнорируется.\n   */\n  openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n   * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n   */\n  defaultActiveTabId?: string;\n  /**\n   * Внешний контроль активной вкладки (controlled-режим).\n   * Если передан — источник истины, defaultActiveTabId игнорируется.\n   */\n  activeTabState?: [\n    string | null,\n    React.Dispatch<React.SetStateAction<string | null>>,\n  ];\n  /**\n   * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n   * При закрытии сайдбара приходит null.\n   */\n  onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n  /**\n   * Кастомные табы\n   */\n  customTabs?: Array<\n    Omit<SidebarTab, 'id'> & {\n      id: Exclude<string, DefaultSidebarTabIds>;\n    }\n  >;\n  /**\n   * Порядок отображения кастомных вкладок\n   */\n  customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n  defaultTabs?: Array<\n    | {\n        id: 'filtering' | 'columns';\n        /** название таба в рамках горизонтального табов внутри таба настройки */\n        label?: string;\n        /** название таба в рамках вертикальных табов сайдбара (если данный таб окажется единственным табом в настройках) */\n        title?: string;\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n        /** @default true */\n        showInSidebar?: boolean;\n        /** тултип иконки шестеренки (для табов с id = filtering и columns - недоступен. Настраивается через таб с id='tableSettings') */\n        iconTooltipText?: undefined;\n      }\n    | {\n        id: 'tableSettings';\n        /** название таба в рамках горизонтального табов внутри таба настройки */\n        label?: string;\n        /** название таба в рамках вертикальных табов сайдбара */\n        title?: string;\n\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n         * Только дл id: 'tableSettings'\n         */\n        customGeneralSettingsSlot?: React.ReactNode;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n        /** @default true */\n        showInSidebar?: boolean;\n        /** тултип иконки шестеренки @default 'Настройки' */\n        iconTooltipText?: string;\n      }\n  >;\n};\n\nexport function activeViewIs<T extends 'cards' | 'rows'>(\n  checkType: T,\n  viewState: 'cards' | 'rows',\n  view: View,\n): view is ViewMods[T] {\n  return checkType === viewState;\n}\n\n/** Размер controlBlock: 'm' и 's' — одинаковые стили, 'xs' — уменьшенный */\nexport type ControlBlockSize = 'm' | 's' | 'xs';\n\nexport type ControlBlockConfig = {\n  /**\n   * show - наличие controlBlock-а\n   * @default true\n   */\n  show?: boolean;\n  /**\n   * Размер controlBlock и его элементов (кнопки, иконки, поиск, отступы).\n   * 'm' и 's' — стандартные стили, 'xs' — компактный режим.\n   * Не влияет на customFeatures и кастомные слоты — они контролируются разработчиком.\n   * @default 'm'\n   */\n  size?: ControlBlockSize;\n  /**\n   * @deprecated Используйте кастомные кнопки через rightSideInner или customFeatures.\n   * leftSideInner - пропс для добавления кнопок в левую часть контролблока.\n   * Продолжает работать для обратной совместимости.\n   */\n  leftSideInner?: ControlBlockButtonProps[];\n  /**\n   * rightSideInner - пропс для добавления кнопок в правую часть контролблока\n   */\n  rightSideInner?: ControlBlockButtonProps[];\n  /**\n   * customFeatures - пропс для добавления кастомных фичей (кнопки-иконки)\n   */\n  customFeatures?: FeatureItem[];\n  /**\n   * pinningMenu - нативная фича закрепления столбцов (SplitIconButton с\n   * дропдауном) в правой зоне иконок. Появляется, когда активировано\n   * закрепление колонок (columnsControl.pinning). Продукт может донастроить\n   * и дополнить пункты меню (см. PinningMenuConfig).\n   */\n  pinningMenu?: PinningMenuConfig;\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n   */\n  leftSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n   */\n  rightSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n   * @default true\n   */\n  enableAdaptiveCompress?: boolean;\n  /**\n   * Панель массовых действий\n   */\n  massActionPanel?: {\n    /**\n     * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n     * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n     */\n    buttons: MassActionButtonProps[];\n    /**\n     * Пропсы для Dropdown, в который сжались кнопки\n     */\n    collapsedDropdownProps?: TableDropdownConfigProps;\n    /**\n     * Отступ панели снизу от контейнера (px)\n     * @default 24\n     */\n    bottom?: number;\n    /**\n     * Управление отображением панели массовых действий.\n     * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n     * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n     * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n     */\n    show?: boolean;\n    /**\n     * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n     * Viewport-логика (1280) в таблице не используется.\n     * @default 's'\n     */\n    size?: MassActionsSize;\n  };\n};\n\n/** Пропсы кнопки редактирования. onClick исключён — используйте onSave/onCancel/onEnableEditing. */\nexport type EditingButtonProps = Omit<\n  Partial<ControlBlockButtonProps>,\n  | 'onClick'\n  | 'size'\n  | 'dropdown'\n  | 'isTargetAction'\n  | 'skipRightDivider'\n  | 'tooltipText'\n>;\n\nexport type EditingConfig<\n  RowType extends ObjectForExtending,\n  RowIdType,\n  SummaryRowType,\n> = {\n  /**\n   * Функция обработки изменений в редактируемой строке\n   */\n  onRowsChange: Maybe<\n    (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n  >;\n  /**\n   * свойство, необходимое для корректного изменения дочерних строк.\n   * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n   *\n   * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n   * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n   *\n   * @example \"child\" или \"uvh367.children\"\n   */\n  subRowsKey?: string;\n  /**\n   * Глубокое копирование строк перед применением правки в режиме редактирования.\n   *\n   * Включите, если строки, передаваемые в таблицу, иммутабельны/заморожены\n   * (напр. стейт под управлением Redux Toolkit или Immer — они вызывают\n   * Object.freeze в dev). При редактировании дочерней строки таблица записывает\n   * изменение ВНУТРЬ объекта родителя; на замороженном объекте это падает с\n   * `TypeError: Cannot assign to read only property`.\n   *\n   * Когда флаг включён, таблица сама делает structuredClone редактируемой строки\n   * перед записью — ваш иммутабельный стейт не мутируется, и редактирование\n   * дочерних строк работает без действий с вашей стороны.\n   *\n   * ⚠️ Данные строки должны быть сериализуемыми. Где доступен structuredClone —\n   * Date/Map/Set и вложенные структуры копируются корректно; на старых средах\n   * без structuredClone используется JSON-фоллбэк (теряет Date/Map/Set, undefined\n   * и функции). Не включайте без необходимости — глубокое копирование добавляет\n   * накладные расходы.\n   *\n   * @default false\n   */\n  deepCloneRows?: boolean;\n  /**\n   * Функция определения уникального id строки\n   * @param row\n   * @returns\n   */\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * Функция определения возможности редактирования строки\n   * @param row\n   * @returns\n   */\n  rowEditable?: (row: RowType) => boolean;\n  /**\n   * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n   * @default false\n   */\n  defaultEnabled?: boolean;\n  /**\n   * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n   * По умолчанию, управление происходит в компоненте.\n   * Приоритетнее, чем defaultEnabled.\n   *\n   * @type boolean - если НЕ нужно переключение в самой таблице\n   * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n   *\n   */\n  enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n   * @default true\n   */\n  showButtons?: boolean;\n  /**\n   * Функция, вызывающаяся при включении фичи.\n   * @param enableEditorMode - функция включающая режим редактирования\n   */\n  onEnableEditing?: (enableEditorMode: () => void) => void;\n  /**\n   * Функция, вызывающаяся при сохранении отредактированного.\n   * @param disableEditorMode - функция выключающая режим редактирования\n   */\n  onSave?: (disableEditorMode: () => void) => void;\n  /**\n   * Функция, вызывающаяся при отмене отредактированного.\n   * @param disableEditorMode - функция выключающая режим редактирования\n   */\n  onCancel?: (disableEditorMode: () => void) => void;\n  /** Пропсы кнопок в controlBlock. */\n  buttons?: {\n    save?: EditingButtonProps;\n    cancel?: EditingButtonProps;\n    edit?: EditingButtonProps;\n  };\n  /**\n   * Кастомный слот, отображаемый левее кнопок «Отменить» / «Сохранить».\n   * Виден только когда режим редактирования активен (editMode = true).\n   * Зона ответственности разработчика — размерная сетка controlBlock не влияет на этот слот.\n   */\n  editModeLeftSlot?: React.ReactNode;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: {\n    enableButton?: DomMetadata;\n    saveButton?: DomMetadata;\n    cancelButton?: DomMetadata;\n  };\n};\n\nexport type SummaryRowsConfig = {\n  showDefault: boolean;\n  showInControl: boolean;\n} & {\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n\n/**\n * Конфиг тултипа при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\nexport type TableConfigTooltip = {\n  /**\n   * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n   * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n   * @default false\n   */\n  enabled?: boolean;\n  /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n  mouseEnterDelay?: number;\n  /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n  mouseLeaveDelay?: number;\n  /**\n   * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n   * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n   * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n   * (per-node), приоритет у неё.\n   */\n  minWidth?: number | string;\n  /**\n   * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n   * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n   * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n   * (per-node), приоритет у неё.\n   */\n  maxWidth?: number | string;\n};\n\nexport type InfinityScrollConfig<RowType extends ObjectForExtending> = {\n  /** Триггер достижения скроллом зоны подгрузки данных. */\n  onTrigger: (rows: RowType[]) => Promise<void> | void;\n  /** Состояние загрузки (скелетоны) новых строк. */\n  isLoading: boolean;\n  /**\n   * Флаг, когда все данные загружены — false.\n   * @default true\n   */\n  hasMore?: boolean;\n  /**\n   * Для mode='region': за сколько строк до конца триггерить загрузку.\n   * @default 5\n   */\n  rowThreshold?: number;\n};\n\nexport type { TableCanvasEmptyStateConfig, TableCanvasErrorStateConfig };\n\n/**\n * Настройка выделения ячеек/колонок/строк в TableCanvas — единый объект.\n * Это отдельная ось взаимодействия — не зависит от `highlightActiveType`.\n */\nexport type CellsSelectionConfig = {\n  /**\n   * Режим фактического выделения ячеек (нативный glide selection). По нему\n   * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n   * @default \"range-cell\"\n   */\n  mode?: CellsSelectionMode;\n  /**\n   * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n   * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n   * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n   * @default true\n   */\n  enableColumnSelection?: boolean;\n  /**\n   * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n   * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n   * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n   * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n   * @default true\n   */\n  enableRowSelection?: boolean;\n  /**\n   * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n   * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n   * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n   * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n   * @default true\n   */\n  enableSelectAll?: boolean;\n  /**\n   * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n   * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n   * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n   * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n   */\n  state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};\n\n/** Один объединённый блок: какие строки и колонки слить. */\nexport type MergedCellsRegion = {\n  rowKeys: Array<string | number>;\n  colKeys: string[];\n  /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n  mergedCellsAlign?: MergedCellsAlign;\n};\n\n/**\n * Видимость сторон рамки ячейки: true рисовать, false не рисовать, не задано -\n * работает уровень ниже (настройка колонки, строки или общая).\n */\nexport type CellBorderVisibility = {\n  top?: boolean;\n  right?: boolean;\n  bottom?: boolean;\n  left?: boolean;\n};\n\n/**\n * Управление рамками (линиями) таблицы: включение и выключение. Уровни, от\n * слабого к сильному: общие настройки (vertical, horizontal), затем колонка\n * (getVerticalBorder) и строка (getHorizontalBorder), затем ячейка\n * (getCellBorder).\n */\nexport type BordersConfig<RowType = ObjectForExtending> = {\n  /** Рисовать ли вертикальные линии между колонками. @default true */\n  vertical?: boolean;\n  /** Рисовать ли горизонтальные линии между строками тела. @default true */\n  horizontal?: boolean;\n  /**\n   * Точечное управление вертикальной линией справа от колонки (разделитель\n   * после неё). Вернуть true или false, чтобы переопределить общую настройку\n   * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n   * колонку при перерисовке, поэтому функция должна быть быстрой.\n   */\n  getVerticalBorder?: (params: {\n    /** Ключ колонки, справа от которой рисуется линия. */\n    columnKey: string;\n    /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n    columnIndex: number;\n  }) => boolean | undefined;\n  /**\n   * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n   * false, чтобы переопределить общую настройку horizontal, или undefined,\n   * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n   * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n   */\n  getHorizontalBorder?: (params: {\n    /** Строка под линией (линия рисуется сверху этой строки). */\n    row: RowType;\n    /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n    rowIndex: number;\n    /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n    treeLvl: number;\n  }) => boolean | undefined;\n  /**\n   * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n   * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n   * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n   * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n   * вызывается.\n   */\n  getCellBorder?: (params: {\n    /** Индекс колонки среди отображаемых (без служебных). */\n    col: number;\n    /** Ключ колонки. */\n    columnKey: string | undefined;\n    /** Строка ячейки. */\n    row: RowType;\n    /** Индекс строки среди отображаемых. */\n    rowIndex: number;\n    /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n    treeLvl: number;\n  }) => CellBorderVisibility | undefined;\n};\n\nexport type TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n   * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n   * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n   */\n  columnsGrouping?: ColumnsGroupingConfig;\n  /**\n   * Подсветка активной сущности в canvas-таблице.\n   * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n   * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * Единый конфиг выделения ячеек: режим (`mode`), оси\n   * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n   * (`state`). См. {@link CellsSelectionConfig}.\n   */\n  cellsSelection?: CellsSelectionConfig;\n  /**\n   * Подсвеченная строка (`highlightActiveType='row'`).\n   * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n   * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n   * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n   * без владения значением).\n   */\n  highlightActiveRow?: {\n    state?: [\n      number | undefined,\n      React.Dispatch<React.SetStateAction<number | undefined>>,\n    ];\n    /**\n     * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n     * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n     * (например, в SplitView) без `onCellClicked`.\n     */\n    onChange?: (params: {\n      index: number | undefined;\n      row: RowType | undefined;\n    }) => void;\n  };\n  /**\n   * Эффекты при наведении (hover)\n   * `row` — подсветка строки под курсором.\n   * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n   * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n   * «остаётся под ними» и снова виден после сброса выделения).\n   *\n   * `{ row: true }` — включить с цветами из темы;\n   * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n   * @default undefined (выключено)\n   */\n  hoverEffects?: HoverEffectsConfig;\n  /**\n   * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n   * Влияет только на grid/header/sticky hairline borders.\n   * @default false\n   */\n  enableLowDprHairline?: boolean;\n  /**\n   * Управление рамками (линиями) таблицы: включение и выключение.\n   *\n   * Уровни, от слабого к сильному: общие настройки (vertical, horizontal),\n   * затем колонка (getVerticalBorder) и строка (getHorizontalBorder), затем\n   * ячейка (getCellBorder).\n   *\n   * `vertical: false` и `horizontal: false` убирают все вертикальные или\n   * горизонтальные линии тела. `getCellBorder` включает и выключает стороны\n   * рамки конкретной ячейки; при его использовании линии рисуются с разбивкой\n   * по ячейкам.\n   */\n  borders?: BordersConfig<RowType>;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *```jsx\n   * import { Table } from '@daisforge/ui';\n   *\n   * <Table\n   * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n   * {...rest}\n   * />\n   * ```\n   */\n  selecting?: {\n    state: [\n      ReadonlySet<RowIdType>,\n      React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n    ];\n    rowKeyGetter: (row: RowType) => RowIdType;\n  } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n       */\n      controlBlock?: {\n        domMetadata?: DomMetadata;\n      };\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n       */\n      sidebar?: {\n        domMetadata?: DomMetadata;\n      };\n    };\n  /**\n   * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n   *\n   * columnConfig=[{editingCell: {...}}]\n   */\n  editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n  /**\n   * cellTransfer — конфигурация копирования, вставки и fill handle.\n   * По умолчанию копирование (Ctrl+C) работает в режиме редактирования.\n   * Данные копируются в формате TSV (tab-separated values), совместимом с Excel.\n   *\n   * Пример:\n   *\n   * tableConfig={{ cellTransfer: { enabled: true, onBeforeCopy: (data) => data } }}\n   */\n  cellTransfer?: CellTransferConfig;\n\n  /**\n   * Объединение ячеек тела таблицы.\n   *\n   * mergeByCellValues — колонки, в которых подряд идущие одинаковые значения\n   * сливаются в один блок (по вертикали). Границы блоков таблица считает сама из\n   * данных; сортировка и фильтр их пересобирают. Данные не меняются — значение и\n   * так повторяется в строках, объединение лишь показывает его одной ячейкой.\n   *\n   * mergedCellsRegions — список блоков, заданных снаружи (как выделение): каждый\n   * блок описан ключами строк (rowKeys) и колонок (colKeys). Нужен rowKeyGetter.\n   * Если после сортировки или скрытия колонок строки/колонки блока перестали идти\n   * подряд — блок не рисуется. Важнее mergeByCellValues.\n   *\n   * Примеры: mergeCells={{ mergeByCellValues: ['dept', 'role'] }},\n   * mergeCells={{ mergedCellsRegions, rowKeyGetter: (r) => r.id }}.\n   */\n  mergeCells?: {\n    mergeByCellValues?: Array<\n      string | { colKey: string; value: (row: RowType) => unknown }\n    >;\n    /** Список блоков, заданных снаружи (по ключам строк и колонок). */\n    mergedCellsRegions?: MergedCellsRegion[];\n    /**\n     * Нужен для mergedCellsRegions: находит строку по её ключу. Должна быть\n     * стабильной функцией; менять её на лету не нужно — в пересборку таблицы она\n     * не входит.\n     */\n    rowKeyGetter?: (row: RowType) => string | number;\n    /**\n     * Выравнивание по умолчанию для всех блоков. Колоночный mergedCellsAlign и\n     * выравнивание конкретного региона важнее.\n     */\n    mergedCellsAlign?: MergedCellsAlign;\n  };\n\n  /**\n   * Модуль нотификаций: стандартизированный канал событий для внешних\n   * потребителей. Таблица UI не рисует — вызывает `onNotification`, потребитель\n   * показывает тост/модалку на своей стороне. Сейчас эмитятся ошибки copy/paste\n   * (в т.ч. multi-range 2D-разброс, readonly/overflow-abort, пропуск валидацией).\n   */\n  notifications?: TableNotificationsConfig;\n\n  /**\n   * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n   *\n   * columnConfig=[{subRow: {...}}]\n   */\n  subRows?: SubRows<RowType, RowIdType>;\n  /**\n   * Столбец с нумерацией строк.\n   * Активируется наличием этого свойства. Поддерживает `subRows` любой глубины.\n   *\n   * @see {@link RowMarkersTableConfig} — полное описание конфигурации и примеры.\n   */\n  rowMarkers?: RowMarkersTableConfig<RowType>;\n  rowsGrouping?: RowsGrouping<RowType, SummaryRowType>;\n\n  /**\n   * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации -  resizableColumn: true. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={resizableColumn: true}\n   *\n   * columnConfig=[{resizable: true}]\n   */\n  resizableColumn?: boolean;\n  /**\n   * style - inline-стили. Для стилей самой таблицы (без вложенности).\n   *\n   * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n   */\n  style?: Omit<\n    CSSProperties,\n    'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n  >;\n  /**\n   * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n   *\n   * Пример:\n   *\n   * ```css\n   * & > .rdg-header-row > .rdgCell {\n   * background-color: red;\n   * }\n   * ```\n   *\n   */\n  css?: string | CSSObject;\n\n  summaryRows?: SummaryRowsConfig;\n  /**\n   * controlBlock - пропс для активации, кастомизации контролблока.\n   */\n  controlBlock?: ControlBlockConfig;\n  /**\n     * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n     * Пример:\n     *\n     * ```tsx\n        tableConfig={{ containerStyle: { height: '70vh' } }}\n     * ```\n     */\n  containerStyle?: CSSProperties | undefined;\n  /**\n   * containerCss - стили для контейнера таблицы и контролблока.\n   * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n   */\n  containerCss?: string | CSSObject | undefined;\n  /**\n   * containerId - html-атрибут id контейнера таблицы.\n   */\n  containerId?: string | undefined;\n\n  /**\n   * unstickyHeader - откреплённая шапка. Header уезжает вместе со скроллом контента.\n   * @default false\n   */\n  unstickyHeader?: boolean;\n\n  /** Тултип при hover по canvas-элементам.\n   *  Для активации фичи необходимо заполнить данный конфиг,\n   * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n   */\n  tooltip?: TableConfigTooltip;\n\n  /**\n   * infinityScroll - бесконечная подгрузка данных при скролле.\n   *\n   *  Условие активации - наличие самого пропса infinityScroll.\n   *\n   * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n   * (Предполагается, что если есть infinityScroll,\n   * то в таблице представлен не весь объем данных,\n   * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n   *\n   */\n  infinityScroll?: InfinityScrollConfig<RowType>;\n  /**\n   * @isLoading - состояние загрузки данных для таблицы.\n   */\n  isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n  /**\n   * loadingOverlay - конфигурация для отображения оверлея загрузки.\n   * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n   */\n  loadingOverlay?: {\n    /**\n     * Активен ли оверлей загрузки\n     * @default true\n     */\n    active?: boolean;\n    /**\n     * Кастомный компонент спиннера\n     * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n     */\n    spinner?: ReactNode;\n    /**\n     * Основной заголовок оверлея\n     * @default \"Загрузка таблицы\"\n     */\n    title?: string;\n    /**\n     * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n     * @default \"\"\n     */\n    subtitle?: string;\n    /**\n     * Задержка перед показом подзаголовка (мс)\n     * @default 10000 (10 секунд)\n     */\n    showSubtitleDelay?: number;\n  };\n  /**\n   * Empty state внутри content-области canvas-таблицы.\n   * Не заменяет control block, header или pagination.\n   */\n  emptyState?: TableCanvasEmptyStateConfig;\n  /**\n   * Error state внутри content-области canvas-таблицы.\n   * Не заменяет control block, header или pagination.\n   */\n  errorState?: TableCanvasErrorStateConfig;\n  // FIXME:\n  // noRowsFallback?: boolean | { custom: ReactNode };\n  columnsControl?: ColumnsControlConfig;\n  // FIXME:\n  // rowDetailPanel?: RowDetailConfig<RowType>;\n  // FIXME: Временно комментирую использование, пока не адаптируем TableCanvas\n  // rowInstruments?: {\n  //   getRowDropdownConfig: RowInstrumentsType<RowType>;\n  //   /**\n  //    * @default false\n  //    */\n  //   defaultOpened?: boolean;\n  //   /**\n  //    * @default true\n  //    */\n  //   showInControl?: boolean;\n  //   /**\n  //    * Внешний стейт видимости\n  //    */\n  //   openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  // };\n  fullScreenEnabled?: FullScreen;\n  /**\n   * Переносит портал editor overlay внутрь контейнера таблицы вместо document.body.\n   * Решает проблему focus trap и сдвига координат при рендере таблицы в модалке с CSS transform.\n   * @default undefined (overlay рендерится в document.body — стандартное поведение)\n   */\n  editorOverlayPortal?: 'inside';\n  keyText?: boolean | KeyTextConfig;\n  /**\n   * pagination - пропс для пагинации.\n   *\n   * Условие активации - наличие самого пропса pagination.\n   *\n   * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n   * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n   *\n   */\n  pagination?: PaginationProps;\n  /**\n   * searching - пропс для поиска по таблицу.\n   *\n   * Условие активации - наличие searching.enabled: true\n   *\n   */\n  /**\n   * Конфигурация табов в сайдбаре\n   */\n  sidebarConfig?: SidebarConfig;\n  searching?: SearchingProps;\n  /**\n   * onHeaderContextMenu - callback открытия контекстного меню.\n   */\n  onHeaderContextMenu?: TableGlideInstanceProps<\n    RowType,\n    SummaryRowType\n  >['onHeaderContextMenu'];\n  onHeaderContextMenuDropdown?: TableGlideInstanceProps<\n    RowType,\n    SummaryRowType\n  >['onHeaderContextMenuDropdown'];\n  onCellContextMenuDropdown?: TableGlideInstanceProps<\n    RowType,\n    SummaryRowType\n  >['onCellContextMenuDropdown'];\n  onCellContextMenu?: TableGlideInstanceProps<\n    RowType,\n    SummaryRowType\n  >['onCellContextMenu'];\n  /**\n   * Обработчик клика по ячейке.\n   *\n   * Получает `cell` readonly [colIndex, rowIndex] от glide, и `info` обогащённый объект\n   * с row, column, ctxs, refTable (аналогично onCellContextMenu).\n   */\n  onCellClicked?: (\n    cell: readonly [number, number],\n    info: TableInfoWithRow<RowType, SummaryRowType>,\n  ) => void;\n} & GlideInstanceOmitted<RowType, SummaryRowType>;\n\ntype GlideInstanceOmitted<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n> = Pick<\n  Omit<\n    TableGlideInstanceProps<RowType, SummaryRowType>,\n    | keyof TableGlideCustomProps<RowType, SummaryRowType>\n    | 'CellReadOnlyEditor' /* CellReadOnlyEditor - свойство только для GlideInstance */\n  >,\n  | 'className'\n  | 'columnSelect'\n  | 'minColumnWidth'\n  | 'maxColumnWidth'\n  | 'maxColumnAutoWidth'\n  | 'onVisibleRegionChanged'\n  | 'onCellClicked'\n  // | 'CellReadOnlyEditor'\n  // | 'onGroupHeaderClicked'\n  | 'onHeaderClicked'\n  | 'onItemHovered'\n  | 'trapFocus'\n  | 'onColumnResize'\n>;\nexport type CellReadOnlyEditorProps<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n> = CellReadOnlyEditorGlideInstanceStaticProps &\n  EditingCellInfo<RowType, SummaryRowType>;\n\n//  & Pick<\n//   DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n//   | 'summaryRowHeight'\n//   | 'onFill'\n//   | 'onCopy'\n//   | 'onPaste'\n//   | 'onCellClick'\n//   | 'onCellDoubleClick'\n//   | 'onCellContextMenu'\n//   | 'onCellKeyDown'\n//   | 'onSelectedCellChange'\n//   | 'onScroll'\n//   | 'onColumnResize'\n//   | 'onColumnsReorder'\n//   | 'enableVirtualization'\n//   | 'rowClass'\n//   | 'data-testid'\n//   | 'headerRowHeight'\n// >;\n\n/**\n * Конфигурация фичи rowMarkers (столбец с нумерацией строк).\n *\n * Столбец frozen, вставляется первым, исключён из reorder/pin/hide/sort/grouping.\n * Поддерживает плоский и древовидный (`subRows`) режимы любой глубины вложенности.\n *\n * **Дефолтное поведение** (без `getRowMarker`): root-only нумерация —\n * корневые строки получают номер (`startIndex + rootIndex`), дочерние — пустую строку.\n *\n * @example\n * ```tsx\n * // Минимальная конфигурация\n * tableConfig={{ rowMarkers: { startIndex: 1 } }}\n *\n * // Сквозная стабильная нумерация\n * tableConfig={{ rowMarkers: { getRowMarker: ({ flatIndex }) => flatIndex + 1 } }}\n * ```\n */\nexport type RowMarkersTableConfig<\n  RowType extends ObjectForExtending = ObjectForExtending,\n> = {\n  /**\n   * Стартовый индекс нумерации (для дефолтной логики без `getRowMarker`).\n   * @default 1\n   */\n  startIndex?: number;\n\n  /**\n   * Ширина столбца с нумерацией (в px).\n   * Если задан `size` — он приоритетнее.\n+  * Если ни `size`, ни `width` не заданы — ширина подстраивается\n+  * под глобальный `tableConfig.rowSize` (small=20, medium=32, big=48).\n   * @default 32\n   */\n  width?: number;\n  /**\n   * Размер столбца. Приоритетнее `width`.\n   * - `xs` = 20px\n   * - `s` = 32px\n   * - `m` = 48px\n   */\n  size?: 'xs' | 's' | 'm';\n  /**\n   * Кастомная функция нумерации. Полностью переопределяет дефолтную root-only логику.\n   * Вызывается при рендере каждой ячейки столбца нумерации.\n   *\n   * ⚠️ Вызывается не только при полной отрисовке таблицы, но и при ховере/скролле —\n   * для **одной** ячейки. Не используйте внешние переменные-счётчики —\n   * используйте аргументы (`siblingPath`, `flatIndex` и др.), они всегда актуальны.\n   *\n   * @example\n   * // Сквозная стабильная нумерация (все строки, номера не прыгают при сворачивании)\n   * getRowMarker: ({ flatIndex }) => flatIndex + 1\n   *\n   * @example\n   * // Корневые — номер, дочерние — прочерк\n   * getRowMarker: ({ isSubRow, flatIndex }) => isSubRow ? '—' : flatIndex + 1\n   *\n   * @example\n   * // Иерархическая нумерация любой глубины: 1, 1.1, 1.1.1, 1.2, 2\n   * getRowMarker: ({ siblingPath }) => siblingPath.map(i => i + 1).join('.')\n   */\n  getRowMarker?: (args: {\n    /** Данные текущей строки. */\n    row: RowType;\n    /** Уровень строки в дереве: `0` — корневая, `1` — дочерняя, `2` — внучка, и т.д. */\n    level: number;\n    /** `true`, если строка дочерняя (`level > 0`). */\n    isSubRow: boolean;\n    /**\n     * Индекс строки в **видимых** строках.\n     * **Нестабильный** — меняется при сворачивании и разворачивании веток.\n     */\n    rowIndex: number;\n    /**\n     * Стабильный 0-based индекс строки в **полном** дереве (включая скрытые/свёрнутые).\n     * Не меняется при collapse/expand — подходит для сквозной нумерации.\n     */\n    flatIndex: number;\n    /**\n     * Порядковый номер среди siblings одного родителя (0-based).\n     * Для корневых строк — порядковый номер среди всех корневых.\n     * Для дочерних — порядковый номер среди children одного `parentKey`.\n     */\n    siblingIndex: number;\n    /**\n     * Путь siblingIndex-ов от корня до текущей строки (каждый элемент 0-based).\n     *\n     * Примеры:\n     * - корневая строка (2-я): `[1]`\n     * - дочерняя (3-й ребёнок 2-го корня): `[1, 2]`\n     * - внучка (1-й ребёнок 1-го ребёнка 1-го корня): `[0, 0, 0]`\n     *\n     * Для иерархической нумерации: `siblingPath.map(i => i + 1).join('.')` → `\"1.1.1\"`\n     *\n     * Для плоской таблицы (без subRows): всегда `[siblingIndex]` (один элемент).\n     */\n    siblingPath: number[];\n    /**\n     * Ключ родительской строки (`rowKeyGetter(parent)`).\n     * `null` для корневых строк. Работает для **любой** глубины вложенности.\n     */\n    parentKey: string | number | null;\n    /** Текущий видимый `flattened` массив строк. */\n    rows: readonly RowType[];\n  }) => string | number;\n};\n```\n\n## FilterComponentInPopoverProps\n\nПропсы, доступные в кастомном компоненте фильтра (`component: 'custom'`).\n\n```typescript\ntype FilterComponentInPopoverProps<\n  FilterStateType extends ObjectForExtending,\n  ColumnConfig,\n> = {\n  popoverIsOpen: boolean;\n  setPopoverIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n  columnConfig: ColumnConfig;\n  tabIndex: number;\n  headerContextState: HeaderContextValueTypeInstance<FilterStateType> &\n    FiltersVariables &\n    HeaderContextValueTypeInstance<ObjectForExtending>;\n  /**\n   * Источник открытия фильтра: из шапки таблицы или из сайдбара\n   * Полезно для условной логики в customRender (например, alwaysOpened для combobox)\n   */\n  filterSource?: 'header' | 'sidebar';\n};\n```",
      "api": [
        {
          "typeName": "FilteringConfig",
          "source": "type FilteringConfig<T> = {\n  state: [T, React.Dispatch<React.SetStateAction<T>>];\n  /**\n   * @deprecated Использовать filtersInfo\n   *\n   * clearedValue - состояние фильтров после очистки. Используется для сравнения:\n   * Например, был ли фильтр конкретной колонки изменен рассчитывается посредством сравнения текущего значения фильтра и значения фильтра в clearedValue.\n   * Если они равны, то фильтр считается не измененным.\n   */\n  clearedValue?: T;\n  /**\n   * Информация о фильтрах для каждой колонки.\n   * Используется для:\n   * 1. Хранения меток (label) фильтров для отображения в UI\n   * 2. Хранения значений по умолчанию (clearedValue) для каждого фильтра\n   * 3. Определения, был ли фильтр изменен (сравнение текущего значения с clearedValue)\n   */\n  filtersInfo?: Record<\n    keyof T,\n    {\n      label: string;\n      clearedValue: T[keyof T];\n    }\n  >;\n  /**\n   * manualFiltering - пропс, активирующий ручную-кастомную (или на стороне бэка) фильтрацию.\n   * @remarks\n   * Для автоматической фильтрации (когда не используется manualFiltering в tableConfig):\n   * - Для всех типов фильтров обязательно должен быть указан `valueInRow`\n   * - Для component: 'select' дополнительно должен быть указан `filteringType`\n   * - Для component: 'input' с кастомным фильтром (когда filter - функция)\n   *   функция фильтрации должна быть передана явно\n   *\n   * Если используется manualFiltering, эти параметры не обязательны,\n   * так как вся логика фильтрации реализуется извне.\n   */\n  manualFiltering?: boolean;\n  /**\n   * Конфигурация для отображения фильтров в правом сайдбаре.\n   *\n   * Позволяет:\n   * 1. Добавлять глобальные фильтры (не привязанные к конкретной колонке)\n   * 2. Управлять порядком отображения фильтров\n   * 3. Переопределять рендер и заголовки колоночных фильтров\n   *\n   * Логика работы:\n   * - По умолчанию в сайдбаре отображаются все колоночные фильтры (из columnConfig)\n   * - Ключом фильтра считается `key` колонки, если его нет, то пытаемся взять `keyInFilterState` (если указан), иначе это не будет работать\n   * - Заголовком фильтра по умолчанию является `name` колонки или ключ фильтра (name || key)\n   * - Глобальные фильтры добавляются через `items` с уникальными ключами\n   *\n   * Особенности:\n   * 1. Порядок отображения:\n   *    - Сначала фильтры из `order` (в указанной последовательности)\n   *    - Затем остальные колоночные фильтры (в порядке columnConfig)\n   *    - В конце - глобальные фильтры (в алфавитном порядке ключей)\n   *\n   * 2. Переопределение колоночных фильтров:\n   *    - Чтобы изменить заголовок: укажите ключ колонки в `items` с новым `label`\n   *    - Чтобы заменить рендер: укажите ключ колонки с `customRenderFn`\n   *    - Оригинальный фильтр из колонки будет проигнорирован\n   *\n   * 3. Глобальные фильтры:\n   *    - Ключ не должен совпадать с ключами колонок\n   *    - Обязательно указать `label` и `customRenderFn`\n   *    - Отображаются после всех колоночных фильтров, если не переопределены в order\n   *\n   * @example\n   * // Добавление глобального фильтра и изменение порядка\n   * sidebarConfig: {\n   *   order: ['status', 'tasks', 'type'], // Сначала статус, затем глобальный поиск\n   *   items: {\n   *     tasks: { // Уникальный ключ\n   *       label: 'Поиск по всем полям',\n   *       customRenderFn: () => <TaskComponent />\n   *     },\n   *     status: { // Переопределение колоночного фильтра\n   *       label: 'Статус заявки', // Новый заголовок\n   *       customRenderFn: () => <CustomStatusFilter /> // Кастомный рендер\n   *     }\n   *     type: { // Переопределение только Label колоночного фильтра\n   *       label: 'Тип', // Новый заголовок\n   *     }\n   *   }\n   * }\n   */\n  sidebarConfig?: {\n    /**\n     * Определяет порядок отображения фильтров.\n     * - Указываются ключи фильтров (колоночных или глобальных)\n     * - Не указанные в order фильтры отображаются после\n     * - Если order пуст, сохраняется порядок: глобальные фильтры + columnConfig фильтры в конце\n     */\n    order?: string[];\n    /**\n     * Конфигурация фильтров для сайдбара.\n     * Ключом может быть:\n     * - Ключ колонки (для переопределения колоночного фильтра)\n     * - Уникальный ключ (для добавления глобального фильтра)\n     */\n    items: Partial<\n      Record<\n        keyof T,\n        {\n          /** Заголовок фильтра (обязателен для глобальных фильтров), можно использовать для переопределения для локальных фильтров */\n          label: string;\n          /**\n           * Функция рендера компонента фильтра.\n           * Для колоночных фильтров переопределяет оригинальный рендер.\n           * Для глобальных фильтров обязательна.\n           */\n          customRenderFn?: (\n            filters: T,\n            setFilters: React.Dispatch<React.SetStateAction<T>>,\n          ) => React.ReactNode;\n        }\n      >\n    >;\n  };\n  /**\n   * Callback для кастомизации стилей чипсов (фильтров) в списке\n   *\n   * @param {ItemOrGroup} itemOrGroup - Текущий элемент или группа фильтров\n   * @param {Item | undefined} item - Конкретный элемент фильтра (если есть)\n   * @returns {CSSObject} Объект стилей, который будет применен к чипсу\n   *\n   * @description\n   * Позволяет динамически задавать стили для каждого чипса в зависимости от его типа и содержимого.\n   * Вызывается для каждого отображаемого чипса (как для отдельных элементов, так и для элементов внутри групп).\n   *\n   * @example\n   * // Пример 1: Стилизация чипсов по типу\n   * chipStyle: (itemOrGroup, item) => {\n   *   if (isGroup(itemOrGroup)) {\n   *     return { backgroundColor: '#f0f0f0' };\n   *   }\n   *   return { backgroundColor: '#e0e0e0' };\n   * }\n   *\n   * @example\n   * // Пример 2: Стилизация по значению фильтра\n   * chipStyle: (itemOrGroup, item) => {\n   *   if (item?.label === 'Высокий приоритет') {\n   *     return {\n   *       backgroundColor: '#ffebee',\n   *       color: '#d32f2f'\n   *     };\n   *   }\n   *   return {};\n   * }\n   *\n   * @example\n   * // Пример 3: Разные стили для элементов в группе и одиночных\n   * chipStyle: (itemOrGroup, item) => {\n   *   if (item) {\n   *     // Стиль для элемента внутри группы\n   *     return { maxWidth: 180 };\n   *   }\n   *   // Стиль для одиночного чипа\n   *   return { maxWidth: 150 };\n   * }\n   */\n  chipStyle?: (itemOrGroup: ItemOrGroup, item: Item | undefined) => CSSObject;\n  /**\n   * Пользовательский форматтер заголовка группы чипсов.\n   *\n   * Используется в блоке активных фильтров для подмены текста заголовка\n   * группы (например, “Статус”, “Тип”, “Автор”). Полезно, когда нужно\n   * динамически менять подпись (добавить счётчик, i18n и т.п.).\n   *\n   * @param {ItemOrGroup} itemOrGroup Объект группы (тип Group). Вызов происходит только для групп,\n   *                                   поэтому безопасно кастовать к Group.\n   * @returns {string} Текст заголовка группы чипсов.\n   *\n   * @default Возвращается `group.groupLabel`.\n   *\n   * @remarks\n   * - Функция должна быть чистой и быстрой (без сетевых запросов и побочных эффектов).\n   * - Возвращайте ТОЛЬКО строку — чипы отображают текстовое значение.\n   * - Для длинных строк применяется усечение (overflow с многоточием) на уровне компонента.\n   *\n   * @example\n   * // Добавить двоеточие и количество выбранных элементов\n   * renderGroupLabel: (group) => `${group.groupLabel}: ${group.items.length}`\n   *\n   * @example\n   * // Локализация заголовка группы\n   * const i18n = { status: 'Статус', type: 'Тип' };\n   * renderGroupLabel: (group) => i18n[group.groupId] ?? group.groupLabel\n   */\n  renderGroupLabel?: (group: Group) => string;\n\n  /**\n   * Пользовательский форматтер текста чипса (элемента внутри группы или одиночного фильтра).\n   *\n   * Позволяет управлять тем, что именно отображается внутри каждого чипса. Особенно полезен\n   * при серверной пагинации/ленивой загрузке, когда в состоянии фильтра хранится только value,\n   * а label необходимо подставить из локального кэша.\n   *\n   * @param {Group | null } group  Группа, внутри которой рендерится чип (или null).\n   * @param {Item} item   Сам элемент чипса. В группах передаётся конкретный `Item`,\n   *                                  для одиночного чипа может быть `undefined`.\n   * @returns {string} Текст, который будет показан в чипсе.\n   *\n   * @default Используется `item?.label.toString()` (или строковое представление value).\n   *\n   * @remarks\n   * - Функция должна быть чистой и быстрой;\n   * - Возвращайте ТОЛЬКО строку.\n   *\n   * @example\n   * // 1) Отображение label из кэша при серверной пагинации\n   * const labelsCacheRef = useRef(new Map<string, string>());\n   * renderChipLabel: (group, item) => {\n   *   if (item?.id != null) {\n   *     const key = String(item.id);\n   *     const fromCache = labelsCacheRef.current.get(key);\n   *     if (fromCache) return fromCache;     // красивый label, если уже загрузили\n   *     return String(item.label ?? key);    // фоллбэк: временно показываем value/label из item\n   *   }\n   *   return ''; // безопасный фоллбэк для одиночных случаев\n   * }\n   *\n   * @example\n   * // 2) Нормализация отображения числовых значений\n   * renderChipLabel: (_group, item) => {\n   *   const v = Number(item?.label);\n   *   return Number.isFinite(v) ? v.toLocaleString('ru-RU') : String(item?.label ?? '');\n   * }\n   *\n   * @example\n   * // 3) Префикс по типу группы\n   * renderChipLabel: (group, item) => {\n   *   const prefix = group.groupId === 'status' ? '' : '#';\n   *   return `${prefix}${item?.label ?? item?.id ?? ''}`;\n   * }\n   */\n  renderChipLabel?: (group: Group | null, item: Item) => string;\n};\n\nexport type DefaultSidebarTabIds = 'columns' | 'tableSettings' | 'filtering';\n\n/**\n * Конфигурация sidebar\n */\nexport type SidebarConfig = {\n  /**\n   * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n   * @default true\n   */\n  enabled?: boolean;\n  /**\n   * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n   * Игнорируется, если передан openState.\n   * @default false\n   */\n  defaultOpen?: boolean;\n  /**\n   * Внешний контроль открытия/закрытия sidebar.\n   * Если передан — источник истины, defaultOpen игнорируется.\n   */\n  openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n   * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n   */\n  defaultActiveTabId?: string;\n  /**\n   * Внешний контроль активной вкладки (controlled-режим).\n   * Если передан — источник истины, defaultActiveTabId игнорируется.\n   */\n  activeTabState?: [\n    string | null,\n    React.Dispatch<React.SetStateAction<string | null>>,\n  ];\n  /**\n   * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n   * При закрытии сайдбара приходит null.\n   */\n  onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n  /**\n   * Кастомные табы\n   */\n  customTabs?: Array<\n    Omit<SidebarTab, 'id'> & {\n      id: Exclude<string, DefaultSidebarTabIds>;\n    }\n  >;\n  /**\n   * Порядок отображения кастомных вкладок\n   */\n  customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n  defaultTabs?: Array<\n    | {\n        id: 'filtering' | 'columns';\n        /** название таба в рамках горизонтального табов внутри таба настройки */\n        label?: string;\n        /** название таба в рамках вертикальных табов сайдбара (если данный таб окажется единственным табом в настройках) */\n        title?: string;\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n        /** @default true */\n        showInSidebar?: boolean;\n        /** тултип иконки шестеренки (для табов с id = filtering и columns - недоступен. Настраивается через таб с id='tableSettings') */\n        iconTooltipText?: undefined;\n      }\n    | {\n        id: 'tableSettings';\n        /** название таба в рамках горизонтального табов внутри таба настройки */\n        label?: string;\n        /** название таба в рамках вертикальных табов сайдбара */\n        title?: string;\n\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n         * Только дл id: 'tableSettings'\n         */\n        customGeneralSettingsSlot?: React.ReactNode;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n        /** @default true */\n        showInSidebar?: boolean;\n        /** тултип иконки шестеренки @default 'Настройки' */\n        iconTooltipText?: string;\n      }\n  >;\n};\n\nexport function activeViewIs<T extends 'cards' | 'rows'>(\n  checkType: T,\n  viewState: 'cards' | 'rows',\n  view: View,\n): view is ViewMods[T] {\n  return checkType === viewState;\n}\n\n/** Размер controlBlock: 'm' и 's' — одинаковые стили, 'xs' — уменьшенный */\nexport type ControlBlockSize = 'm' | 's' | 'xs';\n\nexport type ControlBlockConfig = {\n  /**\n   * show - наличие controlBlock-а\n   * @default true\n   */\n  show?: boolean;\n  /**\n   * Размер controlBlock и его элементов (кнопки, иконки, поиск, отступы).\n   * 'm' и 's' — стандартные стили, 'xs' — компактный режим.\n   * Не влияет на customFeatures и кастомные слоты — они контролируются разработчиком.\n   * @default 'm'\n   */\n  size?: ControlBlockSize;\n  /**\n   * @deprecated Используйте кастомные кнопки через rightSideInner или customFeatures.\n   * leftSideInner - пропс для добавления кнопок в левую часть контролблока.\n   * Продолжает работать для обратной совместимости.\n   */\n  leftSideInner?: ControlBlockButtonProps[];\n  /**\n   * rightSideInner - пропс для добавления кнопок в правую часть контролблока\n   */\n  rightSideInner?: ControlBlockButtonProps[];\n  /**\n   * customFeatures - пропс для добавления кастомных фичей (кнопки-иконки)\n   */\n  customFeatures?: FeatureItem[];\n  /**\n   * pinningMenu - нативная фича закрепления столбцов (SplitIconButton с\n   * дропдауном) в правой зоне иконок. Появляется, когда активировано\n   * закрепление колонок (columnsControl.pinning). Продукт может донастроить\n   * и дополнить пункты меню (см. PinningMenuConfig).\n   */\n  pinningMenu?: PinningMenuConfig;\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n   */\n  leftSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n   */\n  rightSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n   * @default true\n   */\n  enableAdaptiveCompress?: boolean;\n  /**\n   * Панель массовых действий\n   */\n  massActionPanel?: {\n    /**\n     * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n     * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n     */\n    buttons: MassActionButtonProps[];\n    /**\n     * Пропсы для Dropdown, в который сжались кнопки\n     */\n    collapsedDropdownProps?: TableDropdownConfigProps;\n    /**\n     * Отступ панели снизу от контейнера (px)\n     * @default 24\n     */\n    bottom?: number;\n    /**\n     * Управление отображением панели массовых действий.\n     * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n     * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n     * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n     */\n    show?: boolean;\n    /**\n     * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n     * Viewport-логика (1280) в таблице не используется.\n     * @default 's'\n     */\n    size?: MassActionsSize;\n  };\n};\n\n/** Пропсы кнопки редактирования. onClick исключён — используйте onSave/onCancel/onEnableEditing. */\nexport type EditingButtonProps = Omit<\n  Partial<ControlBlockButtonProps>,\n  | 'onClick'\n  | 'size'\n  | 'dropdown'\n  | 'isTargetAction'\n  | 'skipRightDivider'\n  | 'tooltipText'\n>;\n\nexport type EditingConfig<\n  RowType extends ObjectForExtending,\n  RowIdType,\n  SummaryRowType,\n> = {\n  /**\n   * Функция обработки изменений в редактируемой строке\n   */\n  onRowsChange: Maybe<\n    (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n  >;\n  /**\n   * свойство, необходимое для корректного изменения дочерних строк.\n   * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n   *\n   * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n   * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n   *\n   * @example \"child\" или \"uvh367.children\"\n   */\n  subRowsKey?: string;\n  /**\n   * Глубокое копирование строк перед применением правки в режиме редактирования.\n   *\n   * Включите, если строки, передаваемые в таблицу, иммутабельны/заморожены\n   * (напр. стейт под управлением Redux Toolkit или Immer — они вызывают\n   * Object.freeze в dev). При редактировании дочерней строки таблица записывает\n   * изменение ВНУТРЬ объекта родителя; на замороженном объекте это падает с\n   * `TypeError: Cannot assign to read only property`.\n   *\n   * Когда флаг включён, таблица сама делает structuredClone редактируемой строки\n   * перед записью — ваш иммутабельный стейт не мутируется, и редактирование\n   * дочерних строк работает без действий с вашей стороны.\n   *\n   * ⚠️ Данные строки должны быть сериализуемыми. Где доступен structuredClone —\n   * Date/Map/Set и вложенные структуры копируются корректно; на старых средах\n   * без structuredClone используется JSON-фоллбэк (теряет Date/Map/Set, undefined\n   * и функции). Не включайте без необходимости — глубокое копирование добавляет\n   * накладные расходы.\n   *\n   * @default false\n   */\n  deepCloneRows?: boolean;\n  /**\n   * Функция определения уникального id строки\n   * @param row\n   * @returns\n   */\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * Функция определения возможности редактирования строки\n   * @param row\n   * @returns\n   */\n  rowEditable?: (row: RowType) => boolean;\n  /**\n   * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n   * @default false\n   */\n  defaultEnabled?: boolean;\n  /**\n   * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n   * По умолчанию, управление происходит в компоненте.\n   * Приоритетнее, чем defaultEnabled.\n   *\n   * @type boolean - если НЕ нужно переключение в самой таблице\n   * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n   *\n   */\n  enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n   * @default true\n   */\n  showButtons?: boolean;\n  /**\n   * Функция, вызывающаяся при включении фичи.\n   * @param enableEditorMode - функция включающая режим редактирования\n   */\n  onEnableEditing?: (enableEditorMode: () => void) => void;\n  /**\n   * Функция, вызывающаяся при сохранении отредактированного.\n   * @param disableEditorMode - функция выключающая режим редактирования\n   */\n  onSave?: (disableEditorMode: () => void) => void;\n  /**\n   * Функция, вызывающаяся при отмене отредактированного.\n   * @param disableEditorMode - функция выключающая режим редактирования\n   */\n  onCancel?: (disableEditorMode: () => void) => void;\n  /** Пропсы кнопок в controlBlock. */\n  buttons?: {\n    save?: EditingButtonProps;\n    cancel?: EditingButtonProps;\n    edit?: EditingButtonProps;\n  };\n  /**\n   * Кастомный слот, отображаемый левее кнопок «Отменить» / «Сохранить».\n   * Виден только когда режим редактирования активен (editMode = true).\n   * Зона ответственности разработчика — размерная сетка controlBlock не влияет на этот слот.\n   */\n  editModeLeftSlot?: React.ReactNode;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: {\n    enableButton?: DomMetadata;\n    saveButton?: DomMetadata;\n    cancelButton?: DomMetadata;\n  };\n};\n\nexport type SummaryRowsConfig = {\n  showDefault: boolean;\n  showInControl: boolean;\n} & {\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n\n/**\n * Конфиг тултипа при hover по canvas-элементам.\n * Для активации фичи необходимо заполнить данный конфиг,\n * а также добавить нужные изменения в Canvas-элементах или в конфиге колонки.\n */\nexport type TableConfigTooltip = {\n  /**\n   * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n   * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n   * @default false\n   */\n  enabled?: boolean;\n  /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n  mouseEnterDelay?: number;\n  /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n  mouseLeaveDelay?: number;\n  /**\n   * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n   * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n   * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n   * (per-node), приоритет у неё.\n   */\n  minWidth?: number | string;\n  /**\n   * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n   * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n   * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n   * (per-node), приоритет у неё.\n   */\n  maxWidth?: number | string;\n};\n\nexport type InfinityScrollConfig<RowType extends ObjectForExtending> = {\n  /** Триггер достижения скроллом зоны подгрузки данных. */\n  onTrigger: (rows: RowType[]) => Promise<void> | void;\n  /** Состояние загрузки (скелетоны) новых строк. */\n  isLoading: boolean;\n  /**\n   * Флаг, когда все данные загружены — false.\n   * @default true\n   */\n  hasMore?: boolean;\n  /**\n   * Для mode='region': за сколько строк до конца триггерить загрузку.\n   * @default 5\n   */\n  rowThreshold?: number;\n};\n\nexport type { TableCanvasEmptyStateConfig, TableCanvasErrorStateConfig };\n\n/**\n * Настройка выделения ячеек/колонок/строк в TableCanvas — единый объект.\n * Это отдельная ось взаимодействия — не зависит от `highlightActiveType`.\n */\nexport type CellsSelectionConfig = {\n  /**\n   * Режим фактического выделения ячеек (нативный glide selection). По нему\n   * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n   * @default \"range-cell\"\n   */\n  mode?: CellsSelectionMode;\n  /**\n   * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n   * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n   * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n   * @default true\n   */\n  enableColumnSelection?: boolean;\n  /**\n   * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n   * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n   * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n   * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n   * @default true\n   */\n  enableRowSelection?: boolean;\n  /**\n   * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n   * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n   * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n   * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n   * @default true\n   */\n  enableSelectAll?: boolean;\n  /**\n   * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n   * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n   * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n   * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n   */\n  state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};\n\n/** Один объединённый блок: какие строки и колонки слить. */\nexport type MergedCellsRegion = {\n  rowKeys: Array<string | number>;\n  colKeys: string[];\n  /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n  mergedCellsAlign?: MergedCellsAlign;\n};\n\n/**\n * Видимость сторон рамки ячейки: true рисовать, false не рисовать, не задано -\n * работает уровень ниже (настройка колонки, строки или общая).\n */\nexport type CellBorderVisibility = {\n  top?: boolean;\n  right?: boolean;\n  bottom?: boolean;\n  left?: boolean;\n};\n\n/**\n * Управление рамками (линиями) таблицы: включение и выключение. Уровни, от\n * слабого к сильному: общие настройки (vertical, horizontal), затем колонка\n * (getVerticalBorder) и строка (getHorizontalBorder), затем ячейка\n * (getCellBorder).\n */\nexport type BordersConfig<RowType = ObjectForExtending> = {\n  /** Рисовать ли вертикальные линии между колонками. @default true */\n  vertical?: boolean;\n  /** Рисовать ли горизонтальные линии между строками тела. @default true */\n  horizontal?: boolean;\n  /**\n   * Точечное управление вертикальной линией справа от колонки (разделитель\n   * после неё). Вернуть true или false, чтобы переопределить общую настройку\n   * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n   * колонку при перерисовке, поэтому функция должна быть быстрой.\n   */\n  getVerticalBorder?: (params: {\n    /** Ключ колонки, справа от которой рисуется линия. */\n    columnKey: string;\n    /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n    columnIndex: number;\n  }) => boolean | undefined;\n  /**\n   * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n   * false, чтобы переопределить общую настройку horizontal, или undefined,\n   * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n   * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n   */\n  getHorizontalBorder?: (params: {\n    /** Строка под линией (линия рисуется сверху этой строки). */\n    row: RowType;\n    /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n    rowIndex: number;\n    /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n    treeLvl: number;\n  }) => boolean | undefined;\n  /**\n   * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n   * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n   * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n   * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n   * вызывается.\n   */\n  getCellBorder?: (params: {\n    /** Индекс колонки среди отображаемых (без служебных). */\n    col: number;\n    /** Ключ колонки. */\n    columnKey: string | undefined;\n    /** Строка ячейки. */\n    row: RowType;\n    /** Индекс строки среди отображаемых. */\n    rowIndex: number;\n    /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n    treeLvl: number;\n  }) => CellBorderVisibility | undefined;\n};\n\nexport type TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n   * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n   * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n   */\n  columnsGrouping?: ColumnsGroupingConfig;\n  /**\n   * Подсветка активной сущности в canvas-таблице.\n   * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n   * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * Единый конфиг выделения ячеек: режим (`mode`), оси\n   * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n   * (`state`). См. {@link CellsSelectionConfig}.\n   */\n  cellsSelection?: CellsSelectionConfig;\n  /**\n   * Подсвеченная строка (`highlightActiveType='row'`).\n   * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n   * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n   * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n   * без владения значением).\n   */\n  highlightActiveRow?: {\n    state?: [\n      number | undefined,\n      React.Dispatch<React.SetStateAction<number | undefined>>,\n    ];\n    /**\n     * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n     * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n     * (например, в SplitView) без `onCellClicked`.\n     */\n    onChange?: (params: {\n      index: number | undefined;\n      row: RowType | undefined;\n    }) => void;\n  };\n  /**\n   * Эффекты при наведении (hover)\n   * `row` — подсветка строки под курсором.\n   * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n   * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n   * «остаётся под ними» и снова виден после сброса выделения).\n   *\n   * `{ row: true }` — включить с цветами из темы;\n   * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n   * @default undefined (выключено)\n   */\n  hoverEffects?: HoverEffectsConfig;\n  /**\n   * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n   * Влияет только на grid/header/sticky hairline borders.\n   * @default false\n   */\n  enableLowDprHairline?: boolean;\n  /**\n   * Управление рамками (линиями) таблицы: включение и выключение.\n   *\n   * Уровни, от слабого к сильному: общие настройки (vertical, horizontal),\n   * затем колонка (getVerticalBorder) и строка (getHorizontalBorder), затем\n   * ячейка (getCellBorder).\n   *\n   * `vertical: false` и `horizontal: false` убирают все вертикальные или\n   * горизонтальные линии тела. `getCellBorder` включает и выключает стороны\n   * рамки конкретной ячейки; при его использовании линии рисуются с разбивкой\n   * по ячейкам.\n   */\n  borders?: BordersConfig<RowType>;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *"
        },
        {
          "typeName": "FilterComponentInPopoverProps",
          "source": "type FilterComponentInPopoverProps<\n  FilterStateType extends ObjectForExtending,\n  ColumnConfig,\n> = {\n  popoverIsOpen: boolean;\n  setPopoverIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n  columnConfig: ColumnConfig;\n  tabIndex: number;\n  headerContextState: HeaderContextValueTypeInstance<FilterStateType> &\n    FiltersVariables &\n    HeaderContextValueTypeInstance<ObjectForExtending>;\n  /**\n   * Источник открытия фильтра: из шапки таблицы или из сайдбара\n   * Полезно для условной логики в customRender (например, alwaysOpened для combobox)\n   */\n  filterSource?: 'header' | 'sidebar';\n};"
        }
      ],
      "stories": [
        {
          "exportName": "FilteringTable",
          "displayName": "Filtering Table",
          "type": "full-code",
          "code": "import React, { useMemo, useState } from 'react';\nimport {\n  Box,\n  Button,\n  Calendar,\n  Combobox,\n  ComboboxItemOption,\n  Divider,\n} from '@daisforge/ui';\nimport { IconStar } from '@daisforge/ui/icons';\nimport {\n  ColumnConfig,\n  TableCanvas,\n  TableFilterSelect,\n  TableFilterSelectListItem,\n} from '@daisforge/ui/components/TableCanvas';\n\nimport { createRows, type Row } from './data/tableData';\n\n() => {\n    const [isFavorite, setIsFavorite] = useState(true);\n    const [rows] = useState(() => {\n      const seededRandom = createSeededRandom(42);\n      return createRows().map((el) => ({\n        ...el,\n        id: Math.floor(seededRandom() * 1000),\n        date: (() => {\n          const date = new Date(\n            FIXED_DATE_TIMESTAMP +\n              (Math.floor(seededRandom() * 61) - 30) * 86400000,\n          );\n          return `${String(date.getDate()).padStart(2, '0')}.${String(\n            date.getMonth() + 1,\n          ).padStart(2, '0')}.${date.getFullYear()}`;\n        })(),\n      }));\n    });\n\n    const filteringStateAndSetter = useState({\n      id: '',\n      task: '',\n      priority: 'All',\n      issueType: [],\n      issueTypeCustom: [] as string[],\n      complete: '',\n      globalFilter: '',\n      date: undefined as string | undefined,\n    });\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'id',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'date',\n          name: 'Date',\n          filtering: {\n            component: 'custom',\n            customRender: (props) => {\n              const {\n                headerContextState: { filters, setFilters },\n              } = props;\n              return (\n                <Calendar\n                  value={filters?.['date']}\n                  onChangeValue={(v) => {\n                    if (setFilters)\n                      setFilters((prev) => ({\n                        ...prev,\n                        date: v,\n                      }));\n                  }}\n                />\n              );\n            },\n            filter: (filterValue, rowValue) =>\n              filterValue ? rowValue === filterValue : true,\n            valueInRow: (r) => (r as Row & { date: string })?.date,\n            compareWithClearedValue: (clearedValue, currV) =>\n              clearedValue === currV,\n            keyInFilterState: 'date',\n          },\n        },\n\n        {\n          key: 'priority',\n          name: 'Priority',\n          filtering: {\n            component: 'select',\n            selectOptions: {\n              type: 'constant',\n              options: [\n                {\n                  value: 'All',\n                  text: 'Все инциденты и запросы на доработку без ограничения по срочности',\n                },\n                {\n                  value: 'High',\n                  text: 'Высокий приоритет критически важного инцидента',\n                },\n                {\n                  value: 'Critical',\n                  text: 'Критическая ошибка блокирующая работу сервиса',\n                },\n                {\n                  value: 'Medium',\n                  text: 'Средний приоритет плановой доработки функциональности',\n                },\n                {\n                  value: 'Low',\n                  text: 'Низкий приоритет косметического усовершенствования интерфейса',\n                },\n              ],\n            },\n\n            keyInFilterState: 'priority',\n            valueInRow: (r) => r.priority,\n            filter: {\n              typeOfValue: 'single',\n              filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n            },\n          },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          filtering: {\n            beforeList(props) {\n              return (\n                <TableFilterSelectListItem\n                  $size={props.headerContextState.rowSize}\n                >\n                  Произвольный вспомогательный элемент заголовка списка с\n                  подсказкой сверху списка\n                </TableFilterSelectListItem>\n              );\n            },\n            afterList(props) {\n              return (\n                <TableFilterSelectListItem\n                  $size={props.headerContextState.rowSize}\n                >\n                  Произвольный вспомогательный элемент заголовка списка с\n                  подсказкой внизу списка\n                </TableFilterSelectListItem>\n              );\n            },\n            component: 'select',\n            selectOptions: {\n              type: 'stateInHeaderContext',\n              optionsKeyInHeaderContext: 'issueTypeOptions',\n            },\n            keyInFilterState: 'issueType',\n            valueInRow: (r) => r.issueType,\n            filter: {\n              typeOfValue: 'multiple',\n              filteringType: (fv, rv) =>\n                !fv.length || fv.some((fvCurr) => fvCurr === rv),\n            },\n          },\n        },\n        {\n          key: 'issueTypeCustom',\n          name: 'Issue Type (custom render)       ',\n          renderCell({ row }) {\n            return row.issueType;\n          },\n          filtering: {\n            component: 'custom',\n            customRender: (props) => {\n              const {\n                headerContextState: { filters, setFilters, rowSize },\n                setPopoverIsOpen,\n              } = props;\n              // Опции для выпадашки берутся из headerContextValue (см. headerContextValue ниже)\n              const headerContextState = props.headerContextState as Record<\n                string,\n                unknown\n              >;\n              const issueTypeOptions = (headerContextState.issueTypeOptions ??\n                []) as { text: string; value: string }[];\n\n              // Локальный черновик выбранных значений: меняется при кликах по айтемам,\n              // а в реальный стейт фильтров попадает по кнопке «Применить» (afterList).\n              const [draftValue, setDraftValue] = useState<string[]>(\n                (filters?.['issueTypeCustom'] as string[] | undefined) ?? [],\n              );\n\n              const apply = () => {\n                if (setFilters) {\n                  setFilters((prev) => ({\n                    ...prev,\n                    issueTypeCustom: draftValue,\n                  }));\n                  setPopoverIsOpen(false);\n                }\n              };\n\n              return (\n                <TableFilterSelect\n                  mode=\"multiple\"\n                  value={draftValue}\n                  onChange={setDraftValue}\n                  options={issueTypeOptions}\n                  size={rowSize}\n                  width=\"232px\"\n                  beforeList={\n                    <TableFilterSelectListItem $size={rowSize}>\n                      Произвольный вспомогательный элемент заголовка списка с\n                      подсказкой\n                    </TableFilterSelectListItem>\n                  }\n                  afterList={\n                    <Box\n                      $css={`position: sticky; bottom: 0; background-color: white; display: grid; gap: ${\n                        rowSize === 'big' ? '4px' : '4px'\n                      }; margin-top: 4px;`}\n                    >\n                      <Divider />\n                      <Button\n                        size={rowSize === 'small' ? 'xxs' : 's'}\n                        style={{ marginLeft: 'auto ' }}\n                        view=\"accent\"\n                        onClick={apply}\n                      >\n                        Применить\n                      </Button>\n                    </Box>\n                  }\n                />\n              );\n            },\n            filter: (filterValue, rowValue) =>\n              !Array.isArray(filterValue) ||\n              !(filterValue as string[]).length ||\n              (filterValue as string[]).some((fvCurr) => fvCurr === rowValue),\n            valueInRow: (r) => r.issueType,\n            compareWithClearedValue: (clearedValue, currV) =>\n              JSON.stringify(clearedValue) === JSON.stringify(currV),\n            keyInFilterState: 'issueTypeCustom',\n          },\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    const headerContextValue = useMemo(\n      () => ({\n        issueTypeOptions: [\n          {\n            // Ошибка-1212---3232-3---4343434 - для визуальной проверки длинных текстов без пробелов\n            text: 'Ошибка-1212---3232-3---4343434 при формировании выписки по счету',\n            value: 'Bug',\n          },\n          {\n            text: 'Улучшение производительности загрузки списка документов',\n            value: 'Improvement',\n          },\n          {\n            text: 'Эпик крупной функциональности платежного модуля',\n            value: 'Epic',\n          },\n          {\n            text: 'История пользовательского сценария оформления кредита',\n            value: 'Story',\n          },\n        ],\n      }),\n      [],\n    );\n\n    // Combobox из sdds-finai ожидает items в формате { value, label }.\n    const sidebarIssueTypeOptions = useMemo<ComboboxItemOption[]>(\n      () =>\n        headerContextValue.issueTypeOptions.map((option) => ({\n          value: option.value,\n          label: option.text,\n        })),\n      [headerContextValue],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          rowSize: {\n            default: 'big',\n            showInControl: true,\n          },\n          fullScreenEnabled: true,\n          controlBlock: {\n            customFeatures: [\n              // Обязательная кастомная фича\n              {\n                value: 'favorite',\n                label: 'Удалить из избранного',\n                Icon: IconStar,\n                onClick: () => {},\n                mandatory: true,\n                details: {\n                  type: 'switch',\n                  label: 'В избранном',\n                  checked: isFavorite,\n                  onChange: (e) => setIsFavorite(e.target.checked),\n                },\n              },\n            ],\n          },\n          filtering: {\n            state: filteringStateAndSetter,\n            sidebarConfig: {\n              items: {\n                // Переопределяем рендер колоночного фильтра именно для сайдбара:\n                // колоночный customRender остаётся в поповере шапки.\n                issueTypeCustom: {\n                  label: 'Issue Type (custom render)',\n                  customRenderFn: (filters, setFilters) => {\n                    // Хуки здесь допустимы: customRenderFn рендерится как\n                    // компонент (см. RenderSlot в feature-filtering).\n                    // Черновик выбора уезжает в фильтры сайдбара по кнопке\n                    // «Применить» внутри выпадающего списка (afterList).\n                    const [draftValue, setDraftValue] = useState<string[]>(\n                      filters.issueTypeCustom,\n                    );\n\n                    return (\n                      <Combobox\n                        multiple\n                        size=\"s\"\n                        items={sidebarIssueTypeOptions}\n                        value={draftValue}\n                        onChange={(next: string[]) => setDraftValue(next)}\n                        closeAfterSelect={false}\n                        placeholder=\"Выберите Issue Type\"\n                        afterList={\n                          <Box $css=\"display: grid; gap: 4px; margin-top: 4px;\">\n                            <Divider />\n                            <Button\n                              size=\"xs\"\n                              view=\"accent\"\n                              style={{ marginLeft: 'auto' }}\n                              onClick={() =>\n                                setFilters((prev) => ({\n                                  ...prev,\n                                  issueTypeCustom: draftValue,\n                                }))\n                              }\n                            >\n                              Применить\n                            </Button>\n                          </Box>\n                        }\n                      />\n                    );\n                  },\n                },\n              },\n            },\n            filtersInfo: {\n              id: {\n                label: 'id',\n                clearedValue: '',\n              },\n              task: {\n                label: 'task',\n                clearedValue: '',\n              },\n              priority: {\n                label: 'Some Label',\n                clearedValue: 'All',\n              },\n              issueType: {\n                label: 'issueType',\n                clearedValue: [],\n              },\n              issueTypeCustom: {\n                label: 'issueTypeCustom',\n                clearedValue: [],\n              },\n              complete: {\n                label: 'complete',\n                clearedValue: '',\n              },\n              date: {\n                label: 'Дата',\n                clearedValue: undefined,\n              },\n              globalFilter: {\n                label: 'Global filter',\n                clearedValue: '',\n              },\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n        headerContextValue={headerContextValue}\n      />\n    );\n  }"
        },
        {
          "exportName": "ManualFiltering",
          "displayName": "Title",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\n\n() => {\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'task',\n          name: 'Title',\n          filtering: {\n            component: 'input',\n            filter: 'includes',\n\n            valueInRow: (r) => r.task,\n\n            keyInFilterState: 'task',\n          },\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          filtering: {\n            component: 'select',\n            selectOptions: {\n              type: 'constant',\n              options: [\n                { value: 'All', text: 'All' },\n                { value: 'High', text: 'High' },\n                { value: 'Critical', text: 'Critical' },\n                { value: 'Medium', text: 'Medium' },\n                { value: 'Low', text: 'Low' },\n              ],\n            },\n\n            keyInFilterState: 'priority',\n            valueInRow: (r) => r.priority,\n            filter: {\n              typeOfValue: 'single',\n              filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n            },\n          },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          filtering: {\n            component: 'select',\n            selectOptions: {\n              type: 'stateInHeaderContext',\n              optionsKeyInHeaderContext: 'issueTypeOptions',\n            },\n            keyInFilterState: 'issueType',\n            valueInRow: (r) => r.issueType,\n            filter: {\n              typeOfValue: 'multiple',\n              filteringType: (fv, rv) =>\n                !fv.length || fv.some((fvCurr) => fvCurr === rv),\n            },\n          },\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n          filtering: {\n            component: 'input',\n            keyInFilterState: 'complete',\n            valueInRow: (r) => r.complete,\n            filter: (fv, rv) => (+rv || 0) >= (+fv || 0),\n          },\n        },\n      ],\n      [],\n    );\n\n    const rows = useMemo(() => createRows(), []);\n\n    const [filteredRows, setFilteredRows] = useState(rows);\n\n    const filteringStateAndSetter = useState<{\n      task: string;\n      priority: string;\n      issueType: string[];\n      complete: string;\n    }>({\n      task: '',\n      priority: 'All',\n      issueType: [],\n      complete: '',\n    });\n\n    const [state] = filteringStateAndSetter;\n\n    useEffect(() => {\n      const enabledFilters = Object.entries(state).filter((el) =>\n        Array.isArray(el[1]) ? !!el[1].length : !!el[1],\n      );\n      const filterRows = rows.filter((row) =>\n        enabledFilters.every((enabledFilter) => {\n          const colValue = row[enabledFilter[0] as keyof typeof row] as string;\n\n          return Array.isArray(enabledFilter[1])\n            ? enabledFilter[1].includes(colValue)\n            : enabledFilter[1] === colValue.toString() ||\n                enabledFilter[1] === 'All';\n        }),\n      );\n      setFilteredRows(filterRows);\n      // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [state]);\n\n    const headerContextValue = useMemo(\n      () => ({\n        issueTypeOptions: [\n          { text: 'Bug', value: 'Bug' },\n          { text: 'Improvement', value: 'Improvement' },\n          { text: 'Epic', value: 'Epic' },\n          { text: 'Story', value: 'Story' },\n        ],\n      }),\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          filtering: {\n            state: filteringStateAndSetter,\n            filtersInfo: {\n              task: {\n                label: 'task',\n                clearedValue: '',\n              },\n              priority: {\n                label: 'Some Label',\n                clearedValue: 'All',\n              },\n              issueType: {\n                label: 'issueType',\n                clearedValue: [],\n              },\n              complete: {\n                label: 'complete',\n                clearedValue: '',\n              },\n            },\n            manualFiltering: true,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={filteredRows}\n        headerContextValue={headerContextValue}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "FormatCellContent",
      "legacy": false,
      "summary": "*columnConfig.contentFormat**",
      "docs": "# FormatCellContent (TableCanvas)\n\n**columnConfig.contentFormat**\n\nПараметр `contentFormat` позволяет гибко настраивать отображение данных в ячейках таблицы. Поддерживается как на уровне колонки, так и для subRow (дочерних строк).\n\n## Ключевые особенности\n\n- Числовое форматирование с настройкой разделителей, локали, дробной части\n- Кастомное форматирование через `customFormat`\n- Выравнивание содержимого (`alignContent`)\n- Приоритет формата: `subRow.contentFormat` → родительский `contentFormat` → `column.contentFormat`\n\n## Особенности\n\n- Если используется `renderCell` или `renderSubRowCell`, кастомное форматирование не применяется\n- При редактировании с `component: inputNumber` параметры сепараторов и min/max дробной части берутся из `contentFormat`\n\n> Подробнее о типах и пропсах — [FormatCellContent API](?path=/docs/локальные-компоненты-tablecanvas-formatcellcontent-api--docs)",
      "apiDocs": "# FormatCellContent API\n\n## ContentFormat\n\n```typescript\ntype ContentFormat =\n  | 'number' // Стандартное числовое форматирование с локалью ru-RU (разделитель тысяч: пробел, дробная часть: запятая)\n  | CustomFormat\n  | NumberFormatOptions;\n```",
      "api": [
        {
          "typeName": "ContentFormat",
          "source": "type ContentFormat =\n  | 'number' // Стандартное числовое форматирование с локалью ru-RU (разделитель тысяч: пробел, дробная часть: запятая)\n  | CustomFormat\n  | NumberFormatOptions;"
        }
      ],
      "stories": [
        {
          "exportName": "BasicFormatting",
          "displayName": "Форматирование ячеек",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(() => createRowsTree());\n\n    const columns = useMemo<readonly ColumnConfig<TreeRow>[]>(\n      () => [\n        {\n          key: 'block',\n          name: 'Блок / Трайб / Продукт',\n          contentFormat: {\n            customFormat: (val) => `📝 ${val}`,\n          },\n          subRow: {\n            keyOfColumnInSubRow: (lvl) => {\n              switch (lvl) {\n                case 0:\n                  return 'block';\n                case 1:\n                  return 'tribe';\n                case 2:\n                  return 'product';\n                default:\n                  return 'block';\n              }\n            },\n            isColumnWithArrow: true,\n            hideHeaderExpandAllArrow: false,\n          },\n          resizable: true,\n        },\n        {\n          key: 'blockActivity',\n          name: 'Активность блока',\n          title: '123',\n          contentFormat: {\n            customFormat: (val) => `${val}!`,\n          },\n        },\n        {\n          key: '',\n          minWidth: 170,\n          name: 'Локация трайба',\n          subRow: {\n            renderSubRowCell: (props, lvl) => {\n              if (lvl === 1) {\n                return props.row?.tribeZone;\n              }\n              return null;\n            },\n          },\n        },\n        {\n          key: 'q1',\n          name: 'Q1',\n          contentFormat: 'number',\n          subRow: {\n            parentKeyAsDefault: true,\n            /* Форматирование в подстроках */\n            contentFormat: {\n              customFormat: (val) => `${val}%`,\n            },\n          },\n        },\n\n        {\n          key: 'q2',\n          name: 'Q2',\n          contentFormat: {\n            type: 'number',\n            minimumFractionDigits: 1,\n            maximumFractionDigits: 3,\n            decimalSeparator: '.',\n            thousandSeparator: '_',\n            alignContent: 'center',\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n            contentFormat: {\n              type: 'number',\n              minimumFractionDigits: 1,\n              maximumFractionDigits: 3,\n              decimalSeparator: ',',\n              thousandSeparator: '.',\n              alignContent: 'right',\n            },\n          },\n        },\n        {\n          key: 'q3',\n          name: 'Q3',\n          contentFormat: {\n            type: 'number',\n            minimumFractionDigits: 2,\n            locales: ['en-US', 'fr-FR', 'ru-RU'],\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n        {\n          key: 'q4',\n          name: 'Q4',\n          contentFormat: 'number',\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          resizableColumn: true,\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "Borders",
      "legacy": false,
      "summary": "*tableConfig.borders**",
      "docs": "# Borders (TableCanvas)\n\n**tableConfig.borders**\n\nУправление линиями сетки таблицы: их включение и выключение.\n\nНастраивается на четырёх уровнях, от общего к точечному. Каждый следующий уровень\nсильнее предыдущего: настройка ячейки важнее настройки колонки и строки, а те\nважнее общих настроек.\n\n## Уровни\n\n- **вся таблица** — `borders.vertical` и `borders.horizontal`: убрать все\n  вертикальные или все горизонтальные линии тела (по умолчанию линии есть);\n- **колонка** — `borders.getVerticalBorder`: вернуть для колонки `true` или\n  `false`, чтобы переопределить общую настройку вертикалей, или `undefined`,\n  чтобы оставить её (например, убрать разделитель справа от одной колонки);\n- **строка** — `borders.getHorizontalBorder`: вернуть для строки `true` или\n  `false`, чтобы переопределить общую настройку горизонталей, или `undefined`,\n  чтобы оставить её;\n- **ячейка** — `borders.getCellBorder`: включить или выключить каждую из\n  четырёх сторон рамки ячейки; для ячеек без переопределений вернуть `undefined`.\n\n## Точечные колбэки\n\n`getHorizontalBorder` и `getCellBorder` получают саму строку (`row`), её индекс\n(`rowIndex`) и уровень вложенности subRows (`treeLvl`, где `0` это корень). При\nраскрытии дерева индексы строк сдвигаются, поэтому настройку удобно привязывать к\nстроке или к уровню, а не к номеру. Для summary-строк колбэки не вызываются.\n\nТипичные сценарии:\n\n- выключить все линии и точечно дорисовать нужные (например, только контур\n  объединённого блока);\n- оставить горизонтали, но не рисовать их внутри раскрытых subRows\n  (`treeLvl > 0` вернуть `false`), чтобы родитель с детьми выглядел цельным.\n\n## Объединённые ячейки\n\nВнутрь объединённого блока линии не рисуются никогда: остаётся только внешний\nконтур. Чтобы оформить рамку блока, задавайте стороны у его крайних ячеек через\n`getCellBorder` — внутренние рамки всё равно отсекаются.\n\n## Итоговые (summary) строки\n\nНастройки вертикали действуют и на итоговую строку: разделители колонок проходят\nчерез неё насквозь, а `getVerticalBorder` убирает разделитель у выбранной колонки\nи в теле, и в итоге.\n\nТочечные горизонтали (`getHorizontalBorder`) и рамки отдельных ячеек\n(`getCellBorder`) в итоговых строках пока не поддержаны: на их линии влияют только\nпо-колоночная вертикаль и общие настройки. Полное управление линиями внутри\nитоговых строк появится позже.\n\n> Подробнее о типах — [Borders API](?path=/docs/локальные-компоненты-tablecanvas-borders-api--docs)",
      "apiDocs": "# Borders API\n\n## tableConfig.borders\n\n```typescript\ntype BordersConfig<RowType = ObjectForExtending> = {\n  /** Рисовать ли вертикальные линии между колонками. @default true */\n  vertical?: boolean;\n  /** Рисовать ли горизонтальные линии между строками тела. @default true */\n  horizontal?: boolean;\n  /**\n   * Точечное управление вертикальной линией справа от колонки (разделитель\n   * после неё). Вернуть true или false, чтобы переопределить общую настройку\n   * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n   * колонку при перерисовке, поэтому функция должна быть быстрой.\n   */\n  getVerticalBorder?: (params: {\n    /** Ключ колонки, справа от которой рисуется линия. */\n    columnKey: string;\n    /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n    columnIndex: number;\n  }) => boolean | undefined;\n  /**\n   * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n   * false, чтобы переопределить общую настройку horizontal, или undefined,\n   * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n   * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n   */\n  getHorizontalBorder?: (params: {\n    /** Строка под линией (линия рисуется сверху этой строки). */\n    row: RowType;\n    /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n    rowIndex: number;\n    /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n    treeLvl: number;\n  }) => boolean | undefined;\n  /**\n   * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n   * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n   * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n   * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n   * вызывается.\n   */\n  getCellBorder?: (params: {\n    /** Индекс колонки среди отображаемых (без служебных). */\n    col: number;\n    /** Ключ колонки. */\n    columnKey: string | undefined;\n    /** Строка ячейки. */\n    row: RowType;\n    /** Индекс строки среди отображаемых. */\n    rowIndex: number;\n    /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n    treeLvl: number;\n  }) => CellBorderVisibility | undefined;\n};\n```\n\n## CellBorderVisibility\n\nСтороны рамки одной ячейки, которые возвращает `getCellBorder`. Для каждой\nстороны:\n\n- `true` — рисовать линию;\n- `false` — не рисовать линию;\n- поле не задано — сторона берётся с уровня ниже (настройка колонки, строки или\n  общая).\n\n```typescript\ntype CellBorderVisibility = {\n  top?: boolean;\n  right?: boolean;\n  bottom?: boolean;\n  left?: boolean;\n};\n```\n\n## borders.getVerticalBorder\n\nТочечная вертикальная линия справа от колонки. Колбэк получает `columnKey` и\n`columnIndex` (в порядке отрисовки, закреплённые в начале) и возвращает `true`\nили `false`, чтобы переопределить общую настройку `borders.vertical`, или\n`undefined`, чтобы оставить её.\n\nКолбэк зовётся на каждую видимую колонку при каждой перерисовке, поэтому должен\nбыть быстрым. Если условие зависит от набора колонок, держите этот набор в `Set`\nзаранее (вне колбэка) и проверяйте через `has` — так проверка остаётся дешёвой\nи не растёт с числом колонок:\n\n```tsx\nconst COLUMNS_WITHOUT_RIGHT_BORDER = new Set(['priority', 'issueType']);\n\nborders={{\n  getVerticalBorder: ({ columnKey }) =>\n    COLUMNS_WITHOUT_RIGHT_BORDER.has(columnKey) ? false : undefined,\n}}\n```\n\nТот же приём подходит и для `getHorizontalBorder` и `getCellBorder`: тяжёлые\nвычисления и наборы данных готовьте заранее, а в колбэке оставляйте только\nбыструю проверку.",
      "api": [
        {
          "typeName": "BordersConfig",
          "source": "type BordersConfig<RowType = ObjectForExtending> = {\n  /** Рисовать ли вертикальные линии между колонками. @default true */\n  vertical?: boolean;\n  /** Рисовать ли горизонтальные линии между строками тела. @default true */\n  horizontal?: boolean;\n  /**\n   * Точечное управление вертикальной линией справа от колонки (разделитель\n   * после неё). Вернуть true или false, чтобы переопределить общую настройку\n   * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n   * колонку при перерисовке, поэтому функция должна быть быстрой.\n   */\n  getVerticalBorder?: (params: {\n    /** Ключ колонки, справа от которой рисуется линия. */\n    columnKey: string;\n    /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n    columnIndex: number;\n  }) => boolean | undefined;\n  /**\n   * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n   * false, чтобы переопределить общую настройку horizontal, или undefined,\n   * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n   * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n   */\n  getHorizontalBorder?: (params: {\n    /** Строка под линией (линия рисуется сверху этой строки). */\n    row: RowType;\n    /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n    rowIndex: number;\n    /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n    treeLvl: number;\n  }) => boolean | undefined;\n  /**\n   * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n   * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n   * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n   * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n   * вызывается.\n   */\n  getCellBorder?: (params: {\n    /** Индекс колонки среди отображаемых (без служебных). */\n    col: number;\n    /** Ключ колонки. */\n    columnKey: string | undefined;\n    /** Строка ячейки. */\n    row: RowType;\n    /** Индекс строки среди отображаемых. */\n    rowIndex: number;\n    /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n    treeLvl: number;\n  }) => CellBorderVisibility | undefined;\n};"
        },
        {
          "typeName": "CellBorderVisibility",
          "source": "type CellBorderVisibility = {\n  top?: boolean;\n  right?: boolean;\n  bottom?: boolean;\n  left?: boolean;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "NoVerticalLines",
          "displayName": "NoVerticalLines",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst COLS: ColumnConfig<Row>[] = [\n  { key: 'id', name: 'ID', width: 120 },\n  { key: 'task', name: 'Title', width: 160 },\n  { key: 'priority', name: 'Priority', width: 140 },\n  { key: 'issueType', name: 'Issue Type', width: 140 },\n  { key: 'complete', name: '% Complete', width: 140 },\n];\n\n<TableCanvas\n  tableConfig={{ borders: { vertical: false } }}\n  columnConfig={COLS}\n  rows={rows}\n/>"
        },
        {
          "exportName": "HideColumnBorder",
          "displayName": "HideColumnBorder",
          "type": "full-code",
          "code": "import { useMemo } from 'react';\nimport { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst COLS: ColumnConfig<Row>[] = [\n  { key: 'id', name: 'ID', width: 120 },\n  { key: 'task', name: 'Title', width: 160 },\n  { key: 'priority', name: 'Priority', width: 140 },\n  { key: 'issueType', name: 'Issue Type', width: 140 },\n  { key: 'complete', name: '% Complete', width: 140 },\n];\n\nconst columnsWithoutRightBorder = useMemo(\n  () => new Set(['priority', 'issueType']),\n  [],\n);\n\n<TableCanvas\n  tableConfig={{\n    borders: {\n      getVerticalBorder: ({ columnKey }) =>\n        columnsWithoutRightBorder.has(columnKey) ? false : undefined,\n    },\n  }}\n  columnConfig={COLS}\n  rows={rows}\n/>"
        },
        {
          "exportName": "NoHorizontalLines",
          "displayName": "NoHorizontalLines",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst COLS: ColumnConfig<Row>[] = [\n  { key: 'id', name: 'ID', width: 120 },\n  { key: 'task', name: 'Title', width: 160 },\n  { key: 'priority', name: 'Priority', width: 140 },\n  { key: 'issueType', name: 'Issue Type', width: 140 },\n  { key: 'complete', name: '% Complete', width: 140 },\n];\n\n<TableCanvas\n  tableConfig={{ borders: { horizontal: false } }}\n  columnConfig={COLS}\n  rows={rows}\n/>"
        },
        {
          "exportName": "PerCellBorders",
          "displayName": "PerCellBorders",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\nconst COLS: ColumnConfig<Row>[] = [\n  { key: 'id', name: 'ID', width: 120 },\n  { key: 'task', name: 'Title', width: 160 },\n  { key: 'priority', name: 'Priority', width: 140 },\n  { key: 'issueType', name: 'Issue Type', width: 140 },\n  { key: 'complete', name: '% Complete', width: 140 },\n];\n\nconst BOTTOM_ON = { bottom: true } as const;\n\n<TableCanvas\n  tableConfig={{\n    borders: {\n      horizontal: false,\n      getCellBorder: ({ columnKey, row }) =>\n        columnKey === 'complete' && row.complete >= 50 ? BOTTOM_ON : undefined,\n    },\n  }}\n  columnConfig={COLS}\n  rows={rows}\n/>"
        },
        {
          "exportName": "SubRowsWithoutInnerLines",
          "displayName": "Title",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n    const cols: readonly ColumnConfig<Row>[] = [\n      {\n        key: 'task',\n        name: 'Title',\n        width: 220,\n        subRow: { keyOfColumnInSubRow: 'task', isColumnWithArrow: true },\n      },\n      { key: 'priority', name: 'Priority', width: 140 },\n      { key: 'issueType', name: 'Issue Type', width: 140 },\n      { key: 'complete', name: '% Complete', width: 140 },\n    ];\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 420 },\n          rowMarkers: { startIndex: 1 },\n          subRows: {\n            getSubRows: (row) => row.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          borders: {\n            vertical: false,\n            getHorizontalBorder: ({ treeLvl }) =>\n              treeLvl > 0 ? false : undefined,\n          },\n        }}\n        columnConfig={cols}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MillionRows",
          "displayName": "Строк",
          "type": "full-code",
          "code": "({\n    rowsCount,\n    colsCount,\n    perCell,\n  }: {\n    rowsCount: number;\n    colsCount: number;\n    perCell: boolean;\n  }) => {\n    const rows = useMemo(() => makeLeanRows(rowsCount), [rowsCount]);\n    const columnConfig = useMemo(() => makeManyCols(colsCount), [colsCount]);\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 480 },\n          rowMarkers: { startIndex: 1 },\n          borders: perCell\n            ? {\n                horizontal: false,\n                getCellBorder: ({ columnKey, row, rowIndex }) => {\n                  if (rowIndex % 10 === 9) return BOTTOM_ON;\n                  if (columnKey !== 'complete') return undefined;\n                  return row.complete >= 50 ? BOTTOM_ON : undefined;\n                },\n              }\n            : { vertical: false },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "WithMergedCells",
          "displayName": "Регион",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(makeMergeRows);\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 420 },\n          rowMarkers: { startIndex: 1 },\n          mergeCells: { mergeByCellValues: ['region', 'dept'] },\n          hoverEffects: { row: true },\n          cellsSelection: { mode: 'range-cell' },\n          borders: {\n            vertical: false,\n            horizontal: false,\n            getCellBorder: ({ columnKey, row }) => {\n              if (columnKey === 'region' || columnKey === 'dept') {\n                return FRAME_ON;\n              }\n              if (columnKey === 'metric') {\n                return row.metric >= 50 ? SIDES_WITH_BOTTOM : SIDES_ON;\n              }\n              if (columnKey === 'status') {\n                return SIDES_ON;\n              }\n              return undefined;\n            },\n          },\n        }}\n        columnConfig={MERGE_COLS}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "SummaryVerticalBorders",
          "displayName": "ID",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n    const avgComplete = useMemo(\n      () =>\n        Math.round(rows.reduce((sum, r) => sum + r.complete, 0) / rows.length),\n      [rows],\n    );\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 420 },\n          rowMarkers: { startIndex: 1 },\n          summaryRows: { showDefault: true, showInControl: false },\n          borders: {\n            getVerticalBorder: ({ columnKey }) =>\n              columnKey === 'priority' ? false : undefined,\n          },\n        }}\n        columnConfig={SUMMARY_COLS}\n        rows={rows}\n        bottomSummaryRows={[avgComplete]}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "FullScreenMode",
      "legacy": false,
      "summary": "Включение полноэкранного режима",
      "docs": "# FullScreenMode\n\n## Ключевые особенности\n\n- Включение полноэкранного режима\n- Поддержка дефолтно открытого состояния\n- Возможность внешнего управления состоянием\n\n**tableConfig.fullScreenEnabled**\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-fullscreenmode-api--docs).",
      "apiDocs": "# Full Screen Mode API\n\n## FullScreen\n\n```typescript\ntype FullScreenObj = {\n  /**\n   * @default false\n   */\n  defaultOpened?: boolean;\n  state?: [boolean, (arg: (prev: boolean) => typeof prev) => void];\n  /**\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * @default document.body\n   */\n  portal?: Element | DocumentFragment | false;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n```\n\n## FullScreenObj\n\n```typescript\ntype FullScreenObj = {\n  /**\n   * @default false\n   */\n  defaultOpened?: boolean;\n  state?: [boolean, (arg: (prev: boolean) => typeof prev) => void];\n  /**\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * @default document.body\n   */\n  portal?: Element | DocumentFragment | false;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n```",
      "api": [
        {
          "typeName": "FullScreenObj",
          "source": "type FullScreenObj = {\n  /**\n   * @default false\n   */\n  defaultOpened?: boolean;\n  state?: [boolean, (arg: (prev: boolean) => typeof prev) => void];\n  /**\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * @default document.body\n   */\n  portal?: Element | DocumentFragment | false;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};"
        },
        {
          "typeName": "FullScreenObj",
          "source": "type FullScreenObj = {\n  /**\n   * @default false\n   */\n  defaultOpened?: boolean;\n  state?: [boolean, (arg: (prev: boolean) => typeof prev) => void];\n  /**\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * @default document.body\n   */\n  portal?: Element | DocumentFragment | false;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "FullscreenEnabling",
          "displayName": "Полноэкранный режим",
          "type": "full-code",
          "code": "import React, { useMemo, useState } from 'react';\nimport { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport { Button } from '@daisforge/ui';\nimport { IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: (\n            <Canvas.Container\n              direction=\"row\"\n              justifyContent=\"space-between\"\n              alignItems=\"center\"\n            >\n              <Canvas.Text>id</Canvas.Text>\n              <Canvas.Icon icon={<IconSber size=\"xs\" color=\"inherit\" />} />\n            </Canvas.Container>\n          ),\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 200 },\n          fullScreenEnabled: true,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "FullscreenDefaultOpened",
          "displayName": "Включение по умолчанию полноэкранного режима",
          "type": "full-code",
          "code": "import React, { useMemo, useState } from 'react';\nimport { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport { Button } from '@daisforge/ui';\nimport { IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: (\n            <Canvas.Container\n              direction=\"row\"\n              justifyContent=\"space-between\"\n              alignItems=\"center\"\n            >\n              <Canvas.Text>id</Canvas.Text>\n              <Canvas.Icon icon={<IconSber size=\"xs\" color=\"inherit\" />} />\n            </Canvas.Container>\n          ),\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <div style={{ height: 500 }}>\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: 200 },\n            fullScreenEnabled: { defaultOpened: true },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "FullscreenCustomState",
          "displayName": "Полноэкранный режим c ручным управлением и контролем показа иконки в ControlBlock",
          "type": "full-code",
          "code": "import React, { useMemo, useState } from 'react';\nimport { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport { Button } from '@daisforge/ui';\nimport { IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: (\n            <Canvas.Container\n              direction=\"row\"\n              justifyContent=\"space-between\"\n              alignItems=\"center\"\n            >\n              <Canvas.Text>id</Canvas.Text>\n              <Canvas.Icon icon={<IconSber size=\"xs\" color=\"inherit\" />} />\n            </Canvas.Container>\n          ),\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n    const [fullScreened, setFullScreened] = useState(false);\n\n    return (\n      <div style={{ height: 500 }}>\n        <Button view=\"positive\" onClick={() => setFullScreened(true)}>\n          На весь экран\n        </Button>\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: 200 },\n            fullScreenEnabled: {\n              state: [fullScreened, setFullScreened],\n              showInControl: fullScreened,\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "HighlightActiveType",
      "legacy": false,
      "summary": "Две независимые оси:",
      "docs": "# Highlight Active Type\n\nДве независимые оси:\n\n- **`tableConfig.cellsSelection.mode`** — режим фактического выделения ячеек. По нему\n  работают copy/paste, рамка, fill-handle, затемнение шапки/нумерации.\n- **`tableConfig.highlightActiveType`** — чисто визуальная подсветка строки.\n\n## cellsSelection.mode\n\n- `'range-cell'` — выделение диапазона ячеек (по умолчанию)\n- `'cell'` — выделение одной ячейки\n- `'disabled'` — выделение ячеек отключено\n\n## highlightActiveType\n\n- `'row'` — подсветка строки активной ячейки (залипает на строке клика; стрелки\n  двигают выделение, подсветка остаётся; перекрывается выделением на активной\n  ячейке)\n- `'disabled'` — без подсветки строки (по умолчанию)\n\n> **Deprecated:** значения `highlightActiveType` `'cell'` и `'range-cell'`\n> устарели — режим выделения теперь задаётся через `cellsSelection.mode`. Для\n> `highlightActiveType` используйте только `'row'` / `'disabled'`.\n\n## Особенности\n\n- Оси независимы: можно `cellsSelection.mode='range-cell'` + `highlightActiveType='row'`.\n- Работает совместно с row markers и различными размерами строк.\n- Режимы переключаются динамически.\n\n> Подробнее о типах и пропсах — [HighlightActiveType API](?path=/docs/локальные-компоненты-tablecanvas-highlightactivetype-api--docs)\n\n# HighlightActiveType + SplitView\n\nПодсвеченная строка (`highlightActiveType='row'`) выступает источником «открытой»\nстроки: по клику она открывается в боковой панели `SplitView`, при закрытии панели\nподсветка гаснет. Пример — на древовидной таблице (блок → трайб → продукт).\n\n## Ключевые особенности\n\n- **Источник — подсветка, а не чекбоксы.** Открытую строку определяет\n  `highlightActiveType`, а не `tableConfig.selecting`. Это разные оси: можно\n  одновременно иметь чекбоксы и открывать в панели именно подсвеченную строку.\n- **Двусторонняя связь через controlled-стейт.** `tableConfig.highlightActiveRow.state`\n  — внешний `useState`. Клик по строке вызывает сеттер (панель открывается),\n  закрытие панели вызывает `setActiveRow(undefined)` (подсветка гаснет).\n- **Открытость панели = наличие подсветки:** `sidebar.isOpened = activeRow !== undefined`.\n- **Объект строки — из `highlightActiveRow.onChange`.** Колбэк отдаёт и флэт-индекс,\n  и сам узел дерева (`row`) — таблица резолвит его по индексу сама. Отдельный\n  `onCellClicked` не нужен.\n\n## Особенности\n\n- **Навигация стрелками не меняет открытую строку.** Подсветка обновляется только\n  на клик мышью — стрелки двигают выделение ячеек, но открытая в панели строка\n  «залипает» до следующего клика.\n- **Дерево.** Узел может быть блоком, трайбом или продуктом — карточка в панели\n  строит заголовок и поля по уровню узла. Уровень в примере выводится из данных\n  (`id`/`subRows`); в реальном приложении он обычно есть в доменной модели.\n- **Что гасит подсветку — то закрывает панель.** Клик по шапке колонки, по\n  нумерации строк или select-all сбрасывают `highlightActiveRow` → панель\n  закрывается. Если панель должна жить до явного закрытия — заведите отдельный\n  `panelOpen`-стейт вместо привязки к `activeRow`.\n- **Флэт-индекс резолвит таблица.** `highlightActiveRow` — индекс во флэт-строках\n  (с учётом раскрытых subRows). `highlightActiveRow.onChange` отдаёт по этому\n  индексу готовый объект строки, поэтому маппить индекс→узел вручную не нужно.\n\n> Подробнее о подсветке и `highlightActiveRow` — [HighlightActiveType API](?path=/docs/локальные-компоненты-tablecanvas-highlightactivetype-api--docs)",
      "apiDocs": "# HighlightActiveType / CellsSelectionMode API\n\n## CellsSelectionMode\n\nРежим фактического выделения ячеек. По нему работают copy/paste, рамка выделения,\nfill-handle, затемнение шапки/нумерации.\n\n```ts\ntype CellsSelectionMode = 'cell' | 'range-cell' | 'disabled';\n```\n\n- **`'range-cell'`** — выделение диапазона ячеек (по умолчанию)\n- **`'cell'`** — выделение одной ячейки\n- **`'disabled'`** — выделение ячеек отключено\n\n## HighlightActiveType\n\nЧисто визуальная подсветка строки (не влияет на copy/paste).\n\n```ts\ntype HighlightActiveType = 'cell' | 'row' | 'range-cell' | 'disabled';\n```\n\n- **`'row'`** — подсветка строки активной ячейки\n- **`'disabled'`** — без подсветки строки (по умолчанию)\n- **`'cell'`**, **`'range-cell'`** — `@deprecated`, режим выделения теперь задаётся\n  через `cellsSelection.mode`",
      "api": [],
      "stories": [
        {
          "exportName": "HighlightActiveTypePlayground",
          "displayName": "HighlightActiveTypePlayground",
          "type": "full-code",
          "code": "import {\n  type ColumnConfig,\n  type HighlightActiveType,\n  type CellsSelectionMode,\n  type SIZE_GLIDE_INSTANCE as RowSize,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\nconst HIGHLIGHT_ACTIVE_TYPE_OPTIONS: readonly HighlightActiveType[] = [\n  'row',\n  'disabled',\n];\nconst SELECTION_MODE_OPTIONS: readonly CellsSelectionMode[] = [\n  'range-cell',\n  'multi-range-cell',\n  'cell',\n  'disabled',\n];\nconst ROW_SIZE_OPTIONS: readonly RowSize[] = ['big', 'medium', 'small'];\nconst ROW_MARKER_WIDTH_BY_SIZE: Record<RowSize, number> = {\n  big: 48,\n  medium: 32,\n  small: 24,\n};\nconst COLUMN_CONFIG: readonly ColumnConfig<Row>[] = [\n  { key: 'id', name: 'ID', width: 90 },\n  { key: 'task', name: 'Title', width: 260 },\n  { key: 'priority', name: 'Priority', width: 180 },\n  { key: 'issueType', name: 'Issue Type', width: 180 },\n  { key: 'complete', name: '% Complete', width: 160 },\n];\nconst getRowSelectionKey = (row: Row) => row.id + row.issueType;\n\n() => {\n    const [highlightActiveType, setHighlightActiveType] =\n      useState<HighlightActiveType>('row');\n    const [selectionMode, setSelectionMode] =\n      useState<CellsSelectionMode>('range-cell');\n    const [rowSize, setRowSize] = useState<RowSize>('medium');\n    const [rows] = useState(createRows);\n\n    const selectingStateAndSetter = useState<ReadonlySet<string | number>>(\n      () =>\n        new Set(\n          rows\n            .filter((row) => [3, 5].includes(Number(row.id)))\n            .map(getRowSelectionKey),\n        ),\n    );\n\n    const columnConfig = useMemo<readonly ColumnConfig<TableRow>[]>(\n      () => COLUMN_CONFIG,\n      [],\n    );\n\n    return (\n      <>\n        <div\n          style={{ display: 'grid', gap: 12, maxWidth: 420, marginBottom: 16 }}\n        >\n          <div>\n            cellsSelection.mode (режим выделения)\n            <Select\n              value={selectionMode}\n              onChange={(value) =>\n                setSelectionMode(value as CellsSelectionMode)\n              }\n              items={SELECTION_MODE_OPTIONS.map((item) => ({\n                label: item,\n                value: item,\n              }))}\n            />\n          </div>\n\n          <div>\n            highlightActiveType (подсветка строки)\n            <Select\n              value={highlightActiveType}\n              onChange={(value) =>\n                setHighlightActiveType(value as HighlightActiveType)\n              }\n              items={HIGHLIGHT_ACTIVE_TYPE_OPTIONS.map((item) => ({\n                label: item,\n                value: item,\n              }))}\n            />\n          </div>\n\n          <div>\n            Размер строки\n            <Select\n              value={rowSize}\n              onChange={(value) => setRowSize(value as RowSize)}\n              items={ROW_SIZE_OPTIONS.map((item) => ({\n                label: item,\n                value: item,\n              }))}\n            />\n          </div>\n        </div>\n\n        <TableCanvas\n          key={[\n            highlightActiveType,\n            selectionMode,\n            rowSize,\n            'row-markers',\n            'summary-checkbox',\n          ].join('-')}\n          tableConfig={{\n            containerStyle: { height: '700px', maxWidth: 980 },\n            rowSize: {\n              default: rowSize,\n              showInControl: false,\n            },\n            cellsSelection: { mode: selectionMode },\n            highlightActiveType,\n            rowMarkers: {\n              startIndex: 1,\n              width: ROW_MARKER_WIDTH_BY_SIZE[rowSize],\n            },\n            selecting: {\n              state: selectingStateAndSetter,\n              rowKeyGetter: getRowSelectionKey,\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        },
        {
          "exportName": "HighlightActiveRowControlled",
          "displayName": "Контролируемая подсветка строки (controlled)",
          "type": "full-code",
          "code": "import {\n  type ColumnConfig,\n  type HighlightActiveType,\n  type CellsSelectionMode,\n  type SIZE_GLIDE_INSTANCE as RowSize,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\nconst HIGHLIGHT_ACTIVE_TYPE_OPTIONS: readonly HighlightActiveType[] = [\n  'row',\n  'disabled',\n];\nconst SELECTION_MODE_OPTIONS: readonly CellsSelectionMode[] = [\n  'range-cell',\n  'multi-range-cell',\n  'cell',\n  'disabled',\n];\nconst ROW_SIZE_OPTIONS: readonly RowSize[] = ['big', 'medium', 'small'];\nconst ROW_MARKER_WIDTH_BY_SIZE: Record<RowSize, number> = {\n  big: 48,\n  medium: 32,\n  small: 24,\n};\nconst COLUMN_CONFIG: readonly ColumnConfig<Row>[] = [\n  { key: 'id', name: 'ID', width: 90 },\n  { key: 'task', name: 'Title', width: 260 },\n  { key: 'priority', name: 'Priority', width: 180 },\n  { key: 'issueType', name: 'Issue Type', width: 180 },\n  { key: 'complete', name: '% Complete', width: 160 },\n];\nconst getRowSelectionKey = (row: Row) => row.id + row.issueType;\n\n() => {\n    const [rows] = useState(createRows);\n    const columnConfig = useMemo<readonly ColumnConfig<TableRow>[]>(\n      () => COLUMN_CONFIG,\n      [],\n    );\n\n    const highlightActiveRowState = useState<number | undefined>(undefined);\n    const [highlightActiveRow, setHighlightActiveRow] = highlightActiveRowState;\n\n    return (\n      <>\n        <div\n          style={{\n            display: 'flex',\n            gap: 8,\n            flexWrap: 'wrap',\n            marginBottom: 12,\n          }}\n        >\n          <Button onClick={() => setHighlightActiveRow(2)}>\n            Подсветить строку №3\n          </Button>\n          <Button onClick={() => setHighlightActiveRow(undefined)}>\n            Сбросить подсветку строки\n          </Button>\n        </div>\n\n        <StoryHint>\n          Подсветка активной строки — <b>controlled</b> через{' '}\n          <code>tableConfig.highlightActiveRow.state</code>. Кнопки\n          задают/сбрасывают внешний стейт; клик по строке тоже обновляет его.\n          Подсвеченная строка: <b>{highlightActiveRow ?? '—'}</b>.\n        </StoryHint>\n\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '600px' },\n            highlightActiveType: 'row',\n            rowMarkers: { startIndex: 1 },\n            highlightActiveRow: { state: highlightActiveRowState },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        },
        {
          "exportName": "HighlightActiveTypeSplitView",
          "displayName": "HighlightActiveType + SplitView (дерево)",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(() => createRowsTree());\n\n    // Controlled-подсветка: индексом подсвеченной строки владеет внешний стейт.\n    // Он же — признак «панель открыта»: панель показывается, пока строка\n    // подсвечена.\n    const activeRowState = useState<number | undefined>(undefined);\n    const [activeRow, setActiveRow] = activeRowState;\n\n    // Объект подсвеченной строки приходит из highlightActiveRow.onChange —\n    // таблица сама резолвит узел дерева по флэт-индексу, onCellClicked не нужен.\n    const [activeRowData, setActiveRowData] = useState<TreeRow | null>(null);\n    const [fullScreened, setFullScreened] = useState(false);\n\n    // Закрытие панели → обратное связывание: гасим подсветку строки. Данные\n    // чистим после анимации закрытия, чтобы контент не мигал.\n    const closePanel = () => {\n      setActiveRow(undefined);\n      setFullScreened(false);\n      setTimeout(() => setActiveRowData(null), 300);\n    };\n\n    return (\n      <div style={{ backgroundColor: backgroundPrimary }}>\n        <StoryHeader>Header FinAI</StoryHeader>\n\n        <SplitView\n          mainContent={\n            <TableCanvas\n              tableConfig={{\n                containerStyle: { height: '70vh' },\n                subRows: {\n                  getSubRows: (row) => row?.subRows,\n                  rowKeyGetter: (row) => row.id,\n                },\n                cellsSelection: { mode: 'range-cell' },\n                highlightActiveType: 'row',\n                highlightActiveRow: {\n                  state: activeRowState,\n                  // И индекс, и сам узел дерева приходят сюда — без onCellClicked.\n                  onChange: ({ row }) => setActiveRowData(row ?? null),\n                },\n              }}\n              columnConfig={TREE_COLUMNS}\n              rows={rows}\n            />\n          }\n          sidebar={{\n            isOpened: activeRow !== undefined,\n            isFullScreened: fullScreened,\n            defaultWidthPercent: 35,\n            content: ({ avatarSize }: SplitViewSlotSizesProps) => (\n              <RowDetailsWidget\n                row={activeRowData}\n                avatarSize={avatarSize}\n                fullScreened={fullScreened}\n                onClose={closePanel}\n                onToggleFullScreen={() => setFullScreened((prev) => !prev)}\n              />\n            ),\n          }}\n        />\n      </div>\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "HoverEffects",
      "legacy": false,
      "summary": "Эффекты при наведении — единый расширяемый конфиг `tableConfig.hoverEffects`.",
      "docs": "# Hover Effects\n\nЭффекты при наведении — единый расширяемый конфиг `tableConfig.hoverEffects`.\nСейчас поддерживается **подсветка строки под курсором** (`row`). Чисто визуальная фича, по умолчанию\n**выключена**. В будущем в этом же объекте появятся hover по ячейке и т.д.\n\n## Как включить\n\n```tsx\ntableConfig={{ hoverEffects: { row: true } }} // цвета из темы\n```\n\n## Цвета (уровень темы)\n\n- **data-ячейки** hovered-строки — серый `bgRowHovered`;\n- **служебные колонки** (нумерация / чекбокс / инструменты строк) hovered-строки\n  не сереют — темнеют голубым `bgServiceRowHovered`, тем же цветом, что\n  сервис-зона при селектинге;\n- строка, **отмеченная чекбоксом** (`selecting`), под курсором темнеет целиком —\n  `bgSelectedRowHovered` (как hover шапки), вместо серого.\n\n## Приоритеты слоёв (важно)\n\nHover — **самый нижний визуальный слой**, он не конкурирует с выделением:\n\n- выделение ячеек/строк/колонок (`cellsSelection`) и «залипшая» активная строка\n  (`highlightActiveType='row'`) рисуются **поверх** и перекрывают hover;\n- после сброса выделения hover под курсором снова виден;\n- summary-строки hover не получают.\n\n## Особенности\n\n- Работает по всей строке: hover срабатывает над любой ячейкой строки,\n  включая нумерацию и чекбокс.\n- Уход мыши с таблицы (или на шапку/групп-хедер) сбрасывает подсветку.\n- Не требует `themeOverride` и не влияет на copy/paste и прочую логику\n  выделения — ось полностью независимая. Не путать с `highlightActiveType` —\n  тот подсвечивает строку по **клику** («залипает»), hover — по наведению.\n\n> Подробнее о типах — [HoverEffects API](?path=/docs/локальные-компоненты-tablecanvas-hovereffects-api--docs)\n\n> Внутреннее устройство и почему такие приоритеты — в доке\n> `packages/ui-kit/src/components/TableCanvas/docs/SelectionAndHighlighting.md`,\n> раздел 7.",
      "apiDocs": "# HoverEffects API\n\n## HoverEffectsConfig\n\n`tableConfig.hoverEffects` — единый конфиг эффектов при наведении. Значения,\nцвета по зонам строки и приоритет слоёв описаны в комментариях к типу.\n\n```typescript\ntype HoverEffectsConfig = {\n  /**\n   * Подсветка строки под курсором. По умолчанию выключена.\n   * - не задано или `false` — выключена;\n   * - `true` — включена, цвета из темы.\n   *\n   * Цвета по зонам строки берутся из темы:\n   * - data-ячейки — `bgRowHovered`;\n   * - служебные колонки (нумерация, чекбокс) — `bgServiceRowHovered`, тот же\n   *   цвет, что у сервис-зоны при выделении;\n   * - строка, отмеченная чекбоксом, темнеет целиком `bgSelectedRowHovered`.\n   *\n   * Hover — самый нижний слой: выделение ячеек, строк, колонок и залипшая\n   * активная строка (`highlightActiveType: 'row'`) рисуются поверх и\n   * перекрывают его; после сброса выделения он снова виден. Summary-строки\n   * hover не получают.\n   */\n  row?: boolean;\n};\n```",
      "api": [
        {
          "typeName": "HoverEffectsConfig",
          "source": "type HoverEffectsConfig = {\n  /**\n   * Подсветка строки под курсором. По умолчанию выключена.\n   * - не задано или `false` — выключена;\n   * - `true` — включена, цвета из темы.\n   *\n   * Цвета по зонам строки берутся из темы:\n   * - data-ячейки — `bgRowHovered`;\n   * - служебные колонки (нумерация, чекбокс) — `bgServiceRowHovered`, тот же\n   *   цвет, что у сервис-зоны при выделении;\n   * - строка, отмеченная чекбоксом, темнеет целиком `bgSelectedRowHovered`.\n   *\n   * Hover — самый нижний слой: выделение ячеек, строк, колонок и залипшая\n   * активная строка (`highlightActiveType: 'row'`) рисуются поверх и\n   * перекрывают его; после сброса выделения он снова виден. Summary-строки\n   * hover не получают.\n   */\n  row?: boolean;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "HoverEffectsPlayground",
          "displayName": "HoverEffectsPlayground",
          "type": "full-code",
          "code": "import { useMemo, useState } from 'react';\nimport { Select } from '@daisforge/ui/components/Select';\nimport {\n  type CellsSelectionMode,\n  type ColumnConfig,\n  type HighlightActiveType,\n  type HoverEffectsConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\n// Варианты значения tableConfig.hoverEffects для селекта.\ntype HoverEffectsOption = 'disabled' | 'row';\n\nconst HOVER_EFFECTS_OPTIONS: readonly HoverEffectsOption[] = ['row', 'disabled'];\n\n// Каждый вариант это готовое значение tableConfig.hoverEffects.\nconst HOVER_EFFECTS_BY_OPTION: Record<HoverEffectsOption, HoverEffectsConfig> = {\n  disabled: {},\n  row: { row: true },\n};\n\nconst HIGHLIGHT_ACTIVE_TYPE_OPTIONS: readonly HighlightActiveType[] = [\n  'row',\n  'disabled',\n];\n\nconst SELECTION_MODE_OPTIONS: readonly CellsSelectionMode[] = [\n  'range-cell',\n  'multi-range-cell',\n  'cell',\n  'disabled',\n];\n\nconst COLUMN_CONFIG: readonly ColumnConfig<Row>[] = [\n  { key: 'id', name: 'ID', width: 90 },\n  { key: 'task', name: 'Title', width: 260 },\n  { key: 'priority', name: 'Priority', width: 180 },\n  { key: 'issueType', name: 'Issue Type', width: 180 },\n  { key: 'complete', name: '% Complete', width: 160 },\n];\nconst getRowSelectionKey = (row: Row) => row.id + row.issueType;\n\n() => {\n    const [hoverOption, setHoverOption] = useState<HoverEffectsOption>('row');\n    const [highlightActiveType, setHighlightActiveType] =\n      useState<HighlightActiveType>('row');\n    const [selectionMode, setSelectionMode] =\n      useState<CellsSelectionMode>('range-cell');\n    const [rows] = useState(createRows);\n\n    const selectingStateAndSetter = useState<ReadonlySet<string | number>>(\n      () =>\n        new Set(\n          rows\n            .filter((row) => [3, 5].includes(Number(row.id)))\n            .map(getRowSelectionKey),\n        ),\n    );\n\n    const columnConfig = useMemo<readonly ColumnConfig<TableRow>[]>(\n      () => COLUMN_CONFIG,\n      [],\n    );\n\n    return (\n      <>\n        <div\n          style={{ display: 'grid', gap: 12, maxWidth: 420, marginBottom: 16 }}\n        >\n          <div>\n            hoverEffects (эффекты при наведении)\n            <Select\n              value={hoverOption}\n              onChange={(value) => setHoverOption(value as HoverEffectsOption)}\n              items={HOVER_EFFECTS_OPTIONS.map((item) => ({\n                label: item,\n                value: item,\n              }))}\n            />\n          </div>\n\n          <div>\n            highlightActiveType (залипшая активная строка)\n            <Select\n              value={highlightActiveType}\n              onChange={(value) =>\n                setHighlightActiveType(value as HighlightActiveType)\n              }\n              items={HIGHLIGHT_ACTIVE_TYPE_OPTIONS.map((item) => ({\n                label: item,\n                value: item,\n              }))}\n            />\n          </div>\n\n          <div>\n            cellsSelection.mode (режим выделения)\n            <Select\n              value={selectionMode}\n              onChange={(value) =>\n                setSelectionMode(value as CellsSelectionMode)\n              }\n              items={SELECTION_MODE_OPTIONS.map((item) => ({\n                label: item,\n                value: item,\n              }))}\n            />\n          </div>\n        </div>\n\n        <StoryHint>\n          Водите мышью по строкам — data-ячейки подсвечиваются серым, служебные\n          колонки (нумерация/чекбокс) — голубым, как при селектинге.\n          Checkbox-строки (3 и 5) под курсором темнеют целиком. Клик по строке\n          (активная строка / выделение) рисуется <b>поверх</b> hover-подсветки и\n          перекрывает её; после сброса выделения hover снова виден.\n        </StoryHint>\n\n        <TableCanvas\n          key={[hoverOption, highlightActiveType, selectionMode].join('-')}\n          tableConfig={{\n            containerStyle: { height: '700px', maxWidth: 980 },\n            hoverEffects: HOVER_EFFECTS_BY_OPTION[hoverOption],\n            highlightActiveType,\n            cellsSelection: { mode: selectionMode },\n            rowMarkers: { startIndex: 1 },\n            selecting: {\n              state: selectingStateAndSetter,\n              rowKeyGetter: getRowSelectionKey,\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        },
        {
          "exportName": "HoverEffectsRowSimple",
          "displayName": "Минимальное включение",
          "type": "full-code",
          "code": "import {\n  type CellsSelectionMode,\n  type ColumnConfig,\n  type HighlightActiveType,\n  type HoverEffectsConfig,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\nconst COLUMN_CONFIG: readonly ColumnConfig<Row>[] = [\n  { key: 'id', name: 'ID', width: 90 },\n  { key: 'task', name: 'Title', width: 260 },\n  { key: 'priority', name: 'Priority', width: 180 },\n  { key: 'issueType', name: 'Issue Type', width: 180 },\n  { key: 'complete', name: '% Complete', width: 160 },\n];\nconst getRowSelectionKey = (row: Row) => row.id + row.issueType;\n\n() => {\n    const [rows] = useState(createRows);\n    const columnConfig = useMemo<readonly ColumnConfig<TableRow>[]>(\n      () => COLUMN_CONFIG,\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '600px' },\n          hoverEffects: { row: true },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "InfinityScroll",
      "legacy": false,
      "summary": "*tableConfig.infinityScroll**",
      "docs": "# Infinity Scroll\n\n**tableConfig.infinityScroll**\n\nБесконечная подгрузка данных при скролле. Для активации в `tableConfig` заполняется `infinityScroll`.\n\n## Принцип работы\n\nПри приближении скролла к концу таблицы вызывается функция `onTrigger`, в этот момент можно подгружать новую пачку данных и управлять состоянием загрузки через `isLoading`.\n\nПри активации `infinityScroll` **отключается дефолтная сортировка и фильтрация**. Предполагается, что если есть infinityScroll, то в таблице представлен не весь объем данных, по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные. Нужно использовать версии данных фичей с ручным управлением (например, для отправки на бэкенд выбранных фильтров и сортировки).\n\n## Как работает определение позиции скролла\n\nИспользуется callback `onVisibleRegionChanged`. Работа ведётся на уровне индексов строк — триггер срабатывает, когда пользователь доскролливает до `rowThreshold` строк от конца (по умолчанию 5).\n\n```tsx\ntableConfig={{\n  infinityScroll: {\n    rowThreshold: 5,\n    onTrigger,\n    isLoading,\n    hasMore: rows.length < 300,\n  },\n}}\n```\n\n> **Примечание:** К значению `rowThreshold` автоматически прибавляется количество skeleton-строк, чтобы триггер загрузки срабатывал раньше и пользователь не видел скелетоны.\n\n## Конфигурация\n\n```tsx\ninfinityScroll: {\n  onTrigger: (rows: RowType[]) => Promise<void> | void;\n  isLoading: boolean;\n  hasMore?: boolean;              // default: true\n  rowThreshold?: number;          // default: 5 (строк)\n}\n```\n\n- **`onTrigger`** — вызывается при достижении скроллом зоны подгрузки. Получает текущий массив строк.\n- **`isLoading`** — состояние загрузки. При `true` внизу таблицы отображаются skeleton-строки, повторные триггеры блокируются.\n- **`hasMore`** — когда все данные загружены, передать `false`. Скелетоны скроются, триггер перестанет вызываться.\n- **`rowThreshold`** — за сколько строк до конца стригерить загрузку. @default=5\n\nПодробное описание типов доступно в разделе [API](/docs/локальные-компоненты-tablecanvas-infinityscroll-api--docs).",
      "apiDocs": "# Infinity Scroll API\n\n## InfinityScrollConfig\n\n```typescript\ntype InfinityScrollConfig<RowType extends ObjectForExtending> = {\n  /** Триггер достижения скроллом зоны подгрузки данных. */\n  onTrigger: (rows: RowType[]) => Promise<void> | void;\n  /** Состояние загрузки (скелетоны) новых строк. */\n  isLoading: boolean;\n  /**\n   * Флаг, когда все данные загружены — false.\n   * @default true\n   */\n  hasMore?: boolean;\n  /**\n   * Для mode='region': за сколько строк до конца триггерить загрузку.\n   * @default 5\n   */\n  rowThreshold?: number;\n};\n```",
      "api": [
        {
          "typeName": "InfinityScrollConfig",
          "source": "type InfinityScrollConfig<RowType extends ObjectForExtending> = {\n  /** Триггер достижения скроллом зоны подгрузки данных. */\n  onTrigger: (rows: RowType[]) => Promise<void> | void;\n  /** Состояние загрузки (скелетоны) новых строк. */\n  isLoading: boolean;\n  /**\n   * Флаг, когда все данные загружены — false.\n   * @default true\n   */\n  hasMore?: boolean;\n  /**\n   * Для mode='region': за сколько строк до конца триггерить загрузку.\n   * @default 5\n   */\n  rowThreshold?: number;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "RegionModeStory",
          "displayName": "Region Mode (default)",
          "type": "full-code",
          "code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport { Canvas, ColumnConfig, TableCanvas } from '@ui-kit/components/TableCanvas';\nimport React, { useCallback, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.InfinityScroll/TableCanvasInfinityScroll.stories.tsx',\n  'ExampleRegionMode',\n)}"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "IsLoading",
      "legacy": false,
      "summary": "*tableConfig.isLoading / tableConfig.loadingOverlay**",
      "docs": "# IsLoading (TableCanvas)\n\n**tableConfig.isLoading / tableConfig.loadingOverlay**\n\nСостояние загрузки таблицы. Поддерживает скелетон-строки и полноэкранный оверлей.\n\n## Ключевые особенности\n\n- Скелетон-строки при загрузке данных (`isLoading`)\n- Настраиваемое количество скелетон-строк (`skeletonRowsCount`)\n- Полноэкранный оверлей с кастомным спиннером (`loadingOverlay`)\n- Задержка показа подзаголовка (`showSubtitleDelay`)\n\n## Когда использовать loadingOverlay\n\n- Динамическая загрузка схемы таблицы — колонки загружаются с бэкенда\n- Конфигурируемые таблицы — пользователь сам настраивает колонки\n- Ошибки загрузки структуры — не удалось загрузить метаданные\n\n> Подробнее о типах — [IsLoading API](?path=/docs/локальные-компоненты-tablecanvas-isloading-api--docs)",
      "apiDocs": "# IsLoading API\n\n## tableConfig.isLoading\n\n```ts\nisLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n```\n\n- **`boolean`** — простой флаг загрузки, количество skeleton-строк определяется автоматически\n- **`{ boolean, skeletonRowsCount }`** — загрузка с явным указанием количества skeleton-строк\n\n## tableConfig.loadingOverlay\n\n```ts\nloadingOverlay?: {\n  active?: boolean; // default: true\n  spinner?: ReactNode; // default: <Spinner view=\"secondary\" size=\"36\" />\n  title?: string; // default: 'Загрузка таблицы'\n  subtitle?: string; // default: ''\n  showSubtitleDelay?: number; // default: 10000 (10 секунд)\n};\n```",
      "api": [],
      "stories": [
        {
          "exportName": "IsLoading",
          "displayName": "IsLoading",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n    const [isVisibleLoadingOverlay, setIsVisibleLoadingOverlay] =\n      useState(false);\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <>\n        <Switch\n          style={{ width: 'fit-content' }}\n          label={\n            isVisibleLoadingOverlay ? 'Скрыть overlay' : 'Показать overlay'\n          }\n          checked={isVisibleLoadingOverlay}\n          onChange={() => setIsVisibleLoadingOverlay((prev) => !prev)}\n        />\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: 500 },\n            isLoading: { boolean: true, skeletonRowsCount: 5 },\n            loadingOverlay: {\n              active: isVisibleLoadingOverlay,\n              showSubtitleDelay: 3000,\n              subtitle:\n                'Данные обрабатываются, обычно это занимает не более 10 секунд',\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "KeyText",
      "legacy": false,
      "summary": "*tableConfig.keyText**",
      "docs": "# KeyText (TableCanvas)\n\n**tableConfig.keyText**\n\nРежим отображения данных ячеек в формате «ключ — значение». Полезен для компактного представления сложных данных.\n\n## Ключевые особенности\n\n- Переключение между обычным табличным и key-text представлением\n- Кнопка переключения в controlBlock и/или sidebar\n- Кастомная конфигурация отображения через `KeyTextConfig`\n- Поддержка кастомных ключей и значений для каждой колонки\n\n## Особенности\n\n- При активации keyText колонки отображаются в формате `название колонки: значение`\n- Переключение режима не влияет на данные, только на визуальное представление\n- Работает совместно с другими фичами (сортировка, фильтрация, выделение)\n\n> Подробнее о типах — [KeyText API](?path=/docs/локальные-компоненты-tablecanvas-keytext-api--docs)",
      "apiDocs": "# KeyText API\n\n## KeyText\n\n```typescript\ntype KeyText = 'key' | 'text' | 'keyText' | 'textKey';\n```\n\n## KeyTextConfig\n\n```typescript\ntype KeyTextConfig = {\n  showInControl?: boolean;\n  defaultActiveOption?: KeyText;\n  controlBlock: {\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n     */\n    domMetadata?: DomMetadata;\n  };\n  sidebar: {\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n     */\n    domMetadata?: DomMetadata;\n  };\n};\n```",
      "api": [
        {
          "typeName": "KeyText",
          "source": "type KeyText = 'key' | 'text' | 'keyText' | 'textKey';"
        },
        {
          "typeName": "KeyTextConfig",
          "source": "type KeyTextConfig = {\n  showInControl?: boolean;\n  defaultActiveOption?: KeyText;\n  controlBlock: {\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n     */\n    domMetadata?: DomMetadata;\n  };\n  sidebar: {\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n     */\n    domMetadata?: DomMetadata;\n  };\n};"
        }
      ],
      "stories": [
        {
          "exportName": "KeyTextTable",
          "displayName": "Ключ текст",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'task',\n          name: 'Title',\n          keyText: {\n            key: 'kek',\n            name: 'Ключ - Title',\n            renderCell: ({ row }) => String(row.id),\n          },\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          keyText: true,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "Notifications",
      "legacy": false,
      "summary": "Стандартизированный канал событий таблицы для внешних потребителей. Таблица",
      "docs": "# Notifications\n\nСтандартизированный канал событий таблицы для внешних потребителей. Таблица\n**не рисует UI сама** — она вызывает `onNotification`, а тост/модалку/уведомление\nпоказывает потребитель на своей стороне. Задаётся через\n`tableConfig.notifications`.\n\n## Ключевые особенности\n\n- **Единый колбэк** `notifications.onNotification(event)` — вызывается на каждое\n  событие таблицы.\n- **Стандартизированные типы** событий: широкая категория `type` +\n  уточняющий машинный `code` + `level` (серьёзность) + дефолтный `message`.\n- **UI на стороне потребителя** — библиотека не навязывает вид уведомления,\n  отдаёт только данные (`message` можно игнорировать и показать свой текст).\n- **Расширяемость** — новые события добавляются в каталог, конвейер не меняется.\n\n## Каталог событий\n\nСейчас эмитятся события copy / paste / fill и закрепления колонок (pin).\nКаждое событие — это `TableNotification` с полями `type` / `code` / `level`\n(см. [API](?path=/docs/локальные-компоненты-tablecanvas-notifications-api--docs)).\nФормат пункта ниже — `type` · `code` · `level`:\n\n- **`copy` · `multi-range-scattered` · `error`** — копирование при разрозненном\n  выборе сразу по разным строкам И колонкам (2D-разброс).\n- **`paste` · `multi-range-scattered` · `error`** — вставка при таком же\n  2D-разбросе выделения.\n- **`paste` · `readonly-abort` · `error`** — при `paste.readonlyBehavior:\n  'abort'` в области вставки оказалась нередактируемая ячейка.\n- **`paste` · `overflow-abort` · `error`** — при `paste.overflowBehavior:\n  'abort'` данные не поместились в границы таблицы.\n- **`paste` · `validation-skipped` · `warning`** — часть значений пропущена\n  проверкой типа ячеек (в `meta.count` — сколько).\n- **`fill` · `readonly-abort` · `error`** — при автозаполнении (fill handle) в\n  области заполнения оказалась нередактируемая ячейка.\n- **`fill` · `validation-skipped` · `warning`** — при автозаполнении часть\n  значений пропущена проверкой типа ячеек (в `meta.count` — сколько).\n- **`pin` · `no-selection` · `warning`** — попытка закрепить столбцы из меню\n  закрепления (контрл-блок) без выделенных колонок.\n\n## Как подписаться\n\n```tsx\n<TableCanvas\n  tableConfig={{\n    notifications: {\n      onNotification: (event) => {\n        // event: { type, code, level, message, meta? }\n        if (event.level === 'error') showToast(event.message, 'error');\n        // или ветвление по event.code для своих текстов\n      },\n    },\n  }}\n/>\n```\n\n## Особенности\n\n- Событие — это **данные**, а не рендер: показывать/скрывать/группировать\n  уведомления решает потребитель.\n- `meta` несёт детали события (например, `validation-skipped` → `{ count }`).\n- Наличие/отсутствие подписки не меняет поведение copy/paste — при ошибке\n  операция и так не выполняется, `onNotification` лишь дополнительно сообщает о\n  причине.\n\n> Подробнее о типах — [Notifications API](?path=/docs/локальные-компоненты-tablecanvas-notifications-api--docs)",
      "apiDocs": "# Notifications API\n\n## TableNotification\n\nАргумент события `onNotification`.\n\n```typescript\ninterface TableNotification {\n  /** Категория: с какой операцией связано событие. */\n  type: TableNotificationType;\n  /** Серьёзность. */\n  level: TableNotificationLevel;\n  /** Машинный код причины. */\n  code: TableNotificationCode;\n  /** Дефолтный текст (RU). Потребитель может показать свой. */\n  message: string;\n  /** Детали события (напр. кол-во пропущенных ячеек). */\n  meta?: Record<string, unknown>;\n}\n```\n\n## TableNotificationsConfig\n\nКонфиг модуля — `tableConfig.notifications`.\n\n```typescript\ninterface TableNotificationsConfig {\n  /** Вызывается на каждое событие таблицы (ошибки copy/paste и т.д.). */\n  onNotification: (event: TableNotification) => void;\n}\n```\n\n## TableNotificationType\n\nКатегория события (широкая группировка).\n\n```typescript\ntype TableNotificationType = 'copy' | 'paste' | 'fill' | 'pin';\n```\n\n## TableNotificationLevel\n\nУровень серьёзности.\n\n```typescript\ntype TableNotificationLevel = 'error' | 'warning' | 'info';\n```\n\n## TableNotificationCode\n\nУточняющий машинный код причины.\n\n```typescript\ntype TableNotificationCode =\n  | 'multi-range-scattered'\n  | 'readonly-abort'\n  | 'overflow-abort'\n  | 'validation-skipped'\n  | 'no-selection';\n```",
      "api": [
        {
          "typeName": "TableNotification",
          "source": "interface TableNotification {\n  /** Категория: с какой операцией связано событие. */\n  type: TableNotificationType;\n  /** Серьёзность. */\n  level: TableNotificationLevel;\n  /** Машинный код причины. */\n  code: TableNotificationCode;\n  /** Дефолтный текст (RU). Потребитель может показать свой. */\n  message: string;\n  /** Детали события (напр. кол-во пропущенных ячеек). */\n  meta?: Record<string, unknown>;\n}"
        },
        {
          "typeName": "TableNotificationsConfig",
          "source": "interface TableNotificationsConfig {\n  /** Вызывается на каждое событие таблицы (ошибки copy/paste и т.д.). */\n  onNotification: (event: TableNotification) => void;\n}"
        },
        {
          "typeName": "TableNotificationType",
          "source": "type TableNotificationType = 'copy' | 'paste' | 'fill' | 'pin';"
        },
        {
          "typeName": "TableNotificationLevel",
          "source": "type TableNotificationLevel = 'error' | 'warning' | 'info';"
        },
        {
          "typeName": "TableNotificationCode",
          "source": "type TableNotificationCode =\n  | 'multi-range-scattered'\n  | 'readonly-abort'\n  | 'overflow-abort'\n  | 'validation-skipped'\n  | 'no-selection';"
        }
      ],
      "stories": [
        {
          "exportName": "Notifications",
          "displayName": "Подписка на события (onNotification)",
          "type": "full-code",
          "code": "() => {\n    const [rows, setRows] = useState(createRows);\n    const columnConfig = useMemo(() => COLUMNS, []);\n    const [log, setLog] = useState<TableNotification[]>([]);\n\n    return (\n      <div>\n        <StoryHint>\n          Режим <b>multi-range-cell</b>. Как спровоцировать события:\n          <br />• <b>copy / multi-range-scattered</b> — Ctrl-выдели ячейки в\n          РАЗНЫХ строках и колонках → Ctrl+C.\n          <br />• <b>paste / multi-range-scattered</b> — тот же 2D-выбор →\n          Ctrl+V.\n          <br />• <b>paste / readonly-abort</b> — вставь в диапазон, задевающий\n          колонку ID.\n          <br />• <b>paste / overflow-abort</b> — вставь большой блок у\n          нижнего/правого края.\n          <br />• <b>paste / validation-skipped</b> — вставь текст в колонку «%\n          (число)».\n          <br />• <b>fill / readonly-abort</b>, <b>fill / validation-skipped</b>\n          — то же протаскиванием fill-handle.\n        </StoryHint>\n\n        <div style={{ display: 'flex', gap: 16 }}>\n          <div style={{ flex: 1, minWidth: 0 }}>\n            <TableCanvas\n              tableConfig={{\n                containerStyle: { height: '520px' },\n                cellsSelection: { mode: 'multi-range-cell' },\n                rowMarkers: { startIndex: 1 },\n                cellTransfer: {\n                  enabled: true,\n                  paste: {\n                    readonlyBehavior: 'abort',\n                    overflowBehavior: 'abort',\n                  },\n                },\n                editing: {\n                  onRowsChange: setRows,\n                  rowKeyGetter: (r) => `${r.id}`,\n                  defaultEnabled: true,\n                },\n                notifications: {\n                  onNotification: (event) =>\n                    setLog((prev) => [event, ...prev].slice(0, 20)),\n                },\n              }}\n              columnConfig={columnConfig}\n              rows={rows}\n            />\n          </div>\n\n          <div style={{ width: 340, fontSize: 12 }}>\n            <div\n              style={{\n                display: 'flex',\n                justifyContent: 'space-between',\n                alignItems: 'center',\n                marginBottom: 8,\n              }}\n            >\n              <b>Полученные события ({log.length})</b>\n              <button\n                type=\"button\"\n                onClick={() => setLog([])}\n                style={{\n                  padding: '4px 10px',\n                  borderRadius: 8,\n                  border: '1px solid #c7d2e0',\n                  background: '#fff',\n                  cursor: 'pointer',\n                }}\n              >\n                Очистить\n              </button>\n            </div>\n            {log.length === 0 && (\n              <div style={{ color: '#8893a5' }}>Пока пусто</div>\n            )}\n            {log.map((event, i) => (\n              <div\n                key={i}\n                style={{\n                  borderLeft: `3px solid ${LEVEL_COLOR[event.level]}`,\n                  padding: '6px 10px',\n                  marginBottom: 6,\n                  background: '#fafbfc',\n                }}\n              >\n                <div\n                  style={{ color: LEVEL_COLOR[event.level], fontWeight: 600 }}\n                >\n                  {event.type} · {event.code} · {event.level}\n                </div>\n                <div style={{ color: '#556' }}>{event.message}</div>\n              </div>\n            ))}\n          </div>\n        </div>\n      </div>\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "Pagination",
      "legacy": false,
      "summary": "*tableConfig.pagination**",
      "docs": "# Table Pagination\n\n**tableConfig.pagination**\n\nТаблица поддерживает пагинацию. Для активации функционала в `tableConfig` заполняется `pagination`.\n\n## Особенности работы с пагинацией\n\n### Отключение дефолтной сортировки и фильтрации\n\nПри активации `pagination` отключается дефолтная сортировка и фильтрация.\nНужно использовать версии данных фичей с ручным управлением. Например, для отправки на бэкенд выбранных фильтров и сортировки.\n\n**Причина:** Предполагается, что если есть pagination, то в таблице представлен не весь объем данных,\nпо этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные.\n\n### Адаптивные slots\n\nПо умолчанию ВЫКЛЮЧЕНА умная адаптация количества slots пагинации в зависимости от ширины контейнера таблицы и размера пагинации (`size`).\n\nЭту функциональность можно включить, установив `responsiveSlots: true`, тогда количество slots будет фиксированным (задавать `slots` в props не нужно), важно указать `value` как значение текущей выбранной страницы.\n\nПри достижении минимальной ширины контейнера, когда остается только 1 slot, автоматически отображаются навигационные стрелки в `leftContent` и `rightContent`.\n\n## Изменения в API относительно SDDS Pagination\n\n- **`onChangePageValue`** — добавлен параметр `scrollToTop: () => void` для автоматического скролла к началу новой страницы\n- **`onChange`** — добавлен параметр `scrollToTop: () => void` для автоматического скролла к началу новой страницы\n- **`responsiveSlots`** — включение/выключение умной адаптации slots (default: `false`)\n- **`onResize`** — callback при изменении ширины контейнера пагинации\n\nС основной информацией по компоненту Пагинации можно ознакомиться по [ссылке на SDDS Pagination](https://plasma.sberdevices.ru/sdds-finai/components/pagination/)\n\n> Подробнее о типах — [Pagination API](?path=/docs/локальные-компоненты-tablecanvas-pagination-api--docs)",
      "apiDocs": "# Pagination API\n\n## PaginationProps\n\n```typescript\ntype PaginationProps = Omit<\n  ComponentProps<typeof Pagination>,\n  'onChangePageValue' | 'onChange'\n> & {\n  onChangePageValue?: (\n    page: number | undefined,\n    scrollToTop: () => void,\n  ) => void;\n  onChange?: (\n    newPage: number | undefined,\n    perPage: number | undefined,\n    scrollToTop: () => void,\n  ) => void;\n  /**\n   * Нужно ли активировать умную адаптацию изменения количества слотов в зависимости от ширины блока пагинации и от size\n   * @default false\n   */\n  responsiveSlots?: boolean;\n  /**\n   * Callback при ресайзе блока с пагинацией таблицы\n   */\n  onResize?: (width: number) => void;\n};\n```",
      "api": [
        {
          "typeName": "PaginationProps",
          "source": "type PaginationProps = Omit<\n  ComponentProps<typeof Pagination>,\n  'onChangePageValue' | 'onChange'\n> & {\n  onChangePageValue?: (\n    page: number | undefined,\n    scrollToTop: () => void,\n  ) => void;\n  onChange?: (\n    newPage: number | undefined,\n    perPage: number | undefined,\n    scrollToTop: () => void,\n  ) => void;\n  /**\n   * Нужно ли активировать умную адаптацию изменения количества слотов в зависимости от ширины блока пагинации и от size\n   * @default false\n   */\n  responsiveSlots?: boolean;\n  /**\n   * Callback при ресайзе блока с пагинацией таблицы\n   */\n  onResize?: (width: number) => void;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "PaginationTable",
          "displayName": "Таблица с пагинацией",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const total = 300;\n\n    const [perPage, setPerPage] = useState(20);\n    const [currentPage, setCurrentPage] = useState(1);\n    const [rows, setRows] = useState<Row[]>([]);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    // Загрузка данных при монтировании и при изменении страницы/perPage\n    useEffect(() => {\n      const loadData = async () => {\n        const data = await getPaginationDataAsync({\n          page: currentPage,\n          perPage,\n          total,\n        });\n        setRows(data);\n      };\n\n      loadData();\n    }, [currentPage, perPage]);\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          collapsing: {\n            enableCollapse: true,\n          },\n          pagination: {\n            count: total,\n            perPage,\n            value: currentPage, // Важно указать, при активации responsiveSlots\n            responsiveSlots: true,\n            onChangePageValue(page, scrollToTop) {\n              if (typeof page === 'number') {\n                setCurrentPage(page);\n                scrollToTop();\n              }\n            },\n            async onChange(page, perPage, scrollToTop) {\n              if (typeof page === 'number' && typeof perPage === 'number') {\n                setCurrentPage(page);\n                setPerPage(perPage);\n                scrollToTop();\n              }\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "PaginationTableFixedSlots",
          "displayName": "Таблица с фиксированным количеством slots",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const total = 300;\n\n    const [perPage, setPerPage] = useState(20);\n    const [currentPage, setCurrentPage] = useState(1);\n    const [rows, setRows] = useState<Row[]>([]);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    useEffect(() => {\n      const loadData = async () => {\n        const data = await getPaginationDataAsync({\n          page: currentPage,\n          perPage,\n          total,\n        });\n        setRows(data);\n      };\n\n      loadData();\n    }, [currentPage, perPage]);\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          pagination: {\n            count: total,\n            slots: 9,\n            perPage,\n            onChangePageValue(page, scrollToTop) {\n              if (typeof page === 'number') {\n                setCurrentPage(page);\n                scrollToTop();\n              }\n            },\n            async onChange(page, perPage, scrollToTop) {\n              if (typeof page === 'number' && typeof perPage === 'number') {\n                setCurrentPage(page);\n                setPerPage(perPage);\n                scrollToTop();\n              }\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "CellPreview",
      "legacy": false,
      "summary": "Опциональное поле колоночного конфига (`columnConfig.renderCellPreview`). Управляет overlay при двойном клике на readonly-ячейку.",
      "docs": "# Cell Preview (renderCellPreview)\n\nОпциональное поле колоночного конфига (`columnConfig.renderCellPreview`). Управляет overlay при двойном клике на readonly-ячейку.\n\n## Ключевые особенности\n\n- Три режима: `'none'` (отключить превью), `'cellEditorAsPreview'` (стандартный текстовый), функция (кастомный рендер)\n- Работает как для canvas-ячеек (Badge, Icon, кнопки), так и для текстовых\n- Кастомная функция получает полный контекст ячейки: `row`, `column`, `theme`, `cellWidth`, `cellHeight`\n- Полный контроль над содержимым overlay — функция возвращает `ReactNode`\n\n## Особенности\n\n- По умолчанию (поле не задано) — текстовые ячейки показывают стандартный превью, canvas-ячейки — ничего\n- `'none'` — явно отключает превью, в том числе стандартный текстовый\n- `'cellEditorAsPreview'` — включает стандартный текстовый превью (`CellEditorTextArea` с `readOnly`). Полезно для canvas-ячеек, которым нужен текстовый overlay\n- Для текстового отображения рекомендуется `CellEditorTextArea` с активированным `readOnly` — этот компонент используется по умолчанию для отображения текста в ячейках\n- `theme` из аргумента можно использовать для стилизации (padding, цвета)\n\nОписание типов — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-cell-preview-api--docs).",
      "apiDocs": "# Cell Preview API\n\n## renderCellPreview (поле ColumnConfig)\n\nОпциональное поле в конфигурации колонки (`ColumnConfig`).\n\n```typescript\ntype RenderCellPreview<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> =\n  | 'none'\n  | 'cellEditorAsPreview'\n  | ((cellInfo: PreviewCellInfo<Row, SummRow, CustomCtxs>) => ReactNode);\n```\n\n## PreviewCellInfo (аргумент функции renderCellPreview)\n\n```typescript\ntype PreviewCellInfo<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = ObjectForExtending,\n> = Omit<PreviewCellInfoGlideInstance<R, SR, CustomCtxs>, 'column'> & {\n  column: ColumnConfig<R, SR, CustomCtxs>;\n};\n```",
      "api": [
        {
          "typeName": "RenderCellPreview",
          "source": "type RenderCellPreview<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> =\n  | 'none'\n  | 'cellEditorAsPreview'\n  | ((cellInfo: PreviewCellInfo<Row, SummRow, CustomCtxs>) => ReactNode);"
        },
        {
          "typeName": "PreviewCellInfo",
          "source": "type PreviewCellInfo<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = ObjectForExtending,\n> = Omit<PreviewCellInfoGlideInstance<R, SR, CustomCtxs>, 'column'> & {\n  column: ColumnConfig<R, SR, CustomCtxs>;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "RenderCellPreview",
          "displayName": "renderCellPreview",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState<Row[]>(() => createRows(0, 15));\n\n    const columnConfig = useMemo(\n      (): ColumnConfig<Row>[] => [\n        {\n          key: 'id',\n          name: 'ID',\n          width: 80,\n        },\n        {\n          key: 'priority',\n          name: 'Приоритет',\n          width: 200,\n          renderCell: ({ row, theme }) => (\n            <Canvas.Container\n              padding={{\n                left: theme.cellHorizontalPadding,\n                right: theme.cellHorizontalPadding,\n              }}\n              alignItems=\"center\"\n            >\n              <Canvas.Badge text={row.priority} />\n            </Canvas.Container>\n          ),\n          renderCellPreview: ({ row, cellWidth, theme }) => (\n            <div\n              style={{\n                padding: theme.cellHorizontalPadding,\n                minWidth: Math.max(cellWidth, 250),\n                display: 'flex',\n                flexDirection: 'column',\n                gap: 8,\n              }}\n            >\n              <H5>Приоритет</H5>\n              <BodyS>{row.priority}</BodyS>\n              <BodyXS style={{ opacity: 0.6 }}>Задача: {row.task}</BodyXS>\n            </div>\n          ),\n        },\n        {\n          key: 'developer',\n          name: 'Разработчик',\n          width: 200,\n          renderCell: ({ row, theme }) => (\n            <Canvas.Container\n              padding={{\n                left: theme.cellHorizontalPadding,\n                right: theme.cellHorizontalPadding,\n              }}\n              alignItems=\"center\"\n            >\n              <Canvas.Text>{row.developer}</Canvas.Text>\n            </Canvas.Container>\n          ),\n          renderCellPreview: ({ row, cellWidth, theme }) => (\n            <div\n              style={{\n                padding: theme.cellHorizontalPadding,\n                minWidth: Math.max(cellWidth, 200),\n                display: 'flex',\n                flexDirection: 'column',\n                gap: 4,\n              }}\n            >\n              <H5>Разработчик</H5>\n              <BodyS>{row.developer}</BodyS>\n              <BodyXS style={{ marginTop: 4, opacity: 0.6 }}>\n                Задача: {row.task}\n              </BodyXS>\n            </div>\n          ),\n        },\n        {\n          key: 'task',\n          name: 'Задача (без preview)',\n          width: 220,\n        },\n        {\n          key: 'complete',\n          name: 'Прогресс',\n          contentFormat: 'number',\n          width: 120,\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '500px' },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "CellEditorAsPreview",
          "displayName": "cellEditorAsPreview",
          "type": "full-code",
          "code": "() => {\n    const [rows, setRows] = useState<Row[]>(() => createRows(0, 15));\n\n    const columnConfig = useMemo(\n      (): ColumnConfig<Row>[] => [\n        {\n          key: 'id',\n          name: 'ID',\n          width: 80,\n        },\n        {\n          key: 'priority',\n          name: 'Приоритет (cellEditorAsPreview)',\n          width: 250,\n          renderCell: ({ row, theme }) => (\n            <Canvas.Container\n              padding={{\n                left: theme.cellHorizontalPadding,\n                right: theme.cellHorizontalPadding,\n              }}\n              alignItems=\"center\"\n            >\n              <Canvas.Badge text={row.priority} />\n            </Canvas.Container>\n          ),\n          editingCell: {\n            editable: false,\n            component: 'inputString',\n          },\n          renderCellPreview: 'cellEditorAsPreview',\n        },\n        {\n          key: 'task',\n          name: 'Задача',\n          width: 220,\n        },\n        {\n          key: 'complete',\n          name: 'Прогресс',\n          contentFormat: 'number',\n          width: 120,\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          editing: {\n            onRowsChange: setRows,\n            rowKeyGetter: (row) => row.id,\n            defaultEnabled: true,\n          },\n          containerStyle: { height: '500px' },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "DisablePreview",
          "displayName": "renderCellPreview: ",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState<Row[]>(() => createRows(0, 15));\n\n    const columnConfig = useMemo(\n      (): ColumnConfig<Row>[] => [\n        {\n          key: 'id',\n          name: 'ID',\n          width: 80,\n        },\n        {\n          key: 'task',\n          name: \"Задача (preview: 'none')\",\n          width: 250,\n          renderCellPreview: 'none',\n        },\n        {\n          key: 'developer',\n          name: 'Разработчик (стандартный preview)',\n          width: 250,\n        },\n        {\n          key: 'complete',\n          name: 'Прогресс',\n          contentFormat: 'number',\n          width: 120,\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '500px' },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "RowHeight",
      "legacy": false,
      "summary": "*tableConfig.rowHeight + tableConfig.rowSize**",
      "docs": "# RowHeight (TableCanvas)\n\n**tableConfig.rowHeight + tableConfig.rowSize**\n\nНастройка высоты строк таблицы. Поддерживает фиксированную высоту, динамическое вычисление и переключение размера через UI.\n\n## Ключевые особенности\n\n- Фиксированная высота строки (`number`)\n- Динамическая высота через функцию (`RowHeightFunc`)\n- Доступ к данным строки и текущему размеру (`currentRowSize`)\n- Переключатель размера строк в controlBlock (`rowSize`)\n\n## tableConfig.rowHeight\n\nОпределяет высоту каждой строки:\n\n- **`number`** — фиксированная высота в пикселях для всех строк\n- **`RowHeightFunc`** — функция, вычисляющая высоту на основе `row`, `currentRowSize` и `rowIndex`\n\n## tableConfig.rowSize\n\nПереключатель размера строк в controlBlock (кнопка с выпадающим списком):\n\n- **`showInControl`** — показывать ли кнопку в controlBlock\n- **`default`** — размер по умолчанию (`'s'`, `'m'`, `'l'`)\n- **`available`** — список доступных размеров\n- **`onRowSizeChange`** — callback при смене размера\n\n## Особенности\n\n- `RowHeightFunc` получает `currentRowSize` — объект с `rowSizeName` и `rowSizeValue`, что позволяет адаптировать высоту к текущему выбранному размеру\n- При использовании `rowHeight` как функции, рекомендуется мемоизировать её для производительности\n\n> Подробнее о типах и пропсах — [RowHeight API](?path=/docs/локальные-компоненты-tablecanvas-rowheight-api--docs)",
      "apiDocs": "# RowHeight API\n\n## RowSize\n\n```typescript\ntype RowSize = {\n  /**\n   * Показывать кнопку в блоке управления\n   */\n  showInControl: boolean;\n  /**\n   * Значение по умолчанию\n   */\n  default?: SIZE;\n  /**\n   * Список доступных значений размера\n   */\n  available?: SIZE[];\n  /**\n   * Обработчик изменения rowSize\n   * @param size\n   * @returns\n   */\n  onRowSizeChange?: (size: SIZE) => void;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n```\n\n## RowHeightFunc\n\n```typescript\ntype RowHeightFunc<RowType> = (\n  row: RowType,\n  currentRowSize: { rowSizeName: SIZE; rowSizeValue: number },\n  rowIndex: number,\n) => number;\n```",
      "api": [
        {
          "typeName": "RowSize",
          "source": "type RowSize = {\n  /**\n   * Показывать кнопку в блоке управления\n   */\n  showInControl: boolean;\n  /**\n   * Значение по умолчанию\n   */\n  default?: SIZE;\n  /**\n   * Список доступных значений размера\n   */\n  available?: SIZE[];\n  /**\n   * Обработчик изменения rowSize\n   * @param size\n   * @returns\n   */\n  onRowSizeChange?: (size: SIZE) => void;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};"
        },
        {
          "typeName": "RowHeightFunc",
          "source": "type RowHeightFunc<RowType> = (\n  row: RowType,\n  currentRowSize: { rowSizeName: SIZE; rowSizeValue: number },\n  rowIndex: number,\n) => number;"
        }
      ],
      "stories": [
        {
          "exportName": "RowHeight",
          "displayName": "Row height",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'id',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'loremIpsum',\n          name: 'Длинный текст',\n          width: 500,\n          renderCell: ({ row, theme }) => (\n            <Canvas.Container padding={8}>\n              <Canvas.Container>\n                <Canvas.Text\n                  font={theme.baseFontStyle}\n                  lineHeight={1.85}\n                  wordWrap\n                >\n                  {row.loremIpsum}\n                </Canvas.Text>\n              </Canvas.Container>\n            </Canvas.Container>\n          ),\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    const rowHeight: RowHeightFunc<Row> = useCallback((r, currenRowSize) => {\n      const symbolWidth = 11.5;\n\n      const paddingInline = 16;\n      const widthOfLoremCol = 500 - paddingInline * 2;\n      const symbolsInOneLine = Math.round(widthOfLoremCol / symbolWidth);\n      const heightOfLineInitial = 22; // в css\n      const heightOfLine = heightOfLineInitial - 2; // скорректированный\n\n      const allSymbols = r.loremIpsum.length;\n\n      const countOfLine = Math.ceil(allSymbols / symbolsInOneLine);\n      const paddingBlock = Number(\n        SIZES[currenRowSize.rowSizeName].cell['padding-block'].slice(0, -2),\n      );\n\n      const neededHeight = heightOfLine * countOfLine + paddingBlock * 2;\n\n      return neededHeight > currenRowSize.rowSizeValue\n        ? neededHeight\n        : currenRowSize.rowSizeValue;\n    }, []);\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          rowHeight,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "RowMarkers",
      "legacy": false,
      "summary": "*tableConfig.rowMarkers**",
      "docs": "# RowMarkers (TableCanvas)\n\n**tableConfig.rowMarkers**\n\nСервисный столбец с нумерацией строк. Frozen, вставляется первым, исключён из reorder/pin/hide/sort/grouping. Поддерживает плоский и древовидный (`subRows`) режимы любой глубины вложенности.\n\n## Быстрый старт\n\n```tsx\n<TableCanvas\n  tableConfig={{\n    rowMarkers: {\n      startIndex: 1,\n    },\n  }}\n  columnConfig={columnConfig}\n  rows={rows}\n/>\n```\n\n## `flatIndex` vs `rowIndex`\n\nЕсли ветка свернута, но нужно сохранить «сквозные» номера — используйте `flatIndex`.\n\n- полностью раскрыто: `1, 2, 3, 4, 5`\n- после сворачивания середины: `1, 2, 5` (а не `1, 2, 3`)\n\n`rowIndex` зависит только от видимых строк — номера будут «прыгать».\n\n## Частичная перерисовка\n\n`getRowMarker` должна быть чистой функцией. Вызывается не только при полной отрисовке таблицы, но и при ховере/скролле — для одной ячейки. Не используйте внешние переменные-счётчики — используйте аргументы (`siblingPath`, `flatIndex`, `siblingIndex`, `parentKey`), они всегда актуальны.\n\n> Подробнее о типах — [RowMarkers API](?path=/docs/локальные-компоненты-tablecanvas-rowmarkers-api--docs)",
      "apiDocs": "# RowMarkers API\n\n## RowMarkersTableConfig\n\n```typescript\ntype RowMarkersTableConfig<\n  RowType extends ObjectForExtending = ObjectForExtending,\n> = {\n  /**\n   * Стартовый индекс нумерации (для дефолтной логики без `getRowMarker`).\n   * @default 1\n   */\n  startIndex?: number;\n\n  /**\n   * Ширина столбца с нумерацией (в px).\n   * Если задан `size` — он приоритетнее.\n+  * Если ни `size`, ни `width` не заданы — ширина подстраивается\n+  * под глобальный `tableConfig.rowSize` (small=20, medium=32, big=48).\n   * @default 32\n   */\n  width?: number;\n  /**\n   * Размер столбца. Приоритетнее `width`.\n   * - `xs` = 20px\n   * - `s` = 32px\n   * - `m` = 48px\n   */\n  size?: 'xs' | 's' | 'm';\n  /**\n   * Кастомная функция нумерации. Полностью переопределяет дефолтную root-only логику.\n   * Вызывается при рендере каждой ячейки столбца нумерации.\n   *\n   * ⚠️ Вызывается не только при полной отрисовке таблицы, но и при ховере/скролле —\n   * для **одной** ячейки. Не используйте внешние переменные-счётчики —\n   * используйте аргументы (`siblingPath`, `flatIndex` и др.), они всегда актуальны.\n   *\n   * @example\n   * // Сквозная стабильная нумерация (все строки, номера не прыгают при сворачивании)\n   * getRowMarker: ({ flatIndex }) => flatIndex + 1\n   *\n   * @example\n   * // Корневые — номер, дочерние — прочерк\n   * getRowMarker: ({ isSubRow, flatIndex }) => isSubRow ? '—' : flatIndex + 1\n   *\n   * @example\n   * // Иерархическая нумерация любой глубины: 1, 1.1, 1.1.1, 1.2, 2\n   * getRowMarker: ({ siblingPath }) => siblingPath.map(i => i + 1).join('.')\n   */\n  getRowMarker?: (args: {\n    /** Данные текущей строки. */\n    row: RowType;\n    /** Уровень строки в дереве: `0` — корневая, `1` — дочерняя, `2` — внучка, и т.д. */\n    level: number;\n    /** `true`, если строка дочерняя (`level > 0`). */\n    isSubRow: boolean;\n    /**\n     * Индекс строки в **видимых** строках.\n     * **Нестабильный** — меняется при сворачивании и разворачивании веток.\n     */\n    rowIndex: number;\n    /**\n     * Стабильный 0-based индекс строки в **полном** дереве (включая скрытые/свёрнутые).\n     * Не меняется при collapse/expand — подходит для сквозной нумерации.\n     */\n    flatIndex: number;\n    /**\n     * Порядковый номер среди siblings одного родителя (0-based).\n     * Для корневых строк — порядковый номер среди всех корневых.\n     * Для дочерних — порядковый номер среди children одного `parentKey`.\n     */\n    siblingIndex: number;\n    /**\n     * Путь siblingIndex-ов от корня до текущей строки (каждый элемент 0-based).\n     *\n     * Примеры:\n     * - корневая строка (2-я): `[1]`\n     * - дочерняя (3-й ребёнок 2-го корня): `[1, 2]`\n     * - внучка (1-й ребёнок 1-го ребёнка 1-го корня): `[0, 0, 0]`\n     *\n     * Для иерархической нумерации: `siblingPath.map(i => i + 1).join('.')` → `\"1.1.1\"`\n     *\n     * Для плоской таблицы (без subRows): всегда `[siblingIndex]` (один элемент).\n     */\n    siblingPath: number[];\n    /**\n     * Ключ родительской строки (`rowKeyGetter(parent)`).\n     * `null` для корневых строк. Работает для **любой** глубины вложенности.\n     */\n    parentKey: string | number | null;\n    /** Текущий видимый `flattened` массив строк. */\n    rows: readonly RowType[];\n  }) => string | number;\n};\n```",
      "api": [
        {
          "typeName": "RowMarkersTableConfig",
          "source": "type RowMarkersTableConfig<\n  RowType extends ObjectForExtending = ObjectForExtending,\n> = {\n  /**\n   * Стартовый индекс нумерации (для дефолтной логики без `getRowMarker`).\n   * @default 1\n   */\n  startIndex?: number;\n\n  /**\n   * Ширина столбца с нумерацией (в px).\n   * Если задан `size` — он приоритетнее.\n+  * Если ни `size`, ни `width` не заданы — ширина подстраивается\n+  * под глобальный `tableConfig.rowSize` (small=20, medium=32, big=48).\n   * @default 32\n   */\n  width?: number;\n  /**\n   * Размер столбца. Приоритетнее `width`.\n   * - `xs` = 20px\n   * - `s` = 32px\n   * - `m` = 48px\n   */\n  size?: 'xs' | 's' | 'm';\n  /**\n   * Кастомная функция нумерации. Полностью переопределяет дефолтную root-only логику.\n   * Вызывается при рендере каждой ячейки столбца нумерации.\n   *\n   * ⚠️ Вызывается не только при полной отрисовке таблицы, но и при ховере/скролле —\n   * для **одной** ячейки. Не используйте внешние переменные-счётчики —\n   * используйте аргументы (`siblingPath`, `flatIndex` и др.), они всегда актуальны.\n   *\n   * @example\n   * // Сквозная стабильная нумерация (все строки, номера не прыгают при сворачивании)\n   * getRowMarker: ({ flatIndex }) => flatIndex + 1\n   *\n   * @example\n   * // Корневые — номер, дочерние — прочерк\n   * getRowMarker: ({ isSubRow, flatIndex }) => isSubRow ? '—' : flatIndex + 1\n   *\n   * @example\n   * // Иерархическая нумерация любой глубины: 1, 1.1, 1.1.1, 1.2, 2\n   * getRowMarker: ({ siblingPath }) => siblingPath.map(i => i + 1).join('.')\n   */\n  getRowMarker?: (args: {\n    /** Данные текущей строки. */\n    row: RowType;\n    /** Уровень строки в дереве: `0` — корневая, `1` — дочерняя, `2` — внучка, и т.д. */\n    level: number;\n    /** `true`, если строка дочерняя (`level > 0`). */\n    isSubRow: boolean;\n    /**\n     * Индекс строки в **видимых** строках.\n     * **Нестабильный** — меняется при сворачивании и разворачивании веток.\n     */\n    rowIndex: number;\n    /**\n     * Стабильный 0-based индекс строки в **полном** дереве (включая скрытые/свёрнутые).\n     * Не меняется при collapse/expand — подходит для сквозной нумерации.\n     */\n    flatIndex: number;\n    /**\n     * Порядковый номер среди siblings одного родителя (0-based).\n     * Для корневых строк — порядковый номер среди всех корневых.\n     * Для дочерних — порядковый номер среди children одного `parentKey`.\n     */\n    siblingIndex: number;\n    /**\n     * Путь siblingIndex-ов от корня до текущей строки (каждый элемент 0-based).\n     *\n     * Примеры:\n     * - корневая строка (2-я): `[1]`\n     * - дочерняя (3-й ребёнок 2-го корня): `[1, 2]`\n     * - внучка (1-й ребёнок 1-го ребёнка 1-го корня): `[0, 0, 0]`\n     *\n     * Для иерархической нумерации: `siblingPath.map(i => i + 1).join('.')` → `\"1.1.1\"`\n     *\n     * Для плоской таблицы (без subRows): всегда `[siblingIndex]` (один элемент).\n     */\n    siblingPath: number[];\n    /**\n     * Ключ родительской строки (`rowKeyGetter(parent)`).\n     * `null` для корневых строк. Работает для **любой** глубины вложенности.\n     */\n    parentKey: string | number | null;\n    /** Текущий видимый `flattened` массив строк. */\n    rows: readonly RowType[];\n  }) => string | number;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "SimpleRowMarkers",
          "displayName": "Простая нумерация",
          "type": "full-code",
          "code": "const TREE_SUB_ROWS_CONFIG = {\n  getSubRows: (row: TreeRow) => row?.subRows,\n  rowKeyGetter: (row: TreeRow) => row.id,\n};\n\nfunction useFlatColumns(): readonly ColumnConfig<Row>[] {\n  return useMemo(\n    () => [\n      { key: 'id', name: 'ID' },\n      { key: 'task', name: 'Task' },\n      { key: 'priority', name: 'Priority' },\n      { key: 'complete', name: '% Complete' },\n    ],\n    []\n  );\n}\n\nfunction useTreeColumns(): readonly ColumnConfig<TreeRow>[] {\n  return useMemo(\n    () => [\n      {\n        key: 'block',\n        name: 'Блок / Трайб / Продукт',\n        subRow: {\n          keyOfColumnInSubRow: (lvl) => {\n            switch (lvl) {\n              case 0: return 'block';\n              case 1: return 'tribe';\n              case 2: return 'product';\n              default: return 'block';\n            }\n          },\n          isColumnWithArrow: true,\n        },\n      },\n      { key: 'blockActivity', name: 'Активность блока' },\n    ],\n    []\n  );\n}\n\n() => {\n    const [rows] = useState(createRows);\n    const columnConfig = useFlatColumns();\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          rowMarkers: {\n            startIndex: 1,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "CustomStartIndex",
          "displayName": "Стартовый индекс 100",
          "type": "full-code",
          "code": "const TREE_SUB_ROWS_CONFIG = {\n  getSubRows: (row: TreeRow) => row?.subRows,\n  rowKeyGetter: (row: TreeRow) => row.id,\n};\n\nfunction useFlatColumns(): readonly ColumnConfig<Row>[] {\n  return useMemo(\n    () => [\n      { key: 'id', name: 'ID' },\n      { key: 'task', name: 'Task' },\n      { key: 'priority', name: 'Priority' },\n      { key: 'complete', name: '% Complete' },\n    ],\n    []\n  );\n}\n\nfunction useTreeColumns(): readonly ColumnConfig<TreeRow>[] {\n  return useMemo(\n    () => [\n      {\n        key: 'block',\n        name: 'Блок / Трайб / Продукт',\n        subRow: {\n          keyOfColumnInSubRow: (lvl) => {\n            switch (lvl) {\n              case 0: return 'block';\n              case 1: return 'tribe';\n              case 2: return 'product';\n              default: return 'block';\n            }\n          },\n          isColumnWithArrow: true,\n        },\n      },\n      { key: 'blockActivity', name: 'Активность блока' },\n    ],\n    []\n  );\n}\n\n() => {\n    const [rows] = useState(createRows);\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Task' },\n        { key: 'priority', name: 'Priority' },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          rowMarkers: {\n            startIndex: 100,\n            width: 60,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "WithSubRows",
          "displayName": "С subRows (root-only по умолчанию)",
          "type": "full-code",
          "code": "const TREE_SUB_ROWS_CONFIG = {\n  getSubRows: (row: TreeRow) => row?.subRows,\n  rowKeyGetter: (row: TreeRow) => row.id,\n};\n\nfunction useFlatColumns(): readonly ColumnConfig<Row>[] {\n  return useMemo(\n    () => [\n      { key: 'id', name: 'ID' },\n      { key: 'task', name: 'Task' },\n      { key: 'priority', name: 'Priority' },\n      { key: 'complete', name: '% Complete' },\n    ],\n    []\n  );\n}\n\nfunction useTreeColumns(): readonly ColumnConfig<TreeRow>[] {\n  return useMemo(\n    () => [\n      {\n        key: 'block',\n        name: 'Блок / Трайб / Продукт',\n        subRow: {\n          keyOfColumnInSubRow: (lvl) => {\n            switch (lvl) {\n              case 0: return 'block';\n              case 1: return 'tribe';\n              case 2: return 'product';\n              default: return 'block';\n            }\n          },\n          isColumnWithArrow: true,\n        },\n      },\n      { key: 'blockActivity', name: 'Активность блока' },\n    ],\n    []\n  );\n}\n\n() => {\n    const [rows] = useState(() => createRowsTree());\n    const columnConfig = useTreeColumns();\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          rowMarkers: {\n            startIndex: 1,\n          },\n          subRows: TREE_SUB_ROWS_CONFIG,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "CustomGetRowMarkerRootDash",
          "displayName": "getRowMarker: корневые — номер, subRows — прочерк",
          "type": "full-code",
          "code": "const TREE_SUB_ROWS_CONFIG = {\n  getSubRows: (row: TreeRow) => row?.subRows,\n  rowKeyGetter: (row: TreeRow) => row.id,\n};\n\nfunction useFlatColumns(): readonly ColumnConfig<Row>[] {\n  return useMemo(\n    () => [\n      { key: 'id', name: 'ID' },\n      { key: 'task', name: 'Task' },\n      { key: 'priority', name: 'Priority' },\n      { key: 'complete', name: '% Complete' },\n    ],\n    []\n  );\n}\n\nfunction useTreeColumns(): readonly ColumnConfig<TreeRow>[] {\n  return useMemo(\n    () => [\n      {\n        key: 'block',\n        name: 'Блок / Трайб / Продукт',\n        subRow: {\n          keyOfColumnInSubRow: (lvl) => {\n            switch (lvl) {\n              case 0: return 'block';\n              case 1: return 'tribe';\n              case 2: return 'product';\n              default: return 'block';\n            }\n          },\n          isColumnWithArrow: true,\n        },\n      },\n      { key: 'blockActivity', name: 'Активность блока' },\n    ],\n    []\n  );\n}\n\n() => {\n    const [rows] = useState(() => createRowsTree());\n    const columnConfig = useTreeColumns();\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          rowMarkers: {\n            startIndex: 1,\n            getRowMarker: ({ isSubRow, flatIndex }) => {\n              if (isSubRow) {\n                return '—';\n              }\n              return flatIndex + 1;\n            },\n          },\n          subRows: TREE_SUB_ROWS_CONFIG,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "StableIndexWithCollapsed",
          "displayName": "Стабильная нумерация (учёт скрытых строк)",
          "type": "full-code",
          "code": "const TREE_SUB_ROWS_CONFIG = {\n  getSubRows: (row: TreeRow) => row?.subRows,\n  rowKeyGetter: (row: TreeRow) => row.id,\n};\n\nfunction useFlatColumns(): readonly ColumnConfig<Row>[] {\n  return useMemo(\n    () => [\n      { key: 'id', name: 'ID' },\n      { key: 'task', name: 'Task' },\n      { key: 'priority', name: 'Priority' },\n      { key: 'complete', name: '% Complete' },\n    ],\n    []\n  );\n}\n\nfunction useTreeColumns(): readonly ColumnConfig<TreeRow>[] {\n  return useMemo(\n    () => [\n      {\n        key: 'block',\n        name: 'Блок / Трайб / Продукт',\n        subRow: {\n          keyOfColumnInSubRow: (lvl) => {\n            switch (lvl) {\n              case 0: return 'block';\n              case 1: return 'tribe';\n              case 2: return 'product';\n              default: return 'block';\n            }\n          },\n          isColumnWithArrow: true,\n        },\n      },\n      { key: 'blockActivity', name: 'Активность блока' },\n    ],\n    []\n  );\n}\n\n() => {\n    const [rows] = useState(() => createRowsTree());\n    const columnConfig = useTreeColumns();\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          rowMarkers: {\n            startIndex: 1,\n            getRowMarker: ({ flatIndex }) => flatIndex + 1,\n          },\n          subRows: TREE_SUB_ROWS_CONFIG,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "UnstableFlatIndex",
          "displayName": "getRowMarker: нестабильная нумерация (rowIndex)",
          "type": "full-code",
          "code": "const TREE_SUB_ROWS_CONFIG = {\n  getSubRows: (row: TreeRow) => row?.subRows,\n  rowKeyGetter: (row: TreeRow) => row.id,\n};\n\nfunction useFlatColumns(): readonly ColumnConfig<Row>[] {\n  return useMemo(\n    () => [\n      { key: 'id', name: 'ID' },\n      { key: 'task', name: 'Task' },\n      { key: 'priority', name: 'Priority' },\n      { key: 'complete', name: '% Complete' },\n    ],\n    []\n  );\n}\n\nfunction useTreeColumns(): readonly ColumnConfig<TreeRow>[] {\n  return useMemo(\n    () => [\n      {\n        key: 'block',\n        name: 'Блок / Трайб / Продукт',\n        subRow: {\n          keyOfColumnInSubRow: (lvl) => {\n            switch (lvl) {\n              case 0: return 'block';\n              case 1: return 'tribe';\n              case 2: return 'product';\n              default: return 'block';\n            }\n          },\n          isColumnWithArrow: true,\n        },\n      },\n      { key: 'blockActivity', name: 'Активность блока' },\n    ],\n    []\n  );\n}\n\n() => {\n    const [rows] = useState(() => createRowsTree());\n    const columnConfig = useTreeColumns();\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          rowMarkers: {\n            startIndex: 1,\n            getRowMarker: ({ rowIndex }) => rowIndex + 1,\n          },\n          subRows: TREE_SUB_ROWS_CONFIG,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "WithCheckboxes",
          "displayName": "Нумерация + чекбоксы",
          "type": "full-code",
          "code": "const TREE_SUB_ROWS_CONFIG = {\n  getSubRows: (row: TreeRow) => row?.subRows,\n  rowKeyGetter: (row: TreeRow) => row.id,\n};\n\nfunction useFlatColumns(): readonly ColumnConfig<Row>[] {\n  return useMemo(\n    () => [\n      { key: 'id', name: 'ID' },\n      { key: 'task', name: 'Task' },\n      { key: 'priority', name: 'Priority' },\n      { key: 'complete', name: '% Complete' },\n    ],\n    []\n  );\n}\n\nfunction useTreeColumns(): readonly ColumnConfig<TreeRow>[] {\n  return useMemo(\n    () => [\n      {\n        key: 'block',\n        name: 'Блок / Трайб / Продукт',\n        subRow: {\n          keyOfColumnInSubRow: (lvl) => {\n            switch (lvl) {\n              case 0: return 'block';\n              case 1: return 'tribe';\n              case 2: return 'product';\n              default: return 'block';\n            }\n          },\n          isColumnWithArrow: true,\n        },\n      },\n      { key: 'blockActivity', name: 'Активность блока' },\n    ],\n    []\n  );\n}\n\n() => {\n    const [rows] = useState(createRows);\n    const columnConfig = useFlatColumns();\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          rowMarkers: {\n            startIndex: 1,\n          },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "TwoLevelNumbering",
          "displayName": "Двухуровневая нумерация (1, 1.1, 1.2, 2)",
          "type": "full-code",
          "code": "const TREE_SUB_ROWS_CONFIG = {\n  getSubRows: (row: TreeRow) => row?.subRows,\n  rowKeyGetter: (row: TreeRow) => row.id,\n};\n\nfunction useFlatColumns(): readonly ColumnConfig<Row>[] {\n  return useMemo(\n    () => [\n      { key: 'id', name: 'ID' },\n      { key: 'task', name: 'Task' },\n      { key: 'priority', name: 'Priority' },\n      { key: 'complete', name: '% Complete' },\n    ],\n    []\n  );\n}\n\nfunction useTreeColumns(): readonly ColumnConfig<TreeRow>[] {\n  return useMemo(\n    () => [\n      {\n        key: 'block',\n        name: 'Блок / Трайб / Продукт',\n        subRow: {\n          keyOfColumnInSubRow: (lvl) => {\n            switch (lvl) {\n              case 0: return 'block';\n              case 1: return 'tribe';\n              case 2: return 'product';\n              default: return 'block';\n            }\n          },\n          isColumnWithArrow: true,\n        },\n      },\n      { key: 'blockActivity', name: 'Активность блока' },\n    ],\n    []\n  );\n}\n\n() => {\n    const [rows] = useState(() => createRowsTree());\n    const columnConfig = useTreeColumns();\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          rowMarkers: {\n            startIndex: 1,\n            size: 'm',\n            getRowMarker: ({ siblingPath }) =>\n              siblingPath.map((i) => i + 1).join('.'),\n          },\n          subRows: TREE_SUB_ROWS_CONFIG,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "HierarchicalNumberingRich",
          "displayName": "Иерархическая нумерация (богатые данные)",
          "type": "full-code",
          "code": "const TREE_SUB_ROWS_CONFIG = {\n  getSubRows: (row: TreeRow) => row?.subRows,\n  rowKeyGetter: (row: TreeRow) => row.id,\n};\n\nfunction useFlatColumns(): readonly ColumnConfig<Row>[] {\n  return useMemo(\n    () => [\n      { key: 'id', name: 'ID' },\n      { key: 'task', name: 'Task' },\n      { key: 'priority', name: 'Priority' },\n      { key: 'complete', name: '% Complete' },\n    ],\n    []\n  );\n}\n\nfunction useTreeColumns(): readonly ColumnConfig<TreeRow>[] {\n  return useMemo(\n    () => [\n      {\n        key: 'block',\n        name: 'Блок / Трайб / Продукт',\n        subRow: {\n          keyOfColumnInSubRow: (lvl) => {\n            switch (lvl) {\n              case 0: return 'block';\n              case 1: return 'tribe';\n              case 2: return 'product';\n              default: return 'block';\n            }\n          },\n          isColumnWithArrow: true,\n        },\n      },\n      { key: 'blockActivity', name: 'Активность блока' },\n    ],\n    []\n  );\n}\n\n() => {\n    const [rows] = useState<TreeRow[]>(() => RICH_TREE_ROWS);\n    const columnConfig = useTreeColumns();\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '60vh' },\n          rowMarkers: {\n            startIndex: 1,\n            size: 'm',\n            getRowMarker: ({ siblingPath }) =>\n              siblingPath.map((i) => i + 1).join('.'),\n          },\n          subRows: TREE_SUB_ROWS_CONFIG,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "RowsGrouping",
      "legacy": false,
      "summary": "*tableConfig.rowsGrouping + columnConfig.rowsGrouping**",
      "docs": "# RowsGrouping (TableCanvas)\n\n**tableConfig.rowsGrouping + columnConfig.rowsGrouping**\n\nГруппировка строк таблицы по значениям колонок с поддержкой вложенных группировок.\n\n## Ключевые особенности\n\n- Управляемое состояние группировки через `groupByState`\n- Кнопка с выпадающим списком для выбора группировок в controlBlock\n- Кастомный рендер сгруппированных строк через `renderGroupCell`\n- Кастомные элементы в выпадающем списке через `groupButton.defaultCustomItems`\n- Возможность замены данных группированных строк через `groupRowReplaceTo`\n\n## Особенности\n\n- `rowKeyGetter` должен возвращать уникальный идентификатор строки\n- `groupedColumnProps` позволяет настроить колонку с группировкой (ширину, рендер и т.д.)\n- В `columnConfig.rowsGrouping` можно указать `groupByColumn: false` для исключения колонки из группировки\n- `columnGroupLabel` переопределяет лейбл в выпадающем списке (default: `columnConfig.key`)\n\n> Подробнее о типах — [RowsGrouping API](?path=/docs/локальные-компоненты-tablecanvas-rowsgrouping-api--docs)",
      "apiDocs": "# RowsGrouping API\n\n## RowsGrouping\n\n```typescript\ntype RowsGrouping<\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n  ColumnConfig extends LocalColumnInstance = LocalColumnInstance,\n> = {\n  /**\n   * массив группированных колонок и его setter\n   */\n  groupByState: [string[], React.Dispatch<React.SetStateAction<string[]>>];\n  /**\n   * Как показывать группировку.\n   * 'tree' (по умолчанию) — дерево с раскрытием (шевроны) и колонкой группировки.\n   * 'merged' — плоский вид: строки идут по группам, а группирующие колонки\n   * показаны объединёнными ячейками. Раскрытия нет; чекбокс и номер — на всю\n   * группу верхнего уровня.\n   * @default 'tree'\n   */\n  view?: 'tree' | 'merged';\n  /**\n   * Только для view: 'merged'. Выравнивание по умолчанию в объединённых ячейках\n   * группирующих колонок. Колоночный mergedCellsAlign важнее.\n   */\n  mergedCellsAlign?: MergedCellsAlign;\n  /**\n   * Только для view: 'merged'. Запретить сортировку по группирующим колонкам\n   * (как в дереве). По остальным колонкам сортировка остаётся.\n   * @default false\n   */\n  disableGroupColumnsSort?: boolean;\n  /**\n   * Функция определения уникального id строки\n   */\n  rowKeyGetter: (row: RowType) => string | number;\n  /**\n   * Показывать ли кнопку «Группировать» в controlBlock.\n   * При `false` кнопка скрыта и не участвует в компрессии,\n   * но группировка строк продолжает работать от внешнего `groupByState`.\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * Настройки колонки «Группировка» (имя, ширина, свои рендеры). Работает только\n   * в виде дерева: при view: 'merged' эта колонка не создаётся, а сгруппированные\n   * колонки остаются на своих местах.\n   * @default 'Группировка'\n   */\n  groupedColumnProps?: Partial<Pick<ColumnConfig, 'name' | 'width'>> & {\n    renderCell?: (\n      props: CellInfoGlideInstance<RowType, SummaryRowType> & {\n        parentGroupKey: string | undefined;\n        groupByArr: string[];\n      },\n    ) => CanvasContent;\n    rowsGrouping?: Pick<\n      ColumnRowsGrouping<RowType, ColumnConfig>,\n      'renderGroupCell'\n    >;\n  };\n  /** Кнопка «развернуть всё». Работает только в виде дерева: при view: 'merged' шевронов нет. */\n  expandAllBtn?: {\n    /**\n     * Функция для расчета состояния открытости всех раскрываемых строк. Функция должна быть чистой.\n     * @returns boolean\n     */\n    expandedAll: (p: {\n      /**\n       * allRowsIds - уникальные идентификаторы всех строк (группировок и обычных)\n       */\n      allRowsIds: Set<string | number> | null;\n      /**\n       * shownRows - представленные прямо сейчас строки (группировки и обычные). Или видимые строки - видимые не во viewport-е, а которые должны быть показаны из-за раскрытий)\n       */\n      shownRows: readonly RowType[];\n      expandedRowsIds: Set<string | number>;\n    }) => boolean;\n  };\n  /**\n   * `groupButton` - свойство для кастомизации кнопки с выпадающим списком\n   */\n  groupButton?: {\n    getGroupedCount?: (props: {\n      /**\n       * высчитанное автоматически количество активных группировок.\n       */\n      currCount: number;\n      /**\n       * активные группировки.\n       */\n      groupedCols: string[];\n      columns: {\n        /**\n         * `visible` - видимые в выпадающем списке колонки-группировки.\n         */\n        visible: string[];\n        /**\n         * `hidden` - невидимые  или не участвующие в группировке колонки\n         *\n         * (columnConfig.rowsGrouping=undefined ||\n         *  columnConfig.rowsGrouping.groupByColumn=false).\n         */\n        hidden: string[];\n      };\n    }) => number;\n    /**\n     * `defaultCustomItems` - свойство для добавления ключей группировки, которых нет в таблице.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    defaultCustomItems?: DropdownItemOption[];\n    /**\n     * `onItemSelect` - свойство для полного контроля над изменением группировки при выборе опций.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    onItemSelect?: (props: {\n      item: DropdownItemOption;\n      setGroupedCols: React.Dispatch<React.SetStateAction<string[]>>;\n      columns: {\n        visible: string[];\n        hidden: string[];\n      };\n    }) => void;\n  };\n  /**\n   * `groupRowReplaceTo` - свойство для изменения данных сгруппированных строк. Может понадобиться в редких случаях.\n   *\n   * @param groupRow данные сгруппированной строки\n   * @returns измененная группировка или строка без группировки — строка, которые заменит groupRow\n   */\n  groupRowReplaceTo?: (\n    groupRow: GroupRow<RowType>,\n  ) => GroupRow<RowType> | RowType;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n\nexport type RenderGroupCellProps<\n  RowType extends ObjectForExtending,\n  ColumnConfig extends LocalColumnInstance = LocalColumnInstance,\n> = {\n  column: ColumnConfig;\n  tabIndex: number;\n  theme?: Theme;\n  // TODO isExpanded: boolean;\n  // TODO toggleGroup: () => void;\n} & GroupRow<RowType>;\n\nexport type ColumnRowsGrouping<\n  RowType extends ObjectForExtending,\n  ColumnConfig extends LocalColumnInstance,\n> = {\n  /**\n   * @default true - при наличии ColumnConfig.rowsGrouping\n   */\n  groupByColumn?: boolean;\n  /**\n   * @default ColumnConfig.key\n   */\n  columnGroupLabel?: string;\n  /**\n   * Свой контент ячейки строки-группы. Работает только в виде дерева: при\n   * view: 'merged' строк-групп нет (группы показаны объединёнными ячейками),\n   * поэтому этот рендер не вызывается.\n   */\n  renderGroupCell?: (\n    props: RenderGroupCellProps<RowType, ColumnConfig>,\n  ) => CanvasContent;\n};\n```",
      "api": [
        {
          "typeName": "RowsGrouping",
          "source": "type RowsGrouping<\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n  ColumnConfig extends LocalColumnInstance = LocalColumnInstance,\n> = {\n  /**\n   * массив группированных колонок и его setter\n   */\n  groupByState: [string[], React.Dispatch<React.SetStateAction<string[]>>];\n  /**\n   * Как показывать группировку.\n   * 'tree' (по умолчанию) — дерево с раскрытием (шевроны) и колонкой группировки.\n   * 'merged' — плоский вид: строки идут по группам, а группирующие колонки\n   * показаны объединёнными ячейками. Раскрытия нет; чекбокс и номер — на всю\n   * группу верхнего уровня.\n   * @default 'tree'\n   */\n  view?: 'tree' | 'merged';\n  /**\n   * Только для view: 'merged'. Выравнивание по умолчанию в объединённых ячейках\n   * группирующих колонок. Колоночный mergedCellsAlign важнее.\n   */\n  mergedCellsAlign?: MergedCellsAlign;\n  /**\n   * Только для view: 'merged'. Запретить сортировку по группирующим колонкам\n   * (как в дереве). По остальным колонкам сортировка остаётся.\n   * @default false\n   */\n  disableGroupColumnsSort?: boolean;\n  /**\n   * Функция определения уникального id строки\n   */\n  rowKeyGetter: (row: RowType) => string | number;\n  /**\n   * Показывать ли кнопку «Группировать» в controlBlock.\n   * При `false` кнопка скрыта и не участвует в компрессии,\n   * но группировка строк продолжает работать от внешнего `groupByState`.\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * Настройки колонки «Группировка» (имя, ширина, свои рендеры). Работает только\n   * в виде дерева: при view: 'merged' эта колонка не создаётся, а сгруппированные\n   * колонки остаются на своих местах.\n   * @default 'Группировка'\n   */\n  groupedColumnProps?: Partial<Pick<ColumnConfig, 'name' | 'width'>> & {\n    renderCell?: (\n      props: CellInfoGlideInstance<RowType, SummaryRowType> & {\n        parentGroupKey: string | undefined;\n        groupByArr: string[];\n      },\n    ) => CanvasContent;\n    rowsGrouping?: Pick<\n      ColumnRowsGrouping<RowType, ColumnConfig>,\n      'renderGroupCell'\n    >;\n  };\n  /** Кнопка «развернуть всё». Работает только в виде дерева: при view: 'merged' шевронов нет. */\n  expandAllBtn?: {\n    /**\n     * Функция для расчета состояния открытости всех раскрываемых строк. Функция должна быть чистой.\n     * @returns boolean\n     */\n    expandedAll: (p: {\n      /**\n       * allRowsIds - уникальные идентификаторы всех строк (группировок и обычных)\n       */\n      allRowsIds: Set<string | number> | null;\n      /**\n       * shownRows - представленные прямо сейчас строки (группировки и обычные). Или видимые строки - видимые не во viewport-е, а которые должны быть показаны из-за раскрытий)\n       */\n      shownRows: readonly RowType[];\n      expandedRowsIds: Set<string | number>;\n    }) => boolean;\n  };\n  /**\n   * `groupButton` - свойство для кастомизации кнопки с выпадающим списком\n   */\n  groupButton?: {\n    getGroupedCount?: (props: {\n      /**\n       * высчитанное автоматически количество активных группировок.\n       */\n      currCount: number;\n      /**\n       * активные группировки.\n       */\n      groupedCols: string[];\n      columns: {\n        /**\n         * `visible` - видимые в выпадающем списке колонки-группировки.\n         */\n        visible: string[];\n        /**\n         * `hidden` - невидимые  или не участвующие в группировке колонки\n         *\n         * (columnConfig.rowsGrouping=undefined ||\n         *  columnConfig.rowsGrouping.groupByColumn=false).\n         */\n        hidden: string[];\n      };\n    }) => number;\n    /**\n     * `defaultCustomItems` - свойство для добавления ключей группировки, которых нет в таблице.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    defaultCustomItems?: DropdownItemOption[];\n    /**\n     * `onItemSelect` - свойство для полного контроля над изменением группировки при выборе опций.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    onItemSelect?: (props: {\n      item: DropdownItemOption;\n      setGroupedCols: React.Dispatch<React.SetStateAction<string[]>>;\n      columns: {\n        visible: string[];\n        hidden: string[];\n      };\n    }) => void;\n  };\n  /**\n   * `groupRowReplaceTo` - свойство для изменения данных сгруппированных строк. Может понадобиться в редких случаях.\n   *\n   * @param groupRow данные сгруппированной строки\n   * @returns измененная группировка или строка без группировки — строка, которые заменит groupRow\n   */\n  groupRowReplaceTo?: (\n    groupRow: GroupRow<RowType>,\n  ) => GroupRow<RowType> | RowType;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n\nexport type RenderGroupCellProps<\n  RowType extends ObjectForExtending,\n  ColumnConfig extends LocalColumnInstance = LocalColumnInstance,\n> = {\n  column: ColumnConfig;\n  tabIndex: number;\n  theme?: Theme;\n  // TODO isExpanded: boolean;\n  // TODO toggleGroup: () => void;\n} & GroupRow<RowType>;\n\nexport type ColumnRowsGrouping<\n  RowType extends ObjectForExtending,\n  ColumnConfig extends LocalColumnInstance,\n> = {\n  /**\n   * @default true - при наличии ColumnConfig.rowsGrouping\n   */\n  groupByColumn?: boolean;\n  /**\n   * @default ColumnConfig.key\n   */\n  columnGroupLabel?: string;\n  /**\n   * Свой контент ячейки строки-группы. Работает только в виде дерева: при\n   * view: 'merged' строк-групп нет (группы показаны объединёнными ячейками),\n   * поэтому этот рендер не вызывается.\n   */\n  renderGroupCell?: (\n    props: RenderGroupCellProps<RowType, ColumnConfig>,\n  ) => CanvasContent;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "SimpleTable",
          "displayName": "Простая группировка",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRowsForGrouping);\n\n    const [groupByArr, setGroupByArr] = useState<string[]>([]);\n\n    const columnConfig = useMemo<readonly ColumnConfig<RowForGrouping>[]>(\n      () => [\n        {\n          key: 'athlete',\n          name: 'Athlete',\n          rowsGrouping: {\n            columnGroupLabel: 'Athlete',\n          },\n        },\n        {\n          key: 'sport',\n          name: 'Sport',\n\n          rowsGrouping: {\n            columnGroupLabel: 'Sport',\n          },\n        },\n        {\n          key: 'country',\n          name: 'Country',\n\n          rowsGrouping: {\n            columnGroupLabel: 'Country',\n          },\n        },\n        {\n          key: 'year',\n          name: 'Year',\n\n          rowsGrouping: {\n            columnGroupLabel: 'Year',\n          },\n        },\n\n        {\n          key: 'gold',\n          name: 'Gold',\n          rowsGrouping: {\n            groupByColumn: false,\n            columnGroupLabel: 'Gold',\n            renderGroupCell({ childRows }) {\n              return childRows\n                .reduce((prev, { gold }) => prev + gold, 0)\n                .toString();\n            },\n          },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          columnsControl: {\n            enable: true,\n          },\n          rowsGrouping: {\n            rowKeyGetter: (r) => r.id,\n            groupByState: [groupByArr, setGroupByArr],\n\n            groupButton: {\n              defaultCustomItems: [\n                { value: 'gold', label: 'Gold as custom option' },\n              ],\n            },\n            groupedColumnProps: {\n              width: 350,\n              renderCell: (props) => {\n                if (props.parentGroupKey === 'Russian Federation') {\n                  return 'Russia last lvl';\n                }\n                return props.parentGroupKey ?? '';\n              },\n              rowsGrouping: {\n                renderGroupCell(props) {\n                  if (props.groupKey === 'Russian Federation') {\n                    return 'Russia';\n                  }\n                  return props.groupKey;\n                },\n              },\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MultipleFeaturesTable",
          "displayName": "Комбинация с другими фичами",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRowsForGrouping);\n\n    const [groupByArr, setGroupByArr] = useState<string[]>([]);\n\n    const columnConfig = useMemo<readonly ColumnConfig<RowForGrouping>[]>(\n      () => [\n        {\n          key: 'athlete',\n          name: 'Athlete',\n          sortingType: 'stringSort',\n          rowsGrouping: {\n            columnGroupLabel: 'Athlete',\n          },\n          filtering: {\n            component: 'input',\n            filter: 'includes',\n            valueInRow: (r) => r.athlete,\n            keyInFilterState: 'athlete',\n          },\n        },\n        {\n          key: 'sport',\n          name: 'Sport',\n          sortingType: 'stringSort',\n          rowsGrouping: {\n            columnGroupLabel: 'Sport',\n          },\n          filtering: {\n            component: 'input',\n            filter: 'includes',\n            valueInRow: (r) => r.sport,\n            keyInFilterState: 'sport',\n          },\n        },\n        {\n          key: 'country',\n          name: 'Country',\n          sortingType: 'stringSort',\n          rowsGrouping: {\n            columnGroupLabel: 'Country',\n          },\n          filtering: {\n            component: 'input',\n            filter: 'startWith',\n            valueInRow: (r) => r.country,\n            keyInFilterState: 'country',\n          },\n        },\n        {\n          key: 'year',\n          name: 'Year',\n          sortingType: 'numberSort',\n          rowsGrouping: {\n            columnGroupLabel: 'Year',\n          },\n          filtering: {\n            component: 'input',\n            filter: 'startWith',\n            valueInRow: (r) => r.year,\n            keyInFilterState: 'year',\n          },\n        },\n\n        {\n          key: 'gold',\n          name: 'Gold',\n          sortingType: 'numberSort',\n          rowsGrouping: {\n            columnGroupLabel: 'Gold',\n            renderGroupCell({ childRows }) {\n              return String(\n                childRows.reduce((prev, { gold }) => prev + gold, 0),\n              );\n            },\n          },\n        },\n      ],\n      [],\n    );\n    const sortingStateAndSetter = useState<readonly SortColumn[]>([]);\n\n    const filteringStateAndSetter = useState({\n      athlete: '',\n      sport: '',\n      gold: '',\n      country: '',\n      year: '',\n    });\n\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n    const rowCheckboxDisabled = (r: RowForGrouping) => r.id === 1;\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          rowMarkers: {\n            startIndex: 1,\n          },\n          columnsControl: {\n            enable: true,\n          },\n          containerStyle: { height: 700 },\n          rowsGrouping: {\n            rowKeyGetter: (r) => r.id,\n            groupByState: [groupByArr, setGroupByArr],\n            groupedColumnProps: {\n              name: <>моя группировка</>,\n            },\n          },\n          resizableColumn: true,\n          sorting: {\n            state: sortingStateAndSetter,\n          },\n          filtering: {\n            state: filteringStateAndSetter,\n            clearedValue: {\n              athlete: '',\n              sport: '',\n              gold: '',\n              country: '',\n              year: '',\n            },\n          },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id,\n            showDefault: true,\n            rowCheckboxDisabled,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "Searching",
      "legacy": false,
      "summary": "*tableConfig.searching**",
      "docs": "# Searching (TableCanvas)\n\n**tableConfig.searching**\n\nРасширенные возможности поиска по данным, включая клиентскую и серверную фильтрацию, а также автокомплит с подсказками.\n\n## Основные возможности\n\n- Включение/выключение функционала поиска (`enabled`)\n- Начальное значение поиска (`defaultSearchQuery`)\n- Управление видимостью UI поиска (`showSearchBlock`)\n- Контролируемый и неконтролируемый режимы (`searchQueryState`)\n- Настройка debounce для оптимизации производительности (`debounceDelay`)\n- Ручной режим поиска — по Enter или клику (`searchOnType: false`)\n- Автокомплит с подсказками (`autocomplete`)\n\n## Режимы поиска\n\n### Автоматический (по умолчанию)\n\nПоиск запускается при вводе текста с debounce. Подходит для клиентской фильтрации.\n\n### По нажатию (`searchOnType: false`)\n\nПоиск запускается только по нажатию Enter или клику на иконку. Подходит для серверной фильтрации и больших наборов данных.\n\n### Ручной (`manualSearching: true`)\n\nФронтенд-фильтрация отключена. Данные фильтруются на бэкенде, результат передаётся в `rows`.\n\n## Автокомплит\n\nПри передаче `autocomplete` в конфигурацию поиска поле ввода заменяется на компонент Autocomplete с выпадающим списком подсказок. С помощью пропсов Autocomplete можно настроить историю поиска, кастомизировать рендер элементов и другое. Подробнее — в разделе [API](?path=/docs/локальные-компоненты-tablecanvas-searching-api--docs).\n\n## Пагинация и поиск\n\n> **Важно:** если в таблице используется пагинация, поиск необходимо либо **отключать**, либо **переводить в ручной режим** (`manualSearching: true`) и фильтровать строки самостоятельно с учётом всех страниц, взаимодействуя с бэкендом. Клиентский поиск при пагинации будет фильтровать только текущую страницу, что приведёт к некорректным результатам.\n\n## Приоритет фильтрации\n\n1. Сначала применяется глобальный поиск (если `manualSearching` выключен)\n2. Затем применяются колоночные фильтры (если есть)",
      "apiDocs": "# Searching API\n\n## SearchingProps\n\n```typescript\ntype SearchingProps = {\n  /**\n   * Активация функционала поиска (обязательный параметр)\n   */\n  enabled: boolean;\n\n  /**\n   * Если true - поиск НЕ будет работать на фронте (ручное управление)\n   * Полезно когда поисковая логика полностью управляется на бэкенде\n   */\n  manualSearching?: boolean;\n\n  /**\n   * Начальное значение поискового запроса\n   */\n  defaultSearchQuery?: string;\n\n  /**\n   * Видимость UI блока поиска\n   */\n  showSearchBlock?: boolean;\n\n  /**\n   * Состояние и сеттер для контролируемого режима\n   * [текущее значение, функция установки значения]\n   */\n  searchQueryState?: [string, React.Dispatch<React.SetStateAction<string>>];\n\n  /**\n   * Обработчик изменения с debounce\n   * Вызывается с задержкой после окончания ввода\n   * @param value - текущее значение поискового запроса\n   */\n  onDebouncedChange?: (value: string) => void;\n\n  /**\n   * Мгновенный обработчик изменений\n   * Вызывается при каждом изменении input\n   * @param value - текущее значение поискового запроса\n   */\n  onChange?: (value: string) => void;\n\n  /**\n   * Задержка для debounce (в миллисекундах)\n   * @default 300\n   */\n  debounceDelay?: number;\n\n  /**\n   * Активация debounce механизма\n   * @default true\n   */\n  isDebounceActive?: boolean;\n\n  /**\n   * Дополнительные классы для контейнера поиска\n   */\n  searchClasses?: string;\n\n  /**\n   * Placeholder для поискового input\n   * @default \"Поиск\"\n   */\n  placeholder?: string;\n\n  /**\n   * DOM метаданные для аналитики и онбординга\n   */\n  domMetadata?: DomMetadata;\n\n  /**\n   * Режим запуска поиска\n   * - true: поиск запускается автоматически при вводе текста (по умолчанию)\n   * - false: поиск запускается только по клику на иконку поиска или нажатию Enter\n   */\n  searchOnType?: boolean;\n\n  /**\n   * Конфигурация автокомплита для поиска.\n   * При передаче поле поиска заменяется на Autocomplete с подсказками.\n   */\n  autocomplete?: SearchAutocompleteConfig;\n};\n```\n\n## SearchAutocompleteConfig\n\n```typescript\ntype SearchAutocompleteConfig = Pick<\n  AutocompleteProps,\n  | 'suggestions'\n  | 'onSuggestionSelect'\n  | 'threshold'\n  | 'renderList'\n  | 'renderListEnd'\n  | 'beforeList'\n  | 'listMaxHeight'\n  | 'listWidth'\n  | 'portal'\n  | 'hasDivider'\n  | 'beforeList'\n  | 'afterList'\n  | 'virtual'\n  | 'hasDivider'\n  | 'onScroll'\n  | 'zIndex'\n  | 'filter'\n  | 'renderItem'\n>;\n```\n\n## Примеры конфигурации\n\n### Базовый поиск\n\n```tsx\n<TableCanvas\n  tableConfig={{\n    searching: {\n      enabled: true,\n    },\n  }}\n  columnConfig={columnConfig}\n  rows={rows}\n/>\n```\n\n### Серверный поиск\n\n```tsx\n<TableCanvas\n  tableConfig={{\n    searching: {\n      enabled: true,\n      manualSearching: true,\n      onDebouncedChange: (value) => fetchData({ search: value }),\n    },\n  }}\n  columnConfig={columnConfig}\n  rows={rows}\n/>\n```\n\n### Автокомплит с историей\n\n```tsx\n<TableCanvas\n  tableConfig={{\n    searching: {\n      enabled: true,\n      autocomplete: {\n        suggestions: [{ label: 'Запрос 1' }, { label: 'Запрос 2' }],\n        threshold: 0,\n        listMaxHeight: '200px',\n        onSuggestionSelect: (item) => console.log(item.label),\n      },\n    },\n  }}\n  columnConfig={columnConfig}\n  rows={rows}\n/>\n```",
      "api": [
        {
          "typeName": "SearchingProps",
          "source": "type SearchingProps = {\n  /**\n   * Активация функционала поиска (обязательный параметр)\n   */\n  enabled: boolean;\n\n  /**\n   * Если true - поиск НЕ будет работать на фронте (ручное управление)\n   * Полезно когда поисковая логика полностью управляется на бэкенде\n   */\n  manualSearching?: boolean;\n\n  /**\n   * Начальное значение поискового запроса\n   */\n  defaultSearchQuery?: string;\n\n  /**\n   * Видимость UI блока поиска\n   */\n  showSearchBlock?: boolean;\n\n  /**\n   * Состояние и сеттер для контролируемого режима\n   * [текущее значение, функция установки значения]\n   */\n  searchQueryState?: [string, React.Dispatch<React.SetStateAction<string>>];\n\n  /**\n   * Обработчик изменения с debounce\n   * Вызывается с задержкой после окончания ввода\n   * @param value - текущее значение поискового запроса\n   */\n  onDebouncedChange?: (value: string) => void;\n\n  /**\n   * Мгновенный обработчик изменений\n   * Вызывается при каждом изменении input\n   * @param value - текущее значение поискового запроса\n   */\n  onChange?: (value: string) => void;\n\n  /**\n   * Задержка для debounce (в миллисекундах)\n   * @default 300\n   */\n  debounceDelay?: number;\n\n  /**\n   * Активация debounce механизма\n   * @default true\n   */\n  isDebounceActive?: boolean;\n\n  /**\n   * Дополнительные классы для контейнера поиска\n   */\n  searchClasses?: string;\n\n  /**\n   * Placeholder для поискового input\n   * @default \"Поиск\"\n   */\n  placeholder?: string;\n\n  /**\n   * DOM метаданные для аналитики и онбординга\n   */\n  domMetadata?: DomMetadata;\n\n  /**\n   * Режим запуска поиска\n   * - true: поиск запускается автоматически при вводе текста (по умолчанию)\n   * - false: поиск запускается только по клику на иконку поиска или нажатию Enter\n   */\n  searchOnType?: boolean;\n\n  /**\n   * Конфигурация автокомплита для поиска.\n   * При передаче поле поиска заменяется на Autocomplete с подсказками.\n   */\n  autocomplete?: SearchAutocompleteConfig;\n};"
        },
        {
          "typeName": "SearchAutocompleteConfig",
          "source": "type SearchAutocompleteConfig = Pick<\n  AutocompleteProps,\n  | 'suggestions'\n  | 'onSuggestionSelect'\n  | 'threshold'\n  | 'renderList'\n  | 'renderListEnd'\n  | 'beforeList'\n  | 'listMaxHeight'\n  | 'listWidth'\n  | 'portal'\n  | 'hasDivider'\n  | 'beforeList'\n  | 'afterList'\n  | 'virtual'\n  | 'hasDivider'\n  | 'onScroll'\n  | 'zIndex'\n  | 'filter'\n  | 'renderItem'\n>;"
        }
      ],
      "stories": [
        {
          "exportName": "ControlSearching",
          "displayName": "Контролируемый поиск",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n    const [query, setQuery] = useState('Bug');\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          searching: {\n            enabled: true,\n            defaultSearchQuery: 'Epic',\n            showSearchBlock: true,\n            onChange: (value) => console.debug('onChange searching', value),\n            onDebouncedChange: (value) =>\n              console.debug('onDebouncedChange searching', value),\n            searchQueryState: [query, setQuery],\n            debounceDelay: 350,\n            placeholder: 'Введите сумму',\n            searchClasses: 'someClassForSearch',\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "UncontrolledSearching",
          "displayName": "Неконтролируемый поиск",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          searching: {\n            enabled: true,\n            defaultSearchQuery: 'Epic',\n            showSearchBlock: true,\n            onChange: (value) => console.debug('onChange searching', value),\n            onDebouncedChange: (value) =>\n              console.debug('onDebouncedChange searching', value),\n            debounceDelay: 550,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ManualSearching",
          "displayName": "Manual поиск",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows, setRows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          searching: {\n            enabled: true,\n            manualSearching: true,\n            defaultSearchQuery: '',\n            showSearchBlock: true,\n            onChange: (value) => console.debug('onChange searching', value),\n            onDebouncedChange: (value) => {\n              console.debug('onDebouncedChange searching', value);\n              // fetchData from server => then setRows for example\n              setRows(createRows(0, 10));\n            },\n            debounceDelay: 550,\n          },\n          containerStyle: { height: 700 },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "AutocompleteHistory",
          "displayName": "Autocomplete (история поиска)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n    const [searchHistory, setSearchHistory] = useState<string[]>([\n      'Epi',\n      'Bug',\n      'Improvement',\n      '19.628582577979465asdf97.58738810084174',\n      'Critical',\n      'High',\n      'Story',\n      'Task',\n    ]);\n    const lastSubmittedRef = useRef('');\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'developer', name: 'Developer' },\n      ],\n      [],\n    );\n\n    const addToHistory = useCallback((value: string) => {\n      if (!value.trim() || value === lastSubmittedRef.current) return;\n      lastSubmittedRef.current = value;\n      setSearchHistory((prev) => {\n        const filtered = prev.filter((item) => item !== value);\n        return [value, ...filtered].slice(0, 10);\n      });\n    }, []);\n\n    const suggestions = useMemo(\n      () => searchHistory.map((label) => ({ label })),\n      [searchHistory],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          searching: {\n            enabled: true,\n            showSearchBlock: true,\n            onDebouncedChange: (value) => {\n              console.debug('search:', value);\n              addToHistory(value);\n            },\n            debounceDelay: 300,\n            placeholder: 'Поиск',\n            autocomplete: {\n              suggestions,\n              threshold: 0,\n              listMaxHeight: '200px',\n              onSuggestionSelect: (suggestion) => {\n                console.debug('selected:', suggestion.label);\n              },\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "Selecting",
      "legacy": false,
      "summary": "*tableConfig.selecting**",
      "docs": "# Selecting Row\n\n**tableConfig.selecting**\n\nВыбор строк таблицы с помощью чекбоксов.\n\n## Ключевые особенности\n\n- Управляемое состояние через `ReadonlySet<string | number>`\n- Кнопка переключения видимости в control block (`showInControl: true`)\n- Контроль на уровне строк: `rowCheckboxDisabled`, `rowShowCheckbox`\n- Поддержка иерархических таблиц через `selectingRules.levels`\n- Кастомизация summary-чекбокса через `summaryChecked`\n\n## Особенности\n\n- `rowKeyGetter` должен возвращать уникальный идентификатор строки\n- В иерархических таблицах `selectingRules.levels` определяет, на каких уровнях доступен выбор\n- `rowGetStates` позволяет полностью переопределить логику чекбоксов (checked, indeterminate, disabled)\n- Accent-кнопки в mass action panel всегда видимы при компрессии\n\n> Подробнее о типах и пропсах — [Selecting API](?path=/docs/локальные-компоненты-tablecanvas-selecting-api--docs)\n\n## Выделение колонок — `tableConfig.cellsSelection`\n\nОтдельный от чекбоксов механизм: выделение **колонок** кликом по шапке. Не зависит\nот `highlightActiveType` — самостоятельная ось взаимодействия. По умолчанию включено.\n\n- **`enableColumnSelection`** — клик по шапке выделяет колонку. Ctrl/Cmd —\n  добавить/убрать колонку, Shift — диапазон. Клик по иконкам сортировки/фильтрации\n  в шапке выделение не вызывает. Поддерживается copy/paste по выделенным колонкам.\n- **`enableSelectAll`** — клик по «нулевой» ячейке (шапка колонки нумерации, левый\n  верхний угол) выделяет всю таблицу целиком: все строки данных по всем колонкам.\n  Поддерживает copy/paste. Требует включённой нумерации (`rowMarkers`) и активного\n  `cellsSelection.mode`. По умолчанию включено.\n\n### Как читать состояние выделения\n\nВыделенные колонки приходят в обычный коллбэк\n`tableConfig.onGridSelectionChange(selection)` в поле `selection.columns`\n(`CompactSelection`, индексы колонок). Ячейки/диапазоны — там же в\n`selection.current`.\n\nЧекбоксный выбор строк (`tableConfig.selecting`) — независимый механизм со своим\nсостоянием и коллбэками, с этим API не пересекается.\n\n> Типы — раздел `CellsSelectionConfig` в [Selecting API](?path=/docs/локальные-компоненты-tablecanvas-selecting-api--docs)\n\n# SelectingRow + RowsGrouping\n\nПример кастомного выбора строк в группированной таблице.\n\nКомбинация `tableConfig.selecting` и `tableConfig.rowsGrouping` с `columnConfig.rowsGrouping`.\n\n> Типы SelectingRow — [SelectingRow API](?path=/docs/локальные-компоненты-tablecanvas-selectingrow-api--docs)\n\n> Типы RowsGrouping — [RowsGrouping API](?path=/docs/локальные-компоненты-tablecanvas-rowsgrouping-api--docs)",
      "apiDocs": "# SelectingRow API\n\n> **Важно:** `tableConfig.selecting` (этот раздел) — выбор строк **чекбоксами**.\n> Это отдельный механизм от `tableConfig.cellsSelection` (см. ниже) — выделения\n> колонок по клику на шапку.\n\n## SelectingRowConfig\n\nКонфиг чекбоксного выбора строк (`tableConfig.selecting`).\n\n```typescript\ntype SelectingRowConfig<RowType, RowIdType extends string | number> = {\n  /**\n   * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n   */\n  showDefault?: boolean;\n  /**\n   * showState - состояние, отвечающее за то, видны ли чекбоксы.\n   */\n  showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n   */\n  showInControl?: boolean;\n  /**\n   * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n   */\n  selectingRules?: {\n    // TODO доработать логику\n    // changeableOfRowWithoutCheckbox?: boolean;\n    // changeableDisabledRow?: boolean;\n    /**\n     * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n     */\n    levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n  };\n  disableSummaryCheckboxInHeader?: boolean;\n  hideSummaryCheckboxInHeader?: boolean;\n  /**\n   * hideSummaryCheckbox - в островке  массовых действий\n   */\n  hideSummaryCheckbox?: boolean;\n  /**\n   * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n   */\n  summaryChecked?: {\n    checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n    indeterminate:\n      | boolean\n      | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n    getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n    onChange: SummaryCheckedFunc<\n      RowType,\n      void,\n      {\n        checkedAll: boolean;\n        clearButtonClicked?: boolean;\n        setSelectedRowsIds: React.Dispatch<\n          React.SetStateAction<ReadonlySet<string | number>>\n        >;\n      }\n    >;\n  };\n\n  /**\n   * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n   */\n  summaryCheckedUncontrolled?: {\n    onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n  };\n\n  /**\n   * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n   */\n  rowShowCheckbox?: RowShowCheckbox<RowType>;\n  /**\n   * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n   */\n  rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n  /**\n   * Функция для переопределения checked, indeterminate для каждой строки.\n   * Что будет возвращено функцией в объекте, то будет переопределено.\n   */\n  rowGetStates?: (\n    p: RowGetStatesProps<RowType, RowIdType>,\n  ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n  groupedRow?: {\n    /**\n     * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n     * Что будет возвращено функцией в объекте, то будет переопределено.\n     */\n    getStates: (p: {\n      checkedCalculated: boolean;\n      indeterminateCalculated: boolean;\n      row: GroupRow<RowType>;\n      selectedRows: ReadonlySet<string | number>;\n      selectedChildCount: number;\n      childCount: number;\n    }) => {\n      checked?: boolean | null;\n      indeterminate?: boolean | null;\n      showCheckbox?: boolean | null;\n      checkboxDisabled?: boolean | null;\n    } | null;\n    onChange?: (p: {\n      row: GroupRow<RowType>;\n\n      setSelectedRows: React.Dispatch<\n        React.SetStateAction<ReadonlySet<string | number>>\n      >;\n      checked: boolean;\n      indeterminate: boolean;\n      checkboxDisabled: boolean;\n      showCheckbox: boolean;\n      defaultSetter: () => void;\n    }) => void;\n  };\n};\n```\n\n## CellsSelectionConfig\n\nКонфиг выделения **колонок** по клику на шапку — `tableConfig.cellsSelection`. Не\nзависит от `highlightActiveType`, по умолчанию включено. Поддерживает copy/paste\nпо выделенным колонкам.\n\n```typescript\ntype CellsSelectionConfig = {\n  /**\n   * Режим фактического выделения ячеек (нативный glide selection). По нему\n   * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n   * @default \"range-cell\"\n   */\n  mode?: CellsSelectionMode;\n  /**\n   * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n   * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n   * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n   * @default true\n   */\n  enableColumnSelection?: boolean;\n  /**\n   * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n   * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n   * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n   * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n   * @default true\n   */\n  enableRowSelection?: boolean;\n  /**\n   * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n   * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n   * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n   * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n   * @default true\n   */\n  enableSelectAll?: boolean;\n  /**\n   * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n   * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n   * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n   * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n   */\n  state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};\n```\n\n## RowGetStatesProps\n\nАргумент функции `rowGetStates` — позволяет полностью переопределить поведение чекбоксов для каждой строки.\n\n```typescript\ntype RowGetStatesProps<RowType, RowIdType> = {\n  /**\n   * просчитанное по умолчанию значение наличия чекбокса у строки\n   */\n  isHaveCheckboxCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение checked у строки\n   */\n  isRowSelectedCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение indeterminate у строки\n   */\n  isIndeterminateCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение disabled у строки\n   */\n  isRowSelectionDisabled: boolean;\n\n  rowKeyGetter: RowKeyGetter<RowType, RowIdType>;\n  row: RowType;\n  /**\n   * Все строки таблицы в плоском виде с информацией об уровне и родительской строке\n   */\n  flattenedRowsMap: Map<\n    RowIdType,\n    RowType & {\n      level?: number;\n      parent?: RowType | null | undefined;\n    }\n  >;\n  /**\n   * стейт всех выбранных строк (Set)\n   */\n  selectedRows: ReadonlySet<RowIdType>;\n  /**\n   * сеттер стейта всех выбранных строк\n   */\n  setSelectedRows: React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>;\n  /**\n   * уровень вложенности текущей строки\n   */\n  level: number;\n  /**\n   * родительская строка для текущей строки\n   */\n  parent: RowType | null;\n  /**\n   * хендлер для получения детальных данных о дочерних строках текущей строки\n   */\n  getRowChildrenInfo: () => ChildrenInfo<RowType, RowIdType>;\n  rowShowCheckbox: RowShowCheckbox<RowType> | undefined;\n  rowCheckboxDisabled: RowCheckboxDisabled<RowType> | undefined;\n};\n```\n\n## RowGetStatesReturnType\n\nВозвращаемое значение `rowGetStates`.\n\n```typescript\ntype RowGetStatesReturnType<RowType, RowIdType> = {\n  /**\n   * состояние checked, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  checked?: boolean | null;\n  /**\n   * состояние indeterminate, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  indeterminate?: boolean | null;\n  /**\n   * состояние showCheckbox, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  showCheckbox?: boolean | null;\n  /**\n   * состояние checkboxDisabled, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  checkboxDisabled?: boolean | null;\n  /**\n   * onChange у чекбокса, который будет окончательным. Если не передан, то будет взят из расчетов по умолчанию\n   */\n  onChange?:\n    | ((p: {\n        allParentsMap: Map<RowIdType, RowType>;\n        isRowInLevels: (row: RowType) => boolean;\n        defaultSetter: () => void;\n        getRowParentsInfo: () => {\n          all: RowType[];\n          getShouldBeSelectedInfo: (\n            actualSelecteds: ReadonlySet<RowIdType>,\n          ) => {\n            shouldBeSelected: RowIdType[];\n            shouldNotBeSelected: RowIdType[];\n          };\n        };\n      }) => void)\n    | null;\n};\n```\n\n## ChildrenInfo\n\nИнформация о дочерних строках, доступная через `getRowChildrenInfo()`.\n\n```typescript\ntype ChildrenInfo<RowType, RowIdType> = {\n  /**\n   * все дочерние строки\n   */\n  all: RowType[];\n  /**\n   * все дочерние строки, которые disabled\n   */\n  disabled: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ disabled\n   */\n  notDisabled: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox\n   */\n  notDisabledAndNotHidden: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox все выбраны\n   */\n  notDisabledAndNotHiddenAreSelected: boolean;\n  /**\n   * все дочерние строки, которые скрыты через rowShowCheckbox\n   */\n  hidden: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ скрыты через rowShowCheckbox\n   */\n  notHidden: RowIdType[];\n  /**\n   * все дочерние строки, которые selected (уже выбраны, у которых чекбокс проставлен)\n   */\n  selected: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ selected (не выбраны, у которых чекбокс НЕ проставлен)\n   */\n  notSelected: RowIdType[];\n  /**\n   * есть ли хоть одна дочерная строка, которая выбрана (у которой чекбокс проставлен)\n   */\n  someChildrenIsSelected: boolean;\n};\n```",
      "api": [
        {
          "typeName": "SelectingRowConfig",
          "source": "type SelectingRowConfig<RowType, RowIdType extends string | number> = {\n  /**\n   * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n   */\n  showDefault?: boolean;\n  /**\n   * showState - состояние, отвечающее за то, видны ли чекбоксы.\n   */\n  showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n   */\n  showInControl?: boolean;\n  /**\n   * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n   */\n  selectingRules?: {\n    // TODO доработать логику\n    // changeableOfRowWithoutCheckbox?: boolean;\n    // changeableDisabledRow?: boolean;\n    /**\n     * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n     */\n    levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n  };\n  disableSummaryCheckboxInHeader?: boolean;\n  hideSummaryCheckboxInHeader?: boolean;\n  /**\n   * hideSummaryCheckbox - в островке  массовых действий\n   */\n  hideSummaryCheckbox?: boolean;\n  /**\n   * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n   */\n  summaryChecked?: {\n    checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n    indeterminate:\n      | boolean\n      | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n    getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n    onChange: SummaryCheckedFunc<\n      RowType,\n      void,\n      {\n        checkedAll: boolean;\n        clearButtonClicked?: boolean;\n        setSelectedRowsIds: React.Dispatch<\n          React.SetStateAction<ReadonlySet<string | number>>\n        >;\n      }\n    >;\n  };\n\n  /**\n   * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n   */\n  summaryCheckedUncontrolled?: {\n    onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n  };\n\n  /**\n   * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n   */\n  rowShowCheckbox?: RowShowCheckbox<RowType>;\n  /**\n   * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n   */\n  rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n  /**\n   * Функция для переопределения checked, indeterminate для каждой строки.\n   * Что будет возвращено функцией в объекте, то будет переопределено.\n   */\n  rowGetStates?: (\n    p: RowGetStatesProps<RowType, RowIdType>,\n  ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n  groupedRow?: {\n    /**\n     * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n     * Что будет возвращено функцией в объекте, то будет переопределено.\n     */\n    getStates: (p: {\n      checkedCalculated: boolean;\n      indeterminateCalculated: boolean;\n      row: GroupRow<RowType>;\n      selectedRows: ReadonlySet<string | number>;\n      selectedChildCount: number;\n      childCount: number;\n    }) => {\n      checked?: boolean | null;\n      indeterminate?: boolean | null;\n      showCheckbox?: boolean | null;\n      checkboxDisabled?: boolean | null;\n    } | null;\n    onChange?: (p: {\n      row: GroupRow<RowType>;\n\n      setSelectedRows: React.Dispatch<\n        React.SetStateAction<ReadonlySet<string | number>>\n      >;\n      checked: boolean;\n      indeterminate: boolean;\n      checkboxDisabled: boolean;\n      showCheckbox: boolean;\n      defaultSetter: () => void;\n    }) => void;\n  };\n};"
        },
        {
          "typeName": "CellsSelectionConfig",
          "source": "type CellsSelectionConfig = {\n  /**\n   * Режим фактического выделения ячеек (нативный glide selection). По нему\n   * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n   * @default \"range-cell\"\n   */\n  mode?: CellsSelectionMode;\n  /**\n   * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n   * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n   * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n   * @default true\n   */\n  enableColumnSelection?: boolean;\n  /**\n   * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n   * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n   * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n   * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n   * @default true\n   */\n  enableRowSelection?: boolean;\n  /**\n   * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n   * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n   * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n   * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n   * @default true\n   */\n  enableSelectAll?: boolean;\n  /**\n   * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n   * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n   * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n   * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n   */\n  state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};"
        },
        {
          "typeName": "RowGetStatesProps",
          "source": "type RowGetStatesProps<RowType, RowIdType> = {\n  /**\n   * просчитанное по умолчанию значение наличия чекбокса у строки\n   */\n  isHaveCheckboxCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение checked у строки\n   */\n  isRowSelectedCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение indeterminate у строки\n   */\n  isIndeterminateCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение disabled у строки\n   */\n  isRowSelectionDisabled: boolean;\n\n  rowKeyGetter: RowKeyGetter<RowType, RowIdType>;\n  row: RowType;\n  /**\n   * Все строки таблицы в плоском виде с информацией об уровне и родительской строке\n   */\n  flattenedRowsMap: Map<\n    RowIdType,\n    RowType & {\n      level?: number;\n      parent?: RowType | null | undefined;\n    }\n  >;\n  /**\n   * стейт всех выбранных строк (Set)\n   */\n  selectedRows: ReadonlySet<RowIdType>;\n  /**\n   * сеттер стейта всех выбранных строк\n   */\n  setSelectedRows: React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>;\n  /**\n   * уровень вложенности текущей строки\n   */\n  level: number;\n  /**\n   * родительская строка для текущей строки\n   */\n  parent: RowType | null;\n  /**\n   * хендлер для получения детальных данных о дочерних строках текущей строки\n   */\n  getRowChildrenInfo: () => ChildrenInfo<RowType, RowIdType>;\n  rowShowCheckbox: RowShowCheckbox<RowType> | undefined;\n  rowCheckboxDisabled: RowCheckboxDisabled<RowType> | undefined;\n};"
        },
        {
          "typeName": "RowGetStatesReturnType",
          "source": "type RowGetStatesReturnType<RowType, RowIdType> = {\n  /**\n   * состояние checked, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  checked?: boolean | null;\n  /**\n   * состояние indeterminate, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  indeterminate?: boolean | null;\n  /**\n   * состояние showCheckbox, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  showCheckbox?: boolean | null;\n  /**\n   * состояние checkboxDisabled, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  checkboxDisabled?: boolean | null;\n  /**\n   * onChange у чекбокса, который будет окончательным. Если не передан, то будет взят из расчетов по умолчанию\n   */\n  onChange?:\n    | ((p: {\n        allParentsMap: Map<RowIdType, RowType>;\n        isRowInLevels: (row: RowType) => boolean;\n        defaultSetter: () => void;\n        getRowParentsInfo: () => {\n          all: RowType[];\n          getShouldBeSelectedInfo: (\n            actualSelecteds: ReadonlySet<RowIdType>,\n          ) => {\n            shouldBeSelected: RowIdType[];\n            shouldNotBeSelected: RowIdType[];\n          };\n        };\n      }) => void)\n    | null;\n};"
        },
        {
          "typeName": "ChildrenInfo",
          "source": "type ChildrenInfo<RowType, RowIdType> = {\n  /**\n   * все дочерние строки\n   */\n  all: RowType[];\n  /**\n   * все дочерние строки, которые disabled\n   */\n  disabled: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ disabled\n   */\n  notDisabled: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox\n   */\n  notDisabledAndNotHidden: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox все выбраны\n   */\n  notDisabledAndNotHiddenAreSelected: boolean;\n  /**\n   * все дочерние строки, которые скрыты через rowShowCheckbox\n   */\n  hidden: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ скрыты через rowShowCheckbox\n   */\n  notHidden: RowIdType[];\n  /**\n   * все дочерние строки, которые selected (уже выбраны, у которых чекбокс проставлен)\n   */\n  selected: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ selected (не выбраны, у которых чекбокс НЕ проставлен)\n   */\n  notSelected: RowIdType[];\n  /**\n   * есть ли хоть одна дочерная строка, которая выбрана (у которой чекбокс проставлен)\n   */\n  someChildrenIsSelected: boolean;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "CustomRowSelection",
          "displayName": "Независимый выбор строк в иерархии",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          subRow: {\n            keyOfColumnInSubRow: 'id',\n            isColumnWithArrow: true,\n          },\n          resizable: true,\n        },\n        {\n          key: 'issueType',\n          name: 'issue',\n          subRow: {\n            keyOfColumnInSubRow: 'issueType',\n          },\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n      ],\n      [],\n    );\n\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          resizableColumn: true,\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id,\n            selectingRules: {\n              levels: [1, 2],\n            },\n            showDefault: true,\n            summaryChecked: {\n              checked({ allRowsInLevels, selectedRowsIds }) {\n                return (\n                  selectedRowsIds.size > 0 &&\n                  allRowsInLevels.length === selectedRowsIds.size\n                );\n              },\n\n              indeterminate({ checkedAll, allRowsInLevels, selectedRowsIds }) {\n                return (\n                  !checkedAll &&\n                  selectedRowsIds.size > 0 &&\n                  selectedRowsIds.size < allRowsInLevels.length\n                );\n              },\n              getCountOfChecked({ selectedRowsIds }) {\n                return selectedRowsIds.size;\n              },\n              onChange({\n                checkedAll,\n\n                setSelectedRowsIds,\n                allRowsInLevels,\n                rowKeyGetter,\n              }) {\n                if (!checkedAll) {\n                  setSelectedRowsIds(\n                    new Set(...[allRowsInLevels.map((r) => rowKeyGetter(r))]),\n                  );\n                } else {\n                  setSelectedRowsIds(new Set());\n                }\n              },\n            },\n            rowGetStates({\n              row,\n              selectedRows,\n\n              rowKeyGetter,\n              setSelectedRows,\n              isRowSelectedCalculated,\n            }) {\n              return {\n                checked: selectedRows.has(rowKeyGetter(row)),\n                indeterminate: false,\n                onChange() {\n                  setSelectedRows((prev) => {\n                    const newV = new Set(prev);\n                    newV[isRowSelectedCalculated ? 'delete' : 'add'](\n                      rowKeyGetter(row),\n                    );\n                    return newV;\n                  });\n                },\n              };\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "CustomRowSelectionWithDisabledAndHidden",
          "displayName": "Ручная настройка выбора строк с учетом disabled, hidden строк",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          subRow: {\n            keyOfColumnInSubRow: 'id',\n            isColumnWithArrow: true,\n          },\n          resizable: true,\n        },\n        {\n          key: 'issueType',\n          name: 'issue',\n          subRow: {\n            keyOfColumnInSubRow: 'issueType',\n          },\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n      ],\n      [],\n    );\n\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n    const rowShowCheckbox = (r: Row) => r.id !== 2;\n    const rowCheckboxDisabled = (r: Row) => r.id.toString().endsWith('0001');\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          resizableColumn: true,\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id + r.issueType,\n            selectingRules: {\n              levels: [1, 2, 3],\n            },\n            showDefault: true,\n            summaryChecked: {\n              checked({ selectedRowsIds, getAllRowsInfo }) {\n                const { notHidden } = getAllRowsInfo();\n\n                return (\n                  selectedRowsIds.size > 0 &&\n                  notHidden.length === selectedRowsIds.size\n                );\n              },\n              indeterminate({ checkedAll, allRowsInLevels, selectedRowsIds }) {\n                return (\n                  !checkedAll &&\n                  selectedRowsIds.size > 0 &&\n                  selectedRowsIds.size < allRowsInLevels.length\n                );\n              },\n              getCountOfChecked({ selectedRowsIds }) {\n                return selectedRowsIds.size;\n              },\n              onChange({\n                checkedAll,\n                clearButtonClicked,\n                setSelectedRowsIds,\n\n                getAllRowsInfo,\n              }) {\n                // eslint-disable-next-line no-console\n                console.log('========clearButtonClicked:', clearButtonClicked);\n\n                const {\n                  notDisabledAndNotHidden,\n                  notDisabledAndNotHiddenAreSelected,\n                } = getAllRowsInfo();\n\n                if (checkedAll) {\n                  setSelectedRowsIds(new Set());\n                  return;\n                }\n                setSelectedRowsIds((prevSelecteds) => {\n                  const needToDelete = notDisabledAndNotHiddenAreSelected;\n\n                  const newSelecteds = new Set(prevSelecteds);\n                  notDisabledAndNotHidden.forEach((rKey) => {\n                    newSelecteds[needToDelete ? 'delete' : 'add'](rKey);\n                  });\n                  return newSelecteds;\n                });\n              },\n            },\n\n            rowGetStates({\n              isRowSelectedCalculated,\n              getRowChildrenInfo,\n              isHaveCheckboxCalculated,\n              rowKeyGetter,\n              selectedRows,\n              row,\n              setSelectedRows,\n            }) {\n              if (!isHaveCheckboxCalculated) return { showCheckbox: false };\n\n              const rowInfo = getRowChildrenInfo();\n              const hasChildren = !!rowInfo.all.length;\n\n              const allVisible = rowInfo.notHidden;\n              const allSelected = rowInfo.selected;\n              const checked = !hasChildren\n                ? isRowSelectedCalculated\n                : !!allVisible.length &&\n                  allVisible.length === allSelected.length;\n              return {\n                checked,\n                indeterminate:\n                  hasChildren && !checked && rowInfo.someChildrenIsSelected,\n                onChange({ getRowParentsInfo }) {\n                  const {\n                    all,\n                    selected,\n                    notDisabledAndNotHidden,\n                    notHidden,\n                    someChildrenIsSelected,\n                  } = getRowChildrenInfo();\n\n                  const rowKey = rowKeyGetter(row);\n                  const rowIsChecked = selectedRows.has(rowKey);\n\n                  const hasChildren = !!all.length;\n\n                  const checked = !hasChildren\n                    ? rowIsChecked\n                    : someChildrenIsSelected &&\n                      selected.length >= notHidden.length;\n\n                  setSelectedRows((prevSelecteds) => {\n                    const newSelecteds = new Set(prevSelecteds);\n                    // обработка самой строки если она без дочерних строк\n                    if (!hasChildren) {\n                      newSelecteds[checked ? 'delete' : 'add'](\n                        rowKeyGetter(row),\n                      );\n                    } else {\n                      // обработка дочерних строк\n                      // не полагаемся на checked, чтобы обработать логику выбора сразу при checked и indeterminate\n                      const needToAdd = notDisabledAndNotHidden.every((rKey) =>\n                        prevSelecteds.has(rKey),\n                      );\n\n                      notDisabledAndNotHidden.forEach((rKey) => {\n                        newSelecteds[needToAdd ? 'delete' : 'add'](rKey);\n                      });\n\n                      // обработка самой строки. Проверка всех детей для того, чтобы определить выбирать ли текущую строку\n                      const rowChidlrenSelectedAll = notHidden.every((rKey) =>\n                        newSelecteds.has(rKey),\n                      );\n\n                      newSelecteds[rowChidlrenSelectedAll ? 'add' : 'delete'](\n                        rowKey,\n                      );\n                    }\n\n                    // обработка родительских строк\n                    const { shouldBeSelected, shouldNotBeSelected } =\n                      getRowParentsInfo().getShouldBeSelectedInfo(newSelecteds);\n\n                    shouldBeSelected.forEach((rKey) => newSelecteds.add(rKey));\n                    shouldNotBeSelected.forEach((rKey) =>\n                      newSelecteds.delete(rKey),\n                    );\n                    return newSelecteds;\n                  });\n                },\n              };\n            },\n\n            rowCheckboxDisabled,\n            rowShowCheckbox,\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "SelectingWithInfinityScroll",
          "displayName": "SubRows + InfinityScroll + Selecting",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows, setRows] = useState(() => createRows(0, 30));\n    const [isLoading, setIsLoading] = useState(false);\n    const hasMore = rows.length < 200;\n\n    const onTrigger = useCallback(\n      async (currentRows: Row[]) => {\n        if (isLoading) return;\n        setIsLoading(true);\n\n        const newData = await loadMoreRows({\n          indexForStart: currentRows.length,\n          countOfNewRows: 30,\n          timeout: 1500,\n        });\n\n        setRows((prev) => [...prev, ...newData]);\n        setIsLoading(false);\n      },\n      [isLoading],\n    );\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          subRow: {\n            keyOfColumnInSubRow: 'id',\n            isColumnWithArrow: true,\n          },\n          resizable: true,\n        },\n        {\n          key: 'task',\n          name: 'Task',\n          subRow: { keyOfColumnInSubRow: 'task' },\n          renderCell: ({ row }) => <Canvas.Text>{row.task}</Canvas.Text>,\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          renderCell: ({ row }) => (\n            <Canvas.Text>{row.priority ?? '—'}</Canvas.Text>\n          ),\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          renderCell: ({ row }) => (\n            <Canvas.Text>{row.issueType ?? '—'}</Canvas.Text>\n          ),\n        },\n      ],\n      [],\n    );\n\n    const selectingState = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          resizableColumn: true,\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          selecting: {\n            state: selectingState,\n            rowKeyGetter: (r) => r.id,\n            showDefault: true,\n            selectingRules: { levels: 'all' },\n          },\n          controlBlock: {\n            show: true,\n            massActionPanel: {\n              buttons: [\n                {\n                  type: 'button' as const,\n                  text: 'Действие',\n                  view: 'secondary' as const,\n                },\n              ],\n            },\n          },\n          infinityScroll: {\n            rowThreshold: 5,\n            onTrigger,\n            isLoading,\n            hasMore,\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "SelectingRow",
          "displayName": "Пример кастомного выбора строк в группированной таблице",
          "type": "full-code",
          "code": "interface RowForGrouping {\n  id: number;\n  country: string;\n  year: number;\n  sport: string;\n  athlete: string;\n  gold: number;\n  silver: number;\n  bronze: number;\n}\n\n() => {\n    const [rows] = useState(createRowsForGrouping);\n\n    const [groupByArr, setGroupByArr] = useState<string[]>([]);\n\n    const columnConfig = useMemo<readonly ColumnConfig<RowForGrouping>[]>(\n      () => [\n        {\n          key: 'athlete',\n          name: 'Athlete',\n          rowsGrouping: {\n            columnGroupLabel: 'Athlete',\n          },\n        },\n        {\n          key: 'sport',\n          name: 'Sport',\n\n          rowsGrouping: {\n            columnGroupLabel: 'Sport',\n          },\n        },\n        {\n          key: 'country',\n          name: 'Country',\n\n          rowsGrouping: {\n            columnGroupLabel: 'Country',\n          },\n        },\n        {\n          key: 'year',\n          name: 'Year',\n\n          rowsGrouping: {\n            columnGroupLabel: 'Year',\n          },\n        },\n\n        {\n          key: 'gold',\n          name: 'Gold',\n          rowsGrouping: {\n            groupByColumn: false,\n            columnGroupLabel: 'Gold',\n            renderGroupCell({ childRows }) {\n              return childRows\n                .reduce((prev, { gold }) => prev + gold, 0)\n                .toString();\n            },\n          },\n        },\n      ],\n      [],\n    );\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: 700 },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id,\n            groupedRow: {\n              getStates({ row, selectedRows }) {\n                if (row.groupByKey === 'country') {\n                  return {\n                    checked: selectedRows.has(row.groupKey),\n                    indeterminate: false,\n                  };\n                }\n                return null;\n              },\n              onChange({ checked, row, setSelectedRows, defaultSetter }) {\n                const recursive = (rowX: typeof row, groupByKeyX: string) => {\n                  const childGroupsX = rowX.childGroups as (typeof row)[];\n                  if (!childGroupsX || !childGroupsX?.length) {\n                    return;\n                  }\n                  if (childGroupsX[0]?.groupByKey === 'country') {\n                    setSelectedRows((prev) => {\n                      const copy = new Set(prev);\n\n                      childGroupsX.forEach((groupRow) =>\n                        copy[checked ? 'delete' : 'add'](groupRow.groupKey),\n                      );\n                      return copy;\n                    });\n                    return;\n                  }\n\n                  childGroupsX.forEach((groupX) => {\n                    const newChildGroupsX =\n                      groupX.childGroups as (typeof row)[];\n                    if (!newChildGroupsX || !childGroupsX?.length) {\n                      return;\n                    }\n                    recursive(groupX, groupByKeyX);\n                  });\n                };\n                if (row.groupByKey === 'country') {\n                  setSelectedRows((prev) => {\n                    const copy = new Set(prev);\n                    copy[checked ? 'delete' : 'add'](row.groupKey);\n                    return copy;\n                  });\n                  return;\n                }\n                recursive(row, 'country');\n                defaultSetter();\n              },\n            },\n          },\n          rowsGrouping: {\n            rowKeyGetter: (r) => r.id,\n            groupByState: [groupByArr, setGroupByArr],\n            expandAllBtn: {\n              expandedAll({ allRowsIds, shownRows }) {\n                return allRowsIds?.size === shownRows.length;\n              },\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "SelectingRow",
          "displayName": "Простой пример",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'issueType',\n          name: 'issue',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n      ],\n      [],\n    );\n\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    return (\n      <div>\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '700px' },\n            selecting: {\n              rowCheckboxDisabled: (row) => row.id === 2,\n              rowShowCheckbox: (row) => row.id !== 3,\n              state: selectingRowStateAndSetter,\n              rowKeyGetter: (r) => r.id + r.issueType,\n            },\n          }}\n          columnConfig={columns}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "SelectingRow",
          "displayName": "Многоуровневая таблица",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          subRow: {\n            keyOfColumnInSubRow: 'id',\n            isColumnWithArrow: true,\n          },\n          resizable: true,\n        },\n        {\n          key: 'issueType',\n          name: 'issue',\n          subRow: {\n            keyOfColumnInSubRow: 'issueType',\n          },\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n      ],\n      [],\n    );\n\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n    const rowShowCheckbox = (r: Row) => r.id !== 2;\n    const rowCheckboxDisabled = (r: Row) => r.id === 1;\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          resizableColumn: true,\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id + r.issueType,\n            showDefault: true,\n            selectingRules: { levels: 'all' },\n            rowCheckboxDisabled,\n            rowShowCheckbox,\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "CellsSelection",
      "legacy": false,
      "summary": "Выделение в таблице задаётся пропом **`tableConfig.cellsSelection.mode`** — это",
      "docs": "# CellsSelection\n\nВыделение в таблице задаётся пропом **`tableConfig.cellsSelection.mode`** — это\nфактическое нативное выделение ячеек. По нему работают copy/paste, рамка\nвыделения, fill-handle и затемнение шапки/нумерации.\n\n> Это **отдельная ось** от `highlightActiveType` (визуальная подсветка строки) и\n> от `selecting` (выбор строк чекбоксами).\n\n## Значения cellsSelection.mode\n\n- `'range-cell'` — выделение диапазона ячеек (по умолчанию). Тянем мышкой.\n- `'multi-range-cell'` — как `range-cell`, но **Ctrl/Cmd** докидывает несколько\n  диапазонов (см. ниже).\n- `'cell'` — выделение одной ячейки.\n- `'disabled'` — выделение ячеек отключено.\n\n## Мультивыбор диапазонов (multi-range-cell)\n\nПри `cellsSelection: { mode: 'multi-range-cell' }` можно выделить несколько прямоугольных\nдиапазонов: тянем мышкой первый, затем **Ctrl/Cmd + клик/драг** докидываем\nостальные. Заливка и рамка — у всех выделенных.\n\n**Copy (Ctrl+C)** работает для разрозненного выбора, если все ячейки лежат:\n\n- в пределах **одной колонки** — значения копируются подряд, пустые промежутки\n  между ними схлопываются;\n- либо в пределах **одной строки** — аналогично по горизонтали;\n- либо куски складываются в **сплошной прямоугольник** без дыр — тогда он\n  копируется как обычный диапазон.\n\nРазброс сразу **по строкам и колонкам** (2D) не переносится — copy/paste для него\nне срабатывают. Об этом таблица сообщает через модуль\n[Notifications](?path=/docs/локальные-компоненты-tablecanvas-notifications--docs)\n(`copy` / `paste`, code `multi-range-scattered`). Сама таблица тост не рисует:\nподключите `notifications.onNotification` и покажите ошибку пользователю — иначе\nотказ копирования выглядит как молчаливая поломка.\n\n**Paste (Ctrl+V)** зеркально: вставка идёт в выбранные ячейки подряд, схлопывая\nпромежутки. Полный интерактивный пример copy/paste — в разделе\n**Copy-Paste-Fill**.\n\n## Оси выделения\n\nВыделение работает по трём независимым осям. Любая из них поддерживает\ncopy/paste (**Ctrl+C / Ctrl+V**) по текущему выделению.\n\n- **Ячейки / диапазон** — мышью по области данных, зависит от `cellsSelection.mode`.\n- **Колонки** — клик по шапке колонки.\n- **Строки** — клик/драг по колонке нумерации (`rowMarkers`).\n\n### Выделение колонок\n\nКлик по шапке выделяет колонку целиком:\n\n- **Клик** — одна колонка.\n- **Shift + клик** — смежный диапазон колонок (рисуется нативно, с fill-handle).\n- **Ctrl/Cmd + клик** — несмежный выбор: добавить/убрать колонку.\n\nКлик по иконкам сортировки/фильтрации в шапке выделение **не** вызывает.\nУправляется флагом `cellsSelection.enableColumnSelection` (по умолчанию `true`).\n\n### Выделение строк\n\nКлик/драг по колонке нумерации выделяет строку(и):\n\n- **Клик / драг** — смежный диапазон строк (рисуется нативно, с fill-handle).\n- **Ctrl/Cmd + клик** — несмежный выбор отдельных строк.\n\nТребует включённой колонки нумерации (`rowMarkers`). Управляется флагом\n`cellsSelection.enableRowSelection` (по умолчанию `true`).\n\n## Включение / выключение осей\n\nВыделение колонок и строк можно выключать независимо через `tableConfig.cellsSelection`:\n\n```ts\n<TableCanvas\n  tableConfig={{\n    rowMarkers: { startIndex: 1 },\n    cellsSelection: {\n      enableColumnSelection: false, // клик по шапке не выделяет колонку\n      enableRowSelection: false, // клик по нумерации не выделяет строку\n    },\n  }}\n/>;\n```\n\nОба флага по умолчанию `true`. Выделение ячеек/диапазона при этом продолжает\nработать — оно управляется отдельным `cellsSelection.mode`.\n\n## Controlled-режим\n\nВыделением можно управлять снаружи через `state`-кортеж:\n\n```ts\nconst gridSelectionState = useState<GridSelection>(EMPTY_SELECTION);\n\n<TableCanvas\n  tableConfig={{\n    cellsSelection: { mode: 'range-cell', state: gridSelectionState }, // [value, setter]\n  }}\n/>;\n```\n\nСброс: `setter({ current: undefined, rows: CompactSelection.empty(), columns: CompactSelection.empty() })`.\nКонтролируется нативное выделение (ячейки/диапазон/смежные строки и колонки);\nнесмежный Ctrl-выбор колонок/строк — внутренний (own-state), снаружи не задаётся.\n\n`CompactSelection` и тип `GridSelection` реэкспортируются из\n`@daisforge/ui/components/TableCanvas`.\n\n> Подробнее о типах — [CellsSelection API](?path=/docs/локальные-компоненты-tablecanvas-cellsselection-api--docs)",
      "apiDocs": "# CellsSelection API\n\n## CellsSelectionMode\n\nРежим фактического (нативного) выделения ячеек — `tableConfig.cellsSelection.mode`.\n\n```typescript\ntype CellsSelectionMode =\n  | 'cell'\n  | 'range-cell'\n  | 'multi-range-cell'\n  | 'disabled';\n```\n\n## Controlled-режим\n\n`tableConfig.cellsSelection.state` — внешний (controlled) контроль нативного выделения,\n`state`-кортеж `[GridSelection, setter]`:\n\n```ts\ncellsSelection?: {\n  state?: [\n    GridSelection,\n    React.Dispatch<React.SetStateAction<GridSelection>>\n  ];\n};\n```\n\n- Сброс: `setter({ current: undefined, rows: CompactSelection.empty(), columns: CompactSelection.empty() })`.\n- Контролирует нативное выделение (ячейки/диапазон/смежные строки и колонки).\n  Несмежный Ctrl-выбор колонок/строк — внутренний.\n- `CompactSelection` (значение) и `GridSelection` (тип) реэкспортируются из\n  `@daisforge/ui/components/TableCanvas`.\n\n## CellsSelectionConfig\n\nКонфиг выделения колонок (`tableConfig.cellsSelection`).\n\n```typescript\ntype CellsSelectionConfig = {\n  /**\n   * Режим фактического выделения ячеек (нативный glide selection). По нему\n   * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n   * @default \"range-cell\"\n   */\n  mode?: CellsSelectionMode;\n  /**\n   * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n   * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n   * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n   * @default true\n   */\n  enableColumnSelection?: boolean;\n  /**\n   * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n   * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n   * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n   * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n   * @default true\n   */\n  enableRowSelection?: boolean;\n  /**\n   * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n   * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n   * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n   * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n   * @default true\n   */\n  enableSelectAll?: boolean;\n  /**\n   * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n   * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n   * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n   * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n   */\n  state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};\n```",
      "api": [
        {
          "typeName": "CellsSelectionMode",
          "source": "type CellsSelectionMode =\n  | 'cell'\n  | 'range-cell'\n  | 'multi-range-cell'\n  | 'disabled';"
        },
        {
          "typeName": "CellsSelectionConfig",
          "source": "type CellsSelectionConfig = {\n  /**\n   * Режим фактического выделения ячеек (нативный glide selection). По нему\n   * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n   * @default \"range-cell\"\n   */\n  mode?: CellsSelectionMode;\n  /**\n   * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n   * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n   * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n   * @default true\n   */\n  enableColumnSelection?: boolean;\n  /**\n   * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n   * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n   * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n   * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n   * @default true\n   */\n  enableRowSelection?: boolean;\n  /**\n   * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n   * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n   * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n   * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n   * @default true\n   */\n  enableSelectAll?: boolean;\n  /**\n   * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n   * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n   * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n   * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n   */\n  state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};"
        }
      ],
      "stories": [
        {
          "exportName": "SelectionModes",
          "displayName": "Режимы выделения (cellsSelection.mode)",
          "type": "full-code",
          "code": "import {\n  type ColumnConfig,\n  CompactSelection,\n  type GridSelection,\n  type CellsSelectionMode,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\nconst SELECTION_MODE_OPTIONS: Array<{ label: string; value: CellsSelectionMode }> = [\n  { label: 'range-cell', value: 'range-cell' },\n  { label: 'multi-range-cell', value: 'multi-range-cell' },\n  { label: 'cell', value: 'cell' },\n  { label: 'disabled', value: 'disabled' },\n];\n\nconst EMPTY_SELECTION: GridSelection = {\n  current: undefined,\n  rows: CompactSelection.empty(),\n  columns: CompactSelection.empty(),\n};\n\nconst COLUMN_CONFIG: readonly ColumnConfig<Row>[] = [\n  { key: 'id', name: 'ID', width: 90 },\n  { key: 'task', name: 'Title', width: 260 },\n  { key: 'priority', name: 'Priority', width: 180 },\n  { key: 'issueType', name: 'Issue Type', width: 180 },\n  { key: 'complete', name: '% Complete', width: 160 },\n];\n\n() => {\n    const [rows] = useState(createRows);\n    const [selectionMode, setSelectionMode] =\n      useState<CellsSelectionMode>('range-cell');\n    const columnConfig = useMemo(() => COLUMN_CONFIG, []);\n\n    return (\n      <div>\n        <div style={{ maxWidth: 320, marginBottom: 12 }}>\n          <Select\n            label=\"Режим выделения\"\n            value={selectionMode}\n            onChange={(value) => setSelectionMode(value as CellsSelectionMode)}\n            items={SELECTION_MODE_OPTIONS}\n          />\n        </div>\n\n        <StoryHint>\n          <b>range-cell</b> — тянем мышкой диапазон ячеек.{' '}\n          <b>multi-range-cell</b> — то же + Ctrl/Cmd копит несколько диапазонов.{' '}\n          <b>cell</b> — одиночная ячейка. <b>disabled</b> — выделение ячеек\n          отключено.\n          <br />\n          Клик/драг по колонке нумерации → выделение строки (Ctrl — группа).\n          Клик по шапке → выделение колонки (Shift — диапазон, Ctrl — несмежно).\n          Copy/Paste (Ctrl+C/V) работают по выделению.\n        </StoryHint>\n\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '600px' },\n            cellsSelection: { mode: selectionMode },\n            rowMarkers: { startIndex: 1 },\n            editing: {\n              onRowsChange: () => undefined,\n              rowKeyGetter: (r) => `${r.id}`,\n              defaultEnabled: true,\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "Controlled",
          "displayName": "Контролируемое выделение извне (controlled)",
          "type": "full-code",
          "code": "import {\n  type ColumnConfig,\n  CompactSelection,\n  type GridSelection,\n  type CellsSelectionMode,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\nconst SELECTION_MODE_OPTIONS: Array<{ label: string; value: CellsSelectionMode }> = [\n  { label: 'range-cell', value: 'range-cell' },\n  { label: 'multi-range-cell', value: 'multi-range-cell' },\n  { label: 'cell', value: 'cell' },\n  { label: 'disabled', value: 'disabled' },\n];\n\nconst EMPTY_SELECTION: GridSelection = {\n  current: undefined,\n  rows: CompactSelection.empty(),\n  columns: CompactSelection.empty(),\n};\n\nconst COLUMN_CONFIG: readonly ColumnConfig<Row>[] = [\n  { key: 'id', name: 'ID', width: 90 },\n  { key: 'task', name: 'Title', width: 260 },\n  { key: 'priority', name: 'Priority', width: 180 },\n  { key: 'issueType', name: 'Issue Type', width: 180 },\n  { key: 'complete', name: '% Complete', width: 160 },\n];\n\n() => {\n    const [rows] = useState(createRows);\n    const columnConfig = useMemo(() => COLUMN_CONFIG, []);\n\n    const gridSelectionState = useState<GridSelection>(EMPTY_SELECTION);\n    const [gridSelection, setGridSelection] = gridSelectionState;\n\n    const summary = gridSelection.current\n      ? `x=${gridSelection.current.range.x} y=${gridSelection.current.range.y} w=${gridSelection.current.range.width} h=${gridSelection.current.range.height}`\n      : 'нет выделения';\n\n    return (\n      <div>\n        <div\n          style={{\n            display: 'flex',\n            gap: 8,\n            flexWrap: 'wrap',\n            marginBottom: 12,\n          }}\n        >\n          <Button onClick={() => setGridSelection(EMPTY_SELECTION)}>\n            Сбросить выделение\n          </Button>\n          <Button\n            onClick={() =>\n              setGridSelection({\n                current: {\n                  cell: [1, 0],\n                  range: { x: 1, y: 0, width: 2, height: 3 },\n                  rangeStack: [],\n                },\n                rows: CompactSelection.empty(),\n                columns: CompactSelection.empty(),\n              })\n            }\n          >\n            Выделить Title:Priority (строки 1–3)\n          </Button>\n        </div>\n\n        <StoryHint>\n          Выделение — <b>controlled</b> через{' '}\n          <code>tableConfig.cellsSelection.state</code> ([value, setter]).\n          Кнопки задают/сбрасывают внешний стейт, таблица реагирует.\n          Контролируется нативная ось (ячейки/диапазон/смежные строки и\n          колонки); несмежный Ctrl-выбор — внутренний.\n          <br />\n          Текущее выделение: <b>{summary}</b>.\n        </StoryHint>\n\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '600px' },\n            cellsSelection: { mode: 'range-cell', state: gridSelectionState },\n            rowMarkers: { startIndex: 1 },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "MultiRangeSelect",
          "displayName": "Мультивыбор диапазонов (multi-range-cell)",
          "type": "full-code",
          "code": "import {\n  type ColumnConfig,\n  CompactSelection,\n  type GridSelection,\n  type CellsSelectionMode,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\nconst SELECTION_MODE_OPTIONS: Array<{ label: string; value: CellsSelectionMode }> = [\n  { label: 'range-cell', value: 'range-cell' },\n  { label: 'multi-range-cell', value: 'multi-range-cell' },\n  { label: 'cell', value: 'cell' },\n  { label: 'disabled', value: 'disabled' },\n];\n\nconst EMPTY_SELECTION: GridSelection = {\n  current: undefined,\n  rows: CompactSelection.empty(),\n  columns: CompactSelection.empty(),\n};\n\nconst COLUMN_CONFIG: readonly ColumnConfig<Row>[] = [\n  { key: 'id', name: 'ID', width: 90 },\n  { key: 'task', name: 'Title', width: 260 },\n  { key: 'priority', name: 'Priority', width: 180 },\n  { key: 'issueType', name: 'Issue Type', width: 180 },\n  { key: 'complete', name: '% Complete', width: 160 },\n];\n\n() => {\n    const [rows] = useState(createRows);\n    const columnConfig = useMemo(() => COLUMN_CONFIG, []);\n    // Таблица сама тосты не рисует: ошибки copy/paste приходят в notifications,\n    // показ — на стороне потребителя. Здесь показываем последнее событие плашкой.\n    const [lastNotification, setLastNotification] = useState<string | null>(\n      null,\n    );\n\n    return (\n      <div>\n        <StoryHint>\n          <b>multi-range-cell</b>: тяни мышкой диапазон, затем <b>Ctrl/Cmd</b> +\n          клик/драг — докидывай ещё диапазоны. У всех выделенных — заливка и\n          рамка.\n          <br />\n          <b>Copy (Ctrl+C):</b> работает, если разрозненный выбор в пределах{' '}\n          <b>одной колонки</b> или <b>одной строки</b> — промежутки схлопываются\n          (значения копируются подряд), либо если куски складываются в сплошной\n          прямоугольник. Разброс сразу по строкам и колонкам не копируется — в{' '}\n          <b>notifications</b> уходит ошибка (плашка ниже).\n          <br />\n          <b>Paste</b> со схлопыванием промежутков — в режиме редактирования,\n          см. <b>Copy-Paste-Fill</b>.\n        </StoryHint>\n\n        {lastNotification && (\n          <p\n            style={{\n              fontSize: 13,\n              marginBottom: 8,\n              padding: '6px 10px',\n              borderRadius: 6,\n              background: '#fdecec',\n              color: '#a33',\n            }}\n          >\n            notifications: {lastNotification}\n          </p>\n        )}\n\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '600px' },\n            cellsSelection: { mode: 'multi-range-cell' },\n            rowMarkers: { startIndex: 1 },\n            notifications: {\n              onNotification: (event) =>\n                setLastNotification(\n                  `[${event.type}/${event.level}] ${event.message} (${event.code})`,\n                ),\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "EnableToggles",
          "displayName": "Включение/выключение колонок и строк",
          "type": "full-code",
          "code": "import {\n  type ColumnConfig,\n  CompactSelection,\n  type GridSelection,\n  type CellsSelectionMode,\n  TableCanvas,\n} from '@daisforge/ui/components/TableCanvas';\n\nconst SELECTION_MODE_OPTIONS: Array<{ label: string; value: CellsSelectionMode }> = [\n  { label: 'range-cell', value: 'range-cell' },\n  { label: 'multi-range-cell', value: 'multi-range-cell' },\n  { label: 'cell', value: 'cell' },\n  { label: 'disabled', value: 'disabled' },\n];\n\nconst EMPTY_SELECTION: GridSelection = {\n  current: undefined,\n  rows: CompactSelection.empty(),\n  columns: CompactSelection.empty(),\n};\n\nconst COLUMN_CONFIG: readonly ColumnConfig<Row>[] = [\n  { key: 'id', name: 'ID', width: 90 },\n  { key: 'task', name: 'Title', width: 260 },\n  { key: 'priority', name: 'Priority', width: 180 },\n  { key: 'issueType', name: 'Issue Type', width: 180 },\n  { key: 'complete', name: '% Complete', width: 160 },\n];\n\n() => {\n    const [rows] = useState(createRows);\n    const columnConfig = useMemo(() => COLUMN_CONFIG, []);\n    const [enableColumnSelection, setEnableColumnSelection] = useState(true);\n    const [enableRowSelection, setEnableRowSelection] = useState(true);\n\n    return (\n      <div>\n        <div style={{ display: 'flex', gap: 20, marginBottom: 12 }}>\n          <Checkbox\n            checked={enableColumnSelection}\n            onChange={(e) => setEnableColumnSelection(e.target.checked)}\n            label={<div>enableColumnSelection</div>}\n          />\n          <Checkbox\n            checked={enableRowSelection}\n            onChange={(e) => setEnableRowSelection(e.target.checked)}\n            label={<div>enableRowSelection</div>}\n          />\n        </div>\n\n        <StoryHint>\n          Сними галочку — клик по шапке (колонки) или по колонке нумерации\n          (строки) перестанет выделять. Выделение ячеек мышью при этом\n          продолжает работать.\n        </StoryHint>\n\n        <TableCanvas\n          tableConfig={{\n            containerStyle: { height: '600px' },\n            cellsSelection: {\n              mode: 'range-cell',\n              enableColumnSelection,\n              enableRowSelection,\n            },\n            rowMarkers: { startIndex: 1 },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "Sidebar",
      "legacy": false,
      "summary": "*tableConfig.sidebarConfig**",
      "docs": "# Sidebar (TableCanvas)\n\n**tableConfig.sidebarConfig**\n\nПравая панель таблицы с вкладками. Открывается через кнопку-шестерёнку в controlBlock. Позволяет управлять настройками таблицы, фильтрацией и колонками.\n\n## Ключевые особенности\n\n- Три стандартные вкладки: колонки, настройки таблицы, фильтры\n- Добавление пользовательских вкладок через `customTabs`\n- Управление порядком кастомных вкладок через `customTabsOrder`\n- Кастомизация стандартных вкладок через `defaultTabs`\n- Отключение sidebar через `enabled: false`\n\n## Стандартные вкладки\n\n1. **Настройка колонок** (`columns`) — управление видимостью, порядком и закреплением колонок. Появляется автоматически при наличии `columnsControl`\n2. **Настройки таблицы** (`tableSettings`) — итоговые строки, выбор строк, кастомные фичи из ControlBlock. Поддерживает `customGeneralSettingsSlot` для дополнительного контента\n3. **Фильтры** (`filtering`) — управление фильтрацией данных. Появляется автоматически при наличии `filtering`\n\n## Кастомизация стандартных вкладок\n\nЧерез `defaultTabs` можно переопределить:\n\n- `label` — текст на горизонтальном табе в рамках общего одного таба со всеми дефолтными настройками\n- `title` — заголовок в шапке сайдбара\n- `domMetadata` — data-атрибуты для тестирования и аналитики\n- `titleRightSlot` — кастомный элемент справа от заголовка\n- `iconTooltipText` — текст тултипа у иконки шестеренки (передаем данное свойство только табу с id `tableSettings`)\n- `showInSidebar` — управление видимостью дефолтного таба\n\n### Полное отключение стандартных вкладок\n\nкаждому табу в рамках массива `defaultTabs` передать свойство `showInSidebar`=`true`\n\n## Пользовательские вкладки\n\nЧерез `customTabs` можно добавить произвольные вкладки с `label`, `icon` и `renderContent`.\n\n## Управление состоянием сайдбара\n\nПо умолчанию сайдбар закрыт (uncontrolled). Стартовое и внешнее состояние настраивается через `sidebarConfig`:\n\n- `defaultOpen` — сайдбар открыт сразу при первом рендере.\n- `defaultActiveTabId` — какая вкладка выбрана по умолчанию. Актуально при открытом сайдбаре; если id не найден или у вкладки `showInSidebar=false`, берётся первая доступная.\n- `openState` — внешний контроль открытия/закрытия (`[boolean, setter]`). Если передан, `defaultOpen` игнорируется.\n- `activeTabState` — внешний контроль активной вкладки (`[string | null, setter]`). Позволяет, например, открыть нужную вкладку по кнопке над таблицей. Если передан, `defaultActiveTabId` игнорируется.\n- `onActiveTabChange` — колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме; при закрытии сайдбара приходит `null`.\n\nАктивная вкладка имеет смысл только при открытом сайдбаре — при закрытии она сбрасывается в `null`.\n\n> Подробнее о типах — [Sidebar API](?path=/docs/локальные-компоненты-tablecanvas-sidebar-api--docs)",
      "apiDocs": "# Sidebar API\n\n## SidebarConfig\n\n```typescript\ntype SidebarConfig = {\n  /**\n   * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n   * @default true\n   */\n  enabled?: boolean;\n  /**\n   * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n   * Игнорируется, если передан openState.\n   * @default false\n   */\n  defaultOpen?: boolean;\n  /**\n   * Внешний контроль открытия/закрытия sidebar.\n   * Если передан — источник истины, defaultOpen игнорируется.\n   */\n  openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n   * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n   */\n  defaultActiveTabId?: string;\n  /**\n   * Внешний контроль активной вкладки (controlled-режим).\n   * Если передан — источник истины, defaultActiveTabId игнорируется.\n   */\n  activeTabState?: [\n    string | null,\n    React.Dispatch<React.SetStateAction<string | null>>,\n  ];\n  /**\n   * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n   * При закрытии сайдбара приходит null.\n   */\n  onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n  /**\n   * Кастомные табы\n   */\n  customTabs?: Array<\n    Omit<SidebarTab, 'id'> & {\n      id: Exclude<string, DefaultSidebarTabIds>;\n    }\n  >;\n  /**\n   * Порядок отображения кастомных вкладок\n   */\n  customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n  defaultTabs?: Array<\n    | {\n        id: 'filtering' | 'columns';\n        /** название таба в рамках горизонтального табов внутри таба настройки */\n        label?: string;\n        /** название таба в рамках вертикальных табов сайдбара (если данный таб окажется единственным табом в настройках) */\n        title?: string;\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n        /** @default true */\n        showInSidebar?: boolean;\n        /** тултип иконки шестеренки (для табов с id = filtering и columns - недоступен. Настраивается через таб с id='tableSettings') */\n        iconTooltipText?: undefined;\n      }\n    | {\n        id: 'tableSettings';\n        /** название таба в рамках горизонтального табов внутри таба настройки */\n        label?: string;\n        /** название таба в рамках вертикальных табов сайдбара */\n        title?: string;\n\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n         * Только дл id: 'tableSettings'\n         */\n        customGeneralSettingsSlot?: React.ReactNode;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n        /** @default true */\n        showInSidebar?: boolean;\n        /** тултип иконки шестеренки @default 'Настройки' */\n        iconTooltipText?: string;\n      }\n  >;\n};\n```\n\n## DefaultSidebarTabIds\n\n```typescript\ntype DefaultSidebarTabIds = 'columns' | 'tableSettings' | 'filtering';\n```\n\n## SidebarTab\n\n```typescript\ntype SidebarTab = {\n  /**\n   * Уникальный идентификатор таба\n   */\n  id: DefaultSidebarTabIds | string;\n  /**\n   * title таба (для Tooltip)\n   */\n  label: string;\n  /**\n   * Иконка таба\n   */\n  icon: ReactNode;\n  /**\n   * Контентная часть сайдбара\n   */\n  content: React.ReactNode;\n  /**\n   * Показывать ли в сайдбаре\n   * @default true\n   */\n  showInSidebar?: boolean;\n  /**\n   * Заголовок контентной части сайдбара\n   */\n  title?: string;\n  /**\n   * Кастомный элемент справа от title в шапке сайдбара\n   */\n  titleRightSlot?: React.ReactNode;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n```",
      "api": [
        {
          "typeName": "SidebarConfig",
          "source": "type SidebarConfig = {\n  /**\n   * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n   * @default true\n   */\n  enabled?: boolean;\n  /**\n   * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n   * Игнорируется, если передан openState.\n   * @default false\n   */\n  defaultOpen?: boolean;\n  /**\n   * Внешний контроль открытия/закрытия sidebar.\n   * Если передан — источник истины, defaultOpen игнорируется.\n   */\n  openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n   * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n   */\n  defaultActiveTabId?: string;\n  /**\n   * Внешний контроль активной вкладки (controlled-режим).\n   * Если передан — источник истины, defaultActiveTabId игнорируется.\n   */\n  activeTabState?: [\n    string | null,\n    React.Dispatch<React.SetStateAction<string | null>>,\n  ];\n  /**\n   * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n   * При закрытии сайдбара приходит null.\n   */\n  onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n  /**\n   * Кастомные табы\n   */\n  customTabs?: Array<\n    Omit<SidebarTab, 'id'> & {\n      id: Exclude<string, DefaultSidebarTabIds>;\n    }\n  >;\n  /**\n   * Порядок отображения кастомных вкладок\n   */\n  customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n  defaultTabs?: Array<\n    | {\n        id: 'filtering' | 'columns';\n        /** название таба в рамках горизонтального табов внутри таба настройки */\n        label?: string;\n        /** название таба в рамках вертикальных табов сайдбара (если данный таб окажется единственным табом в настройках) */\n        title?: string;\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n        /** @default true */\n        showInSidebar?: boolean;\n        /** тултип иконки шестеренки (для табов с id = filtering и columns - недоступен. Настраивается через таб с id='tableSettings') */\n        iconTooltipText?: undefined;\n      }\n    | {\n        id: 'tableSettings';\n        /** название таба в рамках горизонтального табов внутри таба настройки */\n        label?: string;\n        /** название таба в рамках вертикальных табов сайдбара */\n        title?: string;\n\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n         * Только дл id: 'tableSettings'\n         */\n        customGeneralSettingsSlot?: React.ReactNode;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n        /** @default true */\n        showInSidebar?: boolean;\n        /** тултип иконки шестеренки @default 'Настройки' */\n        iconTooltipText?: string;\n      }\n  >;\n};"
        },
        {
          "typeName": "DefaultSidebarTabIds",
          "source": "type DefaultSidebarTabIds = 'columns' | 'tableSettings' | 'filtering';"
        },
        {
          "typeName": "SidebarTab",
          "source": "type SidebarTab = {\n  /**\n   * Уникальный идентификатор таба\n   */\n  id: DefaultSidebarTabIds | string;\n  /**\n   * title таба (для Tooltip)\n   */\n  label: string;\n  /**\n   * Иконка таба\n   */\n  icon: ReactNode;\n  /**\n   * Контентная часть сайдбара\n   */\n  content: React.ReactNode;\n  /**\n   * Показывать ли в сайдбаре\n   * @default true\n   */\n  showInSidebar?: boolean;\n  /**\n   * Заголовок контентной части сайдбара\n   */\n  title?: string;\n  /**\n   * Кастомный элемент справа от title в шапке сайдбара\n   */\n  titleRightSlot?: React.ReactNode;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "WithCustomTab",
          "displayName": "С кастомной вкладкой",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n    const [selectedRows, setSelectedRows] = useState<ReadonlySet<string>>(\n      new Set(),\n    );\n    const [filters, setFilters] = useState({});\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n      ],\n      [],\n    );\n\n    const CustomInfoTab = () => (\n      <>\n        <p>Всего строк: {rows.length}</p>\n        <p>Выбрано строк: {selectedRows.size}</p>\n      </>\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          sidebarConfig: {\n            customTabs: [\n              {\n                id: 'customInfo',\n                label: 'Информация',\n                icon: <IconInfo size=\"s\" />,\n                content: <CustomInfoTab />,\n                title: 'Информация',\n                showInSidebar: true,\n              },\n            ],\n          },\n          selecting: {\n            state: [selectedRows, setSelectedRows],\n            rowKeyGetter: (row) => row.id.toString(),\n          },\n          filtering: {\n            state: [filters, setFilters],\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "DefaultOpen",
          "displayName": "Открыт по умолчанию на кастомной вкладке",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          sidebarConfig: {\n            defaultOpen: true,\n            defaultActiveTabId: 'customInfo',\n            customTabs: [\n              {\n                id: 'customInfo',\n                label: 'Информация',\n                icon: <IconInfo size=\"s\" />,\n                content: <p>Эта вкладка открыта сразу при первом рендере.</p>,\n                title: 'Информация',\n                showInSidebar: true,\n              },\n            ],\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ControlledActiveTab",
          "displayName": "Внешнее управление активной вкладкой",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n    const [isOpen, setIsOpen] = useState(false);\n    const [activeTab, setActiveTab] = useState<string | null>(null);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n      ],\n      [],\n    );\n\n    const openTab = (id: string) => {\n      setActiveTab(id);\n      setIsOpen(true);\n    };\n\n    return (\n      <>\n        <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>\n          <Button onClick={() => openTab('customInfo')}>Инфо</Button>\n          <Button onClick={() => openTab('customSettings')}>Настройки</Button>\n          <Button onClick={() => setIsOpen(false)}>Закрыть</Button>\n        </div>\n        <TableCanvas\n          tableConfig={{\n            sidebarConfig: {\n              openState: [isOpen, setIsOpen],\n              activeTabState: [activeTab, setActiveTab],\n              customTabs: [\n                {\n                  id: 'customInfo',\n                  label: 'Информация',\n                  icon: <IconInfo size=\"s\" />,\n                  content: <p>Вкладка «Информация».</p>,\n                  title: 'Информация',\n                  showInSidebar: true,\n                },\n                {\n                  id: 'customSettings',\n                  label: 'Настройки',\n                  icon: <IconSettings size=\"s\" />,\n                  content: <p>Вкладка «Настройки».</p>,\n                  title: 'Настройки',\n                  showInSidebar: true,\n                },\n              ],\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        },
        {
          "exportName": "ActiveTabCallback",
          "displayName": "Колбэк активной вкладки",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(createRows);\n    const [currentTab, setCurrentTab] = useState<string | null>(null);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n      ],\n      [],\n    );\n\n    return (\n      <>\n        <p style={{ marginBottom: 12 }}>\n          Активная вкладка: <b>{currentTab ?? 'нет (сайдбар закрыт)'}</b>\n        </p>\n        <TableCanvas\n          tableConfig={{\n            sidebarConfig: {\n              onActiveTabChange: (tabId, tab) =>\n                setCurrentTab(tab?.title ?? tabId),\n              customTabs: [\n                {\n                  id: 'customInfo',\n                  label: 'Информация',\n                  icon: <IconInfo size=\"s\" />,\n                  content: <p>Вкладка «Информация».</p>,\n                  title: 'Информация',\n                  showInSidebar: true,\n                },\n                {\n                  id: 'customSettings',\n                  label: 'Настройки',\n                  icon: <IconSettings size=\"s\" />,\n                  content: <p>Вкладка «Настройки».</p>,\n                  title: 'Настройки',\n                  showInSidebar: true,\n                },\n              ],\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "Sorting",
      "legacy": false,
      "summary": "*tableConfig.sorting + columnConfig.sortingType**",
      "docs": "# Sorting\n\n**tableConfig.sorting + columnConfig.sortingType**\n\nСортировка данных по колонкам.\n\n## Быстрый старт\n\nДля включения сортировки необходимо:\n\n1. Передать `sorting` в `tableConfig`\n2. Указать `sortingType` в конфигурации колонок\n\n```tsx\nconst sortingState = useState<readonly SortColumn[]>([]);\n\n<TableCanvas\n  tableConfig={{\n    sorting: {\n      state: sortingState,\n    },\n  }}\n  columnConfig={[\n    { key: 'name', name: 'Название', sortingType: 'stringSort' },\n    { key: 'amount', name: 'Сумма', sortingType: 'numberSort' },\n  ]}\n  rows={rows}\n/>;\n```\n\n## Стратегии сортировки\n\n- **`'stringSort'`** — текстовые поля, названия, описания. Пример: `\"Яблоко\"`, `\"Apple\"`, `\"100 дней\"`\n- **`'numberSort'`** — числа, ID, коды (даже строковые). Пример: `\"42\"`, `\"1 000\"`, `\"3,14\"`\n- **`Comparator<Row>`** — кастомная логика (enum-приоритеты, даты, и т.д.). Пример: `Critical → High → Medium → Low`\n\n### stringSort\n\nСтроковое сравнение с учётом русской локали.\n\n- Строковые числа сортируются как числа: `\"2\" < \"10\"` (не посимвольно)\n- Регистр не влияет: `\"яблоко\"` = `\"Яблоко\"`\n- Пустые значения всегда внизу\n\nПорядок символов при ASC (локаль `'ru'`):\n\n1. Спецсимволы — `\"#tag\"`, `\"@user\"`, `\"-\"`\n2. Цифры — `\"31.10\"`, `\"100\"`\n3. Кириллица — `\"Авто\"`, `\"Яблоко\"`\n4. Латиница — `\"Apple\"`, `\"MYCHANGE\"`\n5. Пустые — всегда внизу\n\n> Порядок между кириллицей и латиницей определяется русской локалью браузера — кириллица идёт первой.\n\n### numberSort\n\nЧисловое сравнение с поддержкой локальных форматов.\n\n- `\"42\"` → `42`\n- `\"1 000\"` → `1000` (пробелы-разделители)\n- `\"3,14\"` → `3.14` (запятая как десятичный)\n- `\"abc\"`, `\"\"` → уходят вниз\n\n### Кастомный компаратор\n\nФункция `(a: Row, b: Row) => number`. Направление (ASC/DESC) применяется автоматически.\n\n```tsx\n{\n  key: 'priority',\n  name: 'Приоритет',\n  sortingType: (a, b) => {\n    const order = { Critical: 0, High: 1, Medium: 2, Low: 3 };\n    return (order[a.priority] ?? 99) - (order[b.priority] ?? 99);\n  },\n}\n```\n\n## Направление сортировки\n\nКлик по заголовку переключает направление циклически:\n\n**нет сортировки → ASC (↓) → DESC (↑) → нет сортировки**\n\n- **↓ ASC** — по возрастанию (от меньшего к большему)\n- **↑ DESC** — по убыванию (от большего к меньшему)\n- **↕** — сортировка не активна\n\nПустые значения (`null`, `undefined`, `\"\"`, строка из пробелов) всегда остаются внизу, независимо от направления.\n\n## Серверная сортировка\n\nЕсли сортировка выполняется на бэкенде, включите `manualSorting`. Таблица не будет сортировать данные сама, но будет обновлять `state` при кликах по заголовкам.\n\n```tsx\nconst [sortColumns, setSortColumns] = useState<readonly SortColumn[]>([]);\n\n// Реагируем на изменение sortColumns и делаем запрос на сервер\nuseEffect(() => {\n  fetchData({ sort: sortColumns });\n}, [sortColumns]);\n\n<TableCanvas\n  tableConfig={{\n    sorting: {\n      state: [sortColumns, setSortColumns],\n      manualSorting: true,\n    },\n  }}\n  ...\n/>\n```\n\n> Подробнее о типах — [Sorting API](?path=/docs/локальные-компоненты-tablecanvas-sorting-api--docs)",
      "apiDocs": "# Sorting API\n\n## SortColumn\n\n```typescript\ninterface SortColumn {\n  readonly columnKey: string;\n  readonly direction: SortDirection;\n}\n```\n\n## SortDirection\n\n```typescript\ntype SortDirection = 'ASC' | 'DESC';\n```\n\n## Comparator\n\n```typescript\ntype Comparator<Row extends ObjectForExtending> = (\n  a: Row,\n  b: Row,\n) => number;\n```\n\n## sortingType (в ColumnConfig)\n\n```ts\nsortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n```\n\n- **`'stringSort'`** — строковый компаратор. Локаль `'ru'`, `numeric: true`, `sensitivity: 'base'`. Пустые значения — внизу\n- **`'numberSort'`** — числовой компаратор. Поддержка запятых, пробелов-разделителей тысяч. Невалидные и пустые значения — внизу\n- **`Comparator<Row>`** — кастомная функция `(a: Row, b: Row) => number`. Направление (ASC/DESC) применяется автоматически\n\n## sorting (в TableConfig)\n\n```ts\nsorting?: {\n  state: [\n    readonly SortColumn[],\n    React.Dispatch<React.SetStateAction<readonly SortColumn[]>>\n  ];\n  manualSorting?: boolean;\n};\n```\n\n- **`state`** — стейт сортировки. Передать `useState<readonly SortColumn[]>([])`\n- **`manualSorting`** `boolean` — если `true`, таблица не сортирует данные — ожидается серверная сортировка (default: `false`)",
      "api": [
        {
          "typeName": "SortColumn",
          "source": "interface SortColumn {\n  readonly columnKey: string;\n  readonly direction: SortDirection;\n}"
        },
        {
          "typeName": "SortDirection",
          "source": "type SortDirection = 'ASC' | 'DESC';"
        },
        {
          "typeName": "Comparator",
          "source": "type Comparator<Row extends ObjectForExtending> = (\n  a: Row,\n  b: Row,\n) => number;"
        }
      ],
      "stories": [
        {
          "exportName": "ManualSorting",
          "displayName": "ID",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\n\n() => {\n    const rows = useMemo(() => createRows(), []);\n    const [sortedRows, setSortedRows] = useState(rows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          sortingType: 'numberSort',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          sortingType: 'stringSort',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          sortingType: 'stringSort',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          sortingType: 'stringSort',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n          sortingType: 'numberSort',\n        },\n      ],\n      [],\n    );\n\n    const sortingStateAndSetter = useState<readonly SortColumn[]>([]);\n\n    const [state] = sortingStateAndSetter;\n\n    useEffect(() => {\n      const sortColState = state[0];\n      if (!sortColState) {\n        setSortedRows(rows);\n        return;\n      }\n      const sortRows = [...rows].sort((a, b) => {\n        const aValue = a[sortColState.columnKey as keyof Row];\n        const bValue = b[sortColState.columnKey as keyof Row];\n\n        if (typeof aValue === 'number' && typeof bValue === 'number') {\n          return sortColState.direction === 'ASC'\n            ? aValue - bValue\n            : bValue - aValue;\n        }\n\n        if (\n          typeof aValue === 'string' &&\n          typeof bValue === 'string' &&\n          aValue[0] &&\n          bValue[0]\n        ) {\n          return sortColState.direction === 'ASC'\n            ? aValue.localeCompare(bValue)\n            : bValue.localeCompare(aValue);\n        }\n\n        return 0;\n      });\n\n      setSortedRows(sortRows);\n      // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [state]);\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          sorting: {\n            state: sortingStateAndSetter,\n            manualSorting: true,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={sortedRows}\n      />\n    );\n  }"
        },
        {
          "exportName": "Sorting",
          "displayName": "ID",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n\n          sortingType: 'numberSort',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          sortingType: 'stringSort',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          // custom sorting\n          sortingType: (a: Row, b: Row) => {\n            const values = {\n              Critical: 2,\n              High: 3,\n              Medium: 4,\n              Low: 5,\n            };\n            const aValue = values[a.priority as keyof typeof values] ?? 0;\n            const bValue = values[b.priority as keyof typeof values] ?? 0;\n            return aValue - bValue;\n          },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          sortingType: 'stringSort',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n\n          sortingType: 'numberSort',\n        },\n      ],\n      [],\n    );\n\n    const sortingStateAndSetter = useState<readonly SortColumn[]>([]);\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          sorting: {\n            state: sortingStateAndSetter,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "StringSort",
          "displayName": "stringSort",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\n\n() => {\n    const [rows] = useState(mockRows);\n    const columnConfig = useMemo<readonly ColumnConfig<MockRow>[]>(\n      () => [\n        { key: 'UVE0367', name: 'Ключ инициативы', sortingType: 'stringSort' },\n        { key: 'UVE0367_TEXT', name: 'Инициатива', sortingType: 'stringSort' },\n        {\n          key: 'UVE0230_TEXT',\n          name: 'Направление ПАО',\n          sortingType: 'stringSort',\n        },\n        { key: 'ZSERVICE_TEXT', name: 'АС/ФП', sortingType: 'stringSort' },\n        { key: 'ZSERVICE', name: 'Код сервиса', sortingType: 'stringSort' },\n        { key: 'UVE0209_TEXT', name: 'Программа', sortingType: 'stringSort' },\n        { key: 'UVE0499_TEXT', name: 'AI', sortingType: 'stringSort' },\n        { key: 'UVE0500_TEXT', name: 'Источник', sortingType: 'stringSort' },\n      ],\n      [],\n    );\n    const sortingState = useState<readonly SortColumn[]>([]);\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          sorting: { state: sortingState },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MixedComparators",
          "displayName": "numberSort + stringSort",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui';\n\n() => {\n    const [rows] = useState(mockRows);\n    const columnConfig = useMemo<readonly ColumnConfig<MockRow>[]>(\n      () => [\n        { key: 'UVE0367', name: 'Ключ инициативы', sortingType: 'numberSort' },\n        { key: 'UVE0230', name: 'Код направления', sortingType: 'numberSort' },\n        { key: 'ZSERVICE', name: 'Код сервиса', sortingType: 'numberSort' },\n        { key: 'UVE0367_TEXT', name: 'Инициатива', sortingType: 'stringSort' },\n        {\n          key: 'UVE0230_TEXT',\n          name: 'Направление ПАО',\n          sortingType: 'stringSort',\n        },\n        { key: 'ZSERVICE_TEXT', name: 'АС/ФП', sortingType: 'stringSort' },\n        { key: 'UVE0209_TEXT', name: 'Программа', sortingType: 'stringSort' },\n        { key: 'UVE0499_TEXT', name: 'AI', sortingType: 'stringSort' },\n        { key: 'UVE0500_TEXT', name: 'Источник', sortingType: 'stringSort' },\n      ],\n      [],\n    );\n    const sortingState = useState<readonly SortColumn[]>([]);\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          sorting: { state: sortingState },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "SubRows",
      "legacy": false,
      "summary": "*tableConfig.subRows + columnConfig.subRow**",
      "docs": "# SubRows (TableCanvas)\n\n**tableConfig.subRows + columnConfig.subRow**\n\nИерархичное отображение данных с вложенными строками. Поддерживает произвольную глубину вложенности.\n\nКонфигурация состоит из двух частей:\n\n- **`tableConfig.subRows`** — дерево данных: функция получения дочерних строк, ключ строки, состояние раскрытия\n- **`columnConfig[].subRow`** — отображение на уровне колонки: маппинг ключей, рендер ячеек, стрелка раскрытия\n\n## tableConfig.subRows\n\n- **`getSubRows`** `(row) => RowType[] | undefined` — функция получения дочерних строк\n- **`rowKeyGetter`** `(row) => RowIdType` — уникальный ключ строки\n- **`expandedIdsState`** `[Set, setter]` — внешний стейт развёрнутых строк (опционально, иначе внутренний useState)\n\n## columnConfig.subRow\n\n- **`isColumnWithArrow`** `boolean | ((props) => boolean)` — стрелка раскрытия в этой колонке (default: `false`)\n- **`hideHeaderExpandAllArrow`** `boolean` — скрыть кнопку «развернуть все» в header (default: `false`)\n- **`parentKeyAsDefault`** `boolean` — использовать ключ родителя как fallback (default: `false`)\n- **`keyOfColumnInSubRow`** `string | number | ((lvl) => string | number)` — маппинг ключей колонок для каждого уровня\n- **`contentFormat`** `ContentFormat` — формат содержимого подстрок\n- **`renderSubRowCell`** `RenderSubRowCell` — кастомный рендер ячеек подстрок\n\n> Подробнее о типах — [SubRows API](?path=/docs/локальные-компоненты-tablecanvas-subrows-api--docs)",
      "apiDocs": "# SubRows API\n\n## SubRows\n\n```typescript\ntype SubRows<RowType, RowIdType> = {\n  /**\n   * Возвращает дочерние строки узла (или undefined, если их нет).\n   *\n   * Функция должна быть стабильной — не менять поведение между рендерами.\n   * Если она зависит от чего-то меняющегося, оберните её в useCallback.\n   */\n  getSubRows: (row: RowType) => RowType[] | undefined;\n  /**\n   * Возвращает уникальный ключ строки.\n   *\n   * Функция должна быть стабильной — не менять поведение между рендерами.\n   * Если она зависит от чего-то меняющегося, оберните её в useCallback.\n   */\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * Внешний стейт развёрнутых строк.\n   * Если не задан — используется внутренний useState.\n   * При view: 'merged' не используется: сворачивания в этом виде нет.\n   */\n  expandedIdsState?: [\n    Set<string | number>,\n    (\n      newV:\n        | Set<string | number>\n        | ((prev: Set<string | number>) => Set<string | number>),\n    ) => void,\n  ];\n  /**\n   * Как показывать дерево.\n   * 'tree' (по умолчанию) — узлы с раскрытием (шевроны) и отступом по уровню.\n   * 'merged' — дерево разворачивается в листья, а колонки-предки показаны\n   * объединёнными ячейками. Структуру задаёт потребитель через getSubRows;\n   * данные (пагинация, сортировка, поиск) остаются на его стороне.\n   */\n  view?: 'tree' | 'merged';\n  /**\n   * Только для view: 'merged'. Колонки-предки по порядку уровней:\n   * mergedColumns[0] — верхний уровень, дальше глубже. Каждая такая колонка\n   * показывает значение своего узла-предка (узел должен нести поле с этим именем)\n   * и объединяется по его границам. Верхний уровень задаёт чекбокс и номер блока.\n   */\n  mergedColumns?: string[];\n};\n```",
      "api": [
        {
          "typeName": "SubRows",
          "source": "type SubRows<RowType, RowIdType> = {\n  /**\n   * Возвращает дочерние строки узла (или undefined, если их нет).\n   *\n   * Функция должна быть стабильной — не менять поведение между рендерами.\n   * Если она зависит от чего-то меняющегося, оберните её в useCallback.\n   */\n  getSubRows: (row: RowType) => RowType[] | undefined;\n  /**\n   * Возвращает уникальный ключ строки.\n   *\n   * Функция должна быть стабильной — не менять поведение между рендерами.\n   * Если она зависит от чего-то меняющегося, оберните её в useCallback.\n   */\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * Внешний стейт развёрнутых строк.\n   * Если не задан — используется внутренний useState.\n   * При view: 'merged' не используется: сворачивания в этом виде нет.\n   */\n  expandedIdsState?: [\n    Set<string | number>,\n    (\n      newV:\n        | Set<string | number>\n        | ((prev: Set<string | number>) => Set<string | number>),\n    ) => void,\n  ];\n  /**\n   * Как показывать дерево.\n   * 'tree' (по умолчанию) — узлы с раскрытием (шевроны) и отступом по уровню.\n   * 'merged' — дерево разворачивается в листья, а колонки-предки показаны\n   * объединёнными ячейками. Структуру задаёт потребитель через getSubRows;\n   * данные (пагинация, сортировка, поиск) остаются на его стороне.\n   */\n  view?: 'tree' | 'merged';\n  /**\n   * Только для view: 'merged'. Колонки-предки по порядку уровней:\n   * mergedColumns[0] — верхний уровень, дальше глубже. Каждая такая колонка\n   * показывает значение своего узла-предка (узел должен нести поле с этим именем)\n   * и объединяется по его границам. Верхний уровень задаёт чекбокс и номер блока.\n   */\n  mergedColumns?: string[];\n};"
        }
      ],
      "stories": [
        {
          "exportName": "SubRows",
          "displayName": "Иерархичный вид",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    // Разная глубина и число детей у строк — «рваная лестница» отступов\n    const [rows] = useState(() => createRaggedRowsTree());\n\n    const columns = useMemo(\n      (): readonly ColumnConfig<TreeRow>[] => [\n        {\n          key: 'block',\n          name: 'Блок / Трайб / Продукт',\n\n          subRow: {\n            keyOfColumnInSubRow: (lvl) => {\n              switch (lvl) {\n                case 0:\n                  return 'block';\n                case 1:\n                  return 'tribe';\n                default:\n                  return 'product';\n              }\n            },\n\n            isColumnWithArrow: true,\n            hideHeaderExpandAllArrow: false,\n          },\n        },\n        {\n          key: 'blockActivity',\n          name: 'Активность блока',\n        },\n        {\n          key: ' ',\n          name: 'Локация трайба',\n          subRow: {\n            renderSubRowCell: (props, lvl) => {\n              if (lvl === 1) {\n                return (\n                  <Canvas.Container\n                    alignItems=\"center\"\n                    padding={{ left: 8 }}\n                    style={{ width: '100%' }}\n                  >\n                    <Canvas.Badge\n                      id=\"kek\"\n                      text={props.row?.tribeZone}\n                      view=\"accent\"\n                      size=\"m\"\n                    />\n                  </Canvas.Container>\n                );\n              }\n              return '';\n            },\n          },\n        },\n        {\n          key: 'q1',\n          name: 'Q1',\n\n          subRow: {\n            parentKeyAsDefault: true,\n          },\n        },\n\n        {\n          key: 'q2',\n          name: 'Q2',\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n        {\n          key: 'q3',\n          name: 'Q3',\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n        {\n          key: 'q4',\n          name: 'Q4',\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '85vh' },\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          // Отступ уровня зависит от размера строки: big 16/66/116,\n          // medium 6/42/78, small 4/32/60 px\n          rowSize: { showInControl: true, default: 'big' },\n          fullScreenEnabled: true,\n          resizableColumn: true,\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "SummaryRows",
      "legacy": false,
      "summary": "*tableConfig.summaryRows + пропс bottomSummaryRows**",
      "docs": "# Summary Rows\n\n**tableConfig.summaryRows + пропс bottomSummaryRows**\n\nИтоговые строки в нижней части таблицы.\n\nКонфигурация состоит из двух частей:\n\n- **`tableConfig.summaryRows`** (`SummaryRowsConfig`) — настройка видимости и кнопки в control block\n- **Пропс `bottomSummaryRows`** (`SummaryRowType[]`) — массив данных для итоговых строк\n\n## tableConfig.summaryRows (SummaryRowsConfig)\n\n- **`showDefault`** `boolean` — показывать итоговые строки по умолчанию\n- **`showInControl`** `boolean` — кнопка переключения видимости в control block\n\n## Пропс bottomSummaryRows\n\nМассив объектов `SummaryRowType[]`, передаётся напрямую в компонент `TableCanvas`. Количество элементов массива = количество итоговых строк. Пустой массив — итоговые строки не отображаются.\n\n## Рендер в columnConfig\n\nКастомный рендер через `renderSummaryCell` в конфигурации колонки. Данные итоговой строки доступны через `row`.\n\n## Особенности\n\n- Необходимо соблюдать отступы ячеек через `theme.cellHorizontalPadding`\n\n> Подробнее о типах — [Summary Rows API](?path=/docs/локальные-компоненты-tablecanvas-summaryrows-api--docs)",
      "apiDocs": "# Summary Rows API\n\n## SummaryRowsConfig\n\n```typescript\ntype SummaryRowsConfig = {\n  showDefault: boolean;\n  showInControl: boolean;\n} & {\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n```",
      "api": [
        {
          "typeName": "SummaryRowsConfig",
          "source": "type SummaryRowsConfig = {\n  showDefault: boolean;\n  showInControl: boolean;\n} & {\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "SummaryRows",
          "displayName": "ID",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const bottomSummaryRowsData: TSummaryRowData[] = [\n      {\n        type: 'bottom',\n        values: [\n          { columnId: 'id', value: 'Итого' },\n          { columnId: 'task', value: `Всего тасков ${rows.length}` },\n          {\n            columnId: 'priority',\n            value: `Средних приоритетов ${\n              rows.filter((el) => el.priority === 'Medium').length\n            }`,\n          },\n        ],\n      },\n    ];\n\n    const renderCommonSummaryCell = useCallback(\n      (props: SummaryCellInfoGlideInstance<Row, TSummaryRowData>) =>\n        props.row.values.find((el) => el.columnId === props.column.key)\n          ?.value ?? '',\n      [],\n    );\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row, TSummaryRowData>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          renderSummaryCell: renderCommonSummaryCell,\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          renderSummaryCell: renderCommonSummaryCell,\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          renderSummaryCell: (props) => {\n            const { row, theme } = props;\n\n            return (\n              <Canvas.Container\n                padding={{\n                  left: theme.cellHorizontalPadding,\n                  right: theme.cellHorizontalPadding,\n                }}\n              >\n                <Canvas.Text color={row.type === 'top' ? 'red' : 'orange'}>\n                  {renderCommonSummaryCell(props)}\n                </Canvas.Text>\n              </Canvas.Container>\n            );\n          },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [renderCommonSummaryCell],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          summaryRows: {\n            showDefault: true,\n            showInControl: true,\n          },\n        }}\n        columnConfig={columnConfig}\n        bottomSummaryRows={bottomSummaryRowsData}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "ThemeOverride",
      "legacy": false,
      "summary": "*columnConfig.themeOverride**",
      "docs": "# Theme Override\n\n**columnConfig.themeOverride**\n\nПереопределение визуальных свойств ячейки на уровне колоночного конфига. Колбэк вызывается для каждой ячейки колонки и возвращает частичный override темы (`Partial<Theme>`), либо `undefined`, если для ячейки переопределение не нужно.\n\n## Ключевые особенности\n\n- `bgCell` — цвет фона ячейки (рисуется нативно, закрашивает всю площадь ячейки, включая паддинги)\n- `cellHorizontalPadding` — горизонтальные отступы контента ячейки\n- `cellVerticalPadding` — вертикальные отступы контента ячейки\n- Колбэк получает `cellInfo` (row, column, ctxs, theme) и `lvl` — уровень вложенности subRow (0 для корневых строк, 1+ для дочерних)\n- Условное поведение: можно менять стили в зависимости от данных строки или уровня вложенности\n\n## Сигнатура\n\n```ts\nthemeOverride?: (\n  cellInfo: CellInfo<Row, SummRow, CustomCtxs>,\n  lvl: number\n) => CellThemeOverrideResult | undefined;\n```\n\n## Особенности\n\n### Обычные колонки\n\nДля колонок без `subRow.isColumnWithArrow` `cellHorizontalPadding` через `themeOverride` применяется напрямую и одинаково на всех уровнях вложенности (root и subRows). Левый и правый паддинги получают точное значение из override.\n\n### Tree-колонки (с шевроном раскрытия)\n\nДля колонок с `subRow.isColumnWithArrow: true` левый край ячейки рассчитывается формулой `cellHorizontalPadding + step * lvl`, где шаг зависит от размера строки: `big` — 50 (16 → 66 → 116 → 166 px), `medium` — 36 (6 → 42 → 78 → 114 px), `small` — 28 (4 → 32 → 60 → 88 px). Отступ зависит только от уровня вложенности и не зависит от наличия шеврона, поэтому текст дочерней строки всегда правее текста родителя. Шеврон рисуется иконкой без пустого места слева: раскрытый `∨` начинается ровно на линии уровня (там же, где текст соседнего листа), у свёрнутого `>` небольшой отступ, чтобы при раскрытии не было скачка. Справа от шеврона места столько же, сколько у исходной иконки, поэтому расстояние до текста прежнее. Двойной шеврон в шапке (`раскрыть/скрыть все строки`) построен так же и стоит на линии свёрнутого шеврона строки, а заголовок колонки — над текстом строк верхнего уровня. Override влияет на левый край, но итоговое значение `= override + offsets`, а не ровно значение override. Правый край и `bgCell` для tree-колонок работают как обычно.\n\n### Кастомный renderCell\n\nДля колонок с `renderCell` системная обёртка с паддингом не добавляется. Разработчик сам управляет отступами через `theme.cellHorizontalPadding` внутри своего renderCell.\n\n### bgCell\n\n`bgCell` рисуется нативно на уровне самой таблицы. Фон закрашивает всю ячейку целиком, включая области паддингов и любых обёрток.\n\n## См. также\n\n- `getRowThemeOverride` — нативный API таблицы для переопределения темы **строки целиком** (по индексу строки, без cellInfo). Используется для подсветки summary-строк и selected-строк. Если нужен row-level эффект (например, \"выделенная строка целиком\") — используйте этот механизм, а не `themeOverride` на каждой ячейке.\n\n> Подробнее о типах — [Theme Override API](?path=/docs/локальные-компоненты-tablecanvas-themeoverride-api--docs)",
      "apiDocs": "# Theme Override API\n\nПереопределение темы настраивается через свойство `themeOverride` в `columnConfig`.\n\nЯвляется частью `ColumnConfig`.\n\n## CellThemeOverrideResult\n\n```typescript\ntype CellThemeOverrideResult = Partial<{\n  bgCell: string;\n  cellHorizontalPadding: number;\n  cellVerticalPadding: number;\n}>;\n```\n\n## CellInfo\n\n```typescript\ntype CellInfo<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<\n  CellInfoGlideInstance<R, SR, CustomCtxs>,\n  'column' | 'ctxs' | 'hovered' | 'active'\n> & {\n  column: ColumnConfig<R, SR, CustomCtxs>;\n  ctxs: CtxsType<CustomCtxs>;\n  /**\n   * Состояние наведения для текущей ячейки, которую рендерит renderCell.\n   * `cellHover` равно true только у ячейки под курсором, `rowHover` — у всех ячеек ее строки.\n   */\n  hovered: CellHoverState;\n  /**\n   * Состояние активного выделения для текущей ячейки, которую рендерит renderCell.\n   * `cellActive` равно true у активной ячейки или диапазона, `rowActive` — у строк с активной ячейкой или диапазоном.\n   */\n  active: CellActiveState;\n};\n```",
      "api": [
        {
          "typeName": "CellThemeOverrideResult",
          "source": "type CellThemeOverrideResult = Partial<{\n  bgCell: string;\n  cellHorizontalPadding: number;\n  cellVerticalPadding: number;\n}>;"
        },
        {
          "typeName": "CellInfo",
          "source": "type CellInfo<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<\n  CellInfoGlideInstance<R, SR, CustomCtxs>,\n  'column' | 'ctxs' | 'hovered' | 'active'\n> & {\n  column: ColumnConfig<R, SR, CustomCtxs>;\n  ctxs: CtxsType<CustomCtxs>;\n  /**\n   * Состояние наведения для текущей ячейки, которую рендерит renderCell.\n   * `cellHover` равно true только у ячейки под курсором, `rowHover` — у всех ячеек ее строки.\n   */\n  hovered: CellHoverState;\n  /**\n   * Состояние активного выделения для текущей ячейки, которую рендерит renderCell.\n   * `cellActive` равно true у активной ячейки или диапазона, `rowActive` — у строк с активной ячейкой или диапазоном.\n   */\n  active: CellActiveState;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "ThemeOverrideBgCell",
          "displayName": "Переопределение фона ячейки (bgCell)",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState<Row[]>(createRows(0, 10));\n\n    const columnConfig = useMemo(\n      (): ColumnConfig<Row>[] => [\n        { key: 'id', name: 'ID' },\n        {\n          key: 'task',\n          name: 'Задача',\n          themeOverride: ({ row }) => {\n            const id = Number(row.id);\n            if (id % 2 === 0) {\n              return { bgCell: 'rgba(46, 170, 220, 0.15)' };\n            }\n            return undefined;\n          },\n        },\n        { key: 'priority', name: 'Приоритет' },\n        { key: 'developer', name: 'Разработчик' },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '400px' },\n          rowSize: { default: 'medium', showInControl: false },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ThemeOverridePadding",
          "displayName": "Переопределение паддингов ячейки",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState<Row[]>(createRows(0, 10));\n\n    const columnConfig = useMemo(\n      (): ColumnConfig<Row>[] => [\n        { key: 'id', name: 'ID' },\n        {\n          key: 'task',\n          name: 'Задача (padding 32px)',\n          themeOverride: () => ({ cellHorizontalPadding: 32 }),\n        },\n        {\n          key: 'priority',\n          name: 'Приоритет (стандартный)',\n        },\n        {\n          key: 'developer',\n          name: 'Разработчик (padding 4px)',\n          themeOverride: () => ({ cellHorizontalPadding: 4 }),\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '400px' },\n          rowSize: { default: 'medium', showInControl: false },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ThemeOverrideCustomRenderNoPadding",
          "displayName": "Кастомный renderCell без лишних паддингов",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState<Row[]>(createRows(0, 10));\n\n    const render: ColumnConfig<Row>['renderCell'] = ({\n      column,\n      row,\n      theme,\n    }) => {\n      const value = String(row[column.key as keyof Row] ?? '');\n\n      return (\n        <Canvas.Container\n          padding={{\n            left: theme.cellHorizontalPadding,\n            right: theme.cellHorizontalPadding,\n          }}\n          alignItems=\"center\"\n        >\n          <Canvas.Text>{value}</Canvas.Text>\n        </Canvas.Container>\n      );\n    };\n\n    const columnConfig = useMemo(\n      (): ColumnConfig<Row>[] => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Задача (дефолт)' },\n        {\n          key: 'priority',\n          name: 'Приоритет (renderCell)',\n          renderCell: render,\n        },\n        { key: 'developer', name: 'Разработчик (дефолт)' },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '400px' },\n          rowSize: { default: 'small', showInControl: true },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ThemeOverrideSubRowsLvl",
          "displayName": "Subrows: переопределение по уровню (lvl)",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState(() => createRowsTree());\n\n    const columnConfig = useMemo(\n      (): ColumnConfig<TreeRow>[] => [\n        {\n          key: 'block',\n          name: 'Блок / Трайб / Продукт',\n          subRow: {\n            keyOfColumnInSubRow: (lvl) => {\n              switch (lvl) {\n                case 0:\n                  return 'block';\n                case 1:\n                  return 'tribe';\n                case 2:\n                  return 'product';\n                default:\n                  return 'block';\n              }\n            },\n            isColumnWithArrow: true,\n          },\n          // На tree-колонке левый край считается формулой: padding + offset шеврона + offset по lvl.\n          themeOverride: (_cellInfo, lvl) => {\n            if (lvl === 1) return { bgCell: 'rgba(46, 170, 220, 0.12)' };\n            if (lvl === 2) return { bgCell: 'rgba(255, 170, 60, 0.18)' };\n            return undefined;\n          },\n        },\n        {\n          key: 'q1',\n          name: 'Q1 (padding override 64 — применяется на всех уровнях)',\n          contentFormat: 'number',\n          subRow: { parentKeyAsDefault: true },\n          // На обычной колонке padding применяется ровно на всех уровнях.\n          themeOverride: (_cellInfo, lvl) => ({\n            bgCell:\n              lvl === 0\n                ? 'rgba(120, 200, 120, 0.12)'\n                : lvl === 1\n                ? 'rgba(120, 200, 120, 0.20)'\n                : 'rgba(120, 200, 120, 0.30)',\n            cellHorizontalPadding: 64,\n          }),\n        },\n        {\n          key: 'q2',\n          name: 'Q2',\n          contentFormat: 'number',\n          subRow: { keyOfColumnInSubRow: 'q2' },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '500px' },\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          rowSize: { default: 'medium', showInControl: false },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ThemeOverrideBgAndCustomRender",
          "displayName": "Фон + кастомный renderCell",
          "type": "full-code",
          "code": "() => {\n    const [rows] = useState<Row[]>(createRows(0, 10));\n\n    const columnConfig = useMemo(\n      (): ColumnConfig<Row>[] => [\n        { key: 'id', name: 'ID' },\n        {\n          key: 'task',\n          name: 'Задача',\n          themeOverride: ({ row }) => {\n            const id = Number(row.id);\n            if (id % 3 === 0) {\n              return { bgCell: 'rgba(255, 100, 100, 0.15)' };\n            }\n            if (id % 3 === 1) {\n              return { bgCell: 'rgba(100, 255, 100, 0.15)' };\n            }\n            return undefined;\n          },\n          renderCell: ({ column, row, theme }) => {\n            const value = String(row[column.key as keyof Row] ?? '');\n            return (\n              <Canvas.Container\n                padding={{\n                  left: theme.cellHorizontalPadding,\n                  right: theme.cellHorizontalPadding,\n                }}\n                alignItems=\"center\"\n              >\n                <Canvas.Badge view=\"accent\" text={value} />\n              </Canvas.Container>\n            );\n          },\n        },\n        { key: 'priority', name: 'Приоритет' },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          containerStyle: { height: '400px' },\n          rowSize: { default: 'medium', showInControl: false },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "Tooltip",
      "legacy": false,
      "summary": "*tableConfig.tooltip + columnConfig.cellTooltip / headerCellTooltip**",
      "docs": "# Tooltip на канвасной таблице\n\n**tableConfig.tooltip + columnConfig.cellTooltip / headerCellTooltip**\n\nОдин общий тултип для элементов, отрисованных на канвасе (ячейки, заголовки, кнопки и т.д.). Тултип показывается при наведении на те канвас-элементы, которые явно участвуют в механике тултипа.\n\n## Принцип работы\n\n- На таблице работает **один тултип**: при наведении на разные элементы отображается один и тот же тултип-оверлей с нужным текстом/пропсами для текущего элемента.\n- Участие элемента в показе тултипа задаётся через проп **`portalHoverEnabled`** на Canvas-примитиве — без этого пропса наведение на элемент не будет передаваться в подсистему тултипа.\n\n## Три источника конфига (по приоритету)\n\n1. **Проп `tooltip` на Canvas-элементе** — задаётся прямо на `Canvas.Container`, `Canvas.Button` и т.д. Строка или объект с `text`. Самый высокий приоритет. **Работает всегда.**\n2. **Поле `cellTooltip` / `headerCellTooltip` в `columnConfig`** — конфиг на уровне колонки. Может быть строкой, объектом или функцией `(context) => config | null`. Для ячеек используется `cellTooltip`, для заголовков — `headerCellTooltip`. **Требует `tooltip.enabled: true` в `tableConfig`.**\n3. **Встроенный маппинг по `nodeId`** — внутренний словарь (например, иконка drag в заголовке → «Перетащить колонку»). **Работает всегда.**\n\n## Как включить тултип на элементе\n\n### Через `tooltip` на Canvas-примитиве\n\nВ `renderCell` / `renderHeaderCell` задать `portalHoverEnabled` и `tooltip` на нужном элементе:\n\n```tsx\nrenderCell: () => (\n  <Canvas.Button\n    portalHoverEnabled\n    tooltip=\"Нажмите для перехода\"\n    onClick={() => {}}\n  >\n    Подробнее\n  </Canvas.Button>\n);\n```\n\n### Авто-тултип для обрезанного текста (`autoTooltip` на `Canvas.Text`)\n\nЧастный случай node-тултипа: `Canvas.Text` с пропом `autoTooltip` показывает тултип с полным текстом **только когда текст реально обрезан в многоточие** (однострочный ellipsis или многострочный clamp). `portalHoverEnabled` включается автоматически, `tooltip.enabled: true` в `tableConfig` не требуется — работает всегда, как и остальные node-тултипы.\n\n```tsx\nrenderCell: ({ row }) => (\n  <Canvas.Text\n    overflow=\"hidden\"\n    textOverflow=\"ellipsis\"\n    autoTooltip\n    style={{ flexGrow: 1 }}\n  >\n    {row.longText}\n  </Canvas.Text>\n);\n```\n\nПоведение настраивается объектом: `placement`, `view`, `mouseEnterDelay` / `mouseLeaveDelay`, трансформация текста через `text`, выключение через `enabled: false`. Подробности и правила — в [доке Canvas.Text](?path=/docs/локальные-компоненты-tablecanvas-canvaselements-canvastext--docs), тип — `CanvasTextAutoTooltip`.\n\n> Действует только на `Canvas.Text` в canvas-разметке (`renderCell` / `renderHeaderCell`). Обычные текстовые ячейки (примитивные значения без `renderCell`) рисуются встроенным text-рендерером glide — авто-тултип на них пока не распространяется.\n\n### Через `cellTooltip` / `headerCellTooltip` в `columnConfig`\n\nЗадать на уровне колонки — строкой, объектом или функцией. Не забудьте включить `tooltip.enabled: true`:\n\n```tsx\ntableConfig={{\n  tooltip: { enabled: true },\n}}\ncolumnConfig={[\n  {\n    key: 'task',\n    name: 'Title',\n    headerCellTooltip: 'Название задачи',\n    cellTooltip: ({ row }) => `Задача: ${row.task}`,\n  },\n]}\n```\n\n## Ширина тултипа\n\nШирину тултипа можно задать глобально для всей таблицы через `tableConfig.tooltip`:\n\n```tsx\ntableConfig={{\n  tooltip: { minWidth: 120, maxWidth: 440 },\n}}\n```\n\nЭта ширина применяется ко всем canvas-тултипам, включая авто-тултип `Canvas.Text`.\n\nЧисло трактуется как пиксели. Если нужна другая единица, передайте строку: `maxWidth: '20rem'`, `maxWidth: '50%'`.\n\nПриоритет от высокого к низкому:\n\n- ширина, заданная на самом тултипе (`tooltip` или `autoTooltip` на Canvas-элементе);\n- глобальная `tableConfig.tooltip.minWidth` / `maxWidth`;\n- дефолт компонента `Tooltip`.\n\nТо есть глобальное значение работает как значение по умолчанию, а точечное на элементе его перекрывает:\n\n```tsx\n// у этого тултипа своя ширина, глобальная не применится\n<Canvas.Text\n  overflow=\"hidden\"\n  textOverflow=\"ellipsis\"\n  autoTooltip={{ maxWidth: 300 }}\n>\n  {row.longText}\n</Canvas.Text>\n```\n\n## Формат конфига\n\n- **Строка** — используется как текст тултипа с дефолтными пропсами.\n- **Объект** `{ text: string, placement?, view?, mouseEnterDelay?, ... }` — текст и кастомные пропсы для `Tooltip`.\n- **`null`** — тултип для этого элемента не показывается (переход к следующему приоритету или без тултипа).\n\nПодробное описание типов и контракта — в разделе [API](/docs/локальные-компоненты-tablecanvas-tooltip-api--docs).",
      "apiDocs": "# Tooltip API\n\n## Источники конфига тултипа\n\nТултип может быть задан на **трёх уровнях** (проверяются по приоритету, первый непустой побеждает):\n\n1. **Встроенный маппинг по `nodeId`** — внутренний словарь `TOOLTIP_TEXTS` (например, `HEADER_TOOLTIP_DRAG_ID` → «Перетащить колонку»). **Работает всегда.** Наивысший приоритет — колоночный конфиг не может перебить внутренние тултипы UI таблицы.\n2. **Проп `tooltip` на Canvas-элементе** — задаётся прямо на `Canvas.Container`, `Canvas.Button` и т.д. внутри `renderCell` / `renderHeaderCell`. Тип: `CanvasNodeTooltipConfig`. **Работает всегда.**\n3. **Поле `cellTooltip` / `headerCellTooltip` в `columnConfig`** — на уровне конфигурации колонки. Может быть строкой, объектом или функцией `(context) => config | null`. **Работает только при `tooltip.enabled: true`.**\n\n**Формат конфига:** строка (только текст) или объект с обязательным полем `text` и опциональными пропсами `Tooltip` (`placement`, `view` и т.д.; без `opened`, `target`, `style`), а также `mouseEnterDelay` / `mouseLeaveDelay` для per-node задержек.\n\nПо умолчанию текст рендерится с `white-space: normal` — переносы строк (`\\n`) в `text` схлопываются в пробел. Чтобы сохранить переносы (например, в многострочных подсказках), добавьте в объектную форму конфига `preserveLineBreaks: true` — тогда к тексту тултипа применится `white-space: pre-line`. Флаг выключен по умолчанию и не меняет поведение существующих строковых тултипов.\n\n## Модуль tableConfig.tooltip\n\nГлобальные настройки тултипа вынесены в `tableConfig.tooltip` (тип `TableConfigTooltip`):\n\n- **tooltip.enabled** — включает колоночные/кастомные тултипы (`cellTooltip`, `headerCellTooltip`). По умолчанию `false`. Внутренние тултипы (проп `tooltip` на Canvas-элементе и маппинг по `nodeId`) работают всегда, независимо от `enabled`.\n- **tooltip.mouseEnterDelay** — глобальная задержка перед показом (мс, по умолчанию `500`). Per-node переопределяет.\n- **tooltip.mouseLeaveDelay** — глобальная задержка перед скрытием (мс, по умолчанию `0`). Per-node переопределяет.\n- **tooltip.minWidth** — глобальная минимальная ширина тултипа (число = px, строка с единицей отдаётся как есть). Действует на все canvas-тултипы, включая авто-тултип `Canvas.Text`. Per-node переопределяет.\n- **tooltip.maxWidth** — глобальная максимальная ширина тултипа (число = px, строка с единицей отдаётся как есть). Действует на все canvas-тултипы, включая авто-тултип `Canvas.Text`. Per-node переопределяет.\n\nПример:\n\n```tsx\ntableConfig={{\n  tooltip: {\n    enabled: true,\n    mouseEnterDelay: 300,\n    maxWidth: 440,\n  },\n}}\n```\n\n## Колоночные cellTooltip / headerCellTooltip\n\nЗадаются в `columnConfig` на уровне колонки. Значение — строка, объект или функция. Требуют `tooltip.enabled: true` в `tableConfig`:\n\n```tsx\nconst columnConfig = [\n  {\n    key: 'task',\n    name: 'Title',\n    // Строка — простой текст\n    headerCellTooltip: 'Название задачи',\n    // Функция — динамический конфиг\n    cellTooltip: ({ row, column }) => {\n      return `${column.name}: ${row.task}`;\n    },\n  },\n];\n```\n\nКонтекст функции `cellTooltip` содержит: `row`, `column`, `ctxs`, `refTable`, `colInd`, `rowInd`, `theme`.\nКонтекст функции `headerCellTooltip` содержит: `column`, `ctxs`, `refTable`, `colInd`, `theme`.\n\n---\n\n## Типы\n\n### CanvasNodeTooltipConfig\n\nПроп `tooltip` на Canvas-элементах и базовый формат конфига. Строка (текст) или объект с `text` и опциональными пропсами Tooltip.\n\n```typescript\ntype CanvasNodeTooltipConfig =\n  | string\n  | (CanvasNodeTooltipProps & {\n      /** Текст тултипа (только string, не ReactNode). */\n      text: string;\n      /** Задержка перед показом (мс). По умолчанию 0. */\n      mouseEnterDelay?: number;\n      /** Задержка перед скрытием после ухода мыши (мс). По умолчанию 0. */\n      mouseLeaveDelay?: number;\n    });\n```\n\n### CanvasNodeTooltipProps\n\nПропсы Tooltip, которые можно задать через объектную форму конфига. Управляемые внутренне поля (`opened`, `target`, `style`, `text`, `mouseEnterDelay`, `mouseLeaveDelay`, `hoverTimeout`, `trigger`) исключены.\n\n```typescript\ntype CanvasNodeTooltipProps = Pick<\n  TooltipProps,\n  'placement' | 'view' | 'minWidth' | 'maxWidth'\n> & {\n  /** Сохранять переносы строк (\\n) в тексте тултипа через white-space: pre-line. @default false */\n  preserveLineBreaks?: boolean;\n  /**\n   * Сдвиг тултипа по X (px) относительно центра ноды. Нужен, когда видимая\n   * часть ноды смещена внутри неё (например, иконка прижата к краю кнопки).\n   * @default 0\n   */\n  offsetX?: number;\n};\n```\n\n### TooltipConfigResult\n\nАлиас: `CanvasNodeTooltipConfig | null`. Используется как возвращаемый тип функциональной формы `cellTooltip` / `headerCellTooltip`.\n\n```typescript\ntype TooltipConfigResult = CanvasNodeTooltipConfig | null;\n```\n\n### TooltipData\n\nВнутренний результат резолвинга: текст, пропсы тултипа и per-node задержки. Возвращается из `resolveTooltipData` и передаётся в `usePortalHover`.\n\n```typescript\ninterface TooltipData {\n  tooltipText: string;\n  tooltipProps?: CanvasNodeTooltipProps;\n  mouseEnterDelay?: number;\n  mouseLeaveDelay?: number;\n}\n```\n\n### TableConfigTooltip\n\nГлобальные настройки тултипа в `tableConfig.tooltip`.\n\n```typescript\ntype TableConfigTooltip = {\n  /**\n   * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n   * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n   * @default false\n   */\n  enabled?: boolean;\n  /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n  mouseEnterDelay?: number;\n  /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n  mouseLeaveDelay?: number;\n  /**\n   * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n   * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n   * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n   * (per-node), приоритет у неё.\n   */\n  minWidth?: number | string;\n  /**\n   * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n   * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n   * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n   * (per-node), приоритет у неё.\n   */\n  maxWidth?: number | string;\n};\n```\n\n### CanvasPortalHoverDetail\n\nОбъект события hover по canvas-элементу. Содержит координаты, размеры, `nodeId`, `source` (`'header'` | `'cell'`), `tooltipFromNode` и `tooltipContext` (column, row, ctxs, refTable).\n\n```typescript\ninterface CanvasPortalHoverDetail<\n  TContext extends TooltipContextShape = TooltipContextShape\n> {\n  visible: boolean;\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n  node?: CanvasNode | null;\n  nodeId?: string;\n  source?: CanvasPortalSource;\n  originId?: string;\n  /** column, row, ctxs, refTable — тип задаётся generic TContext */\n  tooltipContext?: TContext;\n  /** Конфиг с ноды (проп tooltip на Canvas-элементе). */\n  tooltipFromNode?: CanvasNodeTooltipConfig;\n  /**\n   * Приоритет события. usePortalHover не заменяет активный тултип с бо́льшим приоритетом.\n   * - 1 — canvas-нода (CanvasHoverController)\n   * - 0 — колоночный тултип (useItemHoveredHandler)\n   * @default 0\n   */\n  priority?: number;\n}\n```",
      "api": [
        {
          "typeName": "CanvasNodeTooltipConfig",
          "source": "type CanvasNodeTooltipConfig =\n  | string\n  | (CanvasNodeTooltipProps & {\n      /** Текст тултипа (только string, не ReactNode). */\n      text: string;\n      /** Задержка перед показом (мс). По умолчанию 0. */\n      mouseEnterDelay?: number;\n      /** Задержка перед скрытием после ухода мыши (мс). По умолчанию 0. */\n      mouseLeaveDelay?: number;\n    });"
        },
        {
          "typeName": "CanvasNodeTooltipProps",
          "source": "type CanvasNodeTooltipProps = Pick<\n  TooltipProps,\n  'placement' | 'view' | 'minWidth' | 'maxWidth'\n> & {\n  /** Сохранять переносы строк (\\n) в тексте тултипа через white-space: pre-line. @default false */\n  preserveLineBreaks?: boolean;\n  /**\n   * Сдвиг тултипа по X (px) относительно центра ноды. Нужен, когда видимая\n   * часть ноды смещена внутри неё (например, иконка прижата к краю кнопки).\n   * @default 0\n   */\n  offsetX?: number;\n};"
        },
        {
          "typeName": "TooltipConfigResult",
          "source": "type TooltipConfigResult = CanvasNodeTooltipConfig | null;"
        },
        {
          "typeName": "TooltipData",
          "source": "interface TooltipData {\n  tooltipText: string;\n  tooltipProps?: CanvasNodeTooltipProps;\n  mouseEnterDelay?: number;\n  mouseLeaveDelay?: number;\n}"
        },
        {
          "typeName": "TableConfigTooltip",
          "source": "type TableConfigTooltip = {\n  /**\n   * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n   * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n   * @default false\n   */\n  enabled?: boolean;\n  /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n  mouseEnterDelay?: number;\n  /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n  mouseLeaveDelay?: number;\n  /**\n   * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n   * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n   * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n   * (per-node), приоритет у неё.\n   */\n  minWidth?: number | string;\n  /**\n   * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n   * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n   * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n   * (per-node), приоритет у неё.\n   */\n  maxWidth?: number | string;\n};"
        },
        {
          "typeName": "CanvasPortalHoverDetail",
          "source": "interface CanvasPortalHoverDetail<\n  TContext extends TooltipContextShape = TooltipContextShape\n> {\n  visible: boolean;\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n  node?: CanvasNode | null;\n  nodeId?: string;\n  source?: CanvasPortalSource;\n  originId?: string;\n  /** column, row, ctxs, refTable — тип задаётся generic TContext */\n  tooltipContext?: TContext;\n  /** Конфиг с ноды (проп tooltip на Canvas-элементе). */\n  tooltipFromNode?: CanvasNodeTooltipConfig;\n  /**\n   * Приоритет события. usePortalHover не заменяет активный тултип с бо́льшим приоритетом.\n   * - 1 — canvas-нода (CanvasHoverController)\n   * - 0 — колоночный тултип (useItemHoveredHandler)\n   * @default 0\n   */\n  priority?: number;\n}"
        }
      ],
      "stories": [
        {
          "exportName": "DefaultTooltipStory",
          "displayName": "Встроенный тултип (drag-иконка в шапке)",
          "type": "full-code",
          "code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport { ColumnConfig, TableCanvas } from '@ui-kit/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx',\n  'ExampleDefaultTooltip',\n)}"
        },
        {
          "exportName": "ColumnTooltipStringStory",
          "displayName": "cellTooltip: строка",
          "type": "full-code",
          "code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport { ColumnConfig, TableCanvas } from '@ui-kit/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx',\n  'ExampleColumnTooltipString',\n)}"
        },
        {
          "exportName": "ColumnTooltipObjectStory",
          "displayName": "cellTooltip: объект",
          "type": "full-code",
          "code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport { ColumnConfig, TableCanvas } from '@ui-kit/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx',\n  'ExampleColumnTooltipObject',\n)}"
        },
        {
          "exportName": "ColumnTooltipMultilineStory",
          "displayName": "cellTooltip: preserveLineBreaks",
          "type": "full-code",
          "code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport { ColumnConfig, TableCanvas } from '@ui-kit/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx',\n  'ExampleColumnTooltipMultiline',\n)}"
        },
        {
          "exportName": "ButtonWithTooltipStory",
          "displayName": "Canvas.Button: tooltip",
          "type": "full-code",
          "code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport { Canvas, ColumnConfig, TableCanvas } from '@ui-kit/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx',\n  'ExampleButtonWithTooltip',\n)}"
        },
        {
          "exportName": "GlobalTooltipWidthStory",
          "displayName": "Ширина тултипа: глобальная и своя",
          "type": "full-code",
          "code": "import { createRows, type Row } from '@df-storybook/data/tableData';\nimport { Canvas, ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\nimport React, { useMemo, useState } from 'react';\n\n${getFuncAsString(\n  'packages/storybook/src/stories/TableCanvas/TableCanvas.Tooltip/TableCanvasTooltip.stories.tsx',\n  'ExampleGlobalTooltipWidth',\n)}"
        }
      ]
    },
    {
      "component": "TableCanvas",
      "feature": "UnstickyHeader",
      "legacy": false,
      "summary": "*tableConfig.unstickyHeader**",
      "docs": "# UnstickyHeader (TableCanvas)\n\n**tableConfig.unstickyHeader**\n\nПри активации `unstickyHeader: true` шапка таблицы перестаёт быть закреплённой и уезжает вверх вместе со скроллом контента.\n\n## Ключевые особенности\n\n- Открепление шапки от верхней границы при скролле\n- Работает с группировкой колонок (все уровни group headers уезжают)\n- Совместимость с многоуровневой вложенностью\n\n> Подробнее о типах — [UnstickyHeader API](?path=/docs/локальные-компоненты-tablecanvas-unstickyheader-api--docs)",
      "apiDocs": "# UnstickyHeader API\n\n## tableConfig.unstickyHeader\n\n```ts\nunstickyHeader?: boolean; // default: false\n```\n\nПри `true` шапка таблицы перестаёт быть закреплённой и уезжает вверх вместе со скроллом контента. Работает со всеми уровнями group headers.",
      "api": [],
      "stories": [
        {
          "exportName": "SimpleUnstickyHeader",
          "displayName": "Simple (без группировки)",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          unstickyHeader: true,\n          containerStyle: { height: '70vh' },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "WithColumnGroups",
          "displayName": "С группировкой колонок",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnOrColumnGroupConfig<Row>[]>(\n      () => [\n        {\n          key: 'group-main',\n          name: 'Основные',\n          children: [\n            {\n              key: 'id',\n              name: 'ID',\n            },\n            {\n              key: 'task',\n              name: 'Title',\n            },\n          ],\n        },\n        {\n          key: 'group-details',\n          name: 'Детали',\n          children: [\n            {\n              key: 'priority',\n              name: 'Priority',\n            },\n            {\n              key: 'issueType',\n              name: 'Issue Type',\n            },\n            {\n              key: 'complete',\n              name: '% Complete',\n            },\n          ],\n        },\n      ],\n      [],\n    );\n\n    return (\n      <TableCanvas\n        tableConfig={{\n          unstickyHeader: true,\n          containerStyle: { height: '70vh' },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "WithMultiLevelGroups",
          "displayName": "Многоуровневая группировка",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n({ headerTreeLvl }) => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnOrColumnGroupConfig<Row>[]>(\n      () => [...(dataObj[headerTreeLvl] ?? [])],\n      [headerTreeLvl],\n    );\n\n    return (\n      <TableCanvas\n        key={headerTreeLvl}\n        tableConfig={{\n          unstickyHeader: true,\n          containerStyle: { height: '70vh' },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "StickyVsUnstickyComparison",
          "displayName": "Сравнение sticky vs unsticky",
          "type": "full-code",
          "code": "import { ColumnConfig, TableCanvas } from '@daisforge/ui/components/TableCanvas';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnOrColumnGroupConfig<Row>[]>(\n      () => [\n        {\n          key: 'group-main',\n          name: 'Основные',\n          children: [\n            {\n              key: 'id',\n              name: 'ID',\n            },\n            {\n              key: 'task',\n              name: 'Title',\n            },\n          ],\n        },\n        {\n          key: 'group-details',\n          name: 'Детали',\n          children: [\n            {\n              key: 'priority',\n              name: 'Priority',\n            },\n            {\n              key: 'complete',\n              name: '% Complete',\n            },\n          ],\n        },\n      ],\n      [],\n    );\n\n    return (\n      <div style={{ display: 'flex', gap: 24 }}>\n        <div style={{ flex: 1 }}>\n          <h3 style={{ marginBottom: 8 }}>Sticky (по умолчанию)</h3>\n          <TableCanvas\n            tableConfig={{\n              containerStyle: { height: '60vh' },\n            }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </div>\n        <div style={{ flex: 1 }}>\n          <h3 style={{ marginBottom: 8 }}>Unsticky</h3>\n          <TableCanvas\n            tableConfig={{\n              unstickyHeader: true,\n              containerStyle: { height: '60vh' },\n            }}\n            columnConfig={columnConfig}\n            rows={rows}\n          />\n        </div>\n      </div>\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "simple",
      "legacy": true,
      "summary": "Базовые примеры legacy `Table`: минимальная HTML-таблица и нагрузочный пример с большим количеством ячеек.",
      "docs": "# SimpleTable\n\nБазовые примеры legacy `Table`: минимальная HTML-таблица и нагрузочный пример с большим количеством ячеек.\n\n## Ключевые особенности\n\n- Минимальная связка `rows`, `columnConfig` и `tableConfig`\n- Кастомный заголовок колонки через React-разметку\n- Пример render-функции ячейки для большого набора строк и колонок\n- Управление размерами таблицы через `tableConfig.containerStyle`\n\n## Особенности\n\n`MillionCells` показывает сценарий проверки виртуализации и производительности. Для новых сценариев больших таблиц предпочтительнее `TableCanvas`.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-simple-api--docs).",
      "apiDocs": "# Simple Table API\n\n## TableProps\n\n```typescript\ntype TableProps<\n  FilterStateType extends ObjectForExtending,\n  RowIdType extends string | number,\n  HeaderContextValueType extends ObjectForExtending,\n  RowContextValueType extends ObjectForExtending,\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n> = {\n  /**\n   * columnConfig - Конфигурация колонок.\n   *\n   * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n   */\n  columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n  /**\n   * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n   */\n  rows: RowType[];\n  /**\n   * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n   */\n  topSummaryRows?: SummaryRowType[];\n  /**\n   * rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n   */\n  bottomSummaryRows?: SummaryRowType[];\n  /**\n   * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n   */\n  tableConfig?: Prettify<\n    TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n  >;\n  /**\n   * headerContextValue:  любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext.\n   */\n  headerContextValue?: HeaderContextValueType;\n  /**\n   * rowContextValue:  любые стейты, которые нужны в cell - кладем в rowContextValue.  И получаем доступ с помощью useRowContext.\n   */\n  rowContextValue?: RowContextValueType;\n  refTable?: Ref<DataGridHandle>;\n  refTableContainer?: React.Ref<HTMLDivElement>;\n};\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *```jsx\n   * import { Table } from '@daisforge/ui';\n   *\n   * <Table\n   * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n   * {...rest}\n   * />\n   * ```\n   */\n  selecting?: {\n    state: [\n      ReadonlySet<RowIdType>,\n      React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n    ];\n  } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n       */\n      controlBlock?: {\n        domMetadata?: DomMetadata;\n      };\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n       */\n      sidebar?: {\n        domMetadata?: DomMetadata;\n      };\n    };\n  /**\n   * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n   *\n   * columnConfig=[{editingCell: {...}}]\n   */\n  editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n  /**\n   * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n   *\n   * columnConfig=[{subRow: {...}}]\n   */\n  subRows?: SubRows<RowType, RowIdType>;\n  rowsGrouping?: RowsGrouping<RowType>;\n\n  /**\n   * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации -  resizableColumn: true. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={resizableColumn: true}\n   *\n   * columnConfig=[{resizable: true}]\n   */\n  resizableColumn?: boolean;\n  /**\n   * style - inline-стили. Для стилей самой таблицы (без вложенности).\n   *\n   * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n   */\n  style?: Omit<\n    CSSProperties,\n    'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n  >;\n  /**\n   * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n   *\n   * Пример:\n   *\n   * ```css\n   * & > .rdg-header-row > .rdgCell {\n   * background-color: red;\n   * }\n   * ```\n   *\n   */\n  css?: string | CSSObject;\n\n  summaryRows?: SummaryRowsConfig;\n  /**\n   * controlBlock - пропс для активации, кастомизации контролблока.\n   */\n  controlBlock?: ControlBlockConfig;\n  /**\n     * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n     * Пример:\n     *\n     * ```tsx\n        tableConfig={{ containerStyle: { height: '70vh' } }}\n     * ```\n     */\n  containerStyle?: CSSProperties | undefined;\n  /**\n   * containerCss - стили для контейнера таблицы и контролблока.\n   * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n   */\n  containerCss?: string | CSSObject | undefined;\n  /**\n   * containerId - html-атрибут id контейнера таблицы.\n   */\n  containerId?: string | undefined;\n\n  /**\n   * infinityScroll - бесконечная подгрузка данных при скролле.\n   *\n   *  Условие активации - наличие самого пропса infinityScroll.\n   *\n   * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n   * (Предполагается, что если есть infinityScroll,\n   * то в таблице представлен не весь объем данных,\n   * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n   *\n   */\n  infinityScroll?: {\n    onTrigger: (rows: RowType[]) => Promise<void> | void;\n    isLoading: boolean;\n    /**\n     * @default true\n     */\n    hasMore?: boolean;\n    /**\n     * @default 100   (px)\n     */\n    scrollThreshold?: number;\n  };\n  /**\n   * @isLoading - состояние загрузки данных для таблицы.\n   */\n  isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n  /**\n   * loadingOverlay - конфигурация для отображения оверлея загрузки.\n   * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n   */\n  loadingOverlay?: {\n    /**\n     * Активен ли оверлей загрузки\n     * @default true\n     */\n    active?: boolean;\n    /**\n     * Кастомный компонент спиннера\n     * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n     */\n    spinner?: ReactNode;\n    /**\n     * Основной заголовок оверлея\n     * @default \"Загрузка таблицы\"\n     */\n    title?: string;\n    /**\n     * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n     * @default \"\"\n     */\n    subtitle?: string;\n    /**\n     * Задержка перед показом подзаголовка (мс)\n     * @default 10000 (10 секунд)\n     */\n    showSubtitleDelay?: number;\n  };\n  noRowsFallback?: boolean | { custom: ReactNode };\n  columnsControl?: ColumnsControlConfig;\n  rowDetailPanel?: RowDetailConfig<RowType>;\n  rowInstruments?: {\n    getRowDropdownConfig: RowInstrumentsType<RowType>;\n    /**\n     * @default false\n     */\n    defaultOpened?: boolean;\n    /**\n     * @default true\n     */\n    showInControl?: boolean;\n    /**\n     * Внешний стейт видимости\n     */\n    openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  };\n  fullScreenEnabled?: FullScreen;\n  keyText?: boolean | KeyTextConfig;\n  /**\n   * pagination - пропс для пагинации.\n   *\n   * Условие активации - наличие самого пропса pagination.\n   *\n   * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n   * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n   *\n   */\n  pagination?: PaginationProps;\n  /**\n   * searching - пропс для поиска по таблицу.\n   *\n   * Условие активации - наличие searching.enabled: true\n   *\n   */\n  /**\n   * Конфигурация табов в сайдбаре\n   */\n  sidebarConfig?: SidebarConfig;\n  searching?: SearchingProps;\n  /**\n   * onHeaderContextMenu - пропс для активации открытия контекстного меню.\n   *\n   */\n  onHeaderContextMenu?: HeaderContextMenuProps;\n  onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n  onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n    RowType,\n    SummaryRowType\n  >;\n} & Pick<\n  DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n  | 'summaryRowHeight'\n  | 'onFill'\n  | 'onCopy'\n  | 'onPaste'\n  | 'onCellClick'\n  | 'onCellDoubleClick'\n  | 'onCellContextMenu'\n  | 'onCellKeyDown'\n  | 'onSelectedCellChange'\n  | 'onScroll'\n  | 'onColumnResize'\n  | 'onColumnsReorder'\n  | 'enableVirtualization'\n  | 'rowClass'\n  | 'data-testid'\n  | 'headerRowHeight'\n>;\n```\n\n## ColumnConfig\n\n```typescript\ntype ColumnConfig<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n  /**\n   * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n   */\n  nameAsString?: string;\n  sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n  searching?: {\n    valueInRow: (row: Row) => string | number;\n  };\n  filtering?: {\n    keyInFilterState: string;\n    /**\n     * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n     */\n    valueInRow?: (row: Row) => string | number;\n    /**\n     * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n     */\n  } & (\n    | {\n        component: 'input';\n        filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n      }\n    | {\n        component: 'select';\n        /**\n         * Произвольное содержимое над списком опций фильтра.\n         *\n         * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n         * фильтров. Рендерится как компонент, поэтому внутри можно\n         * использовать хуки и локальное состояние.\n         *\n         * @example\n         * beforeList: ({ headerContextState }) => (\n         *   <TableFilterSelectListItem $size={headerContextState.rowSize}>\n         *     Подсказка над списком\n         *   </TableFilterSelectListItem>\n         * )\n         */\n        beforeList?: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        /**\n         * Произвольное содержимое под списком опций фильтра.\n         *\n         * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n         * фильтров. Рендерится как компонент, поэтому внутри можно\n         * использовать хуки и локальное состояние — например, чтобы держать\n         * черновик выбора и применять его по кнопке.\n         *\n         * @example\n         * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n         *   <TableFilterSelectListItem $size={headerContextState.rowSize}>\n         *     Подсказка под списком\n         *   </TableFilterSelectListItem>\n         * )\n         */\n        afterList?: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        filter:\n          | {\n              typeOfValue: 'single';\n              /**\n               * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n               */\n              filteringType?: FilterCb<'single'>;\n            }\n          | {\n              typeOfValue: 'multiple';\n              /**\n               * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n               */\n              filteringType?: FilterCb<'multiple'>;\n            };\n        selectOptions:\n          | {\n              type: 'constant';\n              options: SelectOptions[];\n            }\n          | {\n              type: 'stateInHeaderContext';\n              /**\n               * тип optionsState, который будет в HeaderContext:\n               * ```ts\n               * {\n               * value: string | number;\n               * text: string | number;\n               * }[];\n               * ```\n               */\n              optionsKeyInHeaderContext: string;\n            };\n        /**\n         * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n         * @default \"360px\"\n         */\n        listMaxHeight?: string;\n      }\n    | {\n        component: 'custom';\n        customRender: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n        compareWithClearedValue?: (\n          clearedValue: unknown,\n          currV: unknown,\n        ) => boolean;\n      }\n  );\n\n  contentFormat?: ContentFormat;\n\n  editingCell?: Editing<Row>;\n\n  subRow?: {\n    /**\n     * @default false\n     */\n    isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n    /**\n     * @default false\n     */\n    hideHeaderExpandAllArrow?: boolean;\n    /**\n     * @default false\n     */\n    parentKeyAsDefault?: boolean;\n    /**\n     * @default undefined\n     */\n    contentFormat?: ContentFormat;\n\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    renderSubRowCell?: RenderSubRowCell<any>;\n  } & (\n    | {\n        keyOfColumnInSubRow:\n          | string\n          | number\n          | ((lvl: number) => string | number);\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        editingCell: Editing<any>;\n      }\n    | {\n        editingCell?: undefined;\n        keyOfColumnInSubRow?:\n          | string\n          | number\n          | ((lvl: number) => string | number);\n      }\n  );\n  rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n  keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
      "api": [
        {
          "typeName": "TableProps",
          "source": "type TableProps<\n  FilterStateType extends ObjectForExtending,\n  RowIdType extends string | number,\n  HeaderContextValueType extends ObjectForExtending,\n  RowContextValueType extends ObjectForExtending,\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n> = {\n  /**\n   * columnConfig - Конфигурация колонок.\n   *\n   * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n   */\n  columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n  /**\n   * rows - данные для таблицы."
        },
        {
          "typeName": "TableConfig",
          "source": "type TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *"
        },
        {
          "typeName": "ColumnConfig",
          "source": "type ColumnConfig<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n  /**\n   * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n   */\n  nameAsString?: string;\n  sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n  searching?: {\n    valueInRow: (row: Row) => string | number;\n  };\n  filtering?: {\n    keyInFilterState: string;\n    /**\n     * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n     */\n    valueInRow?: (row: Row) => string | number;\n    /**\n     *"
        }
      ],
      "stories": [
        {
          "exportName": "SimpleTable",
          "displayName": "Simple Table",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: (\n            <div\n              style={{\n                display: 'flex',\n                justifyContent: 'space-between',\n              }}\n            >\n              id\n              <IconSber size=\"xs\" color=\"inherit\" />\n            </div>\n          ),\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{ containerStyle: { height: 700 } }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MillionCells",
          "displayName": "MillionCells",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rowsCount, setRowsCount] = useState(5000000);\n    const [columnsCount, setColumnsCount] = useState(30);\n    const rows: any[] = useMemo(\n      () => Array.from({ length: rowsCount }, (_, i) => i),\n      [rowsCount],\n    );\n\n    const columns = useMemo(() => {\n      const columns: ColumnConfig<any>[] = [];\n\n      for (let i = 0; i < columnsCount; i += 1) {\n        const key = String(i);\n        columns.push({\n          key,\n          name: key,\n\n          width: 150,\n          resizable: true,\n          renderCell: renderCoordinates,\n        });\n      }\n      return columns;\n    }, [columnsCount]);\n\n    return (\n      <>\n        <div style={{ display: 'flex', gap: 8 }}>\n          columnsCount\n          <TextField\n            value={columnsCount}\n            min={1}\n            width={300}\n            type=\"number\"\n            onChange={(e) => setColumnsCount(+e.target.value)}\n          />\n          rowsCount\n          <TextField\n            value={rowsCount}\n            min={1}\n            width={300}\n            type=\"number\"\n            onChange={(e) => setRowsCount(+e.target.value)}\n          />\n        </div>\n\n        <Table\n          tableConfig={{\n            containerStyle: { height: '80dvh' },\n            fullScreenEnabled: true,\n          }}\n          columnConfig={columns}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "columnResizing",
      "legacy": true,
      "summary": "Изменение ширины колонок в legacy `Table`.",
      "docs": "# ColumnResizing\n\nИзменение ширины колонок в legacy `Table`.\n\n## Ключевые особенности\n\n- Включается через `tableConfig.resizableColumn: true`\n- Для колонки можно задать `resizable`, `width`, `minWidth` и `maxWidth`\n- Совместимо с закреплением колонок через `columnsControl`\n- События изменения ширины доступны через `onColumnResize`\n\n## Особенности\n\nВ старом API флаг `resizable` задается на колонках явно. Если используется `columnsControl`, учитывайте закрепленные колонки и дефолтные состояния.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-columnresizing-api--docs).",
      "apiDocs": "# Column Resizing API\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *```jsx\n   * import { Table } from '@daisforge/ui';\n   *\n   * <Table\n   * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n   * {...rest}\n   * />\n   * ```\n   */\n  selecting?: {\n    state: [\n      ReadonlySet<RowIdType>,\n      React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n    ];\n  } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n       */\n      controlBlock?: {\n        domMetadata?: DomMetadata;\n      };\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n       */\n      sidebar?: {\n        domMetadata?: DomMetadata;\n      };\n    };\n  /**\n   * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n   *\n   * columnConfig=[{editingCell: {...}}]\n   */\n  editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n  /**\n   * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n   *\n   * columnConfig=[{subRow: {...}}]\n   */\n  subRows?: SubRows<RowType, RowIdType>;\n  rowsGrouping?: RowsGrouping<RowType>;\n\n  /**\n   * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации -  resizableColumn: true. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={resizableColumn: true}\n   *\n   * columnConfig=[{resizable: true}]\n   */\n  resizableColumn?: boolean;\n  /**\n   * style - inline-стили. Для стилей самой таблицы (без вложенности).\n   *\n   * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n   */\n  style?: Omit<\n    CSSProperties,\n    'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n  >;\n  /**\n   * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n   *\n   * Пример:\n   *\n   * ```css\n   * & > .rdg-header-row > .rdgCell {\n   * background-color: red;\n   * }\n   * ```\n   *\n   */\n  css?: string | CSSObject;\n\n  summaryRows?: SummaryRowsConfig;\n  /**\n   * controlBlock - пропс для активации, кастомизации контролблока.\n   */\n  controlBlock?: ControlBlockConfig;\n  /**\n     * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n     * Пример:\n     *\n     * ```tsx\n        tableConfig={{ containerStyle: { height: '70vh' } }}\n     * ```\n     */\n  containerStyle?: CSSProperties | undefined;\n  /**\n   * containerCss - стили для контейнера таблицы и контролблока.\n   * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n   */\n  containerCss?: string | CSSObject | undefined;\n  /**\n   * containerId - html-атрибут id контейнера таблицы.\n   */\n  containerId?: string | undefined;\n\n  /**\n   * infinityScroll - бесконечная подгрузка данных при скролле.\n   *\n   *  Условие активации - наличие самого пропса infinityScroll.\n   *\n   * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n   * (Предполагается, что если есть infinityScroll,\n   * то в таблице представлен не весь объем данных,\n   * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n   *\n   */\n  infinityScroll?: {\n    onTrigger: (rows: RowType[]) => Promise<void> | void;\n    isLoading: boolean;\n    /**\n     * @default true\n     */\n    hasMore?: boolean;\n    /**\n     * @default 100   (px)\n     */\n    scrollThreshold?: number;\n  };\n  /**\n   * @isLoading - состояние загрузки данных для таблицы.\n   */\n  isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n  /**\n   * loadingOverlay - конфигурация для отображения оверлея загрузки.\n   * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n   */\n  loadingOverlay?: {\n    /**\n     * Активен ли оверлей загрузки\n     * @default true\n     */\n    active?: boolean;\n    /**\n     * Кастомный компонент спиннера\n     * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n     */\n    spinner?: ReactNode;\n    /**\n     * Основной заголовок оверлея\n     * @default \"Загрузка таблицы\"\n     */\n    title?: string;\n    /**\n     * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n     * @default \"\"\n     */\n    subtitle?: string;\n    /**\n     * Задержка перед показом подзаголовка (мс)\n     * @default 10000 (10 секунд)\n     */\n    showSubtitleDelay?: number;\n  };\n  noRowsFallback?: boolean | { custom: ReactNode };\n  columnsControl?: ColumnsControlConfig;\n  rowDetailPanel?: RowDetailConfig<RowType>;\n  rowInstruments?: {\n    getRowDropdownConfig: RowInstrumentsType<RowType>;\n    /**\n     * @default false\n     */\n    defaultOpened?: boolean;\n    /**\n     * @default true\n     */\n    showInControl?: boolean;\n    /**\n     * Внешний стейт видимости\n     */\n    openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  };\n  fullScreenEnabled?: FullScreen;\n  keyText?: boolean | KeyTextConfig;\n  /**\n   * pagination - пропс для пагинации.\n   *\n   * Условие активации - наличие самого пропса pagination.\n   *\n   * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n   * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n   *\n   */\n  pagination?: PaginationProps;\n  /**\n   * searching - пропс для поиска по таблицу.\n   *\n   * Условие активации - наличие searching.enabled: true\n   *\n   */\n  /**\n   * Конфигурация табов в сайдбаре\n   */\n  sidebarConfig?: SidebarConfig;\n  searching?: SearchingProps;\n  /**\n   * onHeaderContextMenu - пропс для активации открытия контекстного меню.\n   *\n   */\n  onHeaderContextMenu?: HeaderContextMenuProps;\n  onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n  onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n    RowType,\n    SummaryRowType\n  >;\n} & Pick<\n  DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n  | 'summaryRowHeight'\n  | 'onFill'\n  | 'onCopy'\n  | 'onPaste'\n  | 'onCellClick'\n  | 'onCellDoubleClick'\n  | 'onCellContextMenu'\n  | 'onCellKeyDown'\n  | 'onSelectedCellChange'\n  | 'onScroll'\n  | 'onColumnResize'\n  | 'onColumnsReorder'\n  | 'enableVirtualization'\n  | 'rowClass'\n  | 'data-testid'\n  | 'headerRowHeight'\n>;\n```\n\n## ColumnDefault\n\n```typescript\ntype ColumnDefault<TRow, TSummaryRow = unknown> = {\n  /** The name of the column. By default it will be displayed in the header cell */\n  readonly name: string | ReactElement;\n  /** A unique key to distinguish each column */\n  readonly key: string;\n  /** Column width. If not specified, it will be determined automatically based on grid width and specified widths of other columns */\n  readonly width?: Maybe<number | string>;\n  /** Minimum column width in px. */\n  readonly minWidth?: Maybe<number>;\n  /** Maximum column width in px. */\n  readonly maxWidth?: Maybe<number>;\n  readonly cellClass?: Maybe<string | ((row: TRow) => Maybe<string>)>;\n  readonly headerCellClass?: Maybe<string>;\n  readonly summaryCellClass?: Maybe<\n    string | ((row: TSummaryRow) => Maybe<string>)\n  >;\n  /** Render function used to render the content of the column's header cell */\n  readonly renderHeaderCell?: Maybe<\n    (props: RenderHeaderCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of cells */\n  readonly renderCell?: Maybe<\n    (props: RenderCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of summary cells */\n  readonly renderSummaryCell?: Maybe<\n    (props: RenderSummaryCellProps<TSummaryRow, TRow>) => ReactNode\n  >;\n  /** Render function used to render the content of group cells */\n  readonly renderGroupCell?: Maybe<\n    (props: RenderGroupCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of edit cells. When set, the column is automatically set to be editable */\n  readonly renderEditCell?: Maybe<\n    (props: RenderEditCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Enables cell editing. If set and no editor property specified, then a textInput will be used as the cell editor */\n  readonly editable?: Maybe<boolean | ((row: TRow) => boolean)>;\n  readonly colSpan?: Maybe<\n    (args: ColSpanArgs<TRow, TSummaryRow>) => Maybe<number>\n  >;\n  /** Determines whether column is frozen or not */\n  readonly frozen?: Maybe<boolean>;\n  /** Enable resizing of a column */\n  readonly resizable?: Maybe<boolean>;\n  /** Enable sorting of a column */\n  readonly sortable?: Maybe<boolean>;\n  /** Enable dragging of a column */\n  readonly draggable?: Maybe<boolean>;\n  /** Sets the column sort order to be descending instead of ascending the first time the column is sorted */\n  readonly sortDescendingFirst?: Maybe<boolean>;\n  readonly editorOptions?: Maybe<{\n    /**\n     * Render the cell content in addition to the edit cell.\n     * Enable this option when the editor is rendered outside the grid, like a modal for example.\n     * By default, the cell content is not rendered when the edit cell is open.\n     * @default false\n     */\n    readonly displayCellContent?: Maybe<boolean>;\n    /** @default true */\n    readonly commitOnOutsideClick?: Maybe<boolean>;\n  }>;\n};\n\ndeclare type SharedDivProps = Pick<\n  React.HTMLAttributes<HTMLDivElement>,\n  | 'role'\n  | 'aria-label'\n  | 'aria-labelledby'\n  | 'aria-describedby'\n  | 'aria-rowcount'\n  | 'className'\n  | 'style'\n>;\ndeclare type DefaultColumnOptions<R, SR> = Pick<\n  Column<R, SR>,\n  | 'renderCell'\n  | 'width'\n  | 'minWidth'\n  | 'maxWidth'\n  | 'resizable'\n  | 'sortable'\n  | 'draggable'\n>;\n\ntype Direction = 'ltr' | 'rtl';\n\n/**\n * Полная копия типа \"DataGridProps\" из react-data-grid. Скопирован для того, чтобы API в Story проинициализировался\n */\nexport interface DataGridPropsDefault<R, SR = unknown, K extends Key = Key>\n  extends SharedDivProps {\n  /**\n   * Grid and data Props\n   */\n  /** An array of objects representing each column on the grid */\n  columns: readonly ColumnOrColumnGroup<R, SR>[];\n  /** A function called for each rendered row that should return a plain key/value pair object */\n  rows: readonly R[];\n  /**\n   * Rows to be pinned at the top of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  topSummaryRows?: Maybe<readonly SR[]>;\n  /**\n   * Rows to be pinned at the bottom of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  bottomSummaryRows?: Maybe<readonly SR[]>;\n  /** The getter should return a unique key for each row */\n  rowKeyGetter?: Maybe<(row: R) => K>;\n  onRowsChange?: Maybe<(rows: R[], data: RowsChangeData<R, SR>) => void>;\n  /**\n   * Dimensions props\n   */\n  /**\n   * The height of each row in pixels\n   * @default 35\n   */\n  rowHeight?: Maybe<number | ((row: R) => number)>;\n  /**\n   * The height of the header row in pixels\n   * @default 35\n   */\n  headerRowHeight?: Maybe<number>;\n  /**\n   * The height of each summary row in pixels\n   * @default 35\n   */\n  summaryRowHeight?: Maybe<number>;\n  /**\n   * Feature props\n   */\n  /** Set of selected row keys */\n  selectedRows?: Maybe<ReadonlySet<K>>;\n  /** Function called whenever row selection is changed */\n  onSelectedRowsChange?: Maybe<(selectedRows: Set<K>) => void>;\n  /** Used for multi column sorting */\n  sortColumns?: Maybe<readonly SortColumn[]>;\n  onSortColumnsChange?: Maybe<(sortColumns: SortColumn[]) => void>;\n  defaultColumnOptions?: Maybe<DefaultColumnOptions<R, SR>>;\n  onFill?: Maybe<(event: FillEvent<R>) => R>;\n  onCopy?: Maybe<(event: CopyEvent<R>) => void>;\n  onPaste?: Maybe<(event: PasteEvent<R>) => R>;\n  /**\n   * Event props\n   */\n  /** Function called whenever a cell is clicked */\n  onCellClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is double clicked */\n  onCellDoubleClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is right clicked */\n  onCellContextMenu?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  onCellKeyDown?: Maybe<\n    (args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) => void\n  >;\n  /** Function called whenever cell selection is changed */\n  onSelectedCellChange?: Maybe<(args: CellSelectArgs<R, SR>) => void>;\n  /** Called when the grid is scrolled */\n  onScroll?: Maybe<(event: React.UIEvent<HTMLDivElement>) => void>;\n  /** Called when a column is resized */\n  onColumnResize?: Maybe<(idx: number, width: number) => void>;\n  /** Called when a column is reordered */\n  onColumnsReorder?: Maybe<\n    (sourceColumnKey: string, targetColumnKey: string) => void\n  >;\n  /**\n   * Toggles and modes\n   */\n  /** @default true */\n  enableVirtualization?: Maybe<boolean>;\n  /**\n   * Miscellaneous\n   */\n  renderers?: Maybe<Renderers<R, SR>>;\n  rowClass?: Maybe<(row: R, rowIdx: number) => Maybe<string>>;\n  /** @default 'ltr' */\n  direction?: Maybe<Direction>;\n  'data-testid'?: Maybe<string>;\n}\n\nexport type DefaultOmittedKeys =\n  | 'editable'\n  | 'sortable'\n  | 'sortDescendingFirst'\n  | 'renderGroupCell'\n  | 'renderEditCell'\n  | 'frozen'\n  | 'draggable';\n\nexport type ColumnDefaultOmitted<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> = Omit<ColumnDefault<Row, SummRow>, DefaultOmittedKeys>;\n\nexport type { CellClickArgs };\n```",
      "api": [
        {
          "typeName": "TableConfig",
          "source": "type TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *"
        },
        {
          "typeName": "ColumnDefault",
          "source": "type ColumnDefault<TRow, TSummaryRow = unknown> = {\n  /** The name of the column. By default it will be displayed in the header cell */\n  readonly name: string | ReactElement;\n  /** A unique key to distinguish each column */\n  readonly key: string;\n  /** Column width. If not specified, it will be determined automatically based on grid width and specified widths of other columns */\n  readonly width?: Maybe<number | string>;\n  /** Minimum column width in px. */\n  readonly minWidth?: Maybe<number>;\n  /** Maximum column width in px. */\n  readonly maxWidth?: Maybe<number>;\n  readonly cellClass?: Maybe<string | ((row: TRow) => Maybe<string>)>;\n  readonly headerCellClass?: Maybe<string>;\n  readonly summaryCellClass?: Maybe<\n    string | ((row: TSummaryRow) => Maybe<string>)\n  >;\n  /** Render function used to render the content of the column's header cell */\n  readonly renderHeaderCell?: Maybe<\n    (props: RenderHeaderCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of cells */\n  readonly renderCell?: Maybe<\n    (props: RenderCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of summary cells */\n  readonly renderSummaryCell?: Maybe<\n    (props: RenderSummaryCellProps<TSummaryRow, TRow>) => ReactNode\n  >;\n  /** Render function used to render the content of group cells */\n  readonly renderGroupCell?: Maybe<\n    (props: RenderGroupCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of edit cells. When set, the column is automatically set to be editable */\n  readonly renderEditCell?: Maybe<\n    (props: RenderEditCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Enables cell editing. If set and no editor property specified, then a textInput will be used as the cell editor */\n  readonly editable?: Maybe<boolean | ((row: TRow) => boolean)>;\n  readonly colSpan?: Maybe<\n    (args: ColSpanArgs<TRow, TSummaryRow>) => Maybe<number>\n  >;\n  /** Determines whether column is frozen or not */\n  readonly frozen?: Maybe<boolean>;\n  /** Enable resizing of a column */\n  readonly resizable?: Maybe<boolean>;\n  /** Enable sorting of a column */\n  readonly sortable?: Maybe<boolean>;\n  /** Enable dragging of a column */\n  readonly draggable?: Maybe<boolean>;\n  /** Sets the column sort order to be descending instead of ascending the first time the column is sorted */\n  readonly sortDescendingFirst?: Maybe<boolean>;\n  readonly editorOptions?: Maybe<{\n    /**\n     * Render the cell content in addition to the edit cell.\n     * Enable this option when the editor is rendered outside the grid, like a modal for example.\n     * By default, the cell content is not rendered when the edit cell is open.\n     * @default false\n     */\n    readonly displayCellContent?: Maybe<boolean>;\n    /** @default true */\n    readonly commitOnOutsideClick?: Maybe<boolean>;\n  }>;\n};\n\ndeclare type SharedDivProps = Pick<\n  React.HTMLAttributes<HTMLDivElement>,\n  | 'role'\n  | 'aria-label'\n  | 'aria-labelledby'\n  | 'aria-describedby'\n  | 'aria-rowcount'\n  | 'className'\n  | 'style'\n>;\ndeclare type DefaultColumnOptions<R, SR> = Pick<\n  Column<R, SR>,\n  | 'renderCell'\n  | 'width'\n  | 'minWidth'\n  | 'maxWidth'\n  | 'resizable'\n  | 'sortable'\n  | 'draggable'\n>;\n\ntype Direction = 'ltr' | 'rtl';\n\n/**\n * Полная копия типа \"DataGridProps\" из react-data-grid. Скопирован для того, чтобы API в Story проинициализировался\n */\nexport interface DataGridPropsDefault<R, SR = unknown, K extends Key = Key>\n  extends SharedDivProps {\n  /**\n   * Grid and data Props\n   */\n  /** An array of objects representing each column on the grid */\n  columns: readonly ColumnOrColumnGroup<R, SR>[];\n  /** A function called for each rendered row that should return a plain key/value pair object */\n  rows: readonly R[];\n  /**\n   * Rows to be pinned at the top of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  topSummaryRows?: Maybe<readonly SR[]>;\n  /**\n   * Rows to be pinned at the bottom of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  bottomSummaryRows?: Maybe<readonly SR[]>;\n  /** The getter should return a unique key for each row */\n  rowKeyGetter?: Maybe<(row: R) => K>;\n  onRowsChange?: Maybe<(rows: R[], data: RowsChangeData<R, SR>) => void>;\n  /**\n   * Dimensions props\n   */\n  /**\n   * The height of each row in pixels\n   * @default 35\n   */\n  rowHeight?: Maybe<number | ((row: R) => number)>;\n  /**\n   * The height of the header row in pixels\n   * @default 35\n   */\n  headerRowHeight?: Maybe<number>;\n  /**\n   * The height of each summary row in pixels\n   * @default 35\n   */\n  summaryRowHeight?: Maybe<number>;\n  /**\n   * Feature props\n   */\n  /** Set of selected row keys */\n  selectedRows?: Maybe<ReadonlySet<K>>;\n  /** Function called whenever row selection is changed */\n  onSelectedRowsChange?: Maybe<(selectedRows: Set<K>) => void>;\n  /** Used for multi column sorting */\n  sortColumns?: Maybe<readonly SortColumn[]>;\n  onSortColumnsChange?: Maybe<(sortColumns: SortColumn[]) => void>;\n  defaultColumnOptions?: Maybe<DefaultColumnOptions<R, SR>>;\n  onFill?: Maybe<(event: FillEvent<R>) => R>;\n  onCopy?: Maybe<(event: CopyEvent<R>) => void>;\n  onPaste?: Maybe<(event: PasteEvent<R>) => R>;\n  /**\n   * Event props\n   */\n  /** Function called whenever a cell is clicked */\n  onCellClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is double clicked */\n  onCellDoubleClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is right clicked */\n  onCellContextMenu?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  onCellKeyDown?: Maybe<\n    (args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) => void\n  >;\n  /** Function called whenever cell selection is changed */\n  onSelectedCellChange?: Maybe<(args: CellSelectArgs<R, SR>) => void>;\n  /** Called when the grid is scrolled */\n  onScroll?: Maybe<(event: React.UIEvent<HTMLDivElement>) => void>;\n  /** Called when a column is resized */\n  onColumnResize?: Maybe<(idx: number, width: number) => void>;\n  /** Called when a column is reordered */\n  onColumnsReorder?: Maybe<\n    (sourceColumnKey: string, targetColumnKey: string) => void\n  >;\n  /**\n   * Toggles and modes\n   */\n  /** @default true */\n  enableVirtualization?: Maybe<boolean>;\n  /**\n   * Miscellaneous\n   */\n  renderers?: Maybe<Renderers<R, SR>>;\n  rowClass?: Maybe<(row: R, rowIdx: number) => Maybe<string>>;\n  /** @default 'ltr' */\n  direction?: Maybe<Direction>;\n  'data-testid'?: Maybe<string>;\n}\n\nexport type DefaultOmittedKeys =\n  | 'editable'\n  | 'sortable'\n  | 'sortDescendingFirst'\n  | 'renderGroupCell'\n  | 'renderEditCell'\n  | 'frozen'\n  | 'draggable';\n\nexport type ColumnDefaultOmitted<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> = Omit<ColumnDefault<Row, SummRow>, DefaultOmittedKeys>;\n\nexport type { CellClickArgs };"
        }
      ],
      "stories": [
        {
          "exportName": "ColumnResizing",
          "displayName": "Изменение ширины колонки",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const sortingStateAndSetter = useState<readonly SortColumn[]>([]);\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          resizable: true,\n          minWidth: 200,\n          width: 300,\n          maxWidth: 500,\n          sortingType: 'stringSort',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          resizable: true,\n          minWidth: 200,\n          sortingType: 'stringSort',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          sortingType: 'stringSort',\n          resizable: true,\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          sortingType: 'stringSort',\n          resizable: false,\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          columnsControl: {\n            enable: true,\n            pinnedDefault: ['task'],\n          },\n          resizableColumn: true,\n          sorting: {\n            state: sortingStateAndSetter,\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "columnsControl",
      "legacy": true,
      "summary": "Пользовательская настройка колонок legacy `Table`.",
      "docs": "# ColumnsControl\n\nПользовательская настройка колонок legacy `Table`.\n\n## Ключевые особенности\n\n- Включение через `tableConfig.columnsControl.enable`\n- Скрытие, закрепление и переупорядочивание колонок\n- Запрет скрытия или закрепления отдельных колонок\n- Дефолтные состояния `orderDefault`, `hiddenDefault`, `pinnedDefault`\n- Колбэк `onConfirm` для сохранения настроек вне таблицы\n\n## Особенности\n\n`columnsControl` может работать вместе с изменением ширины колонок и с `keyText`. Для группированных колонок проверяйте итоговый порядок leaf-колонок.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-columnscontrol-api--docs).",
      "apiDocs": "# Columns Control API\n\n## ColumnsControlConfig\n\n```typescript\ntype ColumnsControlConfig = {\n  enable: boolean;\n  /**\n   * @default enable\n   */\n  hiding?: boolean;\n  /**\n   * @default enable\n   */\n  pinning?: boolean;\n  /**\n   * @default enable\n   */\n  reorderingAside?: boolean;\n  /**\n   * reorderingHeader  - активация изменения порядка колонок  посредством перемещения шапок колонок таблицы\n   */\n  /**\n   * @default enable\n   */\n  reorderingHeader?: boolean;\n  onReorderingHeader?: (params: {\n    newOrder: string[];\n    sourceKey: string;\n    targetKey: string;\n  }) => void;\n\n  columnsLabel?: Record<\n    string,\n    ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n  >;\n\n  orderDefault?: string[];\n\n  pinnedDefault?: string[];\n  disablePinning?: string[];\n\n  hiddenDefault?: string[];\n  disableHiding?: string[];\n\n  onConfirm?: (\n    params: {\n      pinned: string[];\n      order: string[];\n      hidden: string[];\n      changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n    },\n    setters: {\n      setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n      setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n      setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n    },\n  ) => void;\n  /**\n   * DomMetadata для кнопок закрепления столбцов\n   */\n  pinDomMetadata?: DomMetadata;\n  /**\n   * DomMetadata для свитчеров скрытия/показа столбцов\n   */\n  switchDomMetadata?: DomMetadata;\n};\n```",
      "api": [
        {
          "typeName": "ColumnsControlConfig",
          "source": "type ColumnsControlConfig = {\n  enable: boolean;\n  /**\n   * @default enable\n   */\n  hiding?: boolean;\n  /**\n   * @default enable\n   */\n  pinning?: boolean;\n  /**\n   * @default enable\n   */\n  reorderingAside?: boolean;\n  /**\n   * reorderingHeader  - активация изменения порядка колонок  посредством перемещения шапок колонок таблицы\n   */\n  /**\n   * @default enable\n   */\n  reorderingHeader?: boolean;\n  onReorderingHeader?: (params: {\n    newOrder: string[];\n    sourceKey: string;\n    targetKey: string;\n  }) => void;\n\n  columnsLabel?: Record<\n    string,\n    ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n  >;\n\n  orderDefault?: string[];\n\n  pinnedDefault?: string[];\n  disablePinning?: string[];\n\n  hiddenDefault?: string[];\n  disableHiding?: string[];\n\n  onConfirm?: (\n    params: {\n      pinned: string[];\n      order: string[];\n      hidden: string[];\n      changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n    },\n    setters: {\n      setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n      setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n      setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n    },\n  ) => void;\n  /**\n   * DomMetadata для кнопок закрепления столбцов\n   */\n  pinDomMetadata?: DomMetadata;\n  /**\n   * DomMetadata для свитчеров скрытия/показа столбцов\n   */\n  switchDomMetadata?: DomMetadata;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "ColumnsControl",
          "displayName": "ID",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          columnsControl: {\n            enable: true,\n            hiding: true,\n            disableHiding: ['id'],\n            pinning: true,\n            disablePinning: ['developer'],\n            reorderingAside: true,\n            reorderingHeader: true,\n            columnsLabel: {\n              task: 'Задачи',\n            },\n            orderDefault: ['id', 'issueType', 'task'],\n            hiddenDefault: ['tr1'],\n            pinnedDefault: ['complete'],\n            onConfirm: ({ order, hidden, pinned }, _setters) => {\n              // eslint-disable-next-line no-alert\n              alert(`\n                                    order: ${order.join(', ')}\n                                    pinned: ${pinned.join(', ')}\n                                    hidden: ${hidden.join(', ')}\n                                `);\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ColumnsControlDynamicColumn",
          "displayName": "ColumnsControl: динамическое добавление колонки",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n    const [developerIsShown, setDeveloperIsShown] = useState(false);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        ...(developerIsShown\n          ? [\n              {\n                key: 'developer',\n                name: 'Developer',\n              } satisfies ColumnConfig<Row>,\n            ]\n          : []),\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [developerIsShown],\n    );\n\n    return (\n      <Box $css={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n        <Box>\n          <Button\n            size=\"s\"\n            view=\"secondary\"\n            onClick={() => setDeveloperIsShown((prev) => !prev)}\n          >\n            {developerIsShown\n              ? 'Удалить колонку Developer'\n              : 'Добавить колонку Developer'}\n          </Button>\n        </Box>\n        <Table\n          tableConfig={{\n            containerStyle: { height: 700 },\n            columnsControl: {\n              enable: true,\n              hiding: true,\n              pinning: true,\n              reorderingAside: true,\n              reorderingHeader: true,\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </Box>\n    );\n  }"
        },
        {
          "exportName": "SimpleTableDynamicColumn",
          "displayName": "SimpleTable: динамическое добавление колонки",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n    const [developerIsShown, setDeveloperIsShown] = useState(false);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: (\n            <div\n              style={{\n                display: 'flex',\n                justifyContent: 'space-between',\n              }}\n            >\n              id\n              <IconSber size=\"xs\" color=\"inherit\" />\n            </div>\n          ),\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        ...(developerIsShown\n          ? [\n              {\n                key: 'developer',\n                name: 'Developer',\n              } satisfies ColumnConfig<Row>,\n            ]\n          : []),\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [developerIsShown],\n    );\n\n    return (\n      <Box $css={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n        <Box>\n          <Button\n            size=\"s\"\n            view=\"secondary\"\n            onClick={() => setDeveloperIsShown((prev) => !prev)}\n          >\n            {developerIsShown\n              ? 'Удалить колонку Developer'\n              : 'Добавить колонку Developer'}\n          </Button>\n        </Box>\n        <Table\n          tableConfig={{ containerStyle: { height: 700 } }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </Box>\n    );\n  }"
        },
        {
          "exportName": "ColumnsControlWithServiceColumnsForTest",
          "displayName": "ID",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows, setRows] = useState(createRows);\n    const [groupByArr, setGroupByArr] = useState<string[]>([]);\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          keyText: {\n            key: 'kek',\n            name: 'Ключ - Title',\n            renderCell: ({ row }) => row.id,\n          },\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          rowsGrouping: {\n            groupByColumn: true,\n          },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n    const [value, setValue] = useState(1);\n\n    const getRowDropdownConfig = useCallback<RowInstrumentsType<Row>>(\n      ({ row, rowIdx }) => ({\n        items: [\n          ...(rowIdx === 0\n            ? [\n                {\n                  label: 'Увеличить счетчик',\n                  value: 'counter',\n                  onItemSelect: (_, e) => {\n                    e.preventDefault();\n                    setValue((prev) => prev + (rowIdx || 1));\n                  },\n                  dividerAfter: true,\n                } as RowInstrumentsDropdownItemOption,\n              ]\n            : []),\n          {\n            label: 'Удалить строку',\n            value: 'delete row',\n            onItemSelect: () => {\n              const index = rows.findIndex((r) => r.id === row.id);\n              if (index !== -1) {\n                setRows((prev) => {\n                  const newV = [...prev];\n\n                  newV.splice(index, 1);\n                  return newV;\n                });\n              }\n            },\n            contentLeft: <IconBoxOutline color=\"inherit\" />,\n          },\n          {\n            label: 'Добавить строку вниз',\n            value: 'add row',\n            onItemSelect: () => {\n              const index = rows.findIndex((r) => r.id === row.id);\n              if (index !== -1) {\n                setRows((prev) => {\n                  const newV = [...prev];\n                  const newRow: Row = {\n                    id: createSeededRandom(rows.length)() * 1000 + rows.length,\n                    task: '',\n                    priority: '',\n                    issueType: '',\n                    developer: '',\n                    complete: 0,\n                    tr: '',\n                    loremIpsum: '',\n                  } as Row;\n                  newV.splice(index + 1, 0, newRow);\n\n                  return newV;\n                });\n              }\n            },\n            contentLeft: <IconAddOutline color=\"inherit\" />,\n          },\n        ],\n      }),\n      [rows],\n    );\n\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n    return (\n      <>\n        <div>{value}</div>\n        <Table\n          tableConfig={{\n            keyText: true,\n            selecting: {\n              rowCheckboxDisabled: (row) => row.id === 2,\n              rowShowCheckbox: (row) => row.id !== 3,\n              state: selectingRowStateAndSetter,\n              rowKeyGetter: (r) => r.id + r.issueType,\n            },\n            rowsGrouping: {\n              rowKeyGetter: (r) => r.id,\n              groupByState: [groupByArr, setGroupByArr],\n            },\n            rowInstruments: {\n              getRowDropdownConfig,\n              defaultOpened: true,\n            },\n            containerStyle: { height: 700 },\n            columnsControl: {\n              enable: true,\n              hiding: true,\n              disableHiding: ['id'],\n              pinning: true,\n              disablePinning: ['developer'],\n              reorderingAside: true,\n              reorderingHeader: true,\n              columnsLabel: {\n                task: 'Задачи',\n              },\n              orderDefault: ['id', 'issueType', 'task'],\n              hiddenDefault: ['tr1'],\n              pinnedDefault: ['complete'],\n              onConfirm: ({ order, hidden, pinned }, _setters) => {\n                // eslint-disable-next-line no-alert\n                alert(`\n                                    order: ${order.join(', ')}\n                                    pinned: ${pinned.join(', ')}\n                                    hidden: ${hidden.join(', ')}\n                                `);\n              },\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "columnsGrouping",
      "legacy": true,
      "summary": "Вложенная структура шапки таблицы через групповые колонки.",
      "docs": "# ColumnsGrouping\n\nВложенная структура шапки таблицы через групповые колонки.\n\n## Ключевые особенности\n\n- `columnConfig` может содержать обычные колонки и группы колонок\n- Группа задается через `children`\n- Поддерживает несколько уровней вложенности шапки\n- Совместима с `columnsControl` и `resizableColumn`\n\n## Особенности\n\nУ групповой колонки нет данных строки. Данные отображают leaf-колонки, которые находятся внутри `children`.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-columnsgrouping-api--docs).",
      "apiDocs": "# Columns Grouping API\n\n## ColumnGroupConfig\n\n```typescript\ntype ColumnGroupConfig<R extends ObjectForExtending, SR> = ColumnGroup<\n//     R,\n//     SR\n// >;\n```\n\n## ColumnOrColumnGroupConfig\n\n```typescript\ntype ColumnOrColumnGroupConfig<\n  R extends ObjectForExtending,\n  SR = unknown,\n> = ColumnConfig<R, SR> | ColumnGroupConfig<R, SR>;\n```",
      "api": [
        {
          "typeName": "ColumnGroupConfig",
          "source": "type ColumnGroupConfig<R extends ObjectForExtending, SR> = ColumnGroup<\n//     R,\n//     SR\n// >;"
        },
        {
          "typeName": "ColumnOrColumnGroupConfig",
          "source": "type ColumnOrColumnGroupConfig<\n  R extends ObjectForExtending,\n  SR = unknown,\n> = ColumnConfig<R, SR> | ColumnGroupConfig<R, SR>;"
        }
      ],
      "stories": [
        {
          "exportName": "SimpleTable",
          "displayName": "Columns grouping",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n({ headerTreeLvl }) => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnOrColumnGroupConfig<Row>[]>(\n      () => [...(dataObj[headerTreeLvl] ?? [])],\n      [headerTreeLvl],\n    );\n\n    return (\n      <Table\n        key={headerTreeLvl}\n        tableConfig={{\n          containerStyle: { height: 700 },\n          columnsControl: { enable: true },\n          resizableColumn: true,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "collapsing",
      "legacy": true,
      "summary": "Сворачивание и разворачивание тела таблицы",
      "docs": "# TableCollapsing\n\n## Ключевые особенности\n\n- Сворачивание и разворачивание тела таблицы\n- Кнопка управления в controlBlock\n- Поддержка внутреннего и внешнего состояния\n\n**tableConfig.collapsing**\n\nДля активации функции сворачивания/разворачивания тела таблицы необходимо:\n\n1. Включить collapsing в конфигурации таблицы:\n\n2. Кнопка управления collapsing будет отображаться в controlBlock (крайняя левая часть таблицы)\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-collapsing-api--docs).",
      "apiDocs": "# Collapsing API\n\n## TableCollapseConfig\n\n```typescript\ntype TableCollapseConfig = {\n  /**\n   * Обязательный флаг для активации\n   * @default false\n   */\n  enableCollapse?: boolean;\n  /**\n   * Начальное состояние (опционально)\n   *  @default false\n   */\n  defaultCollapsed?: boolean;\n  /**\n   * Текст для кнопки при раскрытом состоянии (опционально)\n   * @default \"Свернуть\"\n   */\n  collapseText?: string;\n  /**\n   * Текст для кнопки при закрытом состоянии (опционально)\n   * @default \"Развернуть\"\n   */\n  expandText?: string;\n  /**\n   * callback при изменении состояния\n   */\n  onToggleCollapse?: (isCollapsed: boolean) => void;\n  /** Внешнее состояние [isCollapsed, setIsCollapsed] */\n  collapsedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n  /**\n   * Размещение кнопки коллапсинга\n   * - 'inside' - внутри контрол-блока (по умолчанию, участвует в компрессии)\n   * - 'above' - в отдельном блоке сверху контрол-блока (не участвует в компрессии)\n   * @default 'inside'\n   */\n  collapseButtonPlacement?: 'inside' | 'above';\n  /**\n   * Кастомный рендер правого слота кнопки коллапсинга, который используется при collapseButtonPlacement='above'\n   */\n  collapseButtonAboveRightSlot?: React.ReactNode;\n};\n```",
      "api": [
        {
          "typeName": "TableCollapseConfig",
          "source": "type TableCollapseConfig = {\n  /**\n   * Обязательный флаг для активации\n   * @default false\n   */\n  enableCollapse?: boolean;\n  /**\n   * Начальное состояние (опционально)\n   *  @default false\n   */\n  defaultCollapsed?: boolean;\n  /**\n   * Текст для кнопки при раскрытом состоянии (опционально)\n   * @default \"Свернуть\"\n   */\n  collapseText?: string;\n  /**\n   * Текст для кнопки при закрытом состоянии (опционально)\n   * @default \"Развернуть\"\n   */\n  expandText?: string;\n  /**\n   * callback при изменении состояния\n   */\n  onToggleCollapse?: (isCollapsed: boolean) => void;\n  /** Внешнее состояние [isCollapsed, setIsCollapsed] */\n  collapsedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n  /**\n   * Размещение кнопки коллапсинга\n   * - 'inside' - внутри контрол-блока (по умолчанию, участвует в компрессии)\n   * - 'above' - в отдельном блоке сверху контрол-блока (не участвует в компрессии)\n   * @default 'inside'\n   */\n  collapseButtonPlacement?: 'inside' | 'above';\n  /**\n   * Кастомный рендер правого слота кнопки коллапсинга, который используется при collapseButtonPlacement='above'\n   */\n  collapseButtonAboveRightSlot?: React.ReactNode;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "InternalStateCollapsing",
          "displayName": "Collapse тела таблицы (внутреннее состояние)",
          "type": "full-code",
          "code": "import { ColumnConfig, Table } from '@daisforge/ui';\n\n() => {\n    const [rows] = useState(createRows);\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          minWidth: 200,\n          width: 300,\n          maxWidth: 500,\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '400px' },\n          collapsing: {\n            enableCollapse: true,\n            defaultCollapsed: true,\n            expandText: 'Развернуть информацию',\n            collapseText: 'Свернуть информацию',\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ExternalStateCollapsing",
          "displayName": "Collapse тела таблицы (внешнее состояние)",
          "type": "full-code",
          "code": "import { ColumnConfig, Table } from '@daisforge/ui';\n\n() => {\n    const [rows] = useState(createRows);\n    const [externalCollapsed, setExternalCollapsed] = useState(true);\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          minWidth: 200,\n          width: 300,\n          maxWidth: 500,\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n        <Button onClick={() => setExternalCollapsed(!externalCollapsed)}>\n          {externalCollapsed ? 'Развернуть таблицу' : 'Свернуть таблицу'}\n        </Button>\n        <Table\n          tableConfig={{\n            containerStyle: { height: '300px' },\n            collapsing: {\n              enableCollapse: true,\n              collapsedState: [externalCollapsed, setExternalCollapsed],\n              domMetadata: {\n                className: 'testClassNameForCollapsing',\n                dataAttributes: {\n                  'data-test-collapsing': 'test-collapsing',\n                },\n              },\n              onToggleCollapse: (collapsed) =>\n                // eslint-disable-next-line no-console\n                console.debug('Table collapsed:', collapsed),\n            },\n          }}\n          columnConfig={columns}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "contextMenu",
      "legacy": true,
      "summary": "Контекстное меню для заголовков и ячеек legacy `Table`.",
      "docs": "# ContextMenu\n\nКонтекстное меню для заголовков и ячеек legacy `Table`.\n\n## Ключевые особенности\n\n- Обработчик правого клика по заголовку через `onHeaderContextMenu`\n- Dropdown-меню для заголовка через `onHeaderContextMenuDropDown`\n- Dropdown-меню для ячейки через `onCellContextMenuDropDown`\n- Возможность получить контекст строки, колонки и выбранной ячейки\n- Поддержка многоуровневых пунктов меню\n\n## Особенности\n\nЕсли одновременно заданы простой handler и dropdown-конфиг, сначала вызывается handler, затем логика dropdown. Dropdown-конфиг использует не все props базового `Dropdown`: позиционирование и открытие управляются таблицей.\n\n## Асинхронная подгрузка пунктов\n\nКогда пункты меню неизвестны заранее и подгружаются по правому клику. Запросом и его состоянием (загрузка / данные / ошибка) владеет потребитель — таблица только открывает меню и реактивно перечитывает пункты.\n\n- `onOpen` — вызывается при открытии меню; здесь потребитель стартует запрос и хранит своё состояние. Если задан, меню открывается даже при пустом результате `getDropDownItems`.\n- `getDropDownItems` — читается реактивно, пока меню открыто: во время загрузки верните скелетон-пункты, после — реальные. Меню обновляется само, без переоткрытия.\n- Индикатор загрузки — скелетон-пункты (через `renderItem`) или произвольный узел в `beforeList`.\n- Ошибка — узел в `beforeList` (например `EmptyState` с кнопкой повтора, вызывающей повторную загрузку).\n\nПример со скелетонами, успешной загрузкой и ошибкой — в стори ниже.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-contextmenu-api--docs).",
      "apiDocs": "# Context Menu API\n\n## ContextMenuDropdownItem\n\n```typescript\ntype ContextMenuDropdownItem = NonNullable<\n  DropdownProps['items']\n>[number];\n```\n\n## ContextMenuDropDownProps\n\n```typescript\ntype ContextMenuDropDownProps = Omit<\n  DropdownProps,\n  | 'children'\n  | 'items'\n  | 'placement'\n  | 'closeOnOverlayClick'\n  | 'portal'\n  | 'openByRightClick'\n  | 'onItemClick'\n  | 'hoverIndex'\n  | 'size'\n  | 'alwaysOpened'\n  | 'trigger'\n  | 'hasArrow'\n  | 'onItemSelect'\n>;\n```\n\n## DropdownContextMenu\n\n```typescript\ntype DropdownContextMenu = {\n  type: 'dropdown';\n  getDropDownItems: (params: { columnLabel: string }) => DropdownProps['items'];\n} & ContextMenuDropDownProps;\n```\n\n## HeaderContextMenuProps\n\n```typescript\ntype HeaderContextMenuProps = (\n  event: React.MouseEvent,\n  columnLabel: string | undefined,\n  closestTargetElement: HTMLElement | undefined,\n) => void;\n```\n\n## HeaderContextMenuDropDownProps\n\n```typescript\ntype HeaderContextMenuDropDownProps = {\n  type: 'dropdown';\n  getDropDownItems: (params: {\n    columnLabel: string | undefined;\n  }) => DropdownProps['items'];\n  /**\n   * Колбэк открытия меню для асинхронной подгрузки. Если getDropDownItems вернул\n   * пусто, но onOpen задан — меню открывается, а getDropDownItems перечитывается\n   * реактивно, пока меню открыто. Здесь потребитель стартует запрос.\n   */\n  onOpen?: (params: { columnLabel: string | undefined }) => void;\n  onItemSelect?: (\n    item: ContextMenuDropdownItem,\n    context: { columnLabel: string | undefined },\n    event?: React.SyntheticEvent,\n  ) => void;\n} & ContextMenuDropDownProps;\n```\n\n## CellContextMenuDropDownProps\n\n```typescript\ntype CellContextMenuDropDownProps<RowType, SummaryRowType> = {\n  type: 'dropdown';\n  getDropDownItems: (params: {\n    row: RowType;\n    column: CalculatedColumn<RowType, SummaryRowType>;\n  }) => DropdownProps['items'];\n  /**\n   * Колбэк открытия меню для асинхронной подгрузки. Если getDropDownItems вернул\n   * пусто, но onOpen задан — меню открывается, а getDropDownItems перечитывается\n   * реактивно, пока меню открыто. Здесь потребитель стартует запрос.\n   */\n  onOpen?: (params: {\n    row: RowType;\n    column: CalculatedColumn<RowType, SummaryRowType>;\n  }) => void;\n  onItemSelect?: (\n    item: ContextMenuDropdownItem,\n    context: {\n      row: RowType;\n      column: CalculatedColumn<RowType, SummaryRowType>;\n      selectCell: (enableEditor?: boolean) => void;\n    },\n    event?: React.SyntheticEvent,\n  ) => void;\n} & ContextMenuDropDownProps;\n```",
      "api": [
        {
          "typeName": "ContextMenuDropdownItem",
          "source": "type ContextMenuDropdownItem = NonNullable<\n  DropdownProps['items']\n>[number];"
        },
        {
          "typeName": "ContextMenuDropDownProps",
          "source": "type ContextMenuDropDownProps = Omit<\n  DropdownProps,\n  | 'children'\n  | 'items'\n  | 'placement'\n  | 'closeOnOverlayClick'\n  | 'portal'\n  | 'openByRightClick'\n  | 'onItemClick'\n  | 'hoverIndex'\n  | 'size'\n  | 'alwaysOpened'\n  | 'trigger'\n  | 'hasArrow'\n  | 'onItemSelect'\n>;"
        },
        {
          "typeName": "DropdownContextMenu",
          "source": "type DropdownContextMenu = {\n  type: 'dropdown';\n  getDropDownItems: (params: { columnLabel: string }) => DropdownProps['items'];\n} & ContextMenuDropDownProps;"
        },
        {
          "typeName": "HeaderContextMenuProps",
          "source": "type HeaderContextMenuProps = (\n  event: React.MouseEvent,\n  columnLabel: string | undefined,\n  closestTargetElement: HTMLElement | undefined,\n) => void;"
        },
        {
          "typeName": "HeaderContextMenuDropDownProps",
          "source": "type HeaderContextMenuDropDownProps = {\n  type: 'dropdown';\n  getDropDownItems: (params: {\n    columnLabel: string | undefined;\n  }) => DropdownProps['items'];\n  /**\n   * Колбэк открытия меню для асинхронной подгрузки. Если getDropDownItems вернул\n   * пусто, но onOpen задан — меню открывается, а getDropDownItems перечитывается\n   * реактивно, пока меню открыто. Здесь потребитель стартует запрос.\n   */\n  onOpen?: (params: { columnLabel: string | undefined }) => void;\n  onItemSelect?: (\n    item: ContextMenuDropdownItem,\n    context: { columnLabel: string | undefined },\n    event?: React.SyntheticEvent,\n  ) => void;\n} & ContextMenuDropDownProps;"
        },
        {
          "typeName": "CellContextMenuDropDownProps",
          "source": "type CellContextMenuDropDownProps<RowType, SummaryRowType> = {\n  type: 'dropdown';\n  getDropDownItems: (params: {\n    row: RowType;\n    column: CalculatedColumn<RowType, SummaryRowType>;\n  }) => DropdownProps['items'];\n  /**\n   * Колбэк открытия меню для асинхронной подгрузки. Если getDropDownItems вернул\n   * пусто, но onOpen задан — меню открывается, а getDropDownItems перечитывается\n   * реактивно, пока меню открыто. Здесь потребитель стартует запрос.\n   */\n  onOpen?: (params: {\n    row: RowType;\n    column: CalculatedColumn<RowType, SummaryRowType>;\n  }) => void;\n  onItemSelect?: (\n    item: ContextMenuDropdownItem,\n    context: {\n      row: RowType;\n      column: CalculatedColumn<RowType, SummaryRowType>;\n      selectCell: (enableEditor?: boolean) => void;\n    },\n    event?: React.SyntheticEvent,\n  ) => void;\n} & ContextMenuDropDownProps;"
        }
      ],
      "stories": [
        {
          "exportName": "ContextOnHeaderMenuDropDownStory",
          "displayName": "Контекстное меню DropDown (шапка таблицы)",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          onHeaderContextMenuDropDown: {\n            type: 'dropdown',\n            getDropDownItems: ({ columnLabel }) => [\n              {\n                value: `lvl1 ${columnLabel}`,\n                label: `${columnLabel} lvl1`,\n                items: [\n                  {\n                    value: `lvl1_inside ${columnLabel}`,\n                    label: `${columnLabel} lvl1 inside`,\n                  },\n                ],\n              },\n              {\n                value: `lvl2 ${columnLabel}`,\n                label: `${columnLabel} lvl2`,\n              },\n            ],\n            onItemSelect: (item, context, event) => {\n              console.group('onItemSelect for onCellContextMenuDropDown');\n              console.debug(item, 'item');\n              console.debug(context, 'context');\n              console.debug(event, 'event');\n              console.groupEnd();\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ContextOnHeaderMenuStory",
          "displayName": "Контекстное меню, функция обработчик (шапка таблицы)",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          onHeaderContextMenu: (e, columnLabel, closestTarget) =>\n            console.debug(e, columnLabel, closestTarget),\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ContextOnCellMenuDropDownStory",
          "displayName": "Контекстное меню DropDown (cell таблицы)",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          onCellContextMenuDropDown: {\n            type: 'dropdown',\n            getDropDownItems: ({ column, row }) => {\n              console.debug(\n                column,\n                row,\n                'getDropDownItems for onCellContextMenuDropDown',\n              );\n              return [\n                {\n                  value: `lvl1 ${column.name}`,\n                  label: `${column.name} lvl1`,\n                  items: [\n                    {\n                      value: `lvl1_inside ${column.name}`,\n                      label: `${column.name} lvl1 inside`,\n                    },\n                  ],\n                },\n                {\n                  value: `lvl2 ${column.name}`,\n                  label: `${column.name} lvl2`,\n                },\n              ];\n            },\n            onItemSelect: (item, context, event) => {\n              console.group('onItemSelect for onCellContextMenuDropDown');\n              console.debug(item, 'item');\n              console.debug(context, 'context', context.row);\n              console.debug(event, 'event');\n              console.groupEnd();\n              context.selectCell();\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ContextOnCellMenuStory",
          "displayName": "Контекстное меню, функция обработчик (cell таблицы)",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          onCellContextMenu: (args, event) => {\n            console.debug(args, event, 'onCellContextMenu');\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ContextOnCellAndOnHeaderMenuStory",
          "displayName": "Контекстное меню, all features (cell / header таблицы)",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          onCellContextMenu: (args, event) => {\n            console.debug(args, event, 'onCellContextMenu');\n          },\n          onCellContextMenuDropDown: {\n            type: 'dropdown',\n            getDropDownItems: ({ column, row }) => {\n              console.debug(\n                column,\n                row,\n                'getDropDownItems for onCellContextMenuDropDown',\n              );\n              return [\n                {\n                  value: `lvl1 ${column.name}`,\n                  label: `${column.name} lvl1`,\n                  items: [\n                    {\n                      value: `lvl1_inside ${column.name}`,\n                      label: `${column.name} lvl1 inside`,\n                    },\n                  ],\n                },\n                {\n                  value: `lvl2 ${column.name}`,\n                  label: `${column.name} lvl2`,\n                },\n              ];\n            },\n            onItemSelect: (item, context, event) => {\n              console.group('onItemSelect for onCellContextMenuDropDown');\n              console.debug(item, 'item');\n              console.debug(context, 'context');\n              console.debug(event, 'event');\n              console.groupEnd();\n            },\n          },\n          onHeaderContextMenu: (e, closestTarget) =>\n            console.debug(e, closestTarget),\n          onHeaderContextMenuDropDown: {\n            type: 'dropdown',\n            getDropDownItems: ({ columnLabel }) => [\n              {\n                value: `lvl1 ${columnLabel}`,\n                label: `${columnLabel} lvl1`,\n                items: [\n                  {\n                    value: `lvl1_inside ${columnLabel}`,\n                    label: `${columnLabel} lvl1 inside`,\n                  },\n                ],\n              },\n              {\n                value: `lvl2 ${columnLabel}`,\n                label: `${columnLabel} lvl2`,\n              },\n            ],\n            onItemSelect: (item, context, event) => {\n              console.group('onItemSelect for onCellContextMenuDropDown');\n              console.debug(item, 'item');\n              console.debug(context, 'context');\n              console.debug(event, 'event');\n              console.groupEnd();\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ContextOnCellMenuAsyncSuccessStory",
          "displayName": "Async-подгрузка пунктов (успех)",
          "type": "full-code",
          "code": "() => <AsyncCellDropdownExample shouldFail={false} />"
        },
        {
          "exportName": "ContextOnCellMenuAsyncErrorStory",
          "displayName": "Async-подгрузка пунктов (ошибка + ретрай)",
          "type": "full-code",
          "code": "() => <AsyncCellDropdownExample shouldFail />"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "controlBlock",
      "legacy": true,
      "summary": "Верхняя панель инструментов таблицы",
      "docs": "# Control Block Configuration\n\n## Ключевые особенности\n\n- Верхняя панель инструментов таблицы\n- Кастомные фичи с отображением в controlBlock или sidebar\n- Компрессия и перенос фич при нехватке места\n\nВ таблице присутствует возможность настраивать панель управления таблицы (верхний блок с кнопками).\n\n**tableConfig.controlBlock**\n\n## Breaking Changes (v2.0)\n\n### 1. Удалены устаревшие свойства:\n\n- `dropdown` - заменен на `details` для Sidebar-представления\n- `customDropdownItem` - больше не поддерживается\n\n### 2. Новые обязательные требования:\n\n- Для отображения в Sidebar необходимо указывать `details`\n\n### 3. Новые типы фич:\n\n- `button` - кнопка с иконкой и действием\n- `switch` - переключатель\n- `select` - выпадающий список\n- `custom` - кастомный рендер\n\n## Особенности работы ControlBlock\n\n### 1. Лимит отображения\n\nНе более 5 фич одновременно в ControlBlock\n\n### 2. Обязательные фичи\n\nС `mandatory: true` всегда остаются в ControlBlock, при включённой компрессии при минимально возможном размере таблицы они будут скрыты в кнопку-dropdown ... (многоточие). Если это ваша кастомная фича, то надо обязательно описать ее details (будет использоваться для отображения в кнопке-dropdown)\n\n### 3. Автоматическое распределение:\n\n- Фичи с `details` переносятся в Sidebar при превышении лимита (у которых mandatory: false)\n- Фичи без `details` скрываются при превышении лимита\n\n#### Пример миграции с v1 на v2:\n\n```ts\n  // Было (v1):\n  {\n    value: 'feature',\n    dropdown: { contentRight: <Component /> }\n  }\n  // Стало (v2):\n  {\n    value: 'feature',\n    onClick: () => {}, // обязательно\n    details: {\n    type: 'custom',\n    render: () => <Component />\n    }\n  }\n```\n\n#### Конфигурация таблицы (v2.0)\n\n```jsx\nconst [rows] = useState(createRows);\nconst [pinIsActive, setPinIsActive] = useState(false);\n\nconst tableConfig = {\n  controlBlock: {\n    customFeatures: [\n      {\n        value: 'customPin',\n        label: pinIsActive ? 'Открепить' : 'Закрепить',\n        Icon: pinIsActive ? IconPinOutline : IconPinFill,\n        onClick: () => setPinIsActive(!pinIsActive),\n        details: {\n          type: 'switch',\n          label: 'Закрепление колонок',\n          checked: pinIsActive,\n          onChange: () => setPinIsActive(!pinIsActive),\n        },\n      },\n    ],\n  },\n};\n```\n\n### Правила использования:\n\n1. Для Sidebar-представления используйте `details`\n2. Фичи без `details` не попадают в Sidebar\n3. Используйте `mandatory: true` для важных фич\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-controlblock-api--docs).\n\n# Table MassPanelAction\n\n## Ключевые особенности\n\n- Панель действий для выбранных строк\n- Автоматическое появление при активном selecting\n- Компрессия кнопок и отдельное поведение accent-кнопок\n\n**tableConfig.controlBlock.massActionPanel**\n\nПанель массовых действий (MassPanelAction) - это компонент, который отображается внизу таблицы и позволяет применять действия к выбранным строкам. Панель появляется автоматически, когда в таблице выбраны строки.\n\n## Когда открывается панель\n\nПанель массовых действий появляется автоматически, когда:\n\n- Включена функция выбора строк (`selecting` в `tableConfig`)\n- Выбрана хотя бы одна строка в таблице\n- `selectingRowsIsActive` равен `true`\n\nПанель скрывается автоматически, когда все строки сняты с выбора.\n\n## Управление видимостью\n\nПо умолчанию панель показывается автоматически при активном `selecting` и хотя бы одной выбранной строке. Это поведение переопределяется через `massActionPanel.show`:\n\n- `undefined` (по умолчанию) — штатное поведение (selecting + выбранные строки)\n- `false` — панель не рендерится, действиями вы управляете сами\n- `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n\n## Замена leftSideInner\n\n**Важно:** Панель массовых действий (`massActionPanel`) была создана как **замена** для `leftSideInner` в `controlBlock`.\n\n### ⚠️ Не рекомендуется использовать вместе\n\n**НЕ ЖЕЛАТЕЛЬНО** использовать `leftSideInner` и `massActionPanel` одновременно, так как:\n\n- Это создает дублирование функциональности\n- `massActionPanel` специально разработан для работы с выбранными строками\n- `massActionPanel` имеет адаптивную компрессию и автоматическое позиционирование\n- `massActionPanel` лучше интегрирован с функцией выбора строк\n\n### Рекомендация\n\nИспользуйте `massActionPanel` вместо `leftSideInner` для кнопок, которые должны работать с выбранными строками. Кнопки, которые не зависят от выбора строк, можно оставить в `leftSideInner` или `rightSideInner`.\n\n## Особенности работы\n\n### Accent кнопки всегда видимы\n\nКнопки с `view: 'accent'` **никогда не скрываются** в дропдауне скрытых действий, даже если панель не помещается по ширине. Они всегда остаются видимыми и сохраняют свой оригинальный порядок относительно других кнопок.\n\n### Адаптивная компрессия\n\nПри нехватке места панель автоматически:\n\n- Скрывает обычные кнопки в дропдаун скрытых действий\n- Оставляет accent кнопки всегда видимыми\n- Сохраняет порядок кнопок (accent кнопки остаются на своих позициях)\n- Автоматически центрируется с учетом открытого сайдбара\n\n### Взаимодействие с сайдбаром\n\nПри открытии сайдбара:\n\n- Панель автоматически сворачивается (если была развернута)\n- Позиция корректируется с учетом ширины сайдбара\n- При закрытии сайдбара панель автоматически разворачивается\n\n### Размеры кнопок\n\nРазмеры кнопок и дропдаунов панель подбирает сама — по размеру панели (`massActionPanel.size`: `m`/`s`/`xs`) и компактности. Передавать `size` кнопкам отдельно **не нужно**. Если `size` всё же задан — он используется как есть.\n\n## Конфигурация\n\nПанель массовых действий настраивается через `tableConfig.controlBlock.massActionPanel`:\n\n```tsx\ntableConfig={{\n  selecting: {\n    state: selectingRowState,\n    rowKeyGetter: (row) => row.id,\n  },\n  controlBlock: {\n    massActionPanel: {\n      buttons: [\n        {\n          type: 'button',\n          text: 'Действие',\n          view: 'secondary', // или 'accent', 'critical', 'primary' и т.д.\n          onClick: () => {\n            // Обработчик клика\n          },\n        },\n      ],\n    },\n  },\n}}\n```\n\nПомимо `buttons`, у панели есть необязательные пропсы: `size` (размер панели, см. «Размеры кнопок»), `show` (управление видимостью), `bottom` (отступ панели снизу от контейнера, по умолчанию 24px) и `collapsedDropdownProps` (пропсы дропдауна скрытых действий). Полное описание типов — в разделе API.\n\n## Типы кнопок\n\n### Button\n\nИспользуется компонент `Button` с `type: 'button'`:\n\n- Доступны view: `'accent'`, `'secondary'`, `'critical'`, `'primary'` и т.д.\n- `view: 'accent'` - accent кнопки, которые всегда остаются видимыми\n\n### LinkButton\n\nКнопка-ссылка с `type: 'linkButton'` (компонент `LinkButton`). View задаётся в link-нотации:\n\n```tsx\n{\n  type: 'linkButton',\n  text: 'Ссылка-действие',\n  view: 'linkSecondary', // 'linkAccent' / 'linkDefault' и т.д.\n  onClick: () => {},\n}\n```\n\n## Disabled состояние\n\nЕсли кнопка имеет `disabled: true`, можно передать `disabledTooltipProps` для отображения подсказки при наведении на disabled кнопку:\n\n```tsx\n{\n  type: 'button',\n  text: 'Действие',\n  view: 'secondary',\n  disabled: true,\n  disabledTooltipProps: {\n    text: 'Выберите строки для выполнения действия',\n  },\n  onClick: () => {},\n}\n```\n\n**Важно:** disabled кнопка остаётся неактивной и после перемещения в дропдаун скрытых действий — `disabled` пробрасывается на пункт меню. Подсказка `disabledTooltipProps` при этом показывается только у кнопок на самой панели, в меню её нет.\n\n## Dropdown в кнопках\n\nКнопки могут иметь вложенный dropdown:\n\n```tsx\n{\n  type: 'button',\n  text: 'Действие с меню',\n  view: 'secondary',\n  dropdown: {\n    items: [\n      { label: 'Опция 1', value: '1' },\n      { label: 'Опция 2', value: '2' },\n    ],\n    onItemSelect: (item) => {\n      // Обработчик выбора\n    },\n  },\n}\n```\n\n> Подробнее о типах — [MassPanelAction API](?path=/docs/локальные-компоненты-table-controlblock-masspanelaction-api--docs)",
      "apiDocs": "# Control Block API\n\n## ControlBlockConfig\n\n```typescript\ntype ControlBlockConfig = {\n  /**\n   * show - наличие controlBlock-а\n   * @default true\n   */\n  show?: boolean;\n  /**\n   * leftSideInner - пропс для добавления кнопок в левую часть контролблока\n   */\n  leftSideInner?: ControlBlockButtonProps[];\n  /**\n   * rightSideInner - пропс для добавления кнопок в в правую часть контролблока\n   */\n  rightSideInner?: ControlBlockButtonProps[];\n  /**\n   * rightSideInner - пропс для добавления кастомные фичей (кнопки-иконки)\n   */\n  customFeatures?: FeatureItem[];\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n   */\n  leftSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n   */\n  rightSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n   * @default true\n   */\n  enableAdaptiveCompress?: boolean;\n  /**\n   * Панель массовых действий\n   */\n  massActionPanel?: {\n    /**\n     * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n     * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n     */\n    buttons: MassActionsButtonProps[];\n    /**\n     * Пропсы для Dropdown, в который сжались кнопки\n     */\n    collapsedDropdownProps?: TableDropdownConfigProps;\n    /**\n     * Отступ панели снизу от контейнера (px)\n     * @default 24\n     */\n    bottom?: number;\n    /**\n     * Управление отображением панели массовых действий.\n     * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n     * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n     * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n     */\n    show?: boolean;\n    /**\n     * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n     * Viewport-логика (1280) в таблице не используется.\n     * @default 's'\n     */\n    size?: MassActionsSize;\n  };\n};\n```\n\n## ControlBlockButtonProps\n\n```typescript\ntype ControlBlockButtonProps = DataAttributes &\n  Omit<Partial<ButtonProps>, DefPropsKeys> & {\n    view?: LinkView<LinkButtonView> | ButtonProps['view'];\n    dropdown?: TableDropdownProps;\n    isTargetAction?: boolean;\n  };\n```\n\n## FeatureItem\n\n```typescript\ntype FeatureItemWithIcon = FeatureDetailsBase & {\n  /**\n   * Свойства ниже - сохранение старой реализации фичей, до переезда их в sidebar.\n   * Используются для отображения фичи в верхнем controlBlock\n   */\n  value: string;\n  label: string;\n  onClick: () => void;\n  Icon: FC<IconProps>;\n  /**\n   * Добавляет разделитель слева от элемента\n   * @default false\n   */\n  dividerLeft?: boolean;\n  modal?: ReactNode;\n  className?: string;\n} & DataAttributes;\n```\n\n## SidebarTab\n\n```typescript\ntype SidebarTab = {\n  /**\n   * Уникальный идентификатор таба\n   */\n  id: DefaultSidebarTabIds | string;\n  /**\n   * title таба (для Tooltip)\n   */\n  label: string;\n  /**\n   * Иконка таба\n   */\n  icon: ReactNode;\n  /**\n   * Контентная часть сайдбара\n   */\n  content: React.ReactNode;\n  /**\n   * Показывать ли в сайдбаре\n   * @default true\n   */\n  showInSidebar?: boolean;\n  /**\n   * Заголовок контентной части сайдбара\n   */\n  title?: string;\n  /**\n   * Кастомный элемент справа от title в шапке сайдбара\n   */\n  titleRightSlot?: React.ReactNode;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n```\n\n# MassPanelAction API\n\n## MassActionsButtonProps\n\n```typescript\ntype MassActionsButtonPropsButton = DataAttributes &\n  Partial<ButtonCompProps> & {\n    type: 'button';\n    view?: ButtonCompProps['view'];\n    /**\n     * Dropdown для кнопки.\n     * Используется универсальный DropdownProps, который работает и с обычным Dropdown, и с TableDropdown\n     */\n    dropdown?: DropdownProps & { $css?: CSSObject };\n    disabledTooltipProps?: TooltipProps;\n  };\n```",
      "api": [
        {
          "typeName": "ControlBlockConfig",
          "source": "type ControlBlockConfig = {\n  /**\n   * show - наличие controlBlock-а\n   * @default true\n   */\n  show?: boolean;\n  /**\n   * leftSideInner - пропс для добавления кнопок в левую часть контролблока\n   */\n  leftSideInner?: ControlBlockButtonProps[];\n  /**\n   * rightSideInner - пропс для добавления кнопок в в правую часть контролблока\n   */\n  rightSideInner?: ControlBlockButtonProps[];\n  /**\n   * rightSideInner - пропс для добавления кастомные фичей (кнопки-иконки)\n   */\n  customFeatures?: FeatureItem[];\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n   */\n  leftSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n   */\n  rightSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n   * @default true\n   */\n  enableAdaptiveCompress?: boolean;\n  /**\n   * Панель массовых действий\n   */\n  massActionPanel?: {\n    /**\n     * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n     * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n     */\n    buttons: MassActionsButtonProps[];\n    /**\n     * Пропсы для Dropdown, в который сжались кнопки\n     */\n    collapsedDropdownProps?: TableDropdownConfigProps;\n    /**\n     * Отступ панели снизу от контейнера (px)\n     * @default 24\n     */\n    bottom?: number;\n    /**\n     * Управление отображением панели массовых действий.\n     * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n     * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n     * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n     */\n    show?: boolean;\n    /**\n     * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n     * Viewport-логика (1280) в таблице не используется.\n     * @default 's'\n     */\n    size?: MassActionsSize;\n  };\n};"
        },
        {
          "typeName": "ControlBlockButtonProps",
          "source": "type ControlBlockButtonProps = DataAttributes &\n  Omit<Partial<ButtonProps>, DefPropsKeys> & {\n    view?: LinkView<LinkButtonView> | ButtonProps['view'];\n    dropdown?: TableDropdownProps;\n    isTargetAction?: boolean;\n  };"
        },
        {
          "typeName": "FeatureItemWithIcon",
          "source": "type FeatureItemWithIcon = FeatureDetailsBase & {\n  /**\n   * Свойства ниже - сохранение старой реализации фичей, до переезда их в sidebar.\n   * Используются для отображения фичи в верхнем controlBlock\n   */\n  value: string;\n  label: string;\n  onClick: () => void;\n  Icon: FC<IconProps>;\n  /**\n   * Добавляет разделитель слева от элемента\n   * @default false\n   */\n  dividerLeft?: boolean;\n  modal?: ReactNode;\n  className?: string;\n} & DataAttributes;"
        },
        {
          "typeName": "SidebarTab",
          "source": "type SidebarTab = {\n  /**\n   * Уникальный идентификатор таба\n   */\n  id: DefaultSidebarTabIds | string;\n  /**\n   * title таба (для Tooltip)\n   */\n  label: string;\n  /**\n   * Иконка таба\n   */\n  icon: ReactNode;\n  /**\n   * Контентная часть сайдбара\n   */\n  content: React.ReactNode;\n  /**\n   * Показывать ли в сайдбаре\n   * @default true\n   */\n  showInSidebar?: boolean;\n  /**\n   * Заголовок контентной части сайдбара\n   */\n  title?: string;\n  /**\n   * Кастомный элемент справа от title в шапке сайдбара\n   */\n  titleRightSlot?: React.ReactNode;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};"
        },
        {
          "typeName": "MassActionsButtonPropsButton",
          "source": "type MassActionsButtonPropsButton = DataAttributes &\n  Partial<ButtonCompProps> & {\n    type: 'button';\n    view?: ButtonCompProps['view'];\n    /**\n     * Dropdown для кнопки.\n     * Используется универсальный DropdownProps, который работает и с обычным Dropdown, и с TableDropdown\n     */\n    dropdown?: DropdownProps & { $css?: CSSObject };\n    disabledTooltipProps?: TooltipProps;\n  };"
        }
      ],
      "stories": [
        {
          "exportName": "ControlBlockWithCustomFeatures",
          "displayName": "ID",
          "type": "full-code",
          "code": "import { ColumnConfig, Table } from '@daisforge/ui';\n  import {\n  IconBell,\n  IconBellActive,\n  IconCalendar,\n  IconClock,\n  IconEye,\n  IconHeart,\n  IconHeartStroke,\n  IconInfo,\n  IconLock,\n  IconPersone,\n  IconRefresh,\n  IconReset,\n  IconSettings,\n  IconStar,\n  } from '@daisforge/ui/icons';\n import { IconButton } from '@daisforge/ui';\n import React, { useMemo, useState } from 'react';\n\ntype AnalyticsMode = 'basic' | 'advanced';\ntype TimeRange = 'day' | 'week' | 'month';\ntype UserFilter = 'all' | 'my' | 'team';\n\n() => {\n    const columns: readonly ColumnConfig<Row>[] = useMemo(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'developer', name: 'Developer' },\n      ],\n      [],\n    );\n\n    const [rows] = useState(createRows);\n\n    // Состояния для кастомных фич\n    const [isFavorite, setIsFavorite] = useState(false);\n    const [notificationsEnabled, setNotificationsEnabled] = useState(true);\n    const [isLocked, setIsLocked] = useState(false);\n    const [analyticsMode, setAnalyticsMode] = useState<AnalyticsMode>('basic');\n    const [timeRange, setTimeRange] = useState<TimeRange>('week');\n    const [userFilter, setUserFilter] = useState<UserFilter>('all');\n    const [favoritesOnly, setFavoritesOnly] = useState(false);\n    const [autoRefresh, setAutoRefresh] = useState(false);\n    const [darkMode, setDarkMode] = useState(false);\n\n    const filterLabels = {\n      all: 'Все',\n      my: 'Мои',\n      team: 'Команда',\n    };\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          fullScreenEnabled: true,\n          controlBlock: {\n            customFeatures: [\n              // Обязательная кастомная фича\n              {\n                value: 'favorite',\n                label: isFavorite ? 'Удалить из избранного' : 'В избранное',\n                Icon: IconStar,\n                onClick: () => setIsFavorite(!isFavorite),\n                mandatory: true,\n                details: {\n                  type: 'switch',\n                  label: 'В избранном',\n                  checked: isFavorite,\n                  onChange: () => setIsFavorite(!isFavorite),\n                },\n              },\n              {\n                value: 'refresh-feature',\n                CustomIconRender: () => (\n                  <EmbedIconButton\n                    size=\"m\"\n                    onClick={() => {\n                      // eslint-disable-next-line no-alert\n                      alert('Click on refresh-feature in ControlBlock');\n                    }}\n                    style={{\n                      width: '40px',\n                      height: '40px',\n                      display: 'flex',\n                      alignItems: 'center',\n                      justifyContent: 'center',\n                    }}\n                  >\n                    <IconRefresh size=\"s\" />\n                  </EmbedIconButton>\n                ),\n                details: {\n                  type: 'button',\n                  label: 'Обновить',\n                  onClick: () =>\n                    // eslint-disable-next-line no-alert\n                    alert('Click for customFeatureRefresh2 in Sidebar'),\n                  icon: <IconRefresh size=\"s\" />,\n                },\n              },\n\n              // Кастомные фичи\n              {\n                value: 'notifications',\n                label: notificationsEnabled\n                  ? 'Отключить уведомления'\n                  : 'Включить уведомления',\n                Icon: notificationsEnabled ? IconBellActive : IconBell,\n                onClick: () => setNotificationsEnabled(!notificationsEnabled),\n                details: {\n                  type: 'switch',\n                  label: 'Уведомления',\n                  checked: notificationsEnabled,\n                  onChange: () =>\n                    setNotificationsEnabled(!notificationsEnabled),\n                },\n              },\n              {\n                value: 'analytics-mode',\n                label: `Аналитика (${\n                  analyticsMode === 'basic' ? 'базовая' : 'расширенная'\n                })`,\n                Icon: IconInfo, // Замена IconChart на IconInfo\n                onClick: () => {}, // Добавлен обязательный onClick\n                details: {\n                  type: 'select',\n                  label: 'Режим аналитики',\n                  icon: <IconInfo />,\n                  value: analyticsMode,\n                  options: [\n                    { value: 'basic', label: 'Базовая' },\n                    { value: 'advanced', label: 'Расширенная' },\n                  ],\n                  onChange: (val) => setAnalyticsMode(val as AnalyticsMode),\n                },\n              },\n              {\n                value: 'lock-table',\n                label: isLocked ? 'Разблокировать' : 'Заблокировать',\n                Icon: IconLock,\n                onClick: () => setIsLocked(!isLocked),\n                details: {\n                  type: 'button',\n                  label: isLocked ? 'Разблокировать' : 'Заблокировать',\n                  onClick: () => setIsLocked(!isLocked),\n                  icon: <IconLock />,\n                },\n              },\n              {\n                value: 'time-range',\n                label: `Период: ${timeRange}`,\n                Icon: IconCalendar,\n                onClick: () => {}, // Добавлен обязательный onClick\n                details: {\n                  type: 'select',\n                  label: 'Временной период',\n                  icon: <IconCalendar />,\n                  value: timeRange,\n                  options: [\n                    { value: 'day', label: 'День' },\n                    { value: 'week', label: 'Неделя' },\n                    { value: 'month', label: 'Месяц' },\n                  ],\n                  onChange: (val) => setTimeRange(val as TimeRange),\n                },\n              },\n              {\n                value: 'user-filter',\n                label: `Пользователи: ${filterLabels[userFilter]}`,\n                Icon: IconPersone,\n                onClick: () => {},\n                details: {\n                  type: 'select',\n                  label: 'Фильтр пользователей',\n                  icon: <IconPersone />,\n                  value: userFilter,\n                  options: [\n                    { value: 'all', label: 'Все' },\n                    { value: 'my', label: 'Мои' },\n                    { value: 'team', label: 'Команда' },\n                  ],\n                  onChange: (val) => setUserFilter(val as UserFilter),\n                },\n              },\n              {\n                value: 'favorites-only',\n                label: favoritesOnly ? 'Все записи' : 'Только избранные',\n                Icon: favoritesOnly ? IconHeart : IconHeartStroke,\n                onClick: () => setFavoritesOnly(!favoritesOnly),\n                details: {\n                  type: 'switch',\n                  label: 'Только избранные',\n                  checked: favoritesOnly,\n                  onChange: () => setFavoritesOnly(!favoritesOnly),\n                },\n              },\n              {\n                value: 'auto-refresh',\n                label: autoRefresh\n                  ? 'Отключить автообновление'\n                  : 'Включить автообновление',\n                Icon: IconReset,\n                onClick: () => setAutoRefresh(!autoRefresh),\n                details: {\n                  type: 'switch',\n                  label: 'Автообновление',\n                  checked: autoRefresh,\n                  onChange: () => setAutoRefresh(!autoRefresh),\n                },\n              },\n              {\n                value: 'dark-mode',\n                label: darkMode ? 'Светлая тема' : 'Темная тема',\n                Icon: darkMode ? IconEye : IconSettings,\n                onClick: () => setDarkMode(!darkMode),\n                details: {\n                  type: 'switch',\n                  label: 'Темная тема',\n                  checked: darkMode,\n                  onChange: () => setDarkMode(!darkMode),\n                },\n              },\n              {\n                value: 'time-tracker',\n                label: 'Таймер',\n                Icon: IconClock,\n                onClick: () => {}, // Добавлен обязательный onClick\n                details: {\n                  type: 'custom',\n                  render: () => <div>Кастомный компонент таймера</div>,\n                },\n              },\n            ],\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MassPanelActionBasic",
          "displayName": "Базовая панель массовых действий",
          "type": "full-code",
          "code": "import { ColumnConfig, Table } from '@daisforge/ui';\nimport React, { useMemo, useState } from 'react';\n\n() => {\n    const [rows] = useState(createRows);\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (row) => row.id,\n          },\n          controlBlock: {\n            massActionPanel: {\n              buttons: [\n                {\n                  type: 'button',\n                  text: 'Экспорт',\n                  view: 'secondary',\n                  onClick: () => {\n                    alert('Экспорт выбранных строк');\n                  },\n                },\n\n                {\n                  type: 'button',\n                  text: 'Архивировать',\n                  view: 'secondary',\n                  onClick: () => {\n                    alert('Архивирование выбранных строк');\n                  },\n                },\n                {\n                  type: 'button',\n                  text: 'Дублировать',\n                  view: 'secondary',\n                  onClick: () => {\n                    alert('Дублирование выбранных строк');\n                  },\n                },\n                {\n                  type: 'button',\n                  text: 'Accent',\n                  view: 'accent',\n                  onClick: () => {\n                    alert('Accent click');\n                  },\n                },\n              ],\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MassPanelActionWithAccent",
          "displayName": "Панель с accent кнопками",
          "type": "full-code",
          "code": "import { ColumnConfig, Table } from '@daisforge/ui';\nimport React, { useMemo, useState } from 'react';\n\n() => {\n    const [rows] = useState(createRows);\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (row) => row.id,\n          },\n          controlBlock: {\n            massActionPanel: {\n              buttons: [\n                {\n                  type: 'button',\n                  text: 'Обычная кнопка 1',\n                  view: 'secondary',\n                  onClick: () => alert('Кнопка 1'),\n                },\n\n                {\n                  type: 'button',\n                  text: 'Обычная кнопка 2',\n                  view: 'secondary',\n                  onClick: () => alert('Кнопка 2'),\n                },\n                {\n                  type: 'button',\n                  text: 'Еще одна кнопка',\n                  view: 'secondary',\n                  onClick: () => alert('Accent Button'),\n                },\n                {\n                  type: 'button',\n                  text: 'Обычная кнопка 3',\n                  view: 'secondary',\n                  onClick: () => alert('Кнопка 3'),\n                },\n                {\n                  type: 'button',\n                  text: 'Accent кнопка (всегда видима)',\n                  view: 'accent',\n                  onClick: () => alert('Accent кнопка'),\n                },\n              ],\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MassPanelActionWithButton",
          "displayName": "Панель с кнопками типа Button",
          "type": "full-code",
          "code": "import { ColumnConfig, Table } from '@daisforge/ui';\nimport React, { useMemo, useState } from 'react';\n\n() => {\n    const [rows] = useState(createRows);\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (row) => row.id,\n          },\n          controlBlock: {\n            massActionPanel: {\n              buttons: [\n                {\n                  type: 'button',\n                  text: 'Отменить',\n                  view: 'secondary',\n                  onClick: () => alert('Отменить'),\n                },\n                {\n                  type: 'button',\n                  text: 'Действие',\n                  view: 'secondary',\n                  onClick: () => alert('Действие'),\n                },\n                {\n                  type: 'button',\n                  text: 'Сохранить',\n                  view: 'accent',\n                  onClick: () => alert('Сохранить'),\n                },\n              ],\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MassPanelActionWithDisabled",
          "displayName": "Панель с disabled кнопками",
          "type": "full-code",
          "code": "import { ColumnConfig, Table } from '@daisforge/ui';\nimport React, { useMemo, useState } from 'react';\n\n() => {\n    const [rows] = useState(createRows);\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n    const [selectedCount] = selectingRowStateAndSetter;\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (row) => row.id,\n          },\n          controlBlock: {\n            massActionPanel: {\n              buttons: [\n                {\n                  type: 'button',\n                  text: 'Экспорт',\n                  view: 'secondary',\n                  disabled: selectedCount.size === 0,\n                  disabledTooltipProps: {\n                    text: 'Выберите хотя бы одну строку для экспорта',\n                  },\n                  onClick: () => alert('Экспорт'),\n                },\n\n                {\n                  type: 'button',\n                  text: 'Архивировать',\n                  view: 'secondary',\n                  disabled: selectedCount.size < 2,\n                  disabledTooltipProps: {\n                    text: 'Выберите минимум 2 строки для архивирования',\n                  },\n                  onClick: () => alert('Архивировать'),\n                },\n                {\n                  type: 'button',\n                  text: 'Accent',\n                  view: 'accent',\n                  disabled: selectedCount.size === 0,\n                  disabledTooltipProps: {\n                    text: 'Выберите строки для удаления',\n                  },\n                  onClick: () => alert('Accent'),\n                },\n              ],\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MassPanelActionSizeXS",
          "displayName": "Уменьшенная панель (size XS)",
          "type": "full-code",
          "code": "import { ColumnConfig, Table } from '@daisforge/ui';\nimport React, { useMemo, useState } from 'react';\n\n() => {\n    const [rows] = useState(createRows);\n    // Предвыбираем несколько строк, чтобы панель сразу была видна (со счётчиком и «Сбросить всё»).\n    const selectingRowStateAndSetter = useState<ReadonlySet<string | number>>(\n      () => new Set(rows.slice(0, 3).map((r) => r.id)),\n    );\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'developer', name: 'Developer' },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (row) => row.id,\n          },\n          controlBlock: {\n            massActionPanel: {\n              // Размер панели задаётся извне, независимо от вьюпорта.\n              size: 'xs',\n              buttons: [\n                {\n                  type: 'button',\n                  text: 'Экспорт',\n                  view: 'secondary',\n                  onClick: () => alert('Экспорт'),\n                },\n                {\n                  type: 'button',\n                  text: 'Архивировать',\n                  view: 'secondary',\n                  onClick: () => alert('Архивировать'),\n                },\n                {\n                  type: 'button',\n                  text: 'Дублировать',\n                  view: 'secondary',\n                  onClick: () => alert('Дублировать'),\n                },\n                {\n                  type: 'button',\n                  text: 'Accent',\n                  view: 'accent',\n                  onClick: () => alert('Accent'),\n                },\n              ],\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "customRender",
      "legacy": true,
      "summary": "Кастомный рендеринг ячеек таблицы.",
      "docs": "# Custom Render\n\nКастомный рендеринг ячеек таблицы.\n\n## Ключевые особенности\n\n- `renderCell` — кастомный рендер ячеек данных (доступны `row`, `rowIdx`, `column`)\n- `renderHeaderCell` — кастомный рендер заголовков (`name` принимает `string | ReactElement`)\n- `renderSummaryCell` — кастомный рендер итоговых строк\n- Контексты: `useRowContext` и `useHeaderContext` для передачи состояния без лишних ре-рендеров\n\n## Особенности\n\n- Контейнер ячейки должен использовать `width: '100%'` и `height: '100%'`\n- `headerContextValue` предоставляет доступ к состоянию фильтров, сортировки и размера строк\n- `rowContextValue` позволяет передавать кастомное состояние в ячейки без перерисовки таблицы\n\n> Подробнее о типах и пропсах — [Custom Render API](?path=/docs/локальные-компоненты-table-customrender-api--docs)",
      "apiDocs": "# Custom Render API\n\nКастомный рендеринг настраивается через свойства `columnConfig`.\n\n## ColumnDefault\n\n```typescript\ntype ColumnDefault<TRow, TSummaryRow = unknown> = {\n  /** The name of the column. By default it will be displayed in the header cell */\n  readonly name: string | ReactElement;\n  /** A unique key to distinguish each column */\n  readonly key: string;\n  /** Column width. If not specified, it will be determined automatically based on grid width and specified widths of other columns */\n  readonly width?: Maybe<number | string>;\n  /** Minimum column width in px. */\n  readonly minWidth?: Maybe<number>;\n  /** Maximum column width in px. */\n  readonly maxWidth?: Maybe<number>;\n  readonly cellClass?: Maybe<string | ((row: TRow) => Maybe<string>)>;\n  readonly headerCellClass?: Maybe<string>;\n  readonly summaryCellClass?: Maybe<\n    string | ((row: TSummaryRow) => Maybe<string>)\n  >;\n  /** Render function used to render the content of the column's header cell */\n  readonly renderHeaderCell?: Maybe<\n    (props: RenderHeaderCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of cells */\n  readonly renderCell?: Maybe<\n    (props: RenderCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of summary cells */\n  readonly renderSummaryCell?: Maybe<\n    (props: RenderSummaryCellProps<TSummaryRow, TRow>) => ReactNode\n  >;\n  /** Render function used to render the content of group cells */\n  readonly renderGroupCell?: Maybe<\n    (props: RenderGroupCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of edit cells. When set, the column is automatically set to be editable */\n  readonly renderEditCell?: Maybe<\n    (props: RenderEditCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Enables cell editing. If set and no editor property specified, then a textInput will be used as the cell editor */\n  readonly editable?: Maybe<boolean | ((row: TRow) => boolean)>;\n  readonly colSpan?: Maybe<\n    (args: ColSpanArgs<TRow, TSummaryRow>) => Maybe<number>\n  >;\n  /** Determines whether column is frozen or not */\n  readonly frozen?: Maybe<boolean>;\n  /** Enable resizing of a column */\n  readonly resizable?: Maybe<boolean>;\n  /** Enable sorting of a column */\n  readonly sortable?: Maybe<boolean>;\n  /** Enable dragging of a column */\n  readonly draggable?: Maybe<boolean>;\n  /** Sets the column sort order to be descending instead of ascending the first time the column is sorted */\n  readonly sortDescendingFirst?: Maybe<boolean>;\n  readonly editorOptions?: Maybe<{\n    /**\n     * Render the cell content in addition to the edit cell.\n     * Enable this option when the editor is rendered outside the grid, like a modal for example.\n     * By default, the cell content is not rendered when the edit cell is open.\n     * @default false\n     */\n    readonly displayCellContent?: Maybe<boolean>;\n    /** @default true */\n    readonly commitOnOutsideClick?: Maybe<boolean>;\n  }>;\n};\n\ndeclare type SharedDivProps = Pick<\n  React.HTMLAttributes<HTMLDivElement>,\n  | 'role'\n  | 'aria-label'\n  | 'aria-labelledby'\n  | 'aria-describedby'\n  | 'aria-rowcount'\n  | 'className'\n  | 'style'\n>;\ndeclare type DefaultColumnOptions<R, SR> = Pick<\n  Column<R, SR>,\n  | 'renderCell'\n  | 'width'\n  | 'minWidth'\n  | 'maxWidth'\n  | 'resizable'\n  | 'sortable'\n  | 'draggable'\n>;\n\ntype Direction = 'ltr' | 'rtl';\n\n/**\n * Полная копия типа \"DataGridProps\" из react-data-grid. Скопирован для того, чтобы API в Story проинициализировался\n */\nexport interface DataGridPropsDefault<R, SR = unknown, K extends Key = Key>\n  extends SharedDivProps {\n  /**\n   * Grid and data Props\n   */\n  /** An array of objects representing each column on the grid */\n  columns: readonly ColumnOrColumnGroup<R, SR>[];\n  /** A function called for each rendered row that should return a plain key/value pair object */\n  rows: readonly R[];\n  /**\n   * Rows to be pinned at the top of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  topSummaryRows?: Maybe<readonly SR[]>;\n  /**\n   * Rows to be pinned at the bottom of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  bottomSummaryRows?: Maybe<readonly SR[]>;\n  /** The getter should return a unique key for each row */\n  rowKeyGetter?: Maybe<(row: R) => K>;\n  onRowsChange?: Maybe<(rows: R[], data: RowsChangeData<R, SR>) => void>;\n  /**\n   * Dimensions props\n   */\n  /**\n   * The height of each row in pixels\n   * @default 35\n   */\n  rowHeight?: Maybe<number | ((row: R) => number)>;\n  /**\n   * The height of the header row in pixels\n   * @default 35\n   */\n  headerRowHeight?: Maybe<number>;\n  /**\n   * The height of each summary row in pixels\n   * @default 35\n   */\n  summaryRowHeight?: Maybe<number>;\n  /**\n   * Feature props\n   */\n  /** Set of selected row keys */\n  selectedRows?: Maybe<ReadonlySet<K>>;\n  /** Function called whenever row selection is changed */\n  onSelectedRowsChange?: Maybe<(selectedRows: Set<K>) => void>;\n  /** Used for multi column sorting */\n  sortColumns?: Maybe<readonly SortColumn[]>;\n  onSortColumnsChange?: Maybe<(sortColumns: SortColumn[]) => void>;\n  defaultColumnOptions?: Maybe<DefaultColumnOptions<R, SR>>;\n  onFill?: Maybe<(event: FillEvent<R>) => R>;\n  onCopy?: Maybe<(event: CopyEvent<R>) => void>;\n  onPaste?: Maybe<(event: PasteEvent<R>) => R>;\n  /**\n   * Event props\n   */\n  /** Function called whenever a cell is clicked */\n  onCellClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is double clicked */\n  onCellDoubleClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is right clicked */\n  onCellContextMenu?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  onCellKeyDown?: Maybe<\n    (args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) => void\n  >;\n  /** Function called whenever cell selection is changed */\n  onSelectedCellChange?: Maybe<(args: CellSelectArgs<R, SR>) => void>;\n  /** Called when the grid is scrolled */\n  onScroll?: Maybe<(event: React.UIEvent<HTMLDivElement>) => void>;\n  /** Called when a column is resized */\n  onColumnResize?: Maybe<(idx: number, width: number) => void>;\n  /** Called when a column is reordered */\n  onColumnsReorder?: Maybe<\n    (sourceColumnKey: string, targetColumnKey: string) => void\n  >;\n  /**\n   * Toggles and modes\n   */\n  /** @default true */\n  enableVirtualization?: Maybe<boolean>;\n  /**\n   * Miscellaneous\n   */\n  renderers?: Maybe<Renderers<R, SR>>;\n  rowClass?: Maybe<(row: R, rowIdx: number) => Maybe<string>>;\n  /** @default 'ltr' */\n  direction?: Maybe<Direction>;\n  'data-testid'?: Maybe<string>;\n}\n\nexport type DefaultOmittedKeys =\n  | 'editable'\n  | 'sortable'\n  | 'sortDescendingFirst'\n  | 'renderGroupCell'\n  | 'renderEditCell'\n  | 'frozen'\n  | 'draggable';\n\nexport type ColumnDefaultOmitted<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> = Omit<ColumnDefault<Row, SummRow>, DefaultOmittedKeys>;\n\nexport type { CellClickArgs };\n```\n\n## TableProps\n\n```typescript\ntype TableProps<\n  FilterStateType extends ObjectForExtending,\n  RowIdType extends string | number,\n  HeaderContextValueType extends ObjectForExtending,\n  RowContextValueType extends ObjectForExtending,\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n> = {\n  /**\n   * columnConfig - Конфигурация колонок.\n   *\n   * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n   */\n  columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n  /**\n   * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n   */\n  rows: RowType[];\n  /**\n   * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n   */\n  topSummaryRows?: SummaryRowType[];\n  /**\n   * rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n   */\n  bottomSummaryRows?: SummaryRowType[];\n  /**\n   * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n   */\n  tableConfig?: Prettify<\n    TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n  >;\n  /**\n   * headerContextValue:  любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext.\n   */\n  headerContextValue?: HeaderContextValueType;\n  /**\n   * rowContextValue:  любые стейты, которые нужны в cell - кладем в rowContextValue.  И получаем доступ с помощью useRowContext.\n   */\n  rowContextValue?: RowContextValueType;\n  refTable?: Ref<DataGridHandle>;\n  refTableContainer?: React.Ref<HTMLDivElement>;\n};\n```\n\n## HeaderContextValueTypeInstance\n\n```typescript\ntype HeaderContextValueTypeInstance<\n  FilterStateType extends Record<string | number, unknown>,\n> = {\n  filters: FilterStateType | undefined;\n  setFilters: React.Dispatch<React.SetStateAction<FilterStateType>> | undefined;\n  clearedFiltersValue: FilterStateType | undefined;\n  sortState: readonly SortColumn[] | undefined;\n  setSortState:\n    | React.Dispatch<React.SetStateAction<readonly SortColumn[]>>\n    | undefined;\n  sortIsVisible: boolean;\n  setSortIsVisible: React.Dispatch<React.SetStateAction<boolean>>;\n\n  rowSize: SIZE;\n  setRowSize: React.Dispatch<React.SetStateAction<SIZE>>;\n  onRowSizeChange?: (size: SIZE) => void;\n\n  isExpandedAllRows: boolean;\n  toggleExpandAllButton: () => void;\n  activeView: ActiveViewModsType;\n  setActiveView: React.Dispatch<React.SetStateAction<ActiveViewModsType>>;\n};\n```",
      "api": [
        {
          "typeName": "ColumnDefault",
          "source": "type ColumnDefault<TRow, TSummaryRow = unknown> = {\n  /** The name of the column. By default it will be displayed in the header cell */\n  readonly name: string | ReactElement;\n  /** A unique key to distinguish each column */\n  readonly key: string;\n  /** Column width. If not specified, it will be determined automatically based on grid width and specified widths of other columns */\n  readonly width?: Maybe<number | string>;\n  /** Minimum column width in px. */\n  readonly minWidth?: Maybe<number>;\n  /** Maximum column width in px. */\n  readonly maxWidth?: Maybe<number>;\n  readonly cellClass?: Maybe<string | ((row: TRow) => Maybe<string>)>;\n  readonly headerCellClass?: Maybe<string>;\n  readonly summaryCellClass?: Maybe<\n    string | ((row: TSummaryRow) => Maybe<string>)\n  >;\n  /** Render function used to render the content of the column's header cell */\n  readonly renderHeaderCell?: Maybe<\n    (props: RenderHeaderCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of cells */\n  readonly renderCell?: Maybe<\n    (props: RenderCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of summary cells */\n  readonly renderSummaryCell?: Maybe<\n    (props: RenderSummaryCellProps<TSummaryRow, TRow>) => ReactNode\n  >;\n  /** Render function used to render the content of group cells */\n  readonly renderGroupCell?: Maybe<\n    (props: RenderGroupCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of edit cells. When set, the column is automatically set to be editable */\n  readonly renderEditCell?: Maybe<\n    (props: RenderEditCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Enables cell editing. If set and no editor property specified, then a textInput will be used as the cell editor */\n  readonly editable?: Maybe<boolean | ((row: TRow) => boolean)>;\n  readonly colSpan?: Maybe<\n    (args: ColSpanArgs<TRow, TSummaryRow>) => Maybe<number>\n  >;\n  /** Determines whether column is frozen or not */\n  readonly frozen?: Maybe<boolean>;\n  /** Enable resizing of a column */\n  readonly resizable?: Maybe<boolean>;\n  /** Enable sorting of a column */\n  readonly sortable?: Maybe<boolean>;\n  /** Enable dragging of a column */\n  readonly draggable?: Maybe<boolean>;\n  /** Sets the column sort order to be descending instead of ascending the first time the column is sorted */\n  readonly sortDescendingFirst?: Maybe<boolean>;\n  readonly editorOptions?: Maybe<{\n    /**\n     * Render the cell content in addition to the edit cell.\n     * Enable this option when the editor is rendered outside the grid, like a modal for example.\n     * By default, the cell content is not rendered when the edit cell is open.\n     * @default false\n     */\n    readonly displayCellContent?: Maybe<boolean>;\n    /** @default true */\n    readonly commitOnOutsideClick?: Maybe<boolean>;\n  }>;\n};\n\ndeclare type SharedDivProps = Pick<\n  React.HTMLAttributes<HTMLDivElement>,\n  | 'role'\n  | 'aria-label'\n  | 'aria-labelledby'\n  | 'aria-describedby'\n  | 'aria-rowcount'\n  | 'className'\n  | 'style'\n>;\ndeclare type DefaultColumnOptions<R, SR> = Pick<\n  Column<R, SR>,\n  | 'renderCell'\n  | 'width'\n  | 'minWidth'\n  | 'maxWidth'\n  | 'resizable'\n  | 'sortable'\n  | 'draggable'\n>;\n\ntype Direction = 'ltr' | 'rtl';\n\n/**\n * Полная копия типа \"DataGridProps\" из react-data-grid. Скопирован для того, чтобы API в Story проинициализировался\n */\nexport interface DataGridPropsDefault<R, SR = unknown, K extends Key = Key>\n  extends SharedDivProps {\n  /**\n   * Grid and data Props\n   */\n  /** An array of objects representing each column on the grid */\n  columns: readonly ColumnOrColumnGroup<R, SR>[];\n  /** A function called for each rendered row that should return a plain key/value pair object */\n  rows: readonly R[];\n  /**\n   * Rows to be pinned at the top of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  topSummaryRows?: Maybe<readonly SR[]>;\n  /**\n   * Rows to be pinned at the bottom of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  bottomSummaryRows?: Maybe<readonly SR[]>;\n  /** The getter should return a unique key for each row */\n  rowKeyGetter?: Maybe<(row: R) => K>;\n  onRowsChange?: Maybe<(rows: R[], data: RowsChangeData<R, SR>) => void>;\n  /**\n   * Dimensions props\n   */\n  /**\n   * The height of each row in pixels\n   * @default 35\n   */\n  rowHeight?: Maybe<number | ((row: R) => number)>;\n  /**\n   * The height of the header row in pixels\n   * @default 35\n   */\n  headerRowHeight?: Maybe<number>;\n  /**\n   * The height of each summary row in pixels\n   * @default 35\n   */\n  summaryRowHeight?: Maybe<number>;\n  /**\n   * Feature props\n   */\n  /** Set of selected row keys */\n  selectedRows?: Maybe<ReadonlySet<K>>;\n  /** Function called whenever row selection is changed */\n  onSelectedRowsChange?: Maybe<(selectedRows: Set<K>) => void>;\n  /** Used for multi column sorting */\n  sortColumns?: Maybe<readonly SortColumn[]>;\n  onSortColumnsChange?: Maybe<(sortColumns: SortColumn[]) => void>;\n  defaultColumnOptions?: Maybe<DefaultColumnOptions<R, SR>>;\n  onFill?: Maybe<(event: FillEvent<R>) => R>;\n  onCopy?: Maybe<(event: CopyEvent<R>) => void>;\n  onPaste?: Maybe<(event: PasteEvent<R>) => R>;\n  /**\n   * Event props\n   */\n  /** Function called whenever a cell is clicked */\n  onCellClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is double clicked */\n  onCellDoubleClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is right clicked */\n  onCellContextMenu?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  onCellKeyDown?: Maybe<\n    (args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) => void\n  >;\n  /** Function called whenever cell selection is changed */\n  onSelectedCellChange?: Maybe<(args: CellSelectArgs<R, SR>) => void>;\n  /** Called when the grid is scrolled */\n  onScroll?: Maybe<(event: React.UIEvent<HTMLDivElement>) => void>;\n  /** Called when a column is resized */\n  onColumnResize?: Maybe<(idx: number, width: number) => void>;\n  /** Called when a column is reordered */\n  onColumnsReorder?: Maybe<\n    (sourceColumnKey: string, targetColumnKey: string) => void\n  >;\n  /**\n   * Toggles and modes\n   */\n  /** @default true */\n  enableVirtualization?: Maybe<boolean>;\n  /**\n   * Miscellaneous\n   */\n  renderers?: Maybe<Renderers<R, SR>>;\n  rowClass?: Maybe<(row: R, rowIdx: number) => Maybe<string>>;\n  /** @default 'ltr' */\n  direction?: Maybe<Direction>;\n  'data-testid'?: Maybe<string>;\n}\n\nexport type DefaultOmittedKeys =\n  | 'editable'\n  | 'sortable'\n  | 'sortDescendingFirst'\n  | 'renderGroupCell'\n  | 'renderEditCell'\n  | 'frozen'\n  | 'draggable';\n\nexport type ColumnDefaultOmitted<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> = Omit<ColumnDefault<Row, SummRow>, DefaultOmittedKeys>;\n\nexport type { CellClickArgs };"
        },
        {
          "typeName": "TableProps",
          "source": "type TableProps<\n  FilterStateType extends ObjectForExtending,\n  RowIdType extends string | number,\n  HeaderContextValueType extends ObjectForExtending,\n  RowContextValueType extends ObjectForExtending,\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n> = {\n  /**\n   * columnConfig - Конфигурация колонок.\n   *\n   * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n   */\n  columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n  /**\n   * rows - данные для таблицы."
        },
        {
          "typeName": "HeaderContextValueTypeInstance",
          "source": "type HeaderContextValueTypeInstance<\n  FilterStateType extends Record<string | number, unknown>,\n> = {\n  filters: FilterStateType | undefined;\n  setFilters: React.Dispatch<React.SetStateAction<FilterStateType>> | undefined;\n  clearedFiltersValue: FilterStateType | undefined;\n  sortState: readonly SortColumn[] | undefined;\n  setSortState:\n    | React.Dispatch<React.SetStateAction<readonly SortColumn[]>>\n    | undefined;\n  sortIsVisible: boolean;\n  setSortIsVisible: React.Dispatch<React.SetStateAction<boolean>>;\n\n  rowSize: SIZE;\n  setRowSize: React.Dispatch<React.SetStateAction<SIZE>>;\n  onRowSizeChange?: (size: SIZE) => void;\n\n  isExpandedAllRows: boolean;\n  toggleExpandAllButton: () => void;\n  activeView: ActiveViewModsType;\n  setActiveView: React.Dispatch<React.SetStateAction<ActiveViewModsType>>;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "CustomRenderCell",
          "displayName": "Кастомизация рендера ячейки",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n({ rows, columnConfig }) => (\n    <Table\n      tableConfig={{\n        containerStyle: { height: 700 },\n      }}\n      columnConfig={columnConfig}\n      rows={rows}\n    />\n  )"
        },
        {
          "exportName": "CustomRenderHeaderCell",
          "displayName": "Кастомизация рендера заголовка колонки",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n({ rows, columnConfig }) => (\n    <Table\n      tableConfig={{\n        containerStyle: { height: 700 },\n      }}\n      columnConfig={columnConfig}\n      rows={rows}\n    />\n  )"
        },
        {
          "exportName": "Summary",
          "displayName": "ID",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n        {\n          key: 'total',\n          name: 'Сумма title и priority',\n          renderCell: ({ row }) => `${row.task} ${row.priority}`,\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          enableVirtualization: false,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "CellContext",
          "displayName": "Работа с контекстом в кастомных ячейках",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n({ rows, columnConfig }) => {\n    const [checked, setChecked] = useState(false);\n\n    const rowContextValue = useMemo<ICheckboxCtx>(\n      () => ({\n        checkbox: [checked, setChecked],\n      }),\n      [checked, setChecked],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n        rowContextValue={rowContextValue}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "domMetadata",
      "legacy": true,
      "summary": "Data-атрибуты для автотестов и аналитики",
      "docs": "# DomMetadata\n\n## Ключевые особенности\n\n- Data-атрибуты для автотестов и аналитики\n- CSS-классы для элементов таблицы и фич\n- Поддержка action metadata для интерактивных элементов\n\n**Метки для автоматизированного тестирования, аналитики и онбординга**\n\n`DomMetadata` позволяет навешивать CSS-классы, data-атрибуты и обработчики кликов на интерактивные элементы таблицы.\nЭто нужно для:\n\n- **Аналитики** — трекинг кликов по кнопкам таблицы\n- **Автотестов** — поиск элементов по `data-testid`\n- **Онбординга** — привязка подсказок к конкретным элементам\n\n## Поддерживаемые элементы (className, dataAttributes)\n\nСледующие элементы поддерживают `className` и `dataAttributes` через `domMetadata`:\n\n**Control Block (панель управления):**\n\n- **Редактирование** — `tableConfig.editing.domMetadata`\n- **Полноэкранный режим** — `tableConfig.fullScreenEnabled.domMetadata`\n- **Размер строки** — `tableConfig.rowSize.domMetadata`\n- **Переключение вида** (строки/карточки) — `tableConfig.view.domMetadata`\n- **Группировка строк** — `tableConfig.rowsGrouping.domMetadata`\n- **Поиск** — `tableConfig.searching.domMetadata`\n- **Итоговые строки** — `tableConfig.summaryRows.domMetadata`\n- **KeyText** (controlBlock) — `tableConfig.keyText.controlBlock.domMetadata`\n- **KeyText** (sidebar) — `tableConfig.keyText.sidebar.domMetadata`\n\n**Selecting (выбор строк):**\n\n- **Чекбокс \"Выбрать все\"** (controlBlock) — `tableConfig.selecting.controlBlock.domMetadata`\n- **Свитч в сайдбаре** — `tableConfig.selecting.sidebar.domMetadata`\n\n**Sidebar (правая панель):**\n\n- **Табы сайдбара** — `tableConfig.sidebarConfig.defaultTabs[].domMetadata`\n- **Подтабы настроек** (Фильтры, Столбцы) — `tableConfig.sidebarConfig.defaultTabs[{id:'filtering'|'columns'}].domMetadata`\n\n**Другие:**\n\n- **Кнопка сворачивания таблицы** — `tableConfig.collapse.domMetadata`\n\n## Элементы с расширенным onClick (className, dataAttributes, onClick + detail)\n\nВ дополнение к `className` и `dataAttributes`, следующие элементы поддерживают `onClick` с контекстом `detail`:\n\n- **Группировать** (чекбоксы, сброс) — `tableConfig.rowsGrouping.domMetadata` — actions: `toggle-group`, `reset-groups`, `custom-item-select`\n- **Кнопка размера строки** — `tableConfig.rowSize.domMetadata` — action: `change-row-size`\n- **Шестеренка настроек** — `tableConfig.sidebarConfig.defaultTabs[{id:'tableSettings'}].domMetadata` — action: `toggle-sidebar-tab`\n- **Крестик закрыть сайдбар** — тот же `domMetadata` таба — action: `close-sidebar`\n- **Закрепить столбец** — `tableConfig.columnsControl.pinDomMetadata` — actions: `pin-column`, `unpin-column`\n- **Свитчер видимости столбца** — `tableConfig.columnsControl.switchDomMetadata` — actions: `show-column`, `hide-column`\n\n## onClick\n\nОбработчик `onClick` вызывается **после** основной логики элемента. Он не мешает работе кнопки и не вызывает `stopPropagation`.\n\n```tsx\nonClick?: (\n  e?: React.MouseEvent<HTMLElement>,  // MouseEvent (undefined для элементов внутри Dropdown)\n  detail?: Record<string, unknown>     // контекст: action, columnKey, size и др.\n) => void;\n```\n\n### Примеры detail\n\n```ts\n// Группировка\n{ action: 'toggle-group', columnKey: 'status' }\n{ action: 'reset-groups' }\n\n// Размер строки\n{ action: 'change-row-size', size: 'medium' }\n\n// Сайдбар\n{ action: 'toggle-sidebar-tab', tabId: 'tableSettings' }\n{ action: 'close-sidebar' }\n\n// Столбцы\n{ action: 'pin-column', columnKey: 'name' }\n{ action: 'unpin-column', columnKey: 'name' }\n{ action: 'hide-column', columnKey: 'name' }\n{ action: 'show-column', columnKey: 'name' }\n```\n\nПодробнее о типах — в разделе [API](?path=/docs/локальные-компоненты-table-dommetadata-api--docs).",
      "apiDocs": "# DomMetadata API\n\n## DomMetadata\n\n```typescript\ntype DomMetadata = {\n  /**\n   * CSS класс для стилизации и поиска элемента\n   *\n   * @example 'user-profile-card'\n   * @example 'onboarding-step-1'\n   */\n  className?: string;\n  /**\n   * Data-атрибуты для тестирования, аналитики и онбординга\n   *\n   * @example { 'data-testid': 'submit-button', 'data-analytics': 'click-event' }\n   */\n  dataAttributes?: DataAttributes;\n  /**\n   * Обработчик клика для аналитики и трекинга\n   *\n   * Вызывается вместе с основным обработчиком элемента (не заменяет его).\n   * Не вызывает stopPropagation — оригинальная логика кнопки сохраняется.\n   *\n   * @param e - MouseEvent (может быть undefined для элементов внутри Dropdown)\n   * @param detail - контекст действия: action, columnKey, size и др.\n   *\n   * @example onClick: (e, detail) => analytics.track(detail?.action, detail)\n   */\n  onClick?: (\n    e?: React.MouseEvent<HTMLElement>,\n    detail?: Record<string, unknown>,\n  ) => void;\n};\n```\n\n## DOM_METADATA_ACTIONS\n\n```typescript\nexport const DOM_METADATA_ACTIONS = {\n  /** Включение/выключение группировки по столбцу. detail.columnKey — ключ столбца */\n  TOGGLE_GROUP: 'toggle-group',\n  /** Сброс всех группировок */\n  RESET_GROUPS: 'reset-groups',\n  /** Выбор пункта в кастомном onItemSelect группировки. detail.columnKey — ключ */\n  CUSTOM_ITEM_SELECT: 'custom-item-select',\n  /** Переключение размера строки. detail.size — новый размер ('small' | 'medium' | 'big') */\n  CHANGE_ROW_SIZE: 'change-row-size',\n  /** Клик по табу сайдбара (шестерёнка и др.). detail.tabId — id таба */\n  TOGGLE_SIDEBAR_TAB: 'toggle-sidebar-tab',\n  /** Закрытие сайдбара (крестик) */\n  CLOSE_SIDEBAR: 'close-sidebar',\n  /** Закрепление столбца. detail.columnKey — ключ столбца */\n  PIN_COLUMN: 'pin-column',\n  /** Открепление столбца. detail.columnKey — ключ столбца */\n  UNPIN_COLUMN: 'unpin-column',\n  /** Скрытие столбца. detail.columnKey — ключ столбца */\n  HIDE_COLUMN: 'hide-column',\n  /** Показ столбца. detail.columnKey — ключ столбца */\n  SHOW_COLUMN: 'show-column',\n} as const;\n```\n\n## DomMetadataAction\n\n```typescript\ntype DomMetadataAction =\n  (typeof DOM_METADATA_ACTIONS)[keyof typeof DOM_METADATA_ACTIONS];\n```\n\n## ColumnsControlConfig\n\n```typescript\ntype ColumnsControlConfig = {\n  enable: boolean;\n  /**\n   * @default enable\n   */\n  hiding?: boolean;\n  /**\n   * @default enable\n   */\n  pinning?: boolean;\n  /**\n   * @default enable\n   */\n  reorderingAside?: boolean;\n  /**\n   * reorderingHeader  - активация изменения порядка колонок  посредством перемещения шапок колонок таблицы\n   */\n  /**\n   * @default enable\n   */\n  reorderingHeader?: boolean;\n  onReorderingHeader?: (params: {\n    newOrder: string[];\n    sourceKey: string;\n    targetKey: string;\n  }) => void;\n\n  columnsLabel?: Record<\n    string,\n    ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n  >;\n\n  orderDefault?: string[];\n\n  pinnedDefault?: string[];\n  disablePinning?: string[];\n\n  hiddenDefault?: string[];\n  disableHiding?: string[];\n\n  onConfirm?: (\n    params: {\n      pinned: string[];\n      order: string[];\n      hidden: string[];\n      changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n    },\n    setters: {\n      setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n      setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n      setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n    },\n  ) => void;\n  /**\n   * DomMetadata для кнопок закрепления столбцов\n   */\n  pinDomMetadata?: DomMetadata;\n  /**\n   * DomMetadata для свитчеров скрытия/показа столбцов\n   */\n  switchDomMetadata?: DomMetadata;\n};\n```",
      "api": [
        {
          "typeName": "DomMetadata",
          "source": "type DomMetadata = {\n  /**\n   * CSS класс для стилизации и поиска элемента\n   *\n   * @example 'user-profile-card'\n   * @example 'onboarding-step-1'\n   */\n  className?: string;\n  /**\n   * Data-атрибуты для тестирования, аналитики и онбординга\n   *\n   * @example { 'data-testid': 'submit-button', 'data-analytics': 'click-event' }\n   */\n  dataAttributes?: DataAttributes;\n  /**\n   * Обработчик клика для аналитики и трекинга\n   *\n   * Вызывается вместе с основным обработчиком элемента (не заменяет его).\n   * Не вызывает stopPropagation — оригинальная логика кнопки сохраняется.\n   *\n   * @param e - MouseEvent (может быть undefined для элементов внутри Dropdown)\n   * @param detail - контекст действия: action, columnKey, size и др.\n   *\n   * @example onClick: (e, detail) => analytics.track(detail?.action, detail)\n   */\n  onClick?: (\n    e?: React.MouseEvent<HTMLElement>,\n    detail?: Record<string, unknown>,\n  ) => void;\n};"
        },
        {
          "typeName": "Unknown",
          "source": "export const DOM_METADATA_ACTIONS = {\n  /** Включение/выключение группировки по столбцу. detail.columnKey — ключ столбца */\n  TOGGLE_GROUP: 'toggle-group',\n  /** Сброс всех группировок */\n  RESET_GROUPS: 'reset-groups',\n  /** Выбор пункта в кастомном onItemSelect группировки. detail.columnKey — ключ */\n  CUSTOM_ITEM_SELECT: 'custom-item-select',\n  /** Переключение размера строки. detail.size — новый размер ('small' | 'medium' | 'big') */\n  CHANGE_ROW_SIZE: 'change-row-size',\n  /** Клик по табу сайдбара (шестерёнка и др.). detail.tabId — id таба */\n  TOGGLE_SIDEBAR_TAB: 'toggle-sidebar-tab',\n  /** Закрытие сайдбара (крестик) */\n  CLOSE_SIDEBAR: 'close-sidebar',\n  /** Закрепление столбца. detail.columnKey — ключ столбца */\n  PIN_COLUMN: 'pin-column',\n  /** Открепление столбца. detail.columnKey — ключ столбца */\n  UNPIN_COLUMN: 'unpin-column',\n  /** Скрытие столбца. detail.columnKey — ключ столбца */\n  HIDE_COLUMN: 'hide-column',\n  /** Показ столбца. detail.columnKey — ключ столбца */\n  SHOW_COLUMN: 'show-column',\n} as const;"
        },
        {
          "typeName": "DomMetadataAction",
          "source": "type DomMetadataAction =\n  (typeof DOM_METADATA_ACTIONS)[keyof typeof DOM_METADATA_ACTIONS];"
        },
        {
          "typeName": "ColumnsControlConfig",
          "source": "type ColumnsControlConfig = {\n  enable: boolean;\n  /**\n   * @default enable\n   */\n  hiding?: boolean;\n  /**\n   * @default enable\n   */\n  pinning?: boolean;\n  /**\n   * @default enable\n   */\n  reorderingAside?: boolean;\n  /**\n   * reorderingHeader  - активация изменения порядка колонок  посредством перемещения шапок колонок таблицы\n   */\n  /**\n   * @default enable\n   */\n  reorderingHeader?: boolean;\n  onReorderingHeader?: (params: {\n    newOrder: string[];\n    sourceKey: string;\n    targetKey: string;\n  }) => void;\n\n  columnsLabel?: Record<\n    string,\n    ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n  >;\n\n  orderDefault?: string[];\n\n  pinnedDefault?: string[];\n  disablePinning?: string[];\n\n  hiddenDefault?: string[];\n  disableHiding?: string[];\n\n  onConfirm?: (\n    params: {\n      pinned: string[];\n      order: string[];\n      hidden: string[];\n      changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n    },\n    setters: {\n      setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n      setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n      setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n    },\n  ) => void;\n  /**\n   * DomMetadata для кнопок закрепления столбцов\n   */\n  pinDomMetadata?: DomMetadata;\n  /**\n   * DomMetadata для свитчеров скрытия/показа столбцов\n   */\n  switchDomMetadata?: DomMetadata;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "DomMetadataOnClick",
          "displayName": "onClick для аналитики",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n    const [groupedCols, setGroupedCols] = useState<string[]>([]);\n    const [filters, setFilters] = useState({});\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          rowsGrouping: { columnGroupLabel: 'ID' },\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          rowsGrouping: { columnGroupLabel: 'Title' },\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          rowsGrouping: { columnGroupLabel: 'Priority' },\n        },\n      ],\n      [],\n    );\n\n    // Общий обработчик для аналитики.\n    // e — MouseEvent (undefined для элементов внутри Dropdown).\n    // detail — контекст: action, columnKey, size и др.\n    // detail.action — одна из констант DOM_METADATA_ACTIONS\n    const handleDomMetadataClick = (\n      source: string,\n      e?: React.MouseEvent<HTMLElement>,\n      detail?: Record<string, unknown>,\n    ) => {\n      // Пример: проверка конкретного действия через константу\n      if (detail?.action === DOM_METADATA_ACTIONS.TOGGLE_GROUP) {\n        console.debug(\n          `[DomMetadata] Группировка по столбцу: ${detail.columnKey}`,\n        );\n      }\n      console.debug(`[DomMetadata] ${source}:`, {\n        detail,\n        target: e?.currentTarget,\n      });\n    };\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n\n          // 1. Группировка строк\n          // detail.action: 'toggle-group' | 'reset-groups' | 'custom-item-select'\n          // detail.columnKey: ключ столбца (для toggle-group и custom-item-select)\n          rowsGrouping: {\n            groupByState: [groupedCols, setGroupedCols],\n            rowKeyGetter: (row) => row.id.toString(),\n            domMetadata: {\n              className: 'analytics-grouping',\n              dataAttributes: { 'data-feature': 'grouping' },\n              onClick: (e, detail) =>\n                handleDomMetadataClick('rowsGrouping', e, detail),\n            },\n          },\n\n          // 2. Кнопка размера строки\n          // detail.action: 'change-row-size'\n          // detail.size: новый размер ('small' | 'medium' | 'big')\n          rowSize: {\n            showInControl: true,\n            default: 'small',\n            available: ['small', 'medium', 'big'],\n            domMetadata: {\n              className: 'analytics-row-size',\n              dataAttributes: { 'data-feature': 'row-size' },\n              onClick: (e, detail) =>\n                handleDomMetadataClick('rowSize', e, detail),\n            },\n          },\n\n          // 3. Настройки столбцов: закрепление и видимость\n          // pinDomMetadata — detail.action: 'pin-column' | 'unpin-column', detail.columnKey\n          // switchDomMetadata — detail.action: 'show-column' | 'hide-column', detail.columnKey\n          columnsControl: {\n            enable: true,\n            pinDomMetadata: {\n              className: 'analytics-pin',\n              dataAttributes: { 'data-feature': 'pin-column' },\n              onClick: (e, detail) =>\n                handleDomMetadataClick('pinColumn', e, detail),\n            },\n            switchDomMetadata: {\n              className: 'analytics-switch',\n              dataAttributes: { 'data-feature': 'column-visibility' },\n              onClick: (e, detail) =>\n                handleDomMetadataClick('columnVisibility', e, detail),\n            },\n          },\n\n          // 4. Таб настроек сайдбара (шестерёнка + крестик закрыть)\n          // detail.action: 'toggle-sidebar-tab' (шестерёнка) | 'close-sidebar' (крестик)\n          // detail.tabId: id таба (для toggle-sidebar-tab)\n          sidebarConfig: {\n            defaultTabs: [\n              {\n                id: 'tableSettings',\n                domMetadata: {\n                  className: 'analytics-settings',\n                  dataAttributes: { 'data-feature': 'settings' },\n                  onClick: (e, detail) =>\n                    handleDomMetadataClick('settings', e, detail),\n                },\n              },\n            ],\n          },\n\n          filtering: {\n            state: [filters, setFilters],\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "editing",
      "legacy": true,
      "summary": "Редактирование ячеек через columnConfig.editing",
      "docs": "# TableEditing\n\n## Ключевые особенности\n\n- Редактирование ячеек через columnConfig.editing\n- Управление изменением строк через tableConfig.editing\n- Поддержка input, number и select editor-ов\n\nТаблица поддерживает редактирование.\n\nУсловие активации - наличие свойства `editing` в `tableConfig` или, если есть `tableConfig.editing.defaultEnabled`, то значение `tableConfig.editing.defaultEnabled`.\n\nПомимо этого также необходимо сконфигурировать колонки.\n\n**tableConfig.editing**\n\n**columnConfig.editingCell**\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-editing-api--docs).",
      "apiDocs": "# Editing API\n\n## EditingConfig\n\n```typescript\ntype EditingConfig<RowType, RowIdType, SummaryRowType> = {\n  /**\n   * Функция обработки изменений в редактируемой строке\n   */\n  onRowsChange: Maybe<\n    (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n  >;\n  /**\n   * свойство, необходимое для корректного изменения дочерних строк.\n   * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n   *\n   * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n   * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n   *\n   * @example \"child\" или \"uvh367.children\"\n   */\n  subRowsKey?: string;\n  /**\n   * Функция определения уникального id строки\n   * @param row\n   * @returns\n   */\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * Функция определения возможности редактирования строки\n   * @param row\n   * @returns\n   */\n  rowEditable?: (row: RowType) => boolean;\n  /**\n   * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n   * @default false\n   */\n  defaultEnabled?: boolean;\n  /**\n   * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n   * По умолчанию, управление происходит в компоненте.\n   * Приоритетнее, чем defaultEnabled.\n   *\n   * @type boolean - если НЕ нужно переключение в самой таблице\n   * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n   *\n   */\n  enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n   * @default true\n   */\n  showToggleEnabledButton?: boolean;\n  /**\n   * Функция, вызывающаяся при включении/выключении фичи\n   * @param editingIsActive\n   * @returns\n   */\n  onToggleEnableEditing?: (editingIsActive: boolean) => void;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n```\n\n## Editing\n\n```typescript\ntype Editing<RowType extends ObjectForExtending> = {\n  /**\n   * Если `error.value(row) === true`, то у ячейки появляется красная рамка\n   */\n  error?: { value: (row: RowType, treeLevel: number) => boolean };\n  editedSuccessfully?: { value: (row: RowType, treeLevel: number) => boolean };\n  /**\n   * Функция для определения возможности редактирования  ячейки на основе данных строки (приоритетнее, чем rowEditable в tableConfig.editing)\n   */\n  editable?: ((row: RowType) => boolean) | boolean;\n} & (\n  | {\n      component: 'inputString';\n      /**\n       * Дополнительные пропсы для компонента TextField в редактировании\n       * @example { placeholder: \"Введите текст\"}\n       */\n      inputProps?: Partial<\n        Omit<TextFieldProps, 'value' | 'onChange' | 'onBlur' | 'ref' | 'size'>\n      >;\n    }\n  | {\n      component: 'inputNumber';\n      /**\n       * Дополнительные пропсы для компонента NumberFormat в редактировании\n       * @example { placeholder: \"Введите текст\"}\n       */\n      inputProps?: Partial<\n        Omit<\n          ComponentProps<typeof NumberFormat>,\n          'value' | 'onChange' | 'onBlur' | 'ref' | 'size'\n        >\n      >;\n    }\n  | {\n      component: 'select';\n      options: {\n        type: 'constant';\n        options: SelectOptions[];\n      };\n      /**\n       * Дополнительные пропсы для компонента Combobox в редактировании\n       * @example { listMaxHeight: \"100px\"}\n       */\n      selectProps?: Partial<\n        Omit<\n          ComponentProps<typeof Combobox>,\n          'value' | 'onChange' | 'items' | 'ref' | 'size' | 'portal'\n        >\n      >;\n    }\n  | {\n      component: 'select';\n\n      options: {\n        type: 'stateInRowContext';\n        /**\n         * тип optionsState, который будет в RowContext:\n         * ```ts\n         * options: {\n         * value: string | number;\n         * text: string | number;\n         * }[];\n         * ```\n         */\n        optionsKeyInRowContext: string;\n      };\n    }\n  | {\n      /**\n       * Кастомный рендер ячейки редактирования\n       */\n      component: RenderSubRowEditCell<RowType>;\n    }\n);\n```",
      "api": [
        {
          "typeName": "EditingConfig",
          "source": "type EditingConfig<RowType, RowIdType, SummaryRowType> = {\n  /**\n   * Функция обработки изменений в редактируемой строке\n   */\n  onRowsChange: Maybe<\n    (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n  >;\n  /**\n   * свойство, необходимое для корректного изменения дочерних строк.\n   * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n   *\n   * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n   * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n   *\n   * @example \"child\" или \"uvh367.children\"\n   */\n  subRowsKey?: string;\n  /**\n   * Функция определения уникального id строки\n   * @param row\n   * @returns\n   */\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * Функция определения возможности редактирования строки\n   * @param row\n   * @returns\n   */\n  rowEditable?: (row: RowType) => boolean;\n  /**\n   * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n   * @default false\n   */\n  defaultEnabled?: boolean;\n  /**\n   * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n   * По умолчанию, управление происходит в компоненте.\n   * Приоритетнее, чем defaultEnabled.\n   *\n   * @type boolean - если НЕ нужно переключение в самой таблице\n   * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n   *\n   */\n  enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n   * @default true\n   */\n  showToggleEnabledButton?: boolean;\n  /**\n   * Функция, вызывающаяся при включении/выключении фичи\n   * @param editingIsActive\n   * @returns\n   */\n  onToggleEnableEditing?: (editingIsActive: boolean) => void;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};"
        },
        {
          "typeName": "Editing",
          "source": "type Editing<RowType extends ObjectForExtending> = {\n  /**\n   * Если `error.value(row) === true`, то у ячейки появляется красная рамка\n   */\n  error?: { value: (row: RowType, treeLevel: number) => boolean };\n  editedSuccessfully?: { value: (row: RowType, treeLevel: number) => boolean };\n  /**\n   * Функция для определения возможности редактирования  ячейки на основе данных строки (приоритетнее, чем rowEditable в tableConfig.editing)\n   */\n  editable?: ((row: RowType) => boolean) | boolean;\n} & (\n  | {\n      component: 'inputString';\n      /**\n       * Дополнительные пропсы для компонента TextField в редактировании\n       * @example { placeholder: \"Введите текст\"}\n       */\n      inputProps?: Partial<\n        Omit<TextFieldProps, 'value' | 'onChange' | 'onBlur' | 'ref' | 'size'>\n      >;\n    }\n  | {\n      component: 'inputNumber';\n      /**\n       * Дополнительные пропсы для компонента NumberFormat в редактировании\n       * @example { placeholder: \"Введите текст\"}\n       */\n      inputProps?: Partial<\n        Omit<\n          ComponentProps<typeof NumberFormat>,\n          'value' | 'onChange' | 'onBlur' | 'ref' | 'size'\n        >\n      >;\n    }\n  | {\n      component: 'select';\n      options: {\n        type: 'constant';\n        options: SelectOptions[];\n      };\n      /**\n       * Дополнительные пропсы для компонента Combobox в редактировании\n       * @example { listMaxHeight: \"100px\"}\n       */\n      selectProps?: Partial<\n        Omit<\n          ComponentProps<typeof Combobox>,\n          'value' | 'onChange' | 'items' | 'ref' | 'size' | 'portal'\n        >\n      >;\n    }\n  | {\n      component: 'select';\n\n      options: {\n        type: 'stateInRowContext';\n        /**\n         * тип optionsState, который будет в RowContext:\n         *"
        }
      ],
      "stories": [
        {
          "exportName": "Editing",
          "displayName": "Блок",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows, setRows] = useState(() => createRowsTree());\n\n    const columns = useMemo(\n      (): readonly ColumnConfig<TreeRow>[] => [\n        {\n          key: 'block',\n          name: 'Блок',\n          editingCell: {\n            editable: (r) => r.block === BLOCKS[1],\n            error: {\n              value: (r) => r.block === BLOCKS[0],\n            },\n            component: 'select',\n            options: {\n              type: 'constant',\n              options: BLOCKS.map((i) => ({ text: i, value: i })),\n            },\n          },\n          subRow: {\n            keyOfColumnInSubRow: (lvl) => {\n              switch (lvl) {\n                case 0:\n                  return 'block';\n                case 1:\n                  return 'tribe';\n                case 2:\n                  return 'product';\n                default:\n                  return 'block';\n              }\n            },\n            editingCell: {\n              component: 'inputString',\n              inputProps: {\n                placeholder: 'Введите значение',\n              },\n            },\n\n            isColumnWithArrow: true,\n            hideHeaderExpandAllArrow: false,\n          },\n          resizable: true,\n        },\n        {\n          key: 'blockActivity',\n          name: 'Активность блока',\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'tribe',\n          name: 'Трайб',\n          editingCell: {\n            component: 'select',\n            options: {\n              type: 'stateInRowContext',\n              optionsKeyInRowContext: 'tribeOptions',\n            },\n            selectProps: {\n              listMaxHeight: '210px',\n            },\n          },\n        },\n        {\n          key: 'product',\n          name: 'Продукт',\n          editingCell: {\n            component: 'select',\n            options: {\n              type: 'stateInRowContext',\n              optionsKeyInRowContext: 'productOptions',\n            },\n          },\n        },\n        {\n          key: 'q1',\n          name: 'Q1',\n          editingCell: {\n            component: 'inputNumber',\n            inputProps: {\n              placeholder: 'Введите значение',\n            },\n          },\n          contentFormat: {\n            type: 'number',\n            decimalSeparator: ',',\n            thousandSeparator: ' ',\n            alignContent: 'right',\n            minimumFractionDigits: 2,\n            maximumFractionDigits: 2,\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n        {\n          key: 'q2',\n          name: 'Q2',\n          editingCell: {\n            component: ({ row, onRowChange, onClose }) => {\n              const { rowSize } = useRowContext();\n\n              return (\n                <TextField\n                  ref={autoFocusAndSelect}\n                  value={row.q2}\n                  type=\"number\"\n                  size={SIZES[rowSize].input}\n                  onChange={(e) => {\n                    onRowChange({\n                      ...row,\n                      q2: +e.target.value,\n                    });\n                  }}\n                  onBlur={() => onClose(true, false)}\n                />\n              );\n            },\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'q2',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n        {\n          key: 'q3',\n          name: 'Q3',\n          editingCell: { component: 'inputNumber' },\n          subRow: {\n            keyOfColumnInSubRow: 'q3',\n\n            editingCell: {\n              component: 'inputNumber',\n              error: {\n                value(_row, _treeLvl) {\n                  return true;\n                },\n              },\n            },\n          },\n        },\n        {\n          key: 'q4',\n          name: 'Q4',\n          editingCell: { component: 'inputNumber' },\n          subRow: {\n            keyOfColumnInSubRow: 'q4',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n      ],\n      [],\n    );\n\n    const rowContextValue = useMemo(\n      () => ({\n        tribeOptions: TRIBES.map((i) => ({ text: i, value: i })),\n        productOptions: PRODUCTS.map((i) => ({ text: i, value: i })),\n      }),\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          fullScreenEnabled: true,\n          rowSize: {\n            showInControl: true,\n            default: 'big',\n          },\n          editing: {\n            onRowsChange: setRows,\n            rowKeyGetter: (r) => `${r.id}`,\n            rowEditable: (r) => r.block !== BLOCKS[1],\n          },\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          resizableColumn: true,\n        }}\n        columnConfig={columns}\n        rows={rows}\n        rowContextValue={rowContextValue}\n      />\n    );\n  }"
        },
        {
          "exportName": "EditingInModal",
          "displayName": "Блок",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows, setRows] = useState(() => createRowsTree());\n\n    const columns = useMemo(\n      (): readonly ColumnConfig<TreeRow>[] => [\n        {\n          key: 'block',\n          name: 'Блок',\n          editingCell: {\n            editable: (r) => r.block === BLOCKS[1],\n            error: {\n              value: (r) => r.block === BLOCKS[0],\n            },\n            component: 'select',\n            options: {\n              type: 'constant',\n              options: BLOCKS.map((i) => ({ text: i, value: i })),\n            },\n          },\n          subRow: {\n            keyOfColumnInSubRow: (lvl) => {\n              switch (lvl) {\n                case 0:\n                  return 'block';\n                case 1:\n                  return 'tribe';\n                case 2:\n                  return 'product';\n                default:\n                  return 'block';\n              }\n            },\n            editingCell: {\n              component: 'inputString',\n              inputProps: {\n                placeholder: 'Введите значение',\n              },\n            },\n\n            isColumnWithArrow: true,\n            hideHeaderExpandAllArrow: false,\n          },\n          resizable: true,\n        },\n        {\n          key: 'blockActivity',\n          name: 'Активность блока',\n          editingCell: { component: 'inputString' },\n        },\n        {\n          key: 'tribe',\n          name: 'Трайб',\n          editingCell: {\n            component: 'select',\n            options: {\n              type: 'stateInRowContext',\n              optionsKeyInRowContext: 'tribeOptions',\n            },\n            selectProps: {\n              listMaxHeight: '210px',\n            },\n          },\n        },\n        {\n          key: 'product',\n          name: 'Продукт',\n          editingCell: {\n            component: 'select',\n            options: {\n              type: 'stateInRowContext',\n              optionsKeyInRowContext: 'productOptions',\n            },\n          },\n        },\n        {\n          key: 'q1',\n          name: 'Q1',\n          editingCell: {\n            component: 'inputNumber',\n            inputProps: {\n              placeholder: 'Введите значение',\n            },\n          },\n          contentFormat: {\n            type: 'number',\n            decimalSeparator: ',',\n            thousandSeparator: ' ',\n            alignContent: 'right',\n            minimumFractionDigits: 2,\n            maximumFractionDigits: 2,\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n        {\n          key: 'q2',\n          name: 'Q2',\n          editingCell: {\n            component: ({ row, onRowChange, onClose }) => {\n              const { rowSize } = useRowContext();\n\n              return (\n                <TextField\n                  ref={autoFocusAndSelect}\n                  value={row.q2}\n                  type=\"number\"\n                  size={SIZES[rowSize].input}\n                  onChange={(e) => {\n                    onRowChange({\n                      ...row,\n                      q2: +e.target.value,\n                    });\n                  }}\n                  onBlur={() => onClose(true, false)}\n                />\n              );\n            },\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'q2',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n        {\n          key: 'q3',\n          name: 'Q3',\n          editingCell: { component: 'inputNumber' },\n          subRow: {\n            keyOfColumnInSubRow: 'q3',\n\n            editingCell: {\n              component: 'inputNumber',\n              error: {\n                value(_row, _treeLvl) {\n                  return true;\n                },\n              },\n            },\n          },\n        },\n        {\n          key: 'q4',\n          name: 'Q4',\n          editingCell: { component: 'inputNumber' },\n          subRow: {\n            keyOfColumnInSubRow: 'q4',\n            editingCell: { component: 'inputNumber' },\n          },\n        },\n      ],\n      [],\n    );\n\n    const rowContextValue = useMemo(\n      () => ({\n        tribeOptions: TRIBES.map((i) => ({ text: i, value: i })),\n        productOptions: PRODUCTS.map((i) => ({ text: i, value: i })),\n      }),\n      [],\n    );\n    const [modalOpened, setModalOpened] = useState(false);\n\n    return (\n      <ModalDF opened={modalOpened} onClose={() => setModalOpened(false)}>\n        <ModalDF.Main>\n          <ModalDF.Header />\n          <ModalDF.Content>\n            <Table\n              tableConfig={{\n                containerStyle: { height: '700px', width: '700px' },\n                fullScreenEnabled: true,\n                rowSize: {\n                  showInControl: true,\n                  default: 'big',\n                },\n                editing: {\n                  onRowsChange: setRows,\n                  rowKeyGetter: (r) => `${r.id}`,\n                  rowEditable: (r) => r.block !== BLOCKS[1],\n                },\n                subRows: {\n                  getSubRows: (row) => row?.subRows,\n                  rowKeyGetter: (row) => row.id,\n                },\n                resizableColumn: true,\n              }}\n              columnConfig={columns}\n              rows={rows}\n              rowContextValue={rowContextValue}\n            />\n          </ModalDF.Content>\n        </ModalDF.Main>\n      </ModalDF>\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "filtering",
      "legacy": true,
      "summary": "*tableConfig.filtering**",
      "docs": "# Filtering\n\n**tableConfig.filtering**\n\nФильтрация данных таблицы с поддержкой автоматического и ручного режимов.\n\n## Ключевые особенности\n\n- Три типа фильтров: `input`, `select`, `custom`\n- Автоматическая фильтрация по умолчанию, ручная через `manualFiltering: true`\n- Отображение активных фильтров в виде chip-элементов\n- Фильтрация через sidebar с настройкой порядка и глобальных фильтров\n\n## Типы фильтров\n\n### Input\n\nТекстовый фильтр с режимами: `'includes'`, `'startWith'`, `'equal'` или кастомная функция.\n\n### Select\n\nФильтр выбором из списка. Поддержка одиночного и множественного выбора.\n\n### Custom\n\nПолностью кастомный компонент фильтра через `customRender`.\n\n## Особенности\n\n- При `manualFiltering: true` таблица не фильтрует данные — ожидается внешняя логика\n- `sidebarConfig` позволяет добавлять глобальные фильтры, не привязанные к колонкам\n- `filtersInfo` задаёт лейблы и значения по умолчанию для каждого фильтра\n\n> Подробнее о типах и пропсах — [Filtering API](?path=/docs/локальные-компоненты-table-filtering-api--docs)",
      "apiDocs": "# Filtering API\n\n## FilterComponentInPopoverProps\n\nПропсы, доступные в кастомном компоненте фильтра (`component: 'custom'`).\n\n```typescript\ntype FilterComponentInPopoverProps<\n  FilterStateType extends ObjectForExtending,\n  ColumnConfig,\n> = {\n  popoverIsOpen: boolean;\n  setPopoverIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n  columnConfig: ColumnConfig;\n  tabIndex: number;\n  headerContextState: HeaderContextValueTypeInstance<FilterStateType> &\n    FiltersVariables &\n    HeaderContextValueTypeInstance<ObjectForExtending>;\n  /**\n   * Источник открытия фильтра: из шапки таблицы или из сайдбара\n   * Полезно для условной логики в customRender (например, alwaysOpened для combobox)\n   */\n  filterSource?: 'header' | 'sidebar';\n};\n```",
      "api": [
        {
          "typeName": "FilterComponentInPopoverProps",
          "source": "type FilterComponentInPopoverProps<\n  FilterStateType extends ObjectForExtending,\n  ColumnConfig,\n> = {\n  popoverIsOpen: boolean;\n  setPopoverIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n  columnConfig: ColumnConfig;\n  tabIndex: number;\n  headerContextState: HeaderContextValueTypeInstance<FilterStateType> &\n    FiltersVariables &\n    HeaderContextValueTypeInstance<ObjectForExtending>;\n  /**\n   * Источник открытия фильтра: из шапки таблицы или из сайдбара\n   * Полезно для условной логики в customRender (например, alwaysOpened для combobox)\n   */\n  filterSource?: 'header' | 'sidebar';\n};"
        }
      ],
      "stories": [
        {
          "exportName": "Filtering",
          "displayName": "ID",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(() => {\n      const seededRandom = createSeededRandom(42);\n      return createRows().map((el) => ({\n        ...el,\n        id: Math.floor(seededRandom() * 1000),\n        date: (() => {\n          const date = new Date(\n            FIXED_DATE_TIMESTAMP +\n              (Math.floor(seededRandom() * 61) - 30) * 86400000,\n          );\n          return `${String(date.getDate()).padStart(2, '0')}.${String(\n            date.getMonth() + 1,\n          ).padStart(2, '0')}.${date.getFullYear()}`;\n        })(),\n      }));\n    });\n\n    const columnConfig = useMemo<\n      readonly ColumnConfig<Row & { date: string }>[]\n    >(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          filtering: {\n            component: 'input',\n            filter: 'startWith',\n\n            valueInRow: (r) => r.id,\n            keyInFilterState: 'id',\n          },\n        },\n        {\n          key: 'date',\n          name: 'Date',\n          filtering: {\n            component: 'custom',\n            customRender: (props) => {\n              const {\n                headerContextState: { filters, setFilters },\n              } = props;\n              return (\n                <Calendar\n                  value={filters?.['date']}\n                  onChangeValue={(v) => {\n                    if (setFilters)\n                      setFilters((prev) => ({\n                        ...prev,\n                        date: v,\n                      }));\n                  }}\n                />\n              );\n            },\n            filter: (filterValue, rowValue) =>\n              filterValue ? rowValue === filterValue : true,\n            valueInRow: (r) => r.date,\n            compareWithClearedValue: (clearedValue, currV) =>\n              clearedValue === currV,\n            keyInFilterState: 'date',\n          },\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          filtering: {\n            component: 'input',\n            filter: 'includes',\n\n            valueInRow: (r) => `${r.task} ${r.id}`,\n\n            keyInFilterState: 'task',\n          },\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          filtering: {\n            component: 'select',\n            selectOptions: {\n              type: 'constant',\n              options: [\n                { value: 'All', text: 'All' },\n                { value: 'High', text: 'High' },\n                { value: 'Critical', text: 'Critical' },\n                { value: 'Medium', text: 'Medium' },\n                { value: 'Low', text: 'Low' },\n              ],\n            },\n\n            keyInFilterState: 'priority',\n            valueInRow: (r) => r.priority,\n            filter: {\n              typeOfValue: 'single',\n              filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n            },\n          },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          filtering: {\n            beforeList(props) {\n              return (\n                <TableFilterSelectListItem\n                  $size={props.headerContextState.rowSize}\n                >\n                  custom beforeList\n                </TableFilterSelectListItem>\n              );\n            },\n            component: 'select',\n            selectOptions: {\n              type: 'stateInHeaderContext',\n              optionsKeyInHeaderContext: 'issueTypeOptions',\n            },\n            keyInFilterState: 'issueType',\n            valueInRow: (r) => r.issueType,\n            filter: {\n              typeOfValue: 'multiple',\n              filteringType: (fv, rv) =>\n                !fv.length || fv.some((fvCurr) => fvCurr === rv),\n            },\n          },\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n          filtering: {\n            component: 'input',\n            keyInFilterState: 'complete',\n            valueInRow: (r) => r.complete,\n            filter: (fv, rv) => (+rv || 0) >= (+fv || 0),\n          },\n        },\n      ],\n      [],\n    );\n\n    const filteringStateAndSetter = useState({\n      id: '',\n      task: '',\n      priority: 'All',\n      issueType: [],\n      complete: '',\n      date: '',\n      globalFilter: '',\n    });\n\n    const headerContextValue = useMemo(\n      () => ({\n        issueTypeOptions: [\n          { text: 'Bug', value: 'Bug' },\n          { text: 'Improvement', value: 'Improvement' },\n          { text: 'Epic', value: 'Epic' },\n          { text: 'Story', value: 'Story' },\n        ],\n      }),\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          filtering: {\n            state: filteringStateAndSetter,\n            filtersInfo: {\n              id: {\n                label: 'id',\n                clearedValue: '',\n              },\n              task: {\n                label: 'task',\n                clearedValue: '',\n              },\n              priority: {\n                label: 'Some Label',\n                clearedValue: 'All',\n              },\n              issueType: {\n                label: 'issueType',\n                clearedValue: [],\n              },\n              complete: {\n                label: 'complete',\n                clearedValue: '',\n              },\n              date: {\n                label: 'Дата',\n                clearedValue: '',\n              },\n              globalFilter: {\n                label: 'Global filter',\n                clearedValue: '',\n              },\n            },\n            sidebarConfig: {\n              order: ['globalFilter', 'date'],\n              items: {\n                date: {\n                  label: 'Some label for date',\n                  customRenderFn: (filters, setFilters) => (\n                    <DatePicker\n                      value={filters?.['date']}\n                      onCommitDate={(v) => {\n                        if (setFilters && !(v instanceof Date))\n                          setFilters((prev) => ({\n                            ...prev,\n                            date: v,\n                          }));\n                      }}\n                      size=\"s\"\n                      style={{\n                        width: '100%',\n                      }}\n                    />\n                  ),\n                },\n                task: {\n                  label: 'Some label for task',\n                },\n                globalFilter: {\n                  label: 'Some global filter',\n                  customRenderFn: (filters, setFilters) => (\n                    <TextField\n                      value={filters['globalFilter']}\n                      onChange={(e) => {\n                        setFilters((prev) => ({\n                          ...prev,\n                          globalFilter: e.target.value,\n                        }));\n                      }}\n                    />\n                  ),\n                },\n              },\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n        headerContextValue={headerContextValue}\n      />\n    );\n  }"
        },
        {
          "exportName": "FilteringInModal",
          "displayName": "ID",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(() => {\n      const seededRandom = createSeededRandom(42);\n      return createRows().map((el) => ({\n        ...el,\n        id: Math.floor(seededRandom() * 1000),\n        date: (() => {\n          const date = new Date(\n            FIXED_DATE_TIMESTAMP +\n              (Math.floor(seededRandom() * 61) - 30) * 86400000,\n          );\n          return `${String(date.getDate()).padStart(2, '0')}.${String(\n            date.getMonth() + 1,\n          ).padStart(2, '0')}.${date.getFullYear()}`;\n        })(),\n      }));\n    });\n\n    const columnConfig = useMemo(\n      (): readonly ColumnOrColumnGroupConfig<Row & { date: string }>[] => [\n        {\n          key: 'id',\n          name: 'ID',\n          filtering: {\n            component: 'input',\n            filter: 'startWith',\n\n            valueInRow: (r) => r.id,\n            keyInFilterState: 'id',\n          },\n        },\n        {\n          key: 'date',\n          name: 'Date',\n          filtering: {\n            component: 'custom',\n            customRender: (props) => {\n              const {\n                headerContextState: { filters, setFilters },\n              } = props;\n              return (\n                <Calendar\n                  value={filters?.['date']}\n                  onChangeValue={(v) => {\n                    if (setFilters)\n                      setFilters((prev) => ({\n                        ...prev,\n                        date: v,\n                      }));\n                  }}\n                />\n              );\n            },\n            filter: (filterValue, rowValue) =>\n              filterValue ? rowValue === filterValue : true,\n            valueInRow: (r) => r.date,\n            compareWithClearedValue: (clearedValue, currV) =>\n              clearedValue === currV,\n            keyInFilterState: 'date',\n          },\n        },\n        {\n          key: 'taskParent',\n          name: 'taskParent',\n          children: [\n            {\n              key: 'task',\n              name: 'Title 22asdf asdfsdff ddd ',\n              filtering: {\n                component: 'input',\n                filter: 'includes',\n\n                valueInRow: (r) => `${r.task} ${r.id}`,\n\n                keyInFilterState: 'task',\n              },\n            },\n            {\n              key: 'priority',\n              name: 'Priority',\n              filtering: {\n                component: 'select',\n                selectOptions: {\n                  type: 'constant',\n                  options: [\n                    { value: 'All', text: 'All' },\n                    { value: 'High', text: 'High' },\n                    { value: 'Critical', text: 'Critical' },\n                    { value: 'Medium', text: 'Medium' },\n                    { value: 'Low', text: 'Low' },\n                  ],\n                },\n\n                keyInFilterState: 'priority',\n                valueInRow: (r) => r.priority,\n                filter: {\n                  typeOfValue: 'single',\n                  filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n                },\n              },\n            },\n          ],\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          filtering: {\n            beforeList(props) {\n              return (\n                <TableFilterSelectListItem\n                  $size={props.headerContextState.rowSize}\n                >\n                  custom beforeList\n                </TableFilterSelectListItem>\n              );\n            },\n            component: 'select',\n            selectOptions: {\n              type: 'stateInHeaderContext',\n              optionsKeyInHeaderContext: 'issueTypeOptions',\n            },\n            keyInFilterState: 'issueType',\n            valueInRow: (r) => r.issueType,\n            filter: {\n              typeOfValue: 'multiple',\n              filteringType: (fv, rv) =>\n                !fv.length || fv.some((fvCurr) => fvCurr === rv),\n            },\n          },\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n          filtering: {\n            component: 'input',\n            keyInFilterState: 'complete',\n            valueInRow: (r) => r.complete,\n            filter: (fv, rv) => (+rv || 0) >= (+fv || 0),\n          },\n        },\n      ],\n      [],\n    );\n\n    const filteringStateAndSetter = useState({\n      id: '',\n      task: '',\n      priority: 'All',\n      issueType: [],\n      complete: '',\n      date: '',\n      globalFilter: '',\n    });\n\n    const headerContextValue = useMemo(\n      () => ({\n        issueTypeOptions: [\n          { text: 'Bug', value: 'Bug' },\n          { text: 'Improvement', value: 'Improvement' },\n          { text: 'Epic', value: 'Epic' },\n          { text: 'Story', value: 'Story' },\n        ],\n      }),\n      [],\n    );\n\n    const tableJsx = (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          filtering: {\n            state: filteringStateAndSetter,\n            filtersInfo: {\n              id: {\n                label: 'id',\n                clearedValue: '',\n              },\n              task: {\n                label: 'task',\n                clearedValue: '',\n              },\n              priority: {\n                label: 'Some Label',\n                clearedValue: 'All',\n              },\n              issueType: {\n                label: 'issueType',\n                clearedValue: [],\n              },\n              complete: {\n                label: 'complete',\n                clearedValue: '',\n              },\n              date: {\n                label: 'Дата',\n                clearedValue: '',\n              },\n              globalFilter: {\n                label: 'Global filter',\n                clearedValue: '',\n              },\n            },\n            sidebarConfig: {\n              order: ['globalFilter', 'date'],\n              items: {\n                date: {\n                  label: 'Some label for date',\n                  customRenderFn: (filters, setFilters) => (\n                    <DatePicker\n                      value={filters?.['date']}\n                      onCommitDate={(v) => {\n                        if (setFilters && !(v instanceof Date))\n                          setFilters((prev) => ({\n                            ...prev,\n                            date: v,\n                          }));\n                      }}\n                      size=\"s\"\n                      style={{\n                        width: '100%',\n                      }}\n                    />\n                  ),\n                },\n                task: {\n                  label: 'Some label for task',\n                },\n                globalFilter: {\n                  label: 'Some global filter',\n                  customRenderFn: (filters, setFilters) => (\n                    <TextField\n                      value={filters['globalFilter']}\n                      onChange={(e) => {\n                        setFilters((prev) => ({\n                          ...prev,\n                          globalFilter: e.target.value,\n                        }));\n                      }}\n                    />\n                  ),\n                },\n              },\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n        headerContextValue={headerContextValue}\n      />\n    );\n\n    const [modalOpened, setModalOpened] = useState(false);\n\n    return (\n      <ModalDF\n        opened={modalOpened}\n        isFocusTrapped={false}\n        onClose={() => setModalOpened(false)}\n      >\n        <ModalDF.Main>\n          <ModalDF.Header />\n          <ModalDF.Content\n            $css={{\n              '&&': {\n                overflow: 'visible',\n              },\n            }}\n          >\n            {tableJsx}\n          </ModalDF.Content>\n        </ModalDF.Main>\n      </ModalDF>\n    );\n  }"
        },
        {
          "exportName": "ManualFiltering",
          "displayName": "Title",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'task',\n          name: 'Title',\n          filtering: {\n            component: 'input',\n            filter: 'includes',\n\n            valueInRow: (r) => r.task,\n\n            keyInFilterState: 'task',\n          },\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          filtering: {\n            component: 'select',\n            selectOptions: {\n              type: 'constant',\n              options: [\n                { value: 'All', text: 'All' },\n                { value: 'High', text: 'High' },\n                { value: 'Critical', text: 'Critical' },\n                { value: 'Medium', text: 'Medium' },\n                { value: 'Low', text: 'Low' },\n              ],\n            },\n\n            keyInFilterState: 'priority',\n            valueInRow: (r) => r.priority,\n            filter: {\n              typeOfValue: 'single',\n              filteringType: (fv, rv) => (fv !== 'All' ? rv === fv : true),\n            },\n          },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          filtering: {\n            component: 'select',\n            selectOptions: {\n              type: 'stateInHeaderContext',\n              optionsKeyInHeaderContext: 'issueTypeOptions',\n            },\n            keyInFilterState: 'issueType',\n            valueInRow: (r) => r.issueType,\n            filter: {\n              typeOfValue: 'multiple',\n              filteringType: (fv, rv) =>\n                !fv.length || fv.some((fvCurr) => fvCurr === rv),\n            },\n          },\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n          filtering: {\n            component: 'input',\n            keyInFilterState: 'complete',\n            valueInRow: (r) => r.complete,\n            filter: (fv, rv) => (+rv || 0) >= (+fv || 0),\n          },\n        },\n      ],\n      [],\n    );\n\n    const rows = useMemo(() => createRows(), []);\n\n    const [filteredRows, setFilteredRows] = useState(rows);\n\n    const filteringStateAndSetter = useState<{\n      task: string;\n      priority: string;\n      issueType: string[];\n      complete: string;\n    }>({\n      task: '',\n      priority: 'All',\n      issueType: [],\n      complete: '',\n    });\n\n    const [state] = filteringStateAndSetter;\n\n    useEffect(() => {\n      const enabledFilters = Object.entries(state).filter((el) =>\n        Array.isArray(el[1]) ? !!el[1].length : !!el[1],\n      );\n      const filterRows = rows.filter((row) =>\n        enabledFilters.every((enabledFilter) => {\n          const colValue = row[enabledFilter[0] as keyof typeof row] as string;\n\n          return Array.isArray(enabledFilter[1])\n            ? enabledFilter[1].includes(colValue)\n            : enabledFilter[1] === colValue.toString() ||\n                enabledFilter[1] === 'All';\n        }),\n      );\n      setFilteredRows(filterRows);\n      // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [state]);\n\n    const headerContextValue = useMemo(\n      () => ({\n        issueTypeOptions: [\n          { text: 'Bug', value: 'Bug' },\n          { text: 'Improvement', value: 'Improvement' },\n          { text: 'Epic', value: 'Epic' },\n          { text: 'Story', value: 'Story' },\n        ],\n      }),\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          filtering: {\n            state: filteringStateAndSetter,\n            filtersInfo: {\n              task: {\n                label: 'task',\n                clearedValue: '',\n              },\n              priority: {\n                label: 'Some Label',\n                clearedValue: 'All',\n              },\n              issueType: {\n                label: 'issueType',\n                clearedValue: [],\n              },\n              complete: {\n                label: 'complete',\n                clearedValue: '',\n              },\n            },\n            manualFiltering: true,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={filteredRows}\n        headerContextValue={headerContextValue}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "formatCellContent",
      "legacy": true,
      "summary": "Форматирование содержимого ячеек legacy `Table`.",
      "docs": "# FormatCellContent\n\nФорматирование содержимого ячеек legacy `Table`.\n\n## Ключевые особенности\n\n- Форматирование чисел, дат и пользовательских значений\n- Настройка отображения через `columnConfig`\n- Совместимость с вложенными строками\n- Возможность вернуть React-компонент из render-функции ячейки\n\n## Особенности\n\nФорматирование не должно менять исходные `rows`. Если нужно редактирование значения, используйте конфигурацию `editing`, а формат оставляйте только слоем отображения.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-formatcellcontent-api--docs).",
      "apiDocs": "# Format Cell Content API\n\n## ContentFormat\n\n```typescript\ntype ContentFormat =\n  | 'number' // Стандартное числовое форматирование с локалью ru-RU (разделитель тысяч: пробел, дробная часть: запятая)\n  | CustomFormat\n  | NumberFormatOptions;\n```\n\n## CustomFormat\n\n```typescript\ntype CustomFormat = CommonFormat & {\n  customFormat: (value: string) => React.ReactNode;\n};\n```\n\n## NumberFormatOptions\n\n```typescript\ntype NumberFormatOptions = CommonFormat & {\n  type: 'number';\n  /** Кастомный разделитель дробной части (по умолчанию ',') */\n  decimalSeparator?: string;\n  /** Кастомный разделитель тысяч (по умолчанию ' ') */\n  thousandSeparator?: string;\n  /** Минимальное число знаков после запятой (по умолчанию 0) */\n  minimumFractionDigits?: number;\n  /** Максимальное число знаков после запятой (по умолчанию 2) */\n  maximumFractionDigits?: number;\n  /** Включить/отключить группировку разрядов (по умолчанию true) */\n  useGrouping?: boolean;\n  /** Локаль для Intl.NumberFormat (по умолчанию 'ru-RU') */\n  locales?: string | string[];\n  alignContent?: 'right' | 'left' | 'center';\n};\n```",
      "api": [
        {
          "typeName": "ContentFormat",
          "source": "type ContentFormat =\n  | 'number' // Стандартное числовое форматирование с локалью ru-RU (разделитель тысяч: пробел, дробная часть: запятая)\n  | CustomFormat\n  | NumberFormatOptions;"
        },
        {
          "typeName": "CustomFormat",
          "source": "type CustomFormat = CommonFormat & {\n  customFormat: (value: string) => React.ReactNode;\n};"
        },
        {
          "typeName": "NumberFormatOptions",
          "source": "type NumberFormatOptions = CommonFormat & {\n  type: 'number';\n  /** Кастомный разделитель дробной части (по умолчанию ',') */\n  decimalSeparator?: string;\n  /** Кастомный разделитель тысяч (по умолчанию ' ') */\n  thousandSeparator?: string;\n  /** Минимальное число знаков после запятой (по умолчанию 0) */\n  minimumFractionDigits?: number;\n  /** Максимальное число знаков после запятой (по умолчанию 2) */\n  maximumFractionDigits?: number;\n  /** Включить/отключить группировку разрядов (по умолчанию true) */\n  useGrouping?: boolean;\n  /** Локаль для Intl.NumberFormat (по умолчанию 'ru-RU') */\n  locales?: string | string[];\n  alignContent?: 'right' | 'left' | 'center';\n};"
        }
      ],
      "stories": [
        {
          "exportName": "BasicFormatting",
          "displayName": "Форматирование ячеек",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(() => createRowsTree());\n\n    const columns = useMemo<readonly ColumnConfig<TreeRow>[]>(\n      () => [\n        {\n          key: 'block',\n          name: 'Блок / Трайб / Продукт',\n          contentFormat: {\n            customFormat: (val) => `📝 ${val}`,\n          },\n          subRow: {\n            keyOfColumnInSubRow: (lvl) => {\n              switch (lvl) {\n                case 0:\n                  return 'block';\n                case 1:\n                  return 'tribe';\n                case 2:\n                  return 'product';\n                default:\n                  return 'block';\n              }\n            },\n            isColumnWithArrow: true,\n            hideHeaderExpandAllArrow: false,\n          },\n          resizable: true,\n        },\n        {\n          key: 'blockActivity',\n          name: 'Активность блока',\n          title: '123',\n          contentFormat: {\n            customFormat: (val) => `${val}!`,\n          },\n        },\n        {\n          key: '',\n          minWidth: 170,\n          name: 'Локация трайба',\n          subRow: {\n            renderSubRowCell: (props, lvl) => {\n              if (lvl === 1) {\n                return (\n                  <Badge view=\"accent\" size=\"m\">\n                    {props.row?.tribeZone}\n                  </Badge>\n                );\n              }\n              return null;\n            },\n          },\n        },\n        {\n          key: 'q1',\n          name: 'Q1',\n          contentFormat: 'number',\n          subRow: {\n            parentKeyAsDefault: true,\n            /* Форматирование в подстроках */\n            contentFormat: {\n              customFormat: (val) => `${val}%`,\n            },\n          },\n        },\n\n        {\n          key: 'q2',\n          name: 'Q2',\n          contentFormat: {\n            type: 'number',\n            minimumFractionDigits: 1,\n            maximumFractionDigits: 3,\n            decimalSeparator: '.',\n            thousandSeparator: '_',\n            alignContent: 'center',\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n            contentFormat: {\n              type: 'number',\n              minimumFractionDigits: 1,\n              maximumFractionDigits: 3,\n              decimalSeparator: ',',\n              thousandSeparator: '.',\n              alignContent: 'right',\n            },\n          },\n        },\n        {\n          key: 'q3',\n          name: 'Q3',\n          contentFormat: {\n            type: 'number',\n            minimumFractionDigits: 2,\n            locales: ['en-US', 'fr-FR', 'ru-RU'],\n          },\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n        {\n          key: 'q4',\n          name: 'Q4',\n          contentFormat: 'number',\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          resizableColumn: true,\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "fullScreenMode",
      "legacy": true,
      "summary": "Включение полноэкранного режима",
      "docs": "# TableFullScreenMode\n\n## Ключевые особенности\n\n- Включение полноэкранного режима\n- Поддержка дефолтно открытого состояния\n- Возможность внешнего управления состоянием\n\n**tableConfig.fullScreenEnabled**\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-fullscreenmode-api--docs).",
      "apiDocs": "# Full Screen Mode API\n\n## FullScreen\n\n```typescript\ntype FullScreenObj = {\n  /**\n   * @default false\n   */\n  defaultOpened?: boolean;\n  state?: [boolean, (arg: (prev: boolean) => typeof prev) => void];\n  /**\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * @default document.body\n   */\n  portal?: Element | DocumentFragment | false;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n```\n\n## FullScreenObj\n\n```typescript\ntype FullScreenObj = {\n  /**\n   * @default false\n   */\n  defaultOpened?: boolean;\n  state?: [boolean, (arg: (prev: boolean) => typeof prev) => void];\n  /**\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * @default document.body\n   */\n  portal?: Element | DocumentFragment | false;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n```",
      "api": [
        {
          "typeName": "FullScreenObj",
          "source": "type FullScreenObj = {\n  /**\n   * @default false\n   */\n  defaultOpened?: boolean;\n  state?: [boolean, (arg: (prev: boolean) => typeof prev) => void];\n  /**\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * @default document.body\n   */\n  portal?: Element | DocumentFragment | false;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};"
        },
        {
          "typeName": "FullScreenObj",
          "source": "type FullScreenObj = {\n  /**\n   * @default false\n   */\n  defaultOpened?: boolean;\n  state?: [boolean, (arg: (prev: boolean) => typeof prev) => void];\n  /**\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * @default document.body\n   */\n  portal?: Element | DocumentFragment | false;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "FullscreenEnabling",
          "displayName": "Полноэкранный режим",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: (\n            <div\n              style={{\n                display: 'flex',\n                justifyContent: 'space-between',\n              }}\n            >\n              id\n              <IconSber size=\"xs\" color=\"inherit\" />\n            </div>\n          ),\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 200 },\n          fullScreenEnabled: true,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "FullscreenDefaultOpened",
          "displayName": "Включение по умолчанию полноэкранного режима",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: (\n            <div\n              style={{\n                display: 'flex',\n                justifyContent: 'space-between',\n              }}\n            >\n              id\n              <IconSber size=\"xs\" color=\"inherit\" />\n            </div>\n          ),\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <div style={{ height: 500 }}>\n        <Table\n          tableConfig={{\n            containerStyle: { height: 200 },\n            fullScreenEnabled: { defaultOpened: true },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        },
        {
          "exportName": "FullscreenCustomState",
          "displayName": "Полноэкранный режим c ручным управлением и контролем показа иконки в ControlBlock",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: (\n            <div\n              style={{\n                display: 'flex',\n                justifyContent: 'space-between',\n              }}\n            >\n              id\n              <IconSber size=\"xs\" color=\"inherit\" />\n            </div>\n          ),\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n    const [fullScreened, setFullScreened] = useState(false);\n\n    return (\n      <div style={{ height: 500 }}>\n        <Button view=\"positive\" onClick={() => setFullScreened(true)}>\n          На весь экран\n        </Button>\n        <Table\n          tableConfig={{\n            containerStyle: { height: 200 },\n            fullScreenEnabled: {\n              state: [fullScreened, setFullScreened],\n              showInControl: fullScreened,\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </div>\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "highlightActiveType",
      "legacy": true,
      "summary": "Настройка подсветки активной сущности в legacy `Table`.",
      "docs": "# HighlightActiveType\n\nНастройка подсветки активной сущности в legacy `Table`.\n\n## Ключевые особенности\n\n- `cell` подсвечивает активную ячейку\n- `row` подсвечивает активную строку\n- `disabled` отключает подсветку\n- Работает с внешним `refTable` и выбором ячейки\n\n## Особенности\n\nПодсветка отражает активную сущность таблицы, а не состояние выбора строк. Для выбора строк используйте `tableConfig.selecting`.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-highlightactivetype-api--docs).",
      "apiDocs": "# Highlight Active Type API\n\n## HighlightActiveType\n\n```typescript\ntype HighlightActiveType = 'cell' | 'row' | 'disabled';\n```",
      "api": [
        {
          "typeName": "HighlightActiveType",
          "source": "type HighlightActiveType = 'cell' | 'row' | 'disabled';"
        }
      ],
      "stories": [
        {
          "exportName": "HighlightActiveTypeTable",
          "displayName": "Title",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n    const [highlightActiveType, setHighlightActiveType] =\n      useState<HighlightActiveType>('row');\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: (\n            <div\n              style={{\n                display: 'flex',\n                justifyContent: 'space-between',\n              }}\n            >\n              id\n            </div>\n          ),\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n    const refTable = useRef<DataGridHandle>(null);\n\n    useEffect(() => {\n      setTimeout(() => {\n        refTable.current?.selectCell({ idx: 0, rowIdx: 1 });\n      }, 1000);\n    }, []);\n\n    return (\n      <>\n        Выбрать тип выделения\n        <Select\n          value={highlightActiveType}\n          onChange={(v) => setHighlightActiveType(v as HighlightActiveType)}\n          items={['row', 'cell', 'disabled'].map((i) => ({\n            label: i,\n            value: i,\n          }))}\n        />\n        <br />\n        <Table\n          tableConfig={{\n            containerStyle: { height: 700 },\n            highlightActiveType,\n          }}\n          refTable={refTable}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "infinityScroll",
      "legacy": true,
      "summary": "Бесконечная подгрузка данных при прокрутке legacy `Table`.",
      "docs": "# InfinityScroll\n\nБесконечная подгрузка данных при прокрутке legacy `Table`.\n\n## Ключевые особенности\n\n- Включается наличием `tableConfig.infinityScroll`\n- `onTrigger` вызывается при достижении нижней границы\n- `isLoading` блокирует повторный вызов во время загрузки\n- `hasMore` управляет наличием следующей страницы\n- `scrollThreshold` задает расстояние до низа для раннего запуска\n\n## Особенности\n\nПри активном infinity scroll таблица не применяет дефолтные сортировку и фильтрацию, потому что на клиенте обычно находится не весь набор данных.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-infinityscroll-api--docs).",
      "apiDocs": "# Infinity Scroll API\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *```jsx\n   * import { Table } from '@daisforge/ui';\n   *\n   * <Table\n   * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n   * {...rest}\n   * />\n   * ```\n   */\n  selecting?: {\n    state: [\n      ReadonlySet<RowIdType>,\n      React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n    ];\n  } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n       */\n      controlBlock?: {\n        domMetadata?: DomMetadata;\n      };\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n       */\n      sidebar?: {\n        domMetadata?: DomMetadata;\n      };\n    };\n  /**\n   * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n   *\n   * columnConfig=[{editingCell: {...}}]\n   */\n  editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n  /**\n   * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n   *\n   * columnConfig=[{subRow: {...}}]\n   */\n  subRows?: SubRows<RowType, RowIdType>;\n  rowsGrouping?: RowsGrouping<RowType>;\n\n  /**\n   * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации -  resizableColumn: true. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={resizableColumn: true}\n   *\n   * columnConfig=[{resizable: true}]\n   */\n  resizableColumn?: boolean;\n  /**\n   * style - inline-стили. Для стилей самой таблицы (без вложенности).\n   *\n   * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n   */\n  style?: Omit<\n    CSSProperties,\n    'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n  >;\n  /**\n   * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n   *\n   * Пример:\n   *\n   * ```css\n   * & > .rdg-header-row > .rdgCell {\n   * background-color: red;\n   * }\n   * ```\n   *\n   */\n  css?: string | CSSObject;\n\n  summaryRows?: SummaryRowsConfig;\n  /**\n   * controlBlock - пропс для активации, кастомизации контролблока.\n   */\n  controlBlock?: ControlBlockConfig;\n  /**\n     * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n     * Пример:\n     *\n     * ```tsx\n        tableConfig={{ containerStyle: { height: '70vh' } }}\n     * ```\n     */\n  containerStyle?: CSSProperties | undefined;\n  /**\n   * containerCss - стили для контейнера таблицы и контролблока.\n   * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n   */\n  containerCss?: string | CSSObject | undefined;\n  /**\n   * containerId - html-атрибут id контейнера таблицы.\n   */\n  containerId?: string | undefined;\n\n  /**\n   * infinityScroll - бесконечная подгрузка данных при скролле.\n   *\n   *  Условие активации - наличие самого пропса infinityScroll.\n   *\n   * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n   * (Предполагается, что если есть infinityScroll,\n   * то в таблице представлен не весь объем данных,\n   * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n   *\n   */\n  infinityScroll?: {\n    onTrigger: (rows: RowType[]) => Promise<void> | void;\n    isLoading: boolean;\n    /**\n     * @default true\n     */\n    hasMore?: boolean;\n    /**\n     * @default 100   (px)\n     */\n    scrollThreshold?: number;\n  };\n  /**\n   * @isLoading - состояние загрузки данных для таблицы.\n   */\n  isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n  /**\n   * loadingOverlay - конфигурация для отображения оверлея загрузки.\n   * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n   */\n  loadingOverlay?: {\n    /**\n     * Активен ли оверлей загрузки\n     * @default true\n     */\n    active?: boolean;\n    /**\n     * Кастомный компонент спиннера\n     * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n     */\n    spinner?: ReactNode;\n    /**\n     * Основной заголовок оверлея\n     * @default \"Загрузка таблицы\"\n     */\n    title?: string;\n    /**\n     * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n     * @default \"\"\n     */\n    subtitle?: string;\n    /**\n     * Задержка перед показом подзаголовка (мс)\n     * @default 10000 (10 секунд)\n     */\n    showSubtitleDelay?: number;\n  };\n  noRowsFallback?: boolean | { custom: ReactNode };\n  columnsControl?: ColumnsControlConfig;\n  rowDetailPanel?: RowDetailConfig<RowType>;\n  rowInstruments?: {\n    getRowDropdownConfig: RowInstrumentsType<RowType>;\n    /**\n     * @default false\n     */\n    defaultOpened?: boolean;\n    /**\n     * @default true\n     */\n    showInControl?: boolean;\n    /**\n     * Внешний стейт видимости\n     */\n    openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  };\n  fullScreenEnabled?: FullScreen;\n  keyText?: boolean | KeyTextConfig;\n  /**\n   * pagination - пропс для пагинации.\n   *\n   * Условие активации - наличие самого пропса pagination.\n   *\n   * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n   * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n   *\n   */\n  pagination?: PaginationProps;\n  /**\n   * searching - пропс для поиска по таблицу.\n   *\n   * Условие активации - наличие searching.enabled: true\n   *\n   */\n  /**\n   * Конфигурация табов в сайдбаре\n   */\n  sidebarConfig?: SidebarConfig;\n  searching?: SearchingProps;\n  /**\n   * onHeaderContextMenu - пропс для активации открытия контекстного меню.\n   *\n   */\n  onHeaderContextMenu?: HeaderContextMenuProps;\n  onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n  onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n    RowType,\n    SummaryRowType\n  >;\n} & Pick<\n  DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n  | 'summaryRowHeight'\n  | 'onFill'\n  | 'onCopy'\n  | 'onPaste'\n  | 'onCellClick'\n  | 'onCellDoubleClick'\n  | 'onCellContextMenu'\n  | 'onCellKeyDown'\n  | 'onSelectedCellChange'\n  | 'onScroll'\n  | 'onColumnResize'\n  | 'onColumnsReorder'\n  | 'enableVirtualization'\n  | 'rowClass'\n  | 'data-testid'\n  | 'headerRowHeight'\n>;\n```",
      "api": [
        {
          "typeName": "TableConfig",
          "source": "type TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *"
        }
      ],
      "stories": [
        {
          "exportName": "InfinityScroll",
          "displayName": "ID",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const columns: readonly ColumnConfig<Row>[] = useMemo(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n\n        {\n          key: 'task',\n          name: 'Title',\n        },\n\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n      ],\n      [],\n    );\n    const [rows, setRows] = useState(() => createRows(0, 50));\n\n    const [isLoading, setIsLoading] = useState(false);\n\n    const onTrigger = useCallback(\n      async (rows: Row[]) => {\n        if (isLoading) {\n          return;\n        }\n        setIsLoading(true);\n\n        const newData = await loadMoreRows<Row>({\n          indexForStart: rows.length,\n          countOfNewRows: 50,\n          timeout: 2000,\n        });\n\n        setRows((prev) => [...prev, ...newData]);\n        setIsLoading(false);\n      },\n      [isLoading],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n\n          infinityScroll: {\n            scrollThreshold: 50,\n            onTrigger,\n            isLoading,\n            hasMore: rows.length < 6000,\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "isLoading",
      "legacy": true,
      "summary": "Состояние загрузки legacy `Table`.",
      "docs": "# IsLoading\n\nСостояние загрузки legacy `Table`.\n\n## Ключевые особенности\n\n- Простое состояние через `tableConfig.isLoading: true`\n- Настройка количества skeleton-строк\n- Overlay загрузки через `loadingOverlay`\n- Кастомизация заголовка, подзаголовка, задержки и спиннера overlay\n\n## Особенности\n\nИспользуйте skeleton-режим, когда нужно сохранить структуру таблицы во время загрузки. Overlay подходит для блокирующей загрузки поверх уже отображенных данных.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-isloading-api--docs).",
      "apiDocs": "# IsLoading API\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *```jsx\n   * import { Table } from '@daisforge/ui';\n   *\n   * <Table\n   * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n   * {...rest}\n   * />\n   * ```\n   */\n  selecting?: {\n    state: [\n      ReadonlySet<RowIdType>,\n      React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n    ];\n  } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n       */\n      controlBlock?: {\n        domMetadata?: DomMetadata;\n      };\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n       */\n      sidebar?: {\n        domMetadata?: DomMetadata;\n      };\n    };\n  /**\n   * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n   *\n   * columnConfig=[{editingCell: {...}}]\n   */\n  editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n  /**\n   * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n   *\n   * columnConfig=[{subRow: {...}}]\n   */\n  subRows?: SubRows<RowType, RowIdType>;\n  rowsGrouping?: RowsGrouping<RowType>;\n\n  /**\n   * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации -  resizableColumn: true. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={resizableColumn: true}\n   *\n   * columnConfig=[{resizable: true}]\n   */\n  resizableColumn?: boolean;\n  /**\n   * style - inline-стили. Для стилей самой таблицы (без вложенности).\n   *\n   * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n   */\n  style?: Omit<\n    CSSProperties,\n    'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n  >;\n  /**\n   * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n   *\n   * Пример:\n   *\n   * ```css\n   * & > .rdg-header-row > .rdgCell {\n   * background-color: red;\n   * }\n   * ```\n   *\n   */\n  css?: string | CSSObject;\n\n  summaryRows?: SummaryRowsConfig;\n  /**\n   * controlBlock - пропс для активации, кастомизации контролблока.\n   */\n  controlBlock?: ControlBlockConfig;\n  /**\n     * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n     * Пример:\n     *\n     * ```tsx\n        tableConfig={{ containerStyle: { height: '70vh' } }}\n     * ```\n     */\n  containerStyle?: CSSProperties | undefined;\n  /**\n   * containerCss - стили для контейнера таблицы и контролблока.\n   * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n   */\n  containerCss?: string | CSSObject | undefined;\n  /**\n   * containerId - html-атрибут id контейнера таблицы.\n   */\n  containerId?: string | undefined;\n\n  /**\n   * infinityScroll - бесконечная подгрузка данных при скролле.\n   *\n   *  Условие активации - наличие самого пропса infinityScroll.\n   *\n   * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n   * (Предполагается, что если есть infinityScroll,\n   * то в таблице представлен не весь объем данных,\n   * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n   *\n   */\n  infinityScroll?: {\n    onTrigger: (rows: RowType[]) => Promise<void> | void;\n    isLoading: boolean;\n    /**\n     * @default true\n     */\n    hasMore?: boolean;\n    /**\n     * @default 100   (px)\n     */\n    scrollThreshold?: number;\n  };\n  /**\n   * @isLoading - состояние загрузки данных для таблицы.\n   */\n  isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n  /**\n   * loadingOverlay - конфигурация для отображения оверлея загрузки.\n   * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n   */\n  loadingOverlay?: {\n    /**\n     * Активен ли оверлей загрузки\n     * @default true\n     */\n    active?: boolean;\n    /**\n     * Кастомный компонент спиннера\n     * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n     */\n    spinner?: ReactNode;\n    /**\n     * Основной заголовок оверлея\n     * @default \"Загрузка таблицы\"\n     */\n    title?: string;\n    /**\n     * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n     * @default \"\"\n     */\n    subtitle?: string;\n    /**\n     * Задержка перед показом подзаголовка (мс)\n     * @default 10000 (10 секунд)\n     */\n    showSubtitleDelay?: number;\n  };\n  noRowsFallback?: boolean | { custom: ReactNode };\n  columnsControl?: ColumnsControlConfig;\n  rowDetailPanel?: RowDetailConfig<RowType>;\n  rowInstruments?: {\n    getRowDropdownConfig: RowInstrumentsType<RowType>;\n    /**\n     * @default false\n     */\n    defaultOpened?: boolean;\n    /**\n     * @default true\n     */\n    showInControl?: boolean;\n    /**\n     * Внешний стейт видимости\n     */\n    openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  };\n  fullScreenEnabled?: FullScreen;\n  keyText?: boolean | KeyTextConfig;\n  /**\n   * pagination - пропс для пагинации.\n   *\n   * Условие активации - наличие самого пропса pagination.\n   *\n   * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n   * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n   *\n   */\n  pagination?: PaginationProps;\n  /**\n   * searching - пропс для поиска по таблицу.\n   *\n   * Условие активации - наличие searching.enabled: true\n   *\n   */\n  /**\n   * Конфигурация табов в сайдбаре\n   */\n  sidebarConfig?: SidebarConfig;\n  searching?: SearchingProps;\n  /**\n   * onHeaderContextMenu - пропс для активации открытия контекстного меню.\n   *\n   */\n  onHeaderContextMenu?: HeaderContextMenuProps;\n  onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n  onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n    RowType,\n    SummaryRowType\n  >;\n} & Pick<\n  DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n  | 'summaryRowHeight'\n  | 'onFill'\n  | 'onCopy'\n  | 'onPaste'\n  | 'onCellClick'\n  | 'onCellDoubleClick'\n  | 'onCellContextMenu'\n  | 'onCellKeyDown'\n  | 'onSelectedCellChange'\n  | 'onScroll'\n  | 'onColumnResize'\n  | 'onColumnsReorder'\n  | 'enableVirtualization'\n  | 'rowClass'\n  | 'data-testid'\n  | 'headerRowHeight'\n>;\n```",
      "api": [
        {
          "typeName": "TableConfig",
          "source": "type TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *"
        }
      ],
      "stories": [
        {
          "exportName": "IsLoading",
          "displayName": "IsLoading",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n    const [isVisibleLoadingOverlay, setIsVisibleLoadingOverlay] =\n      useState(false);\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <>\n        <Switch\n          style={{ width: 'fit-content' }}\n          label={\n            isVisibleLoadingOverlay ? 'Скрыть overlay' : 'Показать overlay'\n          }\n          checked={isVisibleLoadingOverlay}\n          onChange={() => setIsVisibleLoadingOverlay((prev) => !prev)}\n        />\n        <Table\n          tableConfig={{\n            containerStyle: { height: 500 },\n            isLoading: { boolean: true, skeletonRowsCount: 5 },\n            loadingOverlay: {\n              active: isVisibleLoadingOverlay,\n              showSubtitleDelay: 3000,\n              subtitle:\n                'Данные обрабатываются, обычно это занимает не более 10 секунд',\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "keyText",
      "legacy": true,
      "summary": "Выделение ключевых колонок текстовой меткой",
      "docs": "# TableKeyText\n\n## Ключевые особенности\n\n- Выделение ключевых колонок текстовой меткой\n- Включение через tableConfig.keyText\n- Интеграция с columnsControl\n\n`tableConfig.keyText` включает отображение ключевой текстовой колонки и задаёт способ отображения `key`, `text` или обеих частей.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-keytext-api--docs).",
      "apiDocs": "# Key Text API\n\n## KeyText\n\n```typescript\ntype KeyText = 'key' | 'text' | 'keyText' | 'textKey';\n```\n\n## KeyTextConfig\n\n```typescript\ntype KeyTextConfig = {\n  showInControl?: boolean;\n  defaultActiveOption?: KeyText;\n  controlBlock: {\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n     */\n    domMetadata?: DomMetadata;\n  };\n  sidebar: {\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n     */\n    domMetadata?: DomMetadata;\n  };\n};\n```\n\n## KeyTextColumnConfig\n\n```typescript\ntype KeyTextColumnConfig<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> =\n  | ((props: { keyText: KeyText }) => ColumnConfig<Row, SummRow>)\n  | ColumnConfig<Row, SummRow>;\n```",
      "api": [
        {
          "typeName": "KeyText",
          "source": "type KeyText = 'key' | 'text' | 'keyText' | 'textKey';"
        },
        {
          "typeName": "KeyTextConfig",
          "source": "type KeyTextConfig = {\n  showInControl?: boolean;\n  defaultActiveOption?: KeyText;\n  controlBlock: {\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n     */\n    domMetadata?: DomMetadata;\n  };\n  sidebar: {\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n     */\n    domMetadata?: DomMetadata;\n  };\n};"
        },
        {
          "typeName": "KeyTextColumnConfig",
          "source": "type KeyTextColumnConfig<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> =\n  | ((props: { keyText: KeyText }) => ColumnConfig<Row, SummRow>)\n  | ColumnConfig<Row, SummRow>;"
        }
      ],
      "stories": [
        {
          "exportName": "KeyTextTable",
          "displayName": "Ключ текст",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'task',\n          name: 'Title',\n          keyText: {\n            key: 'kek',\n            name: 'Ключ - Title',\n            renderCell: ({ row }) => row.id,\n          },\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          keyText: true,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "noRowsFallback",
      "legacy": true,
      "summary": "*tableConfig.noRowsFallback**",
      "docs": "# No Rows Fallback\n\n**tableConfig.noRowsFallback**\n\nОтображение заглушки при отсутствии данных в таблице.\n\n## Ключевые особенности\n\n- `noRowsFallback: true` — стандартная заглушка «нет данных»\n- `noRowsFallback: { custom: ReactNode }` — кастомный компонент заглушки\n\n## Особенности\n\n- Кастомный элемент должен использовать `gridColumn: '1/-1'` для растягивания на всю ширину таблицы\n\n> Подробнее о типах и пропсах — [No Rows Fallback API](?path=/docs/локальные-компоненты-table-norowsfallback-api--docs)",
      "apiDocs": "# No Rows Fallback API\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *```jsx\n   * import { Table } from '@daisforge/ui';\n   *\n   * <Table\n   * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n   * {...rest}\n   * />\n   * ```\n   */\n  selecting?: {\n    state: [\n      ReadonlySet<RowIdType>,\n      React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n    ];\n  } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n       */\n      controlBlock?: {\n        domMetadata?: DomMetadata;\n      };\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n       */\n      sidebar?: {\n        domMetadata?: DomMetadata;\n      };\n    };\n  /**\n   * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n   *\n   * columnConfig=[{editingCell: {...}}]\n   */\n  editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n  /**\n   * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n   *\n   * columnConfig=[{subRow: {...}}]\n   */\n  subRows?: SubRows<RowType, RowIdType>;\n  rowsGrouping?: RowsGrouping<RowType>;\n\n  /**\n   * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации -  resizableColumn: true. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={resizableColumn: true}\n   *\n   * columnConfig=[{resizable: true}]\n   */\n  resizableColumn?: boolean;\n  /**\n   * style - inline-стили. Для стилей самой таблицы (без вложенности).\n   *\n   * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n   */\n  style?: Omit<\n    CSSProperties,\n    'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n  >;\n  /**\n   * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n   *\n   * Пример:\n   *\n   * ```css\n   * & > .rdg-header-row > .rdgCell {\n   * background-color: red;\n   * }\n   * ```\n   *\n   */\n  css?: string | CSSObject;\n\n  summaryRows?: SummaryRowsConfig;\n  /**\n   * controlBlock - пропс для активации, кастомизации контролблока.\n   */\n  controlBlock?: ControlBlockConfig;\n  /**\n     * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n     * Пример:\n     *\n     * ```tsx\n        tableConfig={{ containerStyle: { height: '70vh' } }}\n     * ```\n     */\n  containerStyle?: CSSProperties | undefined;\n  /**\n   * containerCss - стили для контейнера таблицы и контролблока.\n   * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n   */\n  containerCss?: string | CSSObject | undefined;\n  /**\n   * containerId - html-атрибут id контейнера таблицы.\n   */\n  containerId?: string | undefined;\n\n  /**\n   * infinityScroll - бесконечная подгрузка данных при скролле.\n   *\n   *  Условие активации - наличие самого пропса infinityScroll.\n   *\n   * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n   * (Предполагается, что если есть infinityScroll,\n   * то в таблице представлен не весь объем данных,\n   * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n   *\n   */\n  infinityScroll?: {\n    onTrigger: (rows: RowType[]) => Promise<void> | void;\n    isLoading: boolean;\n    /**\n     * @default true\n     */\n    hasMore?: boolean;\n    /**\n     * @default 100   (px)\n     */\n    scrollThreshold?: number;\n  };\n  /**\n   * @isLoading - состояние загрузки данных для таблицы.\n   */\n  isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n  /**\n   * loadingOverlay - конфигурация для отображения оверлея загрузки.\n   * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n   */\n  loadingOverlay?: {\n    /**\n     * Активен ли оверлей загрузки\n     * @default true\n     */\n    active?: boolean;\n    /**\n     * Кастомный компонент спиннера\n     * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n     */\n    spinner?: ReactNode;\n    /**\n     * Основной заголовок оверлея\n     * @default \"Загрузка таблицы\"\n     */\n    title?: string;\n    /**\n     * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n     * @default \"\"\n     */\n    subtitle?: string;\n    /**\n     * Задержка перед показом подзаголовка (мс)\n     * @default 10000 (10 секунд)\n     */\n    showSubtitleDelay?: number;\n  };\n  noRowsFallback?: boolean | { custom: ReactNode };\n  columnsControl?: ColumnsControlConfig;\n  rowDetailPanel?: RowDetailConfig<RowType>;\n  rowInstruments?: {\n    getRowDropdownConfig: RowInstrumentsType<RowType>;\n    /**\n     * @default false\n     */\n    defaultOpened?: boolean;\n    /**\n     * @default true\n     */\n    showInControl?: boolean;\n    /**\n     * Внешний стейт видимости\n     */\n    openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  };\n  fullScreenEnabled?: FullScreen;\n  keyText?: boolean | KeyTextConfig;\n  /**\n   * pagination - пропс для пагинации.\n   *\n   * Условие активации - наличие самого пропса pagination.\n   *\n   * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n   * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n   *\n   */\n  pagination?: PaginationProps;\n  /**\n   * searching - пропс для поиска по таблицу.\n   *\n   * Условие активации - наличие searching.enabled: true\n   *\n   */\n  /**\n   * Конфигурация табов в сайдбаре\n   */\n  sidebarConfig?: SidebarConfig;\n  searching?: SearchingProps;\n  /**\n   * onHeaderContextMenu - пропс для активации открытия контекстного меню.\n   *\n   */\n  onHeaderContextMenu?: HeaderContextMenuProps;\n  onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n  onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n    RowType,\n    SummaryRowType\n  >;\n} & Pick<\n  DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n  | 'summaryRowHeight'\n  | 'onFill'\n  | 'onCopy'\n  | 'onPaste'\n  | 'onCellClick'\n  | 'onCellDoubleClick'\n  | 'onCellContextMenu'\n  | 'onCellKeyDown'\n  | 'onSelectedCellChange'\n  | 'onScroll'\n  | 'onColumnResize'\n  | 'onColumnsReorder'\n  | 'enableVirtualization'\n  | 'rowClass'\n  | 'data-testid'\n  | 'headerRowHeight'\n>;\n```",
      "api": [
        {
          "typeName": "TableConfig",
          "source": "type TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *"
        }
      ],
      "stories": [
        {
          "exportName": "NoRowsCustomFallback",
          "displayName": "Кастомизация контента ",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n({ columnConfig, noRowsFallback }) => {\n    const [rows] = useState<Row[]>([]);\n\n    return (\n      <Table\n        tableConfig={{\n          noRowsFallback,\n\n          containerStyle: { height: 500 },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "NoRowsFallback",
          "displayName": "Нет данных",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n({ noRowsFallback, columnConfig }) => {\n    const [rows] = useState<Row[]>([]);\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          noRowsFallback,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "pagination",
      "legacy": true,
      "summary": "Клиентская и ручная пагинация",
      "docs": "# Table Pagination\n\n## Ключевые особенности\n\n- Клиентская и ручная пагинация\n- Контроль страницы и размера страницы\n- Отключение дефолтного поиска, сортировки и фильтрации при активной пагинации\n\n**tableConfig.pagination**\n\nТаблица поддерживает пагинацию. Для активации функционала в `tableConfig` заполняется `pagination`.\n\n## Особенности работы с пагинацией:\n\n### Отключение дефолтной сортировки и фильтрации\n\nПри активации `pagination` отключается дефолтная сортировка и фильтрация.\nНужно использовать версии данных фичей с ручным управлением. Например, для отправки на бэкенд выбранных фильтров и сортировки.\n\n**Причина:** Предполагается, что если есть pagination, то в таблице представлен не весь объем данных,\nпо этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные.\n\n### Адаптивные slots\n\nПо умолчанию ВЫКЛЮЧЕНА умная адаптация количества slots пагинации в зависимости от ширины контейнера таблицы и размера пагинации (`size`).\n\nПринцип работы:\n\nПри достижении минимальной ширины контейнера, когда остается только 1 slot под номер текущей страницы, автоматически отображаются навигационные стрелки в `leftContent` и `rightContent` для переключения между страницами.\n\nЭту функциональность можно включить, установив `responsiveSlots: true`, тогда количество slots будет фиксированным (задавать `slots` в props в таком случае не нужно), важно будет указать `value` в props для пагинации, как значение текущей выбранной страницы, все будет работать под капотом.\n\n## Основная информация\n\nС основной информацией по компоненту Пагинации можно ознакомиться по [ссылке на SDDS Pagination](https://plasma.sberdevices.ru/sdds-finai/components/pagination/)\n\n## Изменения в API относительно SDDS Pagination:\n\n### 1. Измененные пропсы:\n\n- **`onChangePageValue`** - добавлен параметр `scrollToTop: () => void` для автоматического скролла к началу новой страницы\n- **`onChange`** - добавлен параметр `scrollToTop: () => void` для автоматического скролла к началу новой страницы\n\n### 2. Дополнительные пропсы:\n\n- **`responsiveSlots`** - включение/выключение умной адаптации slots (по умолчанию `true`)\n- **`onResize`** - callback при изменении ширины контейнера пагинации\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-pagination-api--docs).",
      "apiDocs": "# Pagination API\n\n## PaginationProps\n\n```typescript\ntype PaginationProps = Omit<\n  ComponentProps<typeof Pagination>,\n  'onChangePageValue' | 'onChange'\n> & {\n  onChangePageValue?: (\n    page: number | undefined,\n    scrollToTop: () => void,\n  ) => void;\n  onChange?: (\n    newPage: number | undefined,\n    perPage: number | undefined,\n    scrollToTop: () => void,\n  ) => void;\n  /**\n   * Нужно ли активировать умную адаптацию изменения количества слотов в зависимости от ширины блока пагинации и от size\n   * @default false\n   */\n  responsiveSlots?: boolean;\n  /**\n   * Callback при ресайзе блока с пагинацией таблицы\n   */\n  onResize?: (width: number) => void;\n};\n```\n\n## PaginationSize\n\n```typescript\ntype PaginationSize = NonNullable<PaginationProps['size']>;\n```\n\n## PaginationSlots\n\n```typescript\ntype PaginationSlots = PaginationProps['slots'];\n```",
      "api": [
        {
          "typeName": "PaginationProps",
          "source": "type PaginationProps = Omit<\n  ComponentProps<typeof Pagination>,\n  'onChangePageValue' | 'onChange'\n> & {\n  onChangePageValue?: (\n    page: number | undefined,\n    scrollToTop: () => void,\n  ) => void;\n  onChange?: (\n    newPage: number | undefined,\n    perPage: number | undefined,\n    scrollToTop: () => void,\n  ) => void;\n  /**\n   * Нужно ли активировать умную адаптацию изменения количества слотов в зависимости от ширины блока пагинации и от size\n   * @default false\n   */\n  responsiveSlots?: boolean;\n  /**\n   * Callback при ресайзе блока с пагинацией таблицы\n   */\n  onResize?: (width: number) => void;\n};"
        },
        {
          "typeName": "PaginationSize",
          "source": "type PaginationSize = NonNullable<PaginationProps['size']>;"
        },
        {
          "typeName": "PaginationSlots",
          "source": "type PaginationSlots = PaginationProps['slots'];"
        }
      ],
      "stories": [
        {
          "exportName": "PaginationTable",
          "displayName": "Таблица с пагинацией",
          "type": "full-code",
          "code": "import { ColumnConfig, Table } from '@daisforge/ui';\n\n() => {\n    const total = 300;\n\n    const [perPage, setPerPage] = useState(20);\n    const [currentPage, setCurrentPage] = useState(1);\n    const [rows, setRows] = useState<Row[]>([]);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    // Загрузка данных при монтировании и при изменении страницы/perPage\n    useEffect(() => {\n      const loadData = async () => {\n        const data = await getPaginationDataAsync({\n          page: currentPage,\n          perPage,\n          total,\n        });\n        setRows(data);\n      };\n\n      loadData();\n    }, [currentPage, perPage]);\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          collapsing: {\n            enableCollapse: true,\n          },\n          pagination: {\n            count: total,\n            perPage,\n            value: currentPage, // Важно указать, при активации responsiveSlots\n            responsiveSlots: true,\n            onChangePageValue(page, scrollToTop) {\n              if (typeof page === 'number') {\n                setCurrentPage(page);\n                scrollToTop();\n              }\n            },\n            async onChange(page, perPage, scrollToTop) {\n              if (typeof page === 'number' && typeof perPage === 'number') {\n                setCurrentPage(page);\n                setPerPage(perPage);\n                scrollToTop();\n              }\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "PaginationTableFixedSlots",
          "displayName": "Таблица с фиксированным количеством slots",
          "type": "full-code",
          "code": "import { ColumnConfig, Table } from '@daisforge/ui';\n\n() => {\n    const total = 300;\n\n    const [perPage, setPerPage] = useState(20);\n    const [currentPage, setCurrentPage] = useState(1);\n    const [rows, setRows] = useState<Row[]>([]);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    useEffect(() => {\n      const loadData = async () => {\n        const data = await getPaginationDataAsync({\n          page: currentPage,\n          perPage,\n          total,\n        });\n        setRows(data);\n      };\n\n      loadData();\n    }, [currentPage, perPage]);\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          pagination: {\n            count: total,\n            slots: 9,\n            perPage,\n            onChangePageValue(page, scrollToTop) {\n              if (typeof page === 'number') {\n                setCurrentPage(page);\n                scrollToTop();\n              }\n            },\n            async onChange(page, perPage, scrollToTop) {\n              if (typeof page === 'number' && typeof perPage === 'number') {\n                setCurrentPage(page);\n                setPerPage(perPage);\n                scrollToTop();\n              }\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "rowHeight",
      "legacy": true,
      "summary": "Настройка высоты строк legacy `Table`.",
      "docs": "# RowHeight\n\nНастройка высоты строк legacy `Table`.\n\n## Ключевые особенности\n\n- Фиксированная высота через число\n- Динамическая высота через функцию `RowHeightFunc`\n- Доступ к текущему размеру строки при расчете высоты\n- Возможность подстраивать высоту под многострочный контент\n\n## Особенности\n\nФункция высоты вызывается для строк таблицы, поэтому держите вычисления легкими и мемоизируйте конфигурацию колонок.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-rowheight-api--docs).",
      "apiDocs": "# Row Height API\n\n## RowHeightFunc\n\n```typescript\ntype RowHeightFunc<RowType> = (\n  row: RowType,\n  currentRowSize: { rowSizeName: SIZE; rowSizeValue: number },\n) => number;\n```",
      "api": [
        {
          "typeName": "RowHeightFunc",
          "source": "type RowHeightFunc<RowType> = (\n  row: RowType,\n  currentRowSize: { rowSizeName: SIZE; rowSizeValue: number },\n) => number;"
        }
      ],
      "stories": [
        {
          "exportName": "RowHeight",
          "displayName": "Row height",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'id',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'loremIpsum',\n          name: 'Длинный текст',\n          width: 500,\n          renderCell: ({ row }) => (\n            <Box as=\"span\" $css={{ textWrap: 'wrap' }}>\n              {row.loremIpsum}\n            </Box>\n          ),\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    const rowHeight: RowHeightFunc<Row> = useCallback((r, currenRowSize) => {\n      const symbolWidth = 11.5;\n\n      const paddingInline = 16;\n      const widthOfLoremCol = 500 - paddingInline * 2;\n      const symbolsInOneLine = Math.round(widthOfLoremCol / symbolWidth);\n      const heightOfLineInitial = 22; // в css\n      const heightOfLine = heightOfLineInitial - 2; // скорректированный\n\n      const allSymbols = r.loremIpsum.length;\n\n      const countOfLine = Math.ceil(allSymbols / symbolsInOneLine);\n      const paddingBlock = Number(\n        SIZES[currenRowSize.rowSizeName].cell['padding-block'].slice(0, -2),\n      );\n\n      const neededHeight = heightOfLine * countOfLine + paddingBlock * 2;\n\n      return neededHeight > currenRowSize.rowSizeValue\n        ? neededHeight\n        : currenRowSize.rowSizeValue;\n    }, []);\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          rowHeight,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "rowDetailPanel",
      "legacy": true,
      "summary": "*tableConfig.rowDetailPanel**",
      "docs": "# Row Detail Panel\n\n**tableConfig.rowDetailPanel**\n\nРаскрывающиеся панели деталей для отдельных строк таблицы.\n\n## Ключевые особенности\n\n- Кастомный рендер содержимого через `renderRowDetail`\n- Контроль высоты панели: фиксированная или динамическая через функцию\n- Кастомные иконки раскрытия/закрытия\n- Совместимость с иерархическими таблицами (subRows)\n\n## Особенности\n\n- `expandButtonColumnKey` определяет, в какой колонке отображается кнопка раскрытия\n- `isRowWithDetail` позволяет включить панель только для определённых строк\n- `detailHeight` принимает число или функцию `(row) => number` для динамической высоты\n- Доступ к `useRefTableContext()` для программного управления выделением ячеек\n\n> Подробнее о типах и пропсах — [Row Detail Panel API](?path=/docs/локальные-компоненты-table-rowdetailpanel-api--docs)",
      "apiDocs": "# Row Detail Panel API\n\n## RowDetailConfig\n\n```typescript\ntype RowDetailConfig<RowType> = {\n  rowKeyGetter: (row: RowType) => string | number;\n  isRowWithDetail: (r: RowType) => boolean;\n  renderRowDetail: (props: {\n    row: RowType;\n    tabIndex: number;\n    onRowChange: (row: RowType) => void;\n    rowIdx: number;\n    colIdx: number;\n  }) => ReactNode;\n\n  detailHeight: number | ((r: RowType) => number);\n  expandButtonColumnKey: string;\n  icons?: Prettify<IconsPropType>;\n\n  // TODO  режим редактирования detailPanel  - выключен и убран из типов, если будет потребность, нужно доработать\n  // renderRowDetailEditing?: (props: {\n  //     row: RowType;\n  //     onRowChange: (row: RowType, commitChanges?: boolean) => void;\n  //     onClose: (commitChanges?: boolean, shouldFocusCell?: boolean) => void;\n  // }) => ReactNode;\n  // rowDetailIsEditable?: boolean | ((row: RowType) => boolean);\n};\n```",
      "api": [
        {
          "typeName": "RowDetailConfig",
          "source": "type RowDetailConfig<RowType> = {\n  rowKeyGetter: (row: RowType) => string | number;\n  isRowWithDetail: (r: RowType) => boolean;\n  renderRowDetail: (props: {\n    row: RowType;\n    tabIndex: number;\n    onRowChange: (row: RowType) => void;\n    rowIdx: number;\n    colIdx: number;\n  }) => ReactNode;\n\n  detailHeight: number | ((r: RowType) => number);\n  expandButtonColumnKey: string;\n  icons?: Prettify<IconsPropType>;\n\n  // TODO  режим редактирования detailPanel  - выключен и убран из типов, если будет потребность, нужно доработать\n  // renderRowDetailEditing?: (props: {\n  //     row: RowType;\n  //     onRowChange: (row: RowType, commitChanges?: boolean) => void;\n  //     onClose: (commitChanges?: boolean, shouldFocusCell?: boolean) => void;\n  // }) => ReactNode;\n  // rowDetailIsEditable?: boolean | ((row: RowType) => boolean);\n};"
        }
      ],
      "stories": [
        {
          "exportName": "RowDetailPanel",
          "displayName": "Row detail panel",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows, setRows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: (\n            <div\n              style={{\n                display: 'flex',\n                justifyContent: 'space-between',\n              }}\n            >\n              id\n              <IconSber size=\"xs\" color=\"inherit\" />\n            </div>\n          ),\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          editing: {\n            onRowsChange: setRows,\n            rowKeyGetter: (r) => r.id,\n          },\n\n          rowDetailPanel: {\n            rowKeyGetter: (r) => r.id,\n            isRowWithDetail: (r) => r.id === 2 || r.id === 3,\n            renderRowDetail: ({ row, onRowChange, tabIndex, rowIdx }) => {\n              const tableRef = useRefTableContext();\n              const [value, setValue] = useState(row.complete);\n\n              const applyChanging = () => {\n                onRowChange({\n                  ...row,\n                  complete: value,\n                });\n\n                if (tableRef) {\n                  tableRef.current?.selectCell({\n                    idx: 4,\n                    rowIdx: rowIdx - 1,\n                  });\n                }\n              };\n\n              return (\n                <div>\n                  complete {value}\n                  <br />\n                  <TextField\n                    tabIndex={tabIndex}\n                    type=\"number\"\n                    value={value}\n                    onChange={(e) => setValue(+e.target.value)}\n                    onKeyDown={inputStopPropagation}\n                  />\n                  <br />\n                  <Button onClick={applyChanging}>применить изменения</Button>\n                </div>\n              );\n            },\n            expandButtonColumnKey: 'issueType',\n            detailHeight: 300,\n            icons: ICONS_PROP,\n          },\n          enableVirtualization: false,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "RowDetailAndSubRows",
          "displayName": "RowDetailAndSubRows",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(() => createRowsTree());\n\n    const columns = useMemo<readonly ColumnConfig<TreeRow>[]>(\n      () => [\n        {\n          key: 'block',\n          name: 'Блок / Трайб / Продукт',\n\n          subRow: {\n            keyOfColumnInSubRow: (lvl) => {\n              switch (lvl) {\n                case 0:\n                  return 'block';\n                case 1:\n                  return 'tribe';\n                case 2:\n                  return 'product';\n                default:\n                  return 'block';\n              }\n            },\n          },\n          resizable: true,\n        },\n        {\n          key: 'blockActivity',\n          name: 'Активность блока',\n\n          title: '123',\n          subRow: {\n            isColumnWithArrow: true,\n          },\n        },\n        {\n          key: '',\n          minWidth: 170,\n\n          name: 'Локация трайба',\n          subRow: {\n            renderSubRowCell: (props, lvl) => {\n              if (lvl === 1) {\n                return (\n                  <Badge view=\"accent\" size=\"m\">\n                    {props.row?.tribeZone}\n                  </Badge>\n                );\n              }\n              return null;\n            },\n          },\n        },\n        {\n          key: 'q1',\n          name: 'Q1',\n\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n\n        {\n          key: 'q2',\n          name: 'Q2',\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n        {\n          key: 'q3',\n          name: 'Q3',\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n        {\n          key: 'q4',\n          name: 'Q4',\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n\n          rowDetailPanel: {\n            rowKeyGetter: (r) => r.id,\n            isRowWithDetail: (r) =>\n              r.id === 2 ||\n              r.id === '2tribe' ||\n              r.id === '2product' ||\n              r.id === 3,\n            renderRowDetail: ({ row }) => <div>rowDetail {row.id}</div>,\n            expandButtonColumnKey: 'blockActivity',\n            detailHeight: 500,\n          },\n          resizableColumn: true,\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "rowInstruments",
      "legacy": true,
      "summary": "Инструменты действий над строкой в legacy `Table`.",
      "docs": "# RowInstruments\n\nИнструменты действий над строкой в legacy `Table`.\n\n## Ключевые особенности\n\n- Конфигурация действий через `getRowDropdownConfig`\n- Кнопка действий может быть открыта по умолчанию\n- Управление видимостью через control block\n- Поддержка внешнего состояния открытия\n- Доступ к данным строки и индексу строки\n\n## Особенности\n\nRow instruments подходят для действий над одной строкой. Для действий над выбранным набором строк используйте `controlBlock.massActionPanel`.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-rowinstruments-api--docs).",
      "apiDocs": "# Row Instruments API\n\n## RowInstrumentsType\n\n```typescript\ntype RowInstrumentsType<RowType extends ObjectForExtending> =\n  (rowProps: {\n    row: RowType;\n    rowIdx: number;\n    onRowChange: (r: RowType) => void;\n    additional: HeaderContextValueTypeInstance<RowType>;\n  }) => {\n    items: (DropdownItemOption & {\n      onItemSelect?: (item: DropdownItemOption, event: SyntheticEvent) => void;\n    })[];\n    dropdownProps?: Partial<DropdownProps> & {\n      /**\n       * При количестве item-ов = 1:  использовать ли contentLeft ?? contentRight\n       * как иконку для основной кнопки и onItemSelect item-а как onClick основной кнопки\n       */\n      useItemContentAsButtonContent?: boolean;\n    };\n  };\n```\n\n## RowInstrumentsDropdownItemOption\n\n```typescript\ntype RowInstrumentsDropdownItemOption = Prettify<\n  DropdownItemOption & {\n    onItemSelect?: (item: DropdownItemOption, event: SyntheticEvent) => void;\n  }\n>;\n```",
      "api": [
        {
          "typeName": "RowInstrumentsType",
          "source": "type RowInstrumentsType<RowType extends ObjectForExtending> =\n  (rowProps: {\n    row: RowType;\n    rowIdx: number;\n    onRowChange: (r: RowType) => void;\n    additional: HeaderContextValueTypeInstance<RowType>;\n  }) => {\n    items: (DropdownItemOption & {\n      onItemSelect?: (item: DropdownItemOption, event: SyntheticEvent) => void;\n    })[];\n    dropdownProps?: Partial<DropdownProps> & {\n      /**\n       * При количестве item-ов = 1:  использовать ли contentLeft ?? contentRight\n       * как иконку для основной кнопки и onItemSelect item-а как onClick основной кнопки\n       */\n      useItemContentAsButtonContent?: boolean;\n    };\n  };"
        },
        {
          "typeName": "RowInstrumentsDropdownItemOption",
          "source": "type RowInstrumentsDropdownItemOption = Prettify<\n  DropdownItemOption & {\n    onItemSelect?: (item: DropdownItemOption, event: SyntheticEvent) => void;\n  }\n>;"
        }
      ],
      "stories": [
        {
          "exportName": "RowInstruments",
          "displayName": "Инструменты строк",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows, setRows] = useState(createRows);\n\n    const columnConfig = useMemo(\n      (): readonly ColumnConfig<Row>[] => [\n        {\n          key: 'id',\n          name: 'id',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n    const [value, setValue] = useState(1);\n\n    const getRowDropdownConfig = useCallback<RowInstrumentsType<Row>>(\n      ({ row, rowIdx }) => ({\n        items: [\n          ...(rowIdx === 0\n            ? [\n                {\n                  label: 'Увеличить счетчик',\n                  value: 'counter',\n                  onItemSelect: (_, e) => {\n                    e.preventDefault();\n                    setValue((prev) => prev + (rowIdx || 1));\n                  },\n                  dividerAfter: true,\n                } as RowInstrumentsDropdownItemOption,\n              ]\n            : []),\n          {\n            label: 'Удалить строку',\n            value: 'delete row',\n            onItemSelect: () => {\n              const index = rows.findIndex((r) => r.id === row.id);\n              if (index !== -1) {\n                setRows((prev) => {\n                  const newV = [...prev];\n\n                  newV.splice(index, 1);\n                  return newV;\n                });\n              }\n            },\n            contentLeft: <IconBoxOutline color=\"inherit\" />,\n          },\n          {\n            label: 'Добавить строку вниз',\n            value: 'add row',\n            onItemSelect: () => {\n              const index = rows.findIndex((r) => r.id === row.id);\n              if (index !== -1) {\n                setRows((prev) => {\n                  const newV = [...prev];\n                  const newRow: Row = {\n                    id: createSeededRandom(rows.length)() * 1000 + rows.length,\n                    task: '',\n                    priority: '',\n                    issueType: '',\n                    developer: '',\n                    complete: 0,\n                    tr: '',\n                    loremIpsum: '',\n                  } as Row;\n                  newV.splice(index + 1, 0, newRow);\n\n                  return newV;\n                });\n              }\n            },\n            contentLeft: <IconAddOutline color=\"inherit\" />,\n          },\n        ],\n      }),\n      [rows],\n    );\n\n    return (\n      <>\n        <Box $css={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n          <TextM>\n            Счетчик, который меняется в инструментах(последняя иконка) первой\n            строки\n          </TextM>\n          <Badge view=\"dark\" text={value.toString()} />\n        </Box>\n\n        <Table\n          tableConfig={{\n            containerStyle: { height: 700 },\n            rowInstruments: {\n              getRowDropdownConfig,\n              showInControl: true,\n              defaultOpened: false,\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        },
        {
          "exportName": "RowInstrumentsExternalVisibleState",
          "displayName": "Инструменты строк (внешнее управление)",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows, setRows] = useState(createRows);\n    const [isVisibleRowInstrument, setIsVisibleRowInstrument] = useState(false); // Внешнее управление\n\n    const columnConfig = useMemo(\n      (): readonly ColumnConfig<Row>[] => [\n        {\n          key: 'id',\n          name: 'id',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n    const [value, setValue] = useState(1);\n\n    const getRowDropdownConfig = useCallback<RowInstrumentsType<Row>>(\n      ({ row, rowIdx }) => ({\n        items: [\n          ...(rowIdx === 0\n            ? [\n                {\n                  label: 'Увеличить счетчик',\n                  value: 'counter',\n                  onItemSelect: (_, e) => {\n                    e.preventDefault();\n                    setValue((prev) => prev + (rowIdx || 1));\n                  },\n                  dividerAfter: true,\n                } as RowInstrumentsDropdownItemOption,\n              ]\n            : []),\n          {\n            label: 'Удалить строку',\n            value: 'delete row',\n            onItemSelect: () => {\n              const index = rows.findIndex((r) => r.id === row.id);\n              if (index !== -1) {\n                setRows((prev) => {\n                  const newV = [...prev];\n\n                  newV.splice(index, 1);\n                  return newV;\n                });\n              }\n            },\n            contentLeft: <IconBoxOutline color=\"inherit\" />,\n          },\n          {\n            label: 'Добавить строку вниз',\n            value: 'add row',\n            onItemSelect: () => {\n              const index = rows.findIndex((r) => r.id === row.id);\n              if (index !== -1) {\n                setRows((prev) => {\n                  const newV = [...prev];\n                  const newRow: Row = {\n                    id: createSeededRandom(rows.length)() * 1000 + rows.length,\n                    task: '',\n                    priority: '',\n                    issueType: '',\n                    developer: '',\n                    complete: 0,\n                    tr: '',\n                    loremIpsum: '',\n                  } as Row;\n                  newV.splice(index + 1, 0, newRow);\n\n                  return newV;\n                });\n              }\n            },\n            contentLeft: <IconAddOutline color=\"inherit\" />,\n          },\n        ],\n      }),\n      [rows],\n    );\n\n    return (\n      <>\n        <Box\n          $css={{\n            display: 'flex',\n            gap: '8px',\n            alignItems: 'center',\n            marginBottom: '10px',\n          }}\n        >\n          <TextM>\n            Счетчик, который меняется в инструментах(последняя иконка) первой\n            строки\n          </TextM>\n          <Badge view=\"dark\" text={value.toString()} />\n          <Button onClick={() => setIsVisibleRowInstrument((prev) => !prev)}>\n            {isVisibleRowInstrument\n              ? 'Закрыть RowInstruments'\n              : 'Открыть RowInstruments'}\n          </Button>\n        </Box>\n\n        <Table\n          tableConfig={{\n            containerStyle: { height: 700 },\n            rowInstruments: {\n              getRowDropdownConfig,\n              showInControl: true,\n              defaultOpened: false,\n              openedState: [isVisibleRowInstrument, setIsVisibleRowInstrument],\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "rowsGrouping",
      "legacy": true,
      "summary": "Группировка строк по выбранным колонкам",
      "docs": "# Группировка данных-строк\n\n## Ключевые особенности\n\n- Группировка строк по выбранным колонкам\n- Кастомизация grouped column и group button\n- Поддержка агрегированных значений в групповых строках\n\nДля активации фичи необходимо настроить `tableConfig?.rowsGrouping` и `columnConfig?.rowsGrouping` у нужных колонок.\n\n## Особенности\n\n- `tableConfig.rowsGrouping` хранит активные группировки, `rowKeyGetter` и настройки grouped column.\n- `columnConfig.rowsGrouping` включает колонку в список доступных группировок и позволяет переопределить рендер групповой строки.\n- `groupButton` настраивает элементы выпадающего списка и подсчёт активных группировок.\n- `groupRowReplaceTo` позволяет заменить данные сгруппированной строки в редких кастомных сценариях.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-rowsgrouping-api--docs).",
      "apiDocs": "# Rows Grouping API\n\n## RowsGrouping\n\n```typescript\ntype RowsGrouping<RowType extends ObjectForExtending> = {\n  /**\n   * массив группированных колонок и его setter\n   */\n  groupByState: [string[], React.Dispatch<React.SetStateAction<string[]>>];\n  /**\n   * Функция определения уникального id строки\n   */\n  rowKeyGetter: (row: RowType) => string | number;\n  /**\n   * Показывать ли кнопку «Группировать» в controlBlock.\n   * При `false` кнопка скрыта и не участвует в компрессии,\n   * но группировка строк продолжает работать от внешнего `groupByState`.\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * @default 'Группировка'\n   */\n  groupedColumnProps?: Partial<\n    Pick<\n      ColumnConfig<RowType>,\n      | 'name'\n      | 'resizable'\n      | 'width'\n      | 'minWidth'\n      | 'maxWidth'\n      | 'renderSummaryCell'\n    >\n  > & {\n    renderCell?: (\n      props: RenderCellProps<RowType> & {\n        parentGroupKey: string | undefined;\n        groupByArr: string[];\n      },\n    ) => ReactNode;\n    rowsGrouping?: Pick<ColumnRowsGrouping<RowType>, 'renderGroupCell'>;\n  };\n  expandAllBtn?: {\n    /**\n     * Функция для расчета состояния открытости всех раскрываемых строк. Функция должна быть чистой.\n     * @returns boolean\n     */\n    expandedAll: (p: {\n      /**\n       * allRowsIds - уникальные идентификаторы всех строк (группировок и обычных)\n       */\n      allRowsIds: Set<string | number> | null;\n      /**\n       * shownRows - представленные прямо сейчас строки (группировки и обычные). Или видимые строки - видимые не во viewport-е, а которые должны быть показаны из-за раскрытий)\n       */\n      shownRows: readonly RowType[];\n      expandedRowsIds: Set<string | number>;\n    }) => boolean;\n  };\n  /**\n   * `groupButton` - свойство для кастомизации кнопки с выпадающим списком\n   */\n  groupButton?: {\n    getGroupedCount?: (props: {\n      /**\n       * высчитанное автоматически количество активных группировок.\n       */\n      currCount: number;\n      /**\n       * активные группировки.\n       */\n      groupedCols: string[];\n      columns: {\n        /**\n         * `visible` - видимые в выпадающем списке колонки-группировки.\n         */\n        visible: string[];\n        /**\n         * `hidden` - невидимые  или не участвующие в группировке колонки\n         *\n         * (columnConfig.rowsGrouping=undefined ||\n         *  columnConfig.rowsGrouping.groupByColumn=false).\n         */\n        hidden: string[];\n      };\n    }) => number;\n    /**\n     * `defaultCustomItems` - свойство для добавления ключей группировки, которых нет в таблице.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    defaultCustomItems?: DropdownItemOption[];\n    /**\n     * `onItemSelect` - свойство для полного контроля над изменением группировки при выборе опций.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    onItemSelect?: (props: {\n      item: DropdownItemOption;\n      setGroupedCols: React.Dispatch<React.SetStateAction<string[]>>;\n      columns: {\n        visible: string[];\n        hidden: string[];\n      };\n    }) => void;\n  };\n  /**\n   * `groupRowReplaceTo` - свойство для изменения данных сгруппированных строк. Может понадобиться в редких случаях.\n   *\n   * @param groupRow данные сгруппированной строки\n   * @returns измененная группировка или строка без группировки — строка, которые заменит groupRow\n   */\n  groupRowReplaceTo?: (\n    groupRow: GroupRow<RowType>,\n  ) => GroupRow<RowType> | RowType;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n\nexport type RenderGroupCellProps<RowType, SummaryRowType = unknown> = {\n  column: CalculatedColumn<RowType, SummaryRowType>;\n  tabIndex: number;\n  // TODO isExpanded: boolean;\n  // TODO toggleGroup: () => void;\n} & GroupRow<RowType>;\nexport type ColumnRowsGrouping<RowType, SummaryRowType = unknown> = {\n  /**\n   * @default true - при наличии ColumnConfig.rowsGrouping\n   */\n  groupByColumn?: boolean;\n  /**\n   * @default ColumnConfig.key\n   */\n  columnGroupLabel?: string;\n  renderGroupCell?: (\n    props: RenderGroupCellProps<RowType, SummaryRowType>,\n  ) => ReactNode;\n};\n```\n\n## GroupRow\n\n```typescript\ntype GroupRow<RowType> = {\n  readonly childRows: readonly RowType[];\n  readonly childGroups: readonly RowType[] | Readonly<GroupRowsOrRows<RowType>>;\n  groupKey: string;\n  groupByKey: string;\n  groupParents: string;\n};\n```\n\n## ColumnRowsGrouping\n\n```typescript\ntype ColumnRowsGrouping<RowType, SummaryRowType = unknown> = {\n  /**\n   * @default true - при наличии ColumnConfig.rowsGrouping\n   */\n  groupByColumn?: boolean;\n  /**\n   * @default ColumnConfig.key\n   */\n  columnGroupLabel?: string;\n  renderGroupCell?: (\n    props: RenderGroupCellProps<RowType, SummaryRowType>,\n  ) => ReactNode;\n};\n```\n\n## RenderGroupCellProps\n\n```typescript\ntype RenderGroupCellProps<RowType, SummaryRowType = unknown> = {\n  column: CalculatedColumn<RowType, SummaryRowType>;\n  tabIndex: number;\n  // TODO isExpanded: boolean;\n  // TODO toggleGroup: () => void;\n} & GroupRow<RowType>;\n```",
      "api": [
        {
          "typeName": "RowsGrouping",
          "source": "type RowsGrouping<RowType extends ObjectForExtending> = {\n  /**\n   * массив группированных колонок и его setter\n   */\n  groupByState: [string[], React.Dispatch<React.SetStateAction<string[]>>];\n  /**\n   * Функция определения уникального id строки\n   */\n  rowKeyGetter: (row: RowType) => string | number;\n  /**\n   * Показывать ли кнопку «Группировать» в controlBlock.\n   * При `false` кнопка скрыта и не участвует в компрессии,\n   * но группировка строк продолжает работать от внешнего `groupByState`.\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * @default 'Группировка'\n   */\n  groupedColumnProps?: Partial<\n    Pick<\n      ColumnConfig<RowType>,\n      | 'name'\n      | 'resizable'\n      | 'width'\n      | 'minWidth'\n      | 'maxWidth'\n      | 'renderSummaryCell'\n    >\n  > & {\n    renderCell?: (\n      props: RenderCellProps<RowType> & {\n        parentGroupKey: string | undefined;\n        groupByArr: string[];\n      },\n    ) => ReactNode;\n    rowsGrouping?: Pick<ColumnRowsGrouping<RowType>, 'renderGroupCell'>;\n  };\n  expandAllBtn?: {\n    /**\n     * Функция для расчета состояния открытости всех раскрываемых строк. Функция должна быть чистой.\n     * @returns boolean\n     */\n    expandedAll: (p: {\n      /**\n       * allRowsIds - уникальные идентификаторы всех строк (группировок и обычных)\n       */\n      allRowsIds: Set<string | number> | null;\n      /**\n       * shownRows - представленные прямо сейчас строки (группировки и обычные). Или видимые строки - видимые не во viewport-е, а которые должны быть показаны из-за раскрытий)\n       */\n      shownRows: readonly RowType[];\n      expandedRowsIds: Set<string | number>;\n    }) => boolean;\n  };\n  /**\n   * `groupButton` - свойство для кастомизации кнопки с выпадающим списком\n   */\n  groupButton?: {\n    getGroupedCount?: (props: {\n      /**\n       * высчитанное автоматически количество активных группировок.\n       */\n      currCount: number;\n      /**\n       * активные группировки.\n       */\n      groupedCols: string[];\n      columns: {\n        /**\n         * `visible` - видимые в выпадающем списке колонки-группировки.\n         */\n        visible: string[];\n        /**\n         * `hidden` - невидимые  или не участвующие в группировке колонки\n         *\n         * (columnConfig.rowsGrouping=undefined ||\n         *  columnConfig.rowsGrouping.groupByColumn=false).\n         */\n        hidden: string[];\n      };\n    }) => number;\n    /**\n     * `defaultCustomItems` - свойство для добавления ключей группировки, которых нет в таблице.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    defaultCustomItems?: DropdownItemOption[];\n    /**\n     * `onItemSelect` - свойство для полного контроля над изменением группировки при выборе опций.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    onItemSelect?: (props: {\n      item: DropdownItemOption;\n      setGroupedCols: React.Dispatch<React.SetStateAction<string[]>>;\n      columns: {\n        visible: string[];\n        hidden: string[];\n      };\n    }) => void;\n  };\n  /**\n   * `groupRowReplaceTo` - свойство для изменения данных сгруппированных строк. Может понадобиться в редких случаях.\n   *\n   * @param groupRow данные сгруппированной строки\n   * @returns измененная группировка или строка без группировки — строка, которые заменит groupRow\n   */\n  groupRowReplaceTo?: (\n    groupRow: GroupRow<RowType>,\n  ) => GroupRow<RowType> | RowType;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n\nexport type RenderGroupCellProps<RowType, SummaryRowType = unknown> = {\n  column: CalculatedColumn<RowType, SummaryRowType>;\n  tabIndex: number;\n  // TODO isExpanded: boolean;\n  // TODO toggleGroup: () => void;\n} & GroupRow<RowType>;\nexport type ColumnRowsGrouping<RowType, SummaryRowType = unknown> = {\n  /**\n   * @default true - при наличии ColumnConfig.rowsGrouping\n   */\n  groupByColumn?: boolean;\n  /**\n   * @default ColumnConfig.key\n   */\n  columnGroupLabel?: string;\n  renderGroupCell?: (\n    props: RenderGroupCellProps<RowType, SummaryRowType>,\n  ) => ReactNode;\n};"
        },
        {
          "typeName": "GroupRow",
          "source": "type GroupRow<RowType> = {\n  readonly childRows: readonly RowType[];\n  readonly childGroups: readonly RowType[] | Readonly<GroupRowsOrRows<RowType>>;\n  groupKey: string;\n  groupByKey: string;\n  groupParents: string;\n};"
        },
        {
          "typeName": "ColumnRowsGrouping",
          "source": "type ColumnRowsGrouping<RowType, SummaryRowType = unknown> = {\n  /**\n   * @default true - при наличии ColumnConfig.rowsGrouping\n   */\n  groupByColumn?: boolean;\n  /**\n   * @default ColumnConfig.key\n   */\n  columnGroupLabel?: string;\n  renderGroupCell?: (\n    props: RenderGroupCellProps<RowType, SummaryRowType>,\n  ) => ReactNode;\n};"
        },
        {
          "typeName": "RenderGroupCellProps",
          "source": "type RenderGroupCellProps<RowType, SummaryRowType = unknown> = {\n  column: CalculatedColumn<RowType, SummaryRowType>;\n  tabIndex: number;\n  // TODO isExpanded: boolean;\n  // TODO toggleGroup: () => void;\n} & GroupRow<RowType>;"
        }
      ],
      "stories": [
        {
          "exportName": "SimpleTable",
          "displayName": "Группировка строк - Группировка данных - Агрегация данных",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRowsForGrouping);\n\n    const [groupByArr, setGroupByArr] = useState<string[]>([]);\n\n    const columnConfig = useMemo<readonly ColumnConfig<RowForGrouping>[]>(\n      () => [\n        {\n          key: 'athlete',\n          name: 'Athlete',\n          rowsGrouping: {\n            columnGroupLabel: 'Athlete',\n          },\n        },\n        {\n          key: 'sport',\n          name: 'Sport',\n\n          rowsGrouping: {\n            columnGroupLabel: 'Sport',\n          },\n        },\n        {\n          key: 'country',\n          name: 'Country',\n\n          rowsGrouping: {\n            columnGroupLabel: 'Country',\n          },\n        },\n        {\n          key: 'year',\n          name: 'Year',\n\n          rowsGrouping: {\n            columnGroupLabel: 'Year',\n          },\n        },\n\n        {\n          key: 'gold',\n          name: 'Gold',\n          rowsGrouping: {\n            groupByColumn: false,\n            columnGroupLabel: 'Gold',\n            renderGroupCell({ childRows }) {\n              return childRows.reduce((prev, { gold }) => prev + gold, 0);\n            },\n          },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          columnsControl: {\n            enable: true,\n          },\n          rowsGrouping: {\n            rowKeyGetter: (r) => r.id,\n            groupByState: [groupByArr, setGroupByArr],\n\n            groupButton: {\n              defaultCustomItems: [\n                { value: 'gold', label: 'Gold as custom option' },\n              ],\n            },\n            groupedColumnProps: {\n              maxWidth: 500,\n              width: 350,\n              minWidth: 250,\n              renderCell: (props) => {\n                if (props.parentGroupKey === 'Russian Federation') {\n                  return 'Russia last lvl';\n                }\n                return props.parentGroupKey;\n              },\n              rowsGrouping: {\n                renderGroupCell(props) {\n                  if (props.groupKey === 'Russian Federation') {\n                    return 'Russia';\n                  }\n                  return props.groupKey;\n                },\n              },\n            },\n            // groupRowReplaceTo(groupRow) {\n            //   if (\n            //     groupRow.groupKey === 'Russian Federation' &&\n            //     groupRow.childRows[0]\n            //   ) {\n            //     return groupRow.childRows[0];\n            //   }\n            //   return groupRow;\n            // },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "MultipleFeaturesTable",
          "displayName": "Комбинация фичи группировка строк и других фичей",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRowsForGrouping);\n\n    const [groupByArr, setGroupByArr] = useState<string[]>([]);\n\n    const columnConfig = useMemo<readonly ColumnConfig<RowForGrouping>[]>(\n      () => [\n        {\n          key: 'athlete',\n          name: 'Athlete',\n          sortingType: 'stringSort',\n          rowsGrouping: {\n            columnGroupLabel: 'Athlete',\n          },\n          filtering: {\n            component: 'input',\n            filter: 'includes',\n            valueInRow: (r) => r.athlete,\n            keyInFilterState: 'athlete',\n          },\n        },\n        {\n          key: 'sport',\n          name: 'Sport',\n          sortingType: 'stringSort',\n          rowsGrouping: {\n            columnGroupLabel: 'Sport',\n          },\n          filtering: {\n            component: 'input',\n            filter: 'includes',\n            valueInRow: (r) => r.sport,\n            keyInFilterState: 'sport',\n          },\n        },\n        {\n          key: 'country',\n          name: 'Country',\n          sortingType: 'stringSort',\n          rowsGrouping: {\n            columnGroupLabel: 'Country',\n          },\n          filtering: {\n            component: 'input',\n            filter: 'startWith',\n            valueInRow: (r) => r.country,\n            keyInFilterState: 'country',\n          },\n        },\n        {\n          key: 'year',\n          name: 'Year',\n          sortingType: 'numberSort',\n          rowsGrouping: {\n            columnGroupLabel: 'Year',\n          },\n          filtering: {\n            component: 'input',\n            filter: 'startWith',\n            valueInRow: (r) => r.year,\n            keyInFilterState: 'year',\n          },\n        },\n\n        {\n          key: 'gold',\n          name: 'Gold',\n          sortingType: 'numberSort',\n          rowsGrouping: {\n            columnGroupLabel: 'Gold',\n            renderGroupCell({ childRows }) {\n              return childRows.reduce((prev, { gold }) => prev + gold, 0);\n            },\n          },\n        },\n      ],\n      [],\n    );\n    const sortingStateAndSetter = useState<readonly SortColumn[]>([]);\n\n    const filteringStateAndSetter = useState({\n      athlete: '',\n      sport: '',\n      gold: '',\n      country: '',\n      year: '',\n    });\n\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n    const rowCheckboxDisabled = (r: RowForGrouping) => r.id === 1;\n    const getRowDropdownConfig = useCallback<\n      RowInstrumentsType<RowForGrouping>\n    >(({ row }) => {\n      if (isGroupRow(row)) {\n        return {\n          items: [{ value: 'kek2', label: 'grouped kek' }],\n        };\n      }\n      return {\n        items: [{ value: 'kek', label: 'kek label' }],\n      };\n    }, []);\n\n    return (\n      <Table\n        tableConfig={{\n          rowInstruments: {\n            getRowDropdownConfig,\n            defaultOpened: true,\n          },\n          columnsControl: {\n            enable: true,\n          },\n          containerStyle: { height: 700 },\n          rowsGrouping: {\n            rowKeyGetter: (r) => r.id,\n            groupByState: [groupByArr, setGroupByArr],\n            groupedColumnProps: {\n              name: <>моя группировка</>,\n              resizable: true,\n            },\n          },\n          resizableColumn: true,\n          sorting: {\n            state: sortingStateAndSetter,\n          },\n          filtering: {\n            state: filteringStateAndSetter,\n            clearedValue: {\n              athlete: '',\n              sport: '',\n              gold: '',\n              country: '',\n              year: '',\n            },\n          },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id,\n            showDefault: true,\n            rowCheckboxDisabled,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "rowSize",
      "legacy": true,
      "summary": "Настройка размера строк",
      "docs": "# TableRowSize\n\n## Ключевые особенности\n\n- Настройка размера строк\n- Переключение размера через controlBlock\n- Дефолтный размер и список доступных размеров\n\n**tableConfig.rowSize**\n\nДоступно три варианта размера высоты строк `'small' | 'medium' | 'big'`. При включении флага `showInControl: true` появляется кнопка\nв блоке управления. С помощью `available` можно указать из каких вариантов пользователь будет переключать размер строк. Не обязательно пользователю\nдавать выбирать размер строк, при этом можно задать значение по умолчанию `default`.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-rowsize-api--docs).",
      "apiDocs": "# Row Size API\n\n## RowSize\n\n```typescript\ntype RowSize = {\n  /**\n   * Показывать кнопку в блоке управления\n   */\n  showInControl: boolean;\n  /**\n   * Значение по умолчанию\n   */\n  default?: SIZE;\n  /**\n   * Список доступных значений размера\n   */\n  available?: SIZE[];\n  /**\n   * Обработчик изменения rowSize\n   * @param size\n   * @returns\n   */\n  onRowSizeChange?: (size: SIZE) => void;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n```",
      "api": [
        {
          "typeName": "RowSize",
          "source": "type RowSize = {\n  /**\n   * Показывать кнопку в блоке управления\n   */\n  showInControl: boolean;\n  /**\n   * Значение по умолчанию\n   */\n  default?: SIZE;\n  /**\n   * Список доступных значений размера\n   */\n  available?: SIZE[];\n  /**\n   * Обработчик изменения rowSize\n   * @param size\n   * @returns\n   */\n  onRowSizeChange?: (size: SIZE) => void;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "RowSize",
          "displayName": "Высота строк",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          rowSize: {\n            showInControl: true,\n            default: 'small',\n            available: ['small', 'medium', 'big'],\n            onRowSizeChange: (size) => {\n              // eslint-disable-next-line no-console\n              console.debug('rowSize changed:', size);\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "searching",
      "legacy": true,
      "summary": "Контролируемый и неконтролируемый поиск",
      "docs": "# Searching (Table)\n\n## Ключевые особенности\n\n- Контролируемый и неконтролируемый поиск\n- Ручной поиск для серверных сценариев\n- История автодополнения в поиске\n\nКомпонент Table предоставляет расширенные возможности поиска по данным, включая клиентскую и серверную фильтрацию, а также автокомплит с подсказками.\n\n## Основные возможности\n\n- Включение/выключение функционала поиска (`enabled`)\n- Начальное значение поиска (`defaultSearchQuery`)\n- Управление видимостью UI поиска (`showSearchBlock`)\n- Контролируемый и неконтролируемый режимы (`searchQueryState`)\n- Настройка debounce для оптимизации производительности (`debounceDelay`)\n- Ручной режим поиска — по Enter или клику (`searchOnType: false`)\n- Автокомплит с подсказками (`autocomplete`)\n\n## Режимы поиска\n\n### Автоматический (по умолчанию)\n\nПоиск запускается при вводе текста с debounce. Подходит для клиентской фильтрации.\n\n### По нажатию (`searchOnType: false`)\n\nПоиск запускается только по нажатию Enter или клику на иконку. Подходит для серверной фильтрации и больших наборов данных.\n\n### Ручной (`manualSearching: true`)\n\nФронтенд-фильтрация отключена. Данные фильтруются на бэкенде, результат передаётся в `rows`.\n\n## Автокомплит\n\nПри передаче `autocomplete` в конфигурацию поиска поле ввода заменяется на компонент Autocomplete с выпадающим списком подсказок. С помощью пропсов Autocomplete можно настроить историю поиска, кастомизировать рендер элементов и другое. Подробнее — в разделе [API](?path=/docs/локальные-компоненты-table-searching-api--docs).\n\n## Пагинация и поиск\n\n> **Важно:** если в таблице используется пагинация, поиск необходимо либо **отключать**, либо **переводить в ручной режим** (`manualSearching: true`) и фильтровать строки самостоятельно с учётом всех страниц, взаимодействуя с бэкендом. Клиентский поиск при пагинации будет фильтровать только текущую страницу, что приведёт к некорректным результатам.\n\n## Приоритет фильтрации\n\n1. Сначала применяется глобальный поиск (если `manualSearching` выключен)\n2. Затем применяются колоночные фильтры (если есть)",
      "apiDocs": "# Searching API\n\n## SearchingProps\n\n```typescript\ntype SearchingProps = {\n  /**\n   * Активация функционала поиска (обязательный параметр)\n   */\n  enabled: boolean;\n\n  /**\n   * Если true - поиск НЕ будет работать на фронте (ручное управление)\n   * Полезно когда поисковая логика полностью управляется на бэкенде\n   */\n  manualSearching?: boolean;\n\n  /**\n   * Начальное значение поискового запроса\n   */\n  defaultSearchQuery?: string;\n\n  /**\n   * Видимость UI блока поиска\n   */\n  showSearchBlock?: boolean;\n\n  /**\n   * Состояние и сеттер для контролируемого режима\n   * [текущее значение, функция установки значения]\n   */\n  searchQueryState?: [string, React.Dispatch<React.SetStateAction<string>>];\n\n  /**\n   * Обработчик изменения с debounce\n   * Вызывается с задержкой после окончания ввода\n   * @param value - текущее значение поискового запроса\n   */\n  onDebouncedChange?: (value: string) => void;\n\n  /**\n   * Мгновенный обработчик изменений\n   * Вызывается при каждом изменении input\n   * @param value - текущее значение поискового запроса\n   */\n  onChange?: (value: string) => void;\n\n  /**\n   * Задержка для debounce (в миллисекундах)\n   * @default 300\n   */\n  debounceDelay?: number;\n\n  /**\n   * Активация debounce механизма\n   * @default true\n   */\n  isDebounceActive?: boolean;\n\n  /**\n   * Дополнительные классы для контейнера поиска\n   */\n  searchClasses?: string;\n\n  /**\n   * Placeholder для поискового input\n   * @default \"Поиск\"\n   */\n  placeholder?: string;\n\n  /**\n   * DOM метаданные для аналитики и онбординга\n   */\n  domMetadata?: DomMetadata;\n\n  /**\n   * Режим запуска поиска\n   * - true: поиск запускается автоматически при вводе текста (по умолчанию)\n   * - false: поиск запускается только по клику на иконку поиска или нажатию Enter\n   */\n  searchOnType?: boolean;\n\n  /**\n   * Конфигурация автокомплита для поиска.\n   * При передаче поле поиска заменяется на Autocomplete с подсказками.\n   */\n  autocomplete?: SearchAutocompleteConfig;\n};\n```\n\n## SearchAutocompleteConfig\n\n```typescript\ntype SearchAutocompleteConfig = Pick<\n  AutocompleteProps,\n  | 'suggestions'\n  | 'onSuggestionSelect'\n  | 'threshold'\n  | 'renderList'\n  | 'renderListEnd'\n  | 'beforeList'\n  | 'listMaxHeight'\n  | 'listWidth'\n  | 'portal'\n  | 'hasDivider'\n  | 'beforeList'\n  | 'afterList'\n  | 'virtual'\n  | 'hasDivider'\n  | 'onScroll'\n  | 'zIndex'\n  | 'filter'\n  | 'renderItem'\n>;\n```\n\n## Примеры конфигурации\n\n### Базовый поиск\n\n```tsx\n<Table\n  tableConfig={{\n    searching: {\n      enabled: true,\n    },\n  }}\n  columnConfig={columnConfig}\n  rows={rows}\n/>\n```\n\n### Серверный поиск\n\n```tsx\n<Table\n  tableConfig={{\n    searching: {\n      enabled: true,\n      manualSearching: true,\n      onDebouncedChange: (value) => fetchData({ search: value }),\n    },\n  }}\n  columnConfig={columnConfig}\n  rows={rows}\n/>\n```\n\n### Автокомплит с историей\n\n```tsx\n<Table\n  tableConfig={{\n    searching: {\n      enabled: true,\n      autocomplete: {\n        suggestions: [{ label: 'Запрос 1' }, { label: 'Запрос 2' }],\n        threshold: 0,\n        listMaxHeight: '200px',\n        onSuggestionSelect: (item) => console.log(item.label),\n      },\n    },\n  }}\n  columnConfig={columnConfig}\n  rows={rows}\n/>\n```",
      "api": [
        {
          "typeName": "SearchingProps",
          "source": "type SearchingProps = {\n  /**\n   * Активация функционала поиска (обязательный параметр)\n   */\n  enabled: boolean;\n\n  /**\n   * Если true - поиск НЕ будет работать на фронте (ручное управление)\n   * Полезно когда поисковая логика полностью управляется на бэкенде\n   */\n  manualSearching?: boolean;\n\n  /**\n   * Начальное значение поискового запроса\n   */\n  defaultSearchQuery?: string;\n\n  /**\n   * Видимость UI блока поиска\n   */\n  showSearchBlock?: boolean;\n\n  /**\n   * Состояние и сеттер для контролируемого режима\n   * [текущее значение, функция установки значения]\n   */\n  searchQueryState?: [string, React.Dispatch<React.SetStateAction<string>>];\n\n  /**\n   * Обработчик изменения с debounce\n   * Вызывается с задержкой после окончания ввода\n   * @param value - текущее значение поискового запроса\n   */\n  onDebouncedChange?: (value: string) => void;\n\n  /**\n   * Мгновенный обработчик изменений\n   * Вызывается при каждом изменении input\n   * @param value - текущее значение поискового запроса\n   */\n  onChange?: (value: string) => void;\n\n  /**\n   * Задержка для debounce (в миллисекундах)\n   * @default 300\n   */\n  debounceDelay?: number;\n\n  /**\n   * Активация debounce механизма\n   * @default true\n   */\n  isDebounceActive?: boolean;\n\n  /**\n   * Дополнительные классы для контейнера поиска\n   */\n  searchClasses?: string;\n\n  /**\n   * Placeholder для поискового input\n   * @default \"Поиск\"\n   */\n  placeholder?: string;\n\n  /**\n   * DOM метаданные для аналитики и онбординга\n   */\n  domMetadata?: DomMetadata;\n\n  /**\n   * Режим запуска поиска\n   * - true: поиск запускается автоматически при вводе текста (по умолчанию)\n   * - false: поиск запускается только по клику на иконку поиска или нажатию Enter\n   */\n  searchOnType?: boolean;\n\n  /**\n   * Конфигурация автокомплита для поиска.\n   * При передаче поле поиска заменяется на Autocomplete с подсказками.\n   */\n  autocomplete?: SearchAutocompleteConfig;\n};"
        },
        {
          "typeName": "SearchAutocompleteConfig",
          "source": "type SearchAutocompleteConfig = Pick<\n  AutocompleteProps,\n  | 'suggestions'\n  | 'onSuggestionSelect'\n  | 'threshold'\n  | 'renderList'\n  | 'renderListEnd'\n  | 'beforeList'\n  | 'listMaxHeight'\n  | 'listWidth'\n  | 'portal'\n  | 'hasDivider'\n  | 'beforeList'\n  | 'afterList'\n  | 'virtual'\n  | 'hasDivider'\n  | 'onScroll'\n  | 'zIndex'\n  | 'filter'\n  | 'renderItem'\n>;"
        }
      ],
      "stories": [
        {
          "exportName": "ControlSearching",
          "displayName": "Контролируемый поиск",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n    const [query, setQuery] = useState('Bug');\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          searching: {\n            enabled: true,\n            defaultSearchQuery: 'Epic',\n            showSearchBlock: true,\n            onChange: (value) => console.debug('onChange searching', value),\n            onDebouncedChange: (value) =>\n              console.debug('onDebouncedChange searching', value),\n            searchQueryState: [query, setQuery],\n            debounceDelay: 350,\n            placeholder: 'Введите сумму',\n            searchClasses: 'someClassForSearch',\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "UncontrolledSearching",
          "displayName": "Неконтролируемый поиск",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          searching: {\n            enabled: true,\n            defaultSearchQuery: 'Epic',\n            showSearchBlock: true,\n            onChange: (value) => console.debug('onChange searching', value),\n            onDebouncedChange: (value) =>\n              console.debug('onDebouncedChange searching', value),\n            debounceDelay: 550,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ManualSearching",
          "displayName": "Manual поиск",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows, setRows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          searching: {\n            enabled: true,\n            manualSearching: true,\n            defaultSearchQuery: '',\n            showSearchBlock: true,\n            onChange: (value) => console.debug('onChange searching', value),\n            onDebouncedChange: (value) => {\n              console.debug('onDebouncedChange searching', value);\n              // fetchData from server => then setRows for example\n              setRows(createRows(0, 10));\n            },\n            debounceDelay: 550,\n          },\n          containerStyle: { height: 700 },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "AutocompleteHistory",
          "displayName": "Autocomplete (история поиска)",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n    const [searchHistory, setSearchHistory] = useState<string[]>([\n      'Epi',\n      'Bug',\n      'Improvement',\n      '19.628582577979465asdf97.58738810084174',\n      'Critical',\n      'High',\n      'Story',\n      'Task',\n    ]);\n    const lastSubmittedRef = useRef('');\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n        { key: 'issueType', name: 'Issue Type' },\n        { key: 'developer', name: 'Developer' },\n      ],\n      [],\n    );\n\n    const addToHistory = useCallback((value: string) => {\n      if (!value.trim() || value === lastSubmittedRef.current) return;\n      lastSubmittedRef.current = value;\n      setSearchHistory((prev) => {\n        const filtered = prev.filter((item) => item !== value);\n        return [value, ...filtered].slice(0, 10);\n      });\n    }, []);\n\n    const suggestions = useMemo(\n      () => searchHistory.map((label) => ({ label })),\n      [searchHistory],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          searching: {\n            enabled: true,\n            showSearchBlock: true,\n            onDebouncedChange: (value) => {\n              console.debug('search:', value);\n              addToHistory(value);\n            },\n            debounceDelay: 300,\n            placeholder: 'Поиск',\n            autocomplete: {\n              suggestions,\n              threshold: 0,\n              listMaxHeight: '200px',\n\n              onSuggestionSelect: (suggestion) => {\n                console.debug('selected:', suggestion.label);\n              },\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "selecting",
      "legacy": true,
      "summary": "*tableConfig.selecting**",
      "docs": "# Selecting Row\n\n**tableConfig.selecting**\n\nВыбор строк таблицы с помощью чекбоксов.\n\n## Ключевые особенности\n\n- Управляемое состояние через `ReadonlySet<string | number>`\n- Кнопка переключения видимости в control block (`showInControl: true`)\n- Контроль на уровне строк: `rowCheckboxDisabled`, `rowShowCheckbox`\n- Поддержка иерархических таблиц через `selectingRules.levels`\n- Кастомизация summary-чекбокса через `summaryChecked`\n- Полное переопределение логики через `rowGetStates`\n\n## Особенности\n\n- `rowKeyGetter` должен возвращать уникальный идентификатор строки\n- В иерархических таблицах `selectingRules.levels` определяет, на каких уровнях доступен выбор\n- `summaryChecked` позволяет кастомизировать логику «Выбрать все»\n- `rowGetStates` переопределяет `checked`, `indeterminate`, `showCheckbox`, `checkboxDisabled` для каждой строки\n\n> Подробнее о типах и пропсах — [Selecting Row API](?path=/docs/локальные-компоненты-table-selectingrow-api--docs)\n\n# TableRowsGrouping\n\n## Ключевые особенности\n\n- Выбор строк в группированной таблице\n- Кастомная логика checked/indeterminate для групп\n- Совместная работа selecting и rowsGrouping\n\n**tableConfig.selecting**\n\n**tableConfig.rowsGrouping**\n\n**columnConfig.rowsGrouping**\n\nОписание типов - в разделах [Selecting API](?path=/docs/локальные-компоненты-table-selectingrow-api--docs) и [RowsGrouping API](?path=/docs/локальные-компоненты-table-rowsgrouping-api--docs).",
      "apiDocs": "# Selecting Row API\n\n## SelectingRowConfig\n\n```typescript\ntype SelectingRowConfig<\n  RowType,\n  RowIdType extends string | number = string | number,\n> = {\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n   */\n  showDefault?: boolean;\n  /**\n   * showState - состояние, отвечающее за то, видны ли чекбоксы.\n   */\n  showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n   */\n  showInControl?: boolean;\n  /**\n   * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n   */\n  selectingRules?: {\n    /**\n     * изменять ли скрытые строки при клике на чекбокс-ы родительских строк\n     * @default true\n     */\n    // changeableOfRowWithoutCheckbox?: boolean;\n    /**\n     * изменять ли задизейбленные строки при клике на чекбокс-ы родительских строк\n     * @default true\n     */\n    // changeableDisabledRow?: boolean;\n    /**\n     * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n     */\n    levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n  };\n  disableSummaryCheckboxInHeader?: boolean;\n  hideSummaryCheckboxInHeader?: boolean;\n  /**\n   * hideSummaryCheckbox - в островке  массовых действий\n   */\n  hideSummaryCheckbox?: boolean;\n  /**\n   * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n   */\n  summaryChecked?: {\n    checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n    indeterminate:\n      | boolean\n      | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n    getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n    onChange: SummaryCheckedFunc<\n      RowType,\n      void,\n      {\n        checkedAll: boolean;\n        clearButtonClicked?: boolean;\n        setSelectedRowsIds: React.Dispatch<\n          React.SetStateAction<ReadonlySet<string | number>>\n        >;\n      }\n    >;\n  };\n\n  /**\n   * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n   */\n  summaryCheckedUncontrolled?: {\n    onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n  };\n\n  /**\n   * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n   */\n  rowShowCheckbox?: RowShowCheckbox<RowType>;\n  /**\n   * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n   */\n  rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n\n  /**\n   * Функция для переопределения checked, indeterminate для каждой строки.\n   * Что будет возвращено функцией в объекте, то будет переопределено.\n   */\n  rowGetStates?: (\n    p: RowGetStatesProps<RowType, RowIdType>,\n  ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n\n  groupedRow?: {\n    /**\n     * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n     * Что будет возвращено функцией в объекте, то будет переопределено.\n     */\n    getStates: (p: {\n      checkedCalculated: boolean;\n      indeterminateCalculated: boolean;\n      row: GroupRow<RowType>;\n      selectedRows: ReadonlySet<string | number>;\n      selectedChildCount: number;\n      childCount: number;\n    }) => {\n      checked?: boolean | null;\n      indeterminate?: boolean | null;\n      showCheckbox?: boolean | null;\n      checkboxDisabled?: boolean | null;\n    } | null;\n    onChange?: (p: {\n      row: GroupRow<RowType>;\n\n      setSelectedRows: React.Dispatch<\n        React.SetStateAction<ReadonlySet<string | number>>\n      >;\n      checked: boolean;\n      indeterminate: boolean;\n      checkboxDisabled: boolean;\n      showCheckbox: boolean;\n      defaultSetter: () => void;\n    }) => void;\n  };\n};\n```\n\n## ChildrenInfo\n\n```typescript\ntype ChildrenInfo<RowType, RowIdType> = {\n  /**\n   * все дочерние строки\n   */\n  all: RowType[];\n  /**\n   * все дочерние строки, которые disabled\n   */\n  disabled: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ disabled\n   */\n  notDisabled: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox\n   */\n  notDisabledAndNotHidden: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox все выбраны\n   */\n  notDisabledAndNotHiddenAreSelected: boolean;\n  /**\n   * все дочерние строки, которые скрыты через rowShowCheckbox\n   */\n  hidden: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ скрыты через rowShowCheckbox\n   */\n  notHidden: RowIdType[];\n  /**\n   * все дочерние строки, которые selected (уже выбраны, у которых чекбокс проставлен)\n   */\n  selected: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ selected (не выбраны, у которых чекбокс НЕ проставлен)\n   */\n  notSelected: RowIdType[];\n  /**\n   * есть ли хоть одна дочерная строка, которая выбрана (у которой чекбокс проставлен)\n   */\n  someChildrenIsSelected: boolean;\n};\n```\n\n## RowShowCheckbox\n\n```typescript\ntype RowShowCheckbox<RowType> = (\n  row: RowType,\n  lvl?: number,\n  parent?: RowType | null,\n) => boolean;\n```\n\n## RowCheckboxDisabled\n\n```typescript\ntype RowCheckboxDisabled<RowType> = (\n  row: RowType,\n  lvl?: number,\n  parent?: RowType | null,\n) => boolean;\n```\n\n## RowGetStatesProps\n\n```typescript\ntype RowGetStatesProps<RowType, RowIdType> = {\n  /**\n   * просчитанное по умолчанию значение наличия чекбокса у строки\n   */\n  isHaveCheckboxCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение checked у строки\n   */\n  isRowSelectedCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение indeterminate у строки\n   */\n  isIndeterminateCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение disabled у строки\n   */\n  isRowSelectionDisabled: boolean;\n\n  rowKeyGetter: RowKeyGetter<RowType, RowIdType>;\n  row: RowType;\n  /**\n   * Все строки таблицы в плоском виде с информацией об уровне и родительской строке\n   */\n  flattenedRowsMap: Map<\n    RowIdType,\n    RowType & {\n      level?: number;\n      parent?: RowType | null | undefined;\n    }\n  >;\n  /**\n   * стейт всех выбранных строк (Set)\n   */\n  selectedRows: ReadonlySet<RowIdType>;\n  /**\n   * сеттер стейта всех выбранных строк\n   */\n  setSelectedRows: React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>;\n  /**\n   * уровень вложенности текущей строки\n   */\n  level: number;\n  /**\n   * родительская строка для текущей строки\n   */\n  parent: RowType | null;\n  /**\n   * хендлер для получения детальных данных о дочерних строках текущей строки\n   */\n  getRowChildrenInfo: () => ChildrenInfo<RowType, RowIdType>;\n  rowShowCheckbox: RowShowCheckbox<RowType> | undefined;\n  rowCheckboxDisabled: RowCheckboxDisabled<RowType> | undefined;\n};\n```\n\n## RowGetStatesReturnType\n\n```typescript\ntype RowGetStatesReturnType<RowType, RowIdType> = {\n  /**\n   * состояние checked, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  checked?: boolean | null;\n  /**\n   * состояние indeterminate, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  indeterminate?: boolean | null;\n  /**\n   * состояние showCheckbox, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  showCheckbox?: boolean | null;\n  /**\n   * состояние checkboxDisabled, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  checkboxDisabled?: boolean | null;\n  /**\n   * onChange у чекбокса, который будет окончательным. Если не передан, то будет взят из расчетов по умолчанию\n   */\n  onChange?:\n    | ((p: {\n        allParentsMap: Map<RowIdType, RowType>;\n        isRowInLevels: (row: RowType) => boolean;\n        defaultSetter: () => void;\n        getRowParentsInfo: () => {\n          all: RowType[];\n          getShouldBeSelectedInfo: (\n            actualSelecteds: ReadonlySet<RowIdType>,\n          ) => {\n            shouldBeSelected: RowIdType[];\n            shouldNotBeSelected: RowIdType[];\n          };\n        };\n      }) => void)\n    | null;\n};\n```",
      "api": [
        {
          "typeName": "SelectingRowConfig",
          "source": "type SelectingRowConfig<\n  RowType,\n  RowIdType extends string | number = string | number,\n> = {\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n   */\n  showDefault?: boolean;\n  /**\n   * showState - состояние, отвечающее за то, видны ли чекбоксы.\n   */\n  showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n   */\n  showInControl?: boolean;\n  /**\n   * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n   */\n  selectingRules?: {\n    /**\n     * изменять ли скрытые строки при клике на чекбокс-ы родительских строк\n     * @default true\n     */\n    // changeableOfRowWithoutCheckbox?: boolean;\n    /**\n     * изменять ли задизейбленные строки при клике на чекбокс-ы родительских строк\n     * @default true\n     */\n    // changeableDisabledRow?: boolean;\n    /**\n     * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n     */\n    levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n  };\n  disableSummaryCheckboxInHeader?: boolean;\n  hideSummaryCheckboxInHeader?: boolean;\n  /**\n   * hideSummaryCheckbox - в островке  массовых действий\n   */\n  hideSummaryCheckbox?: boolean;\n  /**\n   * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n   */\n  summaryChecked?: {\n    checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n    indeterminate:\n      | boolean\n      | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n    getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n    onChange: SummaryCheckedFunc<\n      RowType,\n      void,\n      {\n        checkedAll: boolean;\n        clearButtonClicked?: boolean;\n        setSelectedRowsIds: React.Dispatch<\n          React.SetStateAction<ReadonlySet<string | number>>\n        >;\n      }\n    >;\n  };\n\n  /**\n   * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n   */\n  summaryCheckedUncontrolled?: {\n    onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n  };\n\n  /**\n   * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n   */\n  rowShowCheckbox?: RowShowCheckbox<RowType>;\n  /**\n   * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n   */\n  rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n\n  /**\n   * Функция для переопределения checked, indeterminate для каждой строки.\n   * Что будет возвращено функцией в объекте, то будет переопределено.\n   */\n  rowGetStates?: (\n    p: RowGetStatesProps<RowType, RowIdType>,\n  ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n\n  groupedRow?: {\n    /**\n     * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n     * Что будет возвращено функцией в объекте, то будет переопределено.\n     */\n    getStates: (p: {\n      checkedCalculated: boolean;\n      indeterminateCalculated: boolean;\n      row: GroupRow<RowType>;\n      selectedRows: ReadonlySet<string | number>;\n      selectedChildCount: number;\n      childCount: number;\n    }) => {\n      checked?: boolean | null;\n      indeterminate?: boolean | null;\n      showCheckbox?: boolean | null;\n      checkboxDisabled?: boolean | null;\n    } | null;\n    onChange?: (p: {\n      row: GroupRow<RowType>;\n\n      setSelectedRows: React.Dispatch<\n        React.SetStateAction<ReadonlySet<string | number>>\n      >;\n      checked: boolean;\n      indeterminate: boolean;\n      checkboxDisabled: boolean;\n      showCheckbox: boolean;\n      defaultSetter: () => void;\n    }) => void;\n  };\n};"
        },
        {
          "typeName": "ChildrenInfo",
          "source": "type ChildrenInfo<RowType, RowIdType> = {\n  /**\n   * все дочерние строки\n   */\n  all: RowType[];\n  /**\n   * все дочерние строки, которые disabled\n   */\n  disabled: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ disabled\n   */\n  notDisabled: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox\n   */\n  notDisabledAndNotHidden: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ disabled и НЕ скрыты через rowShowCheckbox все выбраны\n   */\n  notDisabledAndNotHiddenAreSelected: boolean;\n  /**\n   * все дочерние строки, которые скрыты через rowShowCheckbox\n   */\n  hidden: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ скрыты через rowShowCheckbox\n   */\n  notHidden: RowIdType[];\n  /**\n   * все дочерние строки, которые selected (уже выбраны, у которых чекбокс проставлен)\n   */\n  selected: RowIdType[];\n  /**\n   * все дочерние строки, которые НЕ selected (не выбраны, у которых чекбокс НЕ проставлен)\n   */\n  notSelected: RowIdType[];\n  /**\n   * есть ли хоть одна дочерная строка, которая выбрана (у которой чекбокс проставлен)\n   */\n  someChildrenIsSelected: boolean;\n};"
        },
        {
          "typeName": "RowShowCheckbox",
          "source": "type RowShowCheckbox<RowType> = (\n  row: RowType,\n  lvl?: number,\n  parent?: RowType | null,\n) => boolean;"
        },
        {
          "typeName": "RowCheckboxDisabled",
          "source": "type RowCheckboxDisabled<RowType> = (\n  row: RowType,\n  lvl?: number,\n  parent?: RowType | null,\n) => boolean;"
        },
        {
          "typeName": "RowGetStatesProps",
          "source": "type RowGetStatesProps<RowType, RowIdType> = {\n  /**\n   * просчитанное по умолчанию значение наличия чекбокса у строки\n   */\n  isHaveCheckboxCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение checked у строки\n   */\n  isRowSelectedCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение indeterminate у строки\n   */\n  isIndeterminateCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение disabled у строки\n   */\n  isRowSelectionDisabled: boolean;\n\n  rowKeyGetter: RowKeyGetter<RowType, RowIdType>;\n  row: RowType;\n  /**\n   * Все строки таблицы в плоском виде с информацией об уровне и родительской строке\n   */\n  flattenedRowsMap: Map<\n    RowIdType,\n    RowType & {\n      level?: number;\n      parent?: RowType | null | undefined;\n    }\n  >;\n  /**\n   * стейт всех выбранных строк (Set)\n   */\n  selectedRows: ReadonlySet<RowIdType>;\n  /**\n   * сеттер стейта всех выбранных строк\n   */\n  setSelectedRows: React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>;\n  /**\n   * уровень вложенности текущей строки\n   */\n  level: number;\n  /**\n   * родительская строка для текущей строки\n   */\n  parent: RowType | null;\n  /**\n   * хендлер для получения детальных данных о дочерних строках текущей строки\n   */\n  getRowChildrenInfo: () => ChildrenInfo<RowType, RowIdType>;\n  rowShowCheckbox: RowShowCheckbox<RowType> | undefined;\n  rowCheckboxDisabled: RowCheckboxDisabled<RowType> | undefined;\n};"
        },
        {
          "typeName": "RowGetStatesReturnType",
          "source": "type RowGetStatesReturnType<RowType, RowIdType> = {\n  /**\n   * состояние checked, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  checked?: boolean | null;\n  /**\n   * состояние indeterminate, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  indeterminate?: boolean | null;\n  /**\n   * состояние showCheckbox, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  showCheckbox?: boolean | null;\n  /**\n   * состояние checkboxDisabled, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  checkboxDisabled?: boolean | null;\n  /**\n   * onChange у чекбокса, который будет окончательным. Если не передан, то будет взят из расчетов по умолчанию\n   */\n  onChange?:\n    | ((p: {\n        allParentsMap: Map<RowIdType, RowType>;\n        isRowInLevels: (row: RowType) => boolean;\n        defaultSetter: () => void;\n        getRowParentsInfo: () => {\n          all: RowType[];\n          getShouldBeSelectedInfo: (\n            actualSelecteds: ReadonlySet<RowIdType>,\n          ) => {\n            shouldBeSelected: RowIdType[];\n            shouldNotBeSelected: RowIdType[];\n          };\n        };\n      }) => void)\n    | null;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "CustomRowSelection",
          "displayName": "Независимый выбор строк в иерархии",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          subRow: {\n            keyOfColumnInSubRow: 'id',\n            isColumnWithArrow: true,\n          },\n          resizable: true,\n        },\n        {\n          key: 'issueType',\n          name: 'issue',\n          subRow: {\n            keyOfColumnInSubRow: 'issueType',\n          },\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n      ],\n      [],\n    );\n\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          resizableColumn: true,\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id,\n            selectingRules: {\n              levels: [1, 2],\n            },\n            showDefault: true,\n            summaryChecked: {\n              checked({ allRowsInLevels, selectedRowsIds }) {\n                return (\n                  selectedRowsIds.size > 0 &&\n                  allRowsInLevels.length === selectedRowsIds.size\n                );\n              },\n\n              indeterminate({ checkedAll, allRowsInLevels, selectedRowsIds }) {\n                return (\n                  !checkedAll &&\n                  selectedRowsIds.size > 0 &&\n                  selectedRowsIds.size < allRowsInLevels.length\n                );\n              },\n              getCountOfChecked({ selectedRowsIds }) {\n                return selectedRowsIds.size;\n              },\n              onChange({\n                checkedAll,\n                setSelectedRowsIds,\n                allRowsInLevels,\n                rowKeyGetter,\n              }) {\n                if (!checkedAll) {\n                  setSelectedRowsIds(\n                    new Set(...[allRowsInLevels.map((r) => rowKeyGetter(r))]),\n                  );\n                } else {\n                  setSelectedRowsIds(new Set());\n                }\n              },\n            },\n            rowGetStates({\n              row,\n              selectedRows,\n\n              rowKeyGetter,\n              setSelectedRows,\n              isRowSelectedCalculated,\n            }) {\n              return {\n                checked: selectedRows.has(rowKeyGetter(row)),\n                indeterminate: false,\n                onChange() {\n                  setSelectedRows((prev) => {\n                    const newV = new Set(prev);\n                    newV[isRowSelectedCalculated ? 'delete' : 'add'](\n                      rowKeyGetter(row),\n                    );\n                    return newV;\n                  });\n                },\n              };\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "CustomRowSelectionWithDisabledAndHidden",
          "displayName": "Ручная настройка выбора строк с учетом disabled, hidden строк",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          subRow: {\n            keyOfColumnInSubRow: 'id',\n            isColumnWithArrow: true,\n          },\n          resizable: true,\n        },\n        {\n          key: 'issueType',\n          name: 'issue',\n          subRow: {\n            keyOfColumnInSubRow: 'issueType',\n          },\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n      ],\n      [],\n    );\n\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n    const rowShowCheckbox = (r: Row) => r.id !== 2;\n    const rowCheckboxDisabled = (r: Row) => r.id.toString().endsWith('0001');\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          resizableColumn: true,\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id + r.issueType,\n            selectingRules: {\n              levels: [1, 2, 3],\n            },\n            showDefault: true,\n            summaryChecked: {\n              checked({ selectedRowsIds, getAllRowsInfo }) {\n                const { notHidden } = getAllRowsInfo();\n\n                return (\n                  selectedRowsIds.size > 0 &&\n                  notHidden.length === selectedRowsIds.size\n                );\n              },\n              indeterminate({ checkedAll, allRowsInLevels, selectedRowsIds }) {\n                return (\n                  !checkedAll &&\n                  selectedRowsIds.size > 0 &&\n                  selectedRowsIds.size < allRowsInLevels.length\n                );\n              },\n              getCountOfChecked({ selectedRowsIds }) {\n                return selectedRowsIds.size;\n              },\n              onChange({\n                checkedAll,\n                setSelectedRowsIds,\n\n                getAllRowsInfo,\n              }) {\n                const {\n                  notDisabledAndNotHidden,\n                  notDisabledAndNotHiddenAreSelected,\n                } = getAllRowsInfo();\n\n                if (checkedAll) {\n                  setSelectedRowsIds(new Set());\n                  return;\n                }\n                setSelectedRowsIds((prevSelecteds) => {\n                  const needToDelete = notDisabledAndNotHiddenAreSelected;\n\n                  const newSelecteds = new Set(prevSelecteds);\n                  notDisabledAndNotHidden.forEach((rKey) => {\n                    newSelecteds[needToDelete ? 'delete' : 'add'](rKey);\n                  });\n                  return newSelecteds;\n                });\n              },\n            },\n\n            rowGetStates({\n              isRowSelectedCalculated,\n              getRowChildrenInfo,\n              isHaveCheckboxCalculated,\n              rowKeyGetter,\n              selectedRows,\n              row,\n              setSelectedRows,\n            }) {\n              if (!isHaveCheckboxCalculated) return { showCheckbox: false };\n\n              const rowInfo = getRowChildrenInfo();\n              const hasChildren = !!rowInfo.all.length;\n\n              const allVisible = rowInfo.notHidden;\n              const allSelected = rowInfo.selected;\n              const checked = !hasChildren\n                ? isRowSelectedCalculated\n                : !!allVisible.length &&\n                  allVisible.length === allSelected.length;\n              return {\n                checked,\n                indeterminate:\n                  hasChildren && !checked && rowInfo.someChildrenIsSelected,\n                onChange({ getRowParentsInfo }) {\n                  const {\n                    all,\n                    selected,\n                    notDisabledAndNotHidden,\n                    notHidden,\n                    someChildrenIsSelected,\n                  } = getRowChildrenInfo();\n\n                  const rowKey = rowKeyGetter(row);\n                  const rowIsChecked = selectedRows.has(rowKey);\n\n                  const hasChildren = !!all.length;\n\n                  const checked = !hasChildren\n                    ? rowIsChecked\n                    : someChildrenIsSelected &&\n                      selected.length >= notHidden.length;\n\n                  setSelectedRows((prevSelecteds) => {\n                    const newSelecteds = new Set(prevSelecteds);\n                    // обработка самой строки если она без дочерних строк\n                    if (!hasChildren) {\n                      newSelecteds[checked ? 'delete' : 'add'](\n                        rowKeyGetter(row),\n                      );\n                    } else {\n                      // обработка дочерних строк\n                      // не полагаемся на checked, чтобы обработать логику выбора сразу при checked и indeterminate\n                      const needToAdd = notDisabledAndNotHidden.every((rKey) =>\n                        prevSelecteds.has(rKey),\n                      );\n\n                      notDisabledAndNotHidden.forEach((rKey) => {\n                        newSelecteds[needToAdd ? 'delete' : 'add'](rKey);\n                      });\n\n                      // обработка самой строки. Проверка всех детей для того, чтобы определить выбирать ли текущую строку\n                      const rowChidlrenSelectedAll = notHidden.every((rKey) =>\n                        newSelecteds.has(rKey),\n                      );\n\n                      newSelecteds[rowChidlrenSelectedAll ? 'add' : 'delete'](\n                        rowKey,\n                      );\n                    }\n\n                    // обработка родительских строк\n                    const { shouldBeSelected, shouldNotBeSelected } =\n                      getRowParentsInfo().getShouldBeSelectedInfo(newSelecteds);\n\n                    shouldBeSelected.forEach((rKey) => newSelecteds.add(rKey));\n                    shouldNotBeSelected.forEach((rKey) =>\n                      newSelecteds.delete(rKey),\n                    );\n                    return newSelecteds;\n                  });\n                },\n              };\n            },\n\n            rowCheckboxDisabled,\n            rowShowCheckbox,\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "SelectingRow",
          "displayName": "Пример кастомного выбора строк в группированной таблице",
          "type": "full-code",
          "code": "interface RowForGrouping {\n  id: number;\n  country: string;\n  year: number;\n  sport: string;\n  athlete: string;\n  gold: number;\n  silver: number;\n  bronze: number;\n}\n\n() => {\n    const [rows] = useState(createRowsForGrouping);\n\n    const [groupByArr, setGroupByArr] = useState<string[]>([]);\n\n    const columnConfig = useMemo<readonly ColumnConfig<RowForGrouping>[]>(\n      () => [\n        {\n          key: 'athlete',\n          name: 'Athlete',\n          rowsGrouping: {\n            columnGroupLabel: 'Athlete',\n          },\n        },\n        {\n          key: 'sport',\n          name: 'Sport',\n\n          rowsGrouping: {\n            columnGroupLabel: 'Sport',\n          },\n        },\n        {\n          key: 'country',\n          name: 'Country',\n\n          rowsGrouping: {\n            columnGroupLabel: 'Country',\n          },\n        },\n        {\n          key: 'year',\n          name: 'Year',\n\n          rowsGrouping: {\n            columnGroupLabel: 'Year',\n          },\n        },\n\n        {\n          key: 'gold',\n          name: 'Gold',\n          rowsGrouping: {\n            groupByColumn: false,\n            columnGroupLabel: 'Gold',\n            renderGroupCell({ childRows }) {\n              return childRows.reduce((prev, { gold }) => prev + gold, 0);\n            },\n          },\n        },\n      ],\n      [],\n    );\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: 700 },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id,\n            groupedRow: {\n              getStates({ row, selectedRows }) {\n                if (row.groupByKey === 'country') {\n                  return {\n                    checked: selectedRows.has(row.groupKey),\n                    indeterminate: false,\n                  };\n                }\n                return null;\n              },\n              onChange({ checked, row, setSelectedRows, defaultSetter }) {\n                const recursive = (rowX: typeof row, groupByKeyX: string) => {\n                  const childGroupsX = rowX.childGroups as (typeof row)[];\n                  if (!childGroupsX || !childGroupsX?.length) {\n                    return;\n                  }\n                  if (childGroupsX[0]?.groupByKey === 'country') {\n                    setSelectedRows((prev) => {\n                      const copy = new Set(prev);\n\n                      childGroupsX.forEach((groupRow) =>\n                        copy[checked ? 'delete' : 'add'](groupRow.groupKey),\n                      );\n                      return copy;\n                    });\n                    return;\n                  }\n\n                  childGroupsX.forEach((groupX) => {\n                    const newChildGroupsX =\n                      groupX.childGroups as (typeof row)[];\n                    if (!newChildGroupsX || !childGroupsX?.length) {\n                      return;\n                    }\n                    recursive(groupX, groupByKeyX);\n                  });\n                };\n                if (row.groupByKey === 'country') {\n                  setSelectedRows((prev) => {\n                    const copy = new Set(prev);\n                    copy[checked ? 'delete' : 'add'](row.groupKey);\n                    return copy;\n                  });\n                  return;\n                }\n                recursive(row, 'country');\n                defaultSetter();\n              },\n            },\n          },\n          rowsGrouping: {\n            rowKeyGetter: (r) => r.id,\n            groupByState: [groupByArr, setGroupByArr],\n            expandAllBtn: {\n              expandedAll({ allRowsIds, shownRows }) {\n                return allRowsIds?.size === shownRows.length;\n              },\n            },\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "SelectingRow",
          "displayName": "Простой пример",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'issueType',\n          name: 'issue',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n      ],\n      [],\n    );\n\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          selecting: {\n            rowCheckboxDisabled: (row) => row.id === 2,\n            rowShowCheckbox: (row) => row.id !== 3,\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id + r.issueType,\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "SelectingRow",
          "displayName": "Многоуровневая таблица",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          subRow: {\n            keyOfColumnInSubRow: 'id',\n            isColumnWithArrow: true,\n          },\n          resizable: true,\n        },\n        {\n          key: 'issueType',\n          name: 'issue',\n          subRow: {\n            keyOfColumnInSubRow: 'issueType',\n          },\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n      ],\n      [],\n    );\n\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n    const rowShowCheckbox = (r: Row) => r.id !== 2;\n    const rowCheckboxDisabled = (r: Row) => r.id === '10001';\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          resizableColumn: true,\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id + r.issueType,\n            showDefault: true,\n            selectingRules: { levels: [1, 2] },\n            rowCheckboxDisabled,\n            rowShowCheckbox,\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "SelectingRowSummary",
          "displayName": "Общий Checkbox ",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columns = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          resizable: true,\n          subRow: {\n            keyOfColumnInSubRow: 'id',\n            isColumnWithArrow: true,\n          },\n        },\n        {\n          key: 'issueType',\n          name: 'issue',\n          subRow: {\n            keyOfColumnInSubRow: 'issueType',\n          },\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n      ],\n      [],\n    );\n\n    const selectingRowStateAndSetter = useState(\n      (): ReadonlySet<string | number> => new Set(),\n    );\n    const [_, setSelectedRows] = selectingRowStateAndSetter;\n    const rowShowCheckbox = (r: Row) => r.id !== 2;\n    const rowCheckboxDisabled = (r: Row) => r.id === 1;\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          resizableColumn: true,\n          selecting: {\n            state: selectingRowStateAndSetter,\n            rowKeyGetter: (r) => r.id + r.issueType,\n            showDefault: true,\n            selectingRules: { levels: [1, 2] },\n            rowShowCheckbox,\n            rowCheckboxDisabled,\n            summaryChecked: {\n              checked: ({ rows, selectedRowsIds }) =>\n                // Любая логика для включения Checkbox\n                // ...\n                selectedRowsIds.size === rows.length,\n              indeterminate: ({ rows, selectedRowsIds, checkedAll }) => {\n                // Любая логика для отображения indeterminate у Checkbox\n                // ...\n                const isIndet =\n                  rows.length > 0 && selectedRowsIds.size > 0 && !checkedAll;\n\n                return isIndet;\n              },\n              onChange: ({ selectedRowsIds }) => {\n                // Любая логика для обработки события изменения состояния выбора строки\n                // ...\n                setSelectedRows(selectedRowsIds);\n              },\n              getCountOfChecked: ({ selectedRowsIds }) =>\n                // Любая логика для отображения количества выбранных строк\n                // ...\n                selectedRowsIds.size,\n            },\n          },\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "sidebar",
      "legacy": true,
      "summary": "Правая боковая панель таблицы",
      "docs": "# TableSidebar\n\n## Ключевые особенности\n\n- Правая боковая панель таблицы\n- Кастомные tabs и стандартные tabs таблицы\n- Интеграция с controlBlock и настройками фич\n\n**tableConfig.sidebarConfig**\n\nКомпонент Table предоставляет гибкую настройку сайдбара с вкладками,\nпозволяя добавлять новые.\n\n## Основные возможности\n\n### Гибкая настройка вкладок\n\n- Добавление пользовательских вкладок\n- Настройка порядка отображения\n\n### Стандартные вкладки\n\n1.  **Настройка колонок** (`columns`)\n\n- Управление видимостью, порядком и закреплением колонок\n\n2.  **Настройки таблицы**\n\n- Управление итоговыми строками, выбором строк, инструментами в строках + кастомные фичи, которые не помещаются в ControlBlock\n\n3.  **Фильтры** (`filtering`)\n\n- Управление фильтрацией данных\n\n### Управление состоянием сайдбара\n\nПо умолчанию сайдбар закрыт (uncontrolled). Стартовое и внешнее состояние настраивается через `sidebarConfig`:\n\n- `defaultOpen` — сайдбар открыт сразу при первом рендере.\n- `defaultActiveTabId` — какая вкладка выбрана по умолчанию. Актуально при открытом сайдбаре; если id не найден или у вкладки `showInSidebar=false`, берётся первая доступная.\n- `openState` — внешний контроль открытия/закрытия (`[boolean, setter]`). Если передан, `defaultOpen` игнорируется.\n- `activeTabState` — внешний контроль активной вкладки (`[string | null, setter]`). Позволяет, например, открыть нужную вкладку по кнопке над таблицей. Если передан, `defaultActiveTabId` игнорируется.\n- `onActiveTabChange` — колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме; при закрытии сайдбара приходит `null`.\n\nАктивная вкладка имеет смысл только при открытом сайдбаре — при закрытии она сбрасывается в `null`.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-sidebar-api--docs).",
      "apiDocs": "# Sidebar API\n\n## SidebarConfig\n\n```typescript\ntype SidebarConfig = {\n  /**\n   * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n   * @default true\n   */\n  enabled?: boolean;\n  /**\n   * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n   * Игнорируется, если передан openState.\n   * @default false\n   */\n  defaultOpen?: boolean;\n  /**\n   * Внешний контроль открытия/закрытия sidebar.\n   * Если передан — источник истины, defaultOpen игнорируется.\n   */\n  openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n   * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n   */\n  defaultActiveTabId?: string;\n  /**\n   * Внешний контроль активной вкладки (controlled-режим).\n   * Если передан — источник истины, defaultActiveTabId игнорируется.\n   */\n  activeTabState?: [\n    string | null,\n    React.Dispatch<React.SetStateAction<string | null>>,\n  ];\n  /**\n   * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n   * При закрытии сайдбара приходит null.\n   */\n  onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n  /**\n   * Кастомные табы\n   */\n  customTabs?: Array<\n    Omit<SidebarTab, 'id'> & {\n      id: Exclude<string, DefaultSidebarTabIds>;\n    }\n  >;\n  /**\n   * Порядок отображения кастомных вкладок\n   */\n  customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n  defaultTabs?: Array<\n    | {\n        id: 'filtering' | 'columns';\n        label?: string;\n        title?: string;\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n      }\n    | {\n        id: 'tableSettings';\n        label?: string;\n        title?: string;\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n         * Только дл id: 'tableSettings'\n         */\n        customGeneralSettingsSlot?: React.ReactNode;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n      }\n  >;\n};\n```\n\n## SidebarTab\n\n```typescript\ntype SidebarTab = {\n  /**\n   * Уникальный идентификатор таба\n   */\n  id: DefaultSidebarTabIds | string;\n  /**\n   * title таба (для Tooltip)\n   */\n  label: string;\n  /**\n   * Иконка таба\n   */\n  icon: ReactNode;\n  /**\n   * Контентная часть сайдбара\n   */\n  content: React.ReactNode;\n  /**\n   * Показывать ли в сайдбаре\n   * @default true\n   */\n  showInSidebar?: boolean;\n  /**\n   * Заголовок контентной части сайдбара\n   */\n  title?: string;\n  /**\n   * Кастомный элемент справа от title в шапке сайдбара\n   */\n  titleRightSlot?: React.ReactNode;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n```",
      "api": [
        {
          "typeName": "SidebarConfig",
          "source": "type SidebarConfig = {\n  /**\n   * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n   * @default true\n   */\n  enabled?: boolean;\n  /**\n   * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n   * Игнорируется, если передан openState.\n   * @default false\n   */\n  defaultOpen?: boolean;\n  /**\n   * Внешний контроль открытия/закрытия sidebar.\n   * Если передан — источник истины, defaultOpen игнорируется.\n   */\n  openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n   * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n   */\n  defaultActiveTabId?: string;\n  /**\n   * Внешний контроль активной вкладки (controlled-режим).\n   * Если передан — источник истины, defaultActiveTabId игнорируется.\n   */\n  activeTabState?: [\n    string | null,\n    React.Dispatch<React.SetStateAction<string | null>>,\n  ];\n  /**\n   * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n   * При закрытии сайдбара приходит null.\n   */\n  onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n  /**\n   * Кастомные табы\n   */\n  customTabs?: Array<\n    Omit<SidebarTab, 'id'> & {\n      id: Exclude<string, DefaultSidebarTabIds>;\n    }\n  >;\n  /**\n   * Порядок отображения кастомных вкладок\n   */\n  customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n  defaultTabs?: Array<\n    | {\n        id: 'filtering' | 'columns';\n        label?: string;\n        title?: string;\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n      }\n    | {\n        id: 'tableSettings';\n        label?: string;\n        title?: string;\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n         * Только дл id: 'tableSettings'\n         */\n        customGeneralSettingsSlot?: React.ReactNode;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n      }\n  >;\n};"
        },
        {
          "typeName": "SidebarTab",
          "source": "type SidebarTab = {\n  /**\n   * Уникальный идентификатор таба\n   */\n  id: DefaultSidebarTabIds | string;\n  /**\n   * title таба (для Tooltip)\n   */\n  label: string;\n  /**\n   * Иконка таба\n   */\n  icon: ReactNode;\n  /**\n   * Контентная часть сайдбара\n   */\n  content: React.ReactNode;\n  /**\n   * Показывать ли в сайдбаре\n   * @default true\n   */\n  showInSidebar?: boolean;\n  /**\n   * Заголовок контентной части сайдбара\n   */\n  title?: string;\n  /**\n   * Кастомный элемент справа от title в шапке сайдбара\n   */\n  titleRightSlot?: React.ReactNode;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};"
        }
      ],
      "stories": [
        {
          "exportName": "WithCustomTab",
          "displayName": "С кастомной вкладкой",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n    const [selectedRows, setSelectedRows] = useState<ReadonlySet<string>>(\n      new Set(),\n    );\n    const [filters, setFilters] = useState({});\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n      ],\n      [],\n    );\n\n    const CustomInfoTab = () => (\n      <>\n        <p>Всего строк: {rows.length}</p>\n        <p>Выбрано строк: {selectedRows.size}</p>\n      </>\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          sidebarConfig: {\n            customTabs: [\n              {\n                id: 'customInfo',\n                label: 'Информация',\n                icon: <IconInfo size=\"s\" />,\n                content: <CustomInfoTab />,\n                title: 'Информация',\n                showInSidebar: true,\n              },\n            ],\n          },\n          selecting: {\n            state: [selectedRows, setSelectedRows],\n            rowKeyGetter: (row) => row.id.toString(),\n          },\n          filtering: {\n            state: [filters, setFilters],\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "DefaultOpen",
          "displayName": "Открыт по умолчанию на кастомной вкладке",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          sidebarConfig: {\n            defaultOpen: true,\n            defaultActiveTabId: 'customInfo',\n            customTabs: [\n              {\n                id: 'customInfo',\n                label: 'Информация',\n                icon: <IconInfo size=\"s\" />,\n                content: <p>Эта вкладка открыта сразу при первом рендере.</p>,\n                title: 'Информация',\n                showInSidebar: true,\n              },\n            ],\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        },
        {
          "exportName": "ControlledActiveTab",
          "displayName": "Внешнее управление активной вкладкой",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n    const [isOpen, setIsOpen] = useState(false);\n    const [activeTab, setActiveTab] = useState<string | null>(null);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n      ],\n      [],\n    );\n\n    const openTab = (id: string) => {\n      setActiveTab(id);\n      setIsOpen(true);\n    };\n\n    return (\n      <>\n        <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>\n          <Button onClick={() => openTab('customInfo')}>Инфо</Button>\n          <Button onClick={() => openTab('customSettings')}>Настройки</Button>\n          <Button onClick={() => setIsOpen(false)}>Закрыть</Button>\n        </div>\n        <Table\n          tableConfig={{\n            sidebarConfig: {\n              openState: [isOpen, setIsOpen],\n              activeTabState: [activeTab, setActiveTab],\n              customTabs: [\n                {\n                  id: 'customInfo',\n                  label: 'Информация',\n                  icon: <IconInfo size=\"s\" />,\n                  content: <p>Вкладка «Информация».</p>,\n                  title: 'Информация',\n                  showInSidebar: true,\n                },\n                {\n                  id: 'customSettings',\n                  label: 'Настройки',\n                  icon: <IconSettings size=\"s\" />,\n                  content: <p>Вкладка «Настройки».</p>,\n                  title: 'Настройки',\n                  showInSidebar: true,\n                },\n              ],\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        },
        {
          "exportName": "ActiveTabCallback",
          "displayName": "Колбэк активной вкладки",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n    const [currentTab, setCurrentTab] = useState<string | null>(null);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        { key: 'id', name: 'ID' },\n        { key: 'task', name: 'Title' },\n        { key: 'priority', name: 'Priority' },\n      ],\n      [],\n    );\n\n    return (\n      <>\n        <p style={{ marginBottom: 12 }}>\n          Активная вкладка: <b>{currentTab ?? 'нет (сайдбар закрыт)'}</b>\n        </p>\n        <Table\n          tableConfig={{\n            sidebarConfig: {\n              onActiveTabChange: (tabId, tab) =>\n                setCurrentTab(tab?.title ?? tabId),\n              customTabs: [\n                {\n                  id: 'customInfo',\n                  label: 'Информация',\n                  icon: <IconInfo size=\"s\" />,\n                  content: <p>Вкладка «Информация».</p>,\n                  title: 'Информация',\n                  showInSidebar: true,\n                },\n                {\n                  id: 'customSettings',\n                  label: 'Настройки',\n                  icon: <IconSettings size=\"s\" />,\n                  content: <p>Вкладка «Настройки».</p>,\n                  title: 'Настройки',\n                  showInSidebar: true,\n                },\n              ],\n            },\n          }}\n          columnConfig={columnConfig}\n          rows={rows}\n        />\n      </>\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "sorting",
      "legacy": true,
      "summary": "Сортировка по колонкам",
      "docs": "# Sorting\n\n## Ключевые особенности\n\n- Сортировка по колонкам\n- Строковый, числовой и кастомный компаратор\n- Ручная сортировка для серверных сценариев\n\nКомпонент `Table` поддерживает сортировку данных по колонкам.\n\n## Быстрый старт\n\nДля включения сортировки необходимо:\n\n1. Передать `sorting` в `tableConfig`\n2. Указать `sortingType` в конфигурации колонок\n\n```tsx\nconst sortingState = useState<readonly SortColumn[]>([]);\n\n<Table\n  tableConfig={{\n    sorting: {\n      state: sortingState,\n    },\n  }}\n  columnConfig={[\n    { key: 'name', name: 'Название', sortingType: 'stringSort' },\n    { key: 'amount', name: 'Сумма', sortingType: 'numberSort' },\n  ]}\n  rows={rows}\n/>;\n```\n\n## Стратегии сортировки\n\n<table>\n  <thead>\n    <tr>\n      <th>sortingType</th>\n      <th>Когда использовать</th>\n      <th>Пример данных</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>\n        <code>stringSort</code>\n      </td>\n      <td>Текстовые поля, названия, описания</td>\n      <td>\n        <code>\"Яблоко\"</code>, <code>\"Apple\"</code>, <code>\"100 дней\"</code>\n      </td>\n    </tr>\n    <tr>\n      <td>\n        <code>numberSort</code>\n      </td>\n      <td>Числа, ID, коды (даже строковые)</td>\n      <td>\n        <code>\"42\"</code>, <code>\"1 000\"</code>, <code>\"3,14\"</code>\n      </td>\n    </tr>\n    <tr>\n      <td>\n        <code>Comparator&lt;Row&gt;</code>\n      </td>\n      <td>Кастомная логика (enum-приоритеты, даты, и т.д.)</td>\n      <td>\n        <code>Critical → High → Medium → Low</code>\n      </td>\n    </tr>\n  </tbody>\n</table>\n\n### stringSort\n\nСтроковое сравнение с учётом русской локали.\n\n- Строковые числа сортируются как числа: `\"2\" < \"10\"` (не посимвольно)\n- Регистр не влияет: `\"яблоко\"` = `\"Яблоко\"`\n- Пустые значения всегда внизу\n\nПорядок символов при ASC (локаль `'ru'`):\n\n<table>\n  <thead>\n    <tr>\n      <th>Порядок</th>\n      <th>Категория</th>\n      <th>Пример</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>1</td>\n      <td>Спецсимволы</td>\n      <td>\n        <code>\"#tag\"</code>, <code>\"@user\"</code>, <code>\"-\"</code>\n      </td>\n    </tr>\n    <tr>\n      <td>2</td>\n      <td>Цифры</td>\n      <td>\n        <code>\"31.10\"</code>, <code>\"100\"</code>\n      </td>\n    </tr>\n    <tr>\n      <td>3</td>\n      <td>Кириллица</td>\n      <td>\n        <code>\"Авто\"</code>, <code>\"Яблоко\"</code>\n      </td>\n    </tr>\n    <tr>\n      <td>4</td>\n      <td>Латиница</td>\n      <td>\n        <code>\"Apple\"</code>, <code>\"MYCHANGE\"</code>\n      </td>\n    </tr>\n    <tr>\n      <td>—</td>\n      <td>Пустые</td>\n      <td>Всегда внизу</td>\n    </tr>\n  </tbody>\n</table>\n> Порядок между кириллицей и латиницей определяется русской локалью браузера — кириллица\nидёт первой.\n\n### numberSort\n\nЧисловое сравнение с поддержкой локальных форматов.\n\n<table>\n  <thead>\n    <tr>\n      <th>Входное значение</th>\n      <th>Результат</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>\n        <code>\"42\"</code>\n      </td>\n      <td>\n        <code>42</code>\n      </td>\n    </tr>\n    <tr>\n      <td>\n        <code>\"1 000\"</code>\n      </td>\n      <td>\n        <code>1000</code> (пробелы-разделители)\n      </td>\n    </tr>\n    <tr>\n      <td>\n        <code>\"3,14\"</code>\n      </td>\n      <td>\n        <code>3.14</code> (запятая как десятичный)\n      </td>\n    </tr>\n    <tr>\n      <td>\n        <code>\"abc\"</code>, <code>\"\"</code>\n      </td>\n      <td>Уходят вниз</td>\n    </tr>\n  </tbody>\n</table>\n\n### Кастомный компаратор\n\nФункция `(a: Row, b: Row) => number`. Направление (ASC/DESC) применяется автоматически.\n\n```tsx\n{\n  key: 'priority',\n  name: 'Приоритет',\n  sortingType: (a, b) => {\n    const order = { Critical: 0, High: 1, Medium: 2, Low: 3 };\n    return (order[a.priority] ?? 99) - (order[b.priority] ?? 99);\n  },\n}\n```\n\n## Направление сортировки\n\nКлик по заголовку переключает направление циклически:\n\n**нет сортировки → ASC (↓) → DESC (↑) → нет сортировки**\n\n<table>\n  <thead>\n    <tr>\n      <th>Иконка</th>\n      <th>Направление</th>\n      <th>Описание</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <td>↓</td>\n      <td>ASC</td>\n      <td>По возрастанию (от меньшего к большему)</td>\n    </tr>\n    <tr>\n      <td>↑</td>\n      <td>DESC</td>\n      <td>По убыванию (от большего к меньшему)</td>\n    </tr>\n    <tr>\n      <td>↕</td>\n      <td>—</td>\n      <td>Сортировка не активна</td>\n    </tr>\n  </tbody>\n</table>\n\nПустые значения (`null`, `undefined`, `\"\"`, строка из пробелов) всегда остаются внизу, независимо от направления.\n\n## Серверная сортировка\n\nЕсли сортировка выполняется на бэкенде, включите `manualSorting`. Таблица не будет сортировать данные сама, но будет обновлять `state` при кликах по заголовкам.\n\n```tsx\nconst [sortColumns, setSortColumns] = useState<readonly SortColumn[]>([]);\n\n// Реагируем на изменение sortColumns и делаем запрос на сервер\nuseEffect(() => {\n  fetchData({ sort: sortColumns });\n}, [sortColumns]);\n\n<Table\n  tableConfig={{\n    sorting: {\n      state: [sortColumns, setSortColumns],\n      manualSorting: true,\n    },\n  }}\n  ...\n/>\n```\n\n## API\n\nПодробное описание типов доступно в разделе [API](?path=/docs/локальные-компоненты-table-sorting-api--docs).",
      "apiDocs": "# Sorting API\n\n## Comparator\n\n```typescript\ntype Comparator<Row extends ObjectForExtending> = (\n  a: Row,\n  b: Row,\n) => number;\n```\n\n## TableConfig\n\n```typescript\ntype TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *```jsx\n   * import { Table } from '@daisforge/ui';\n   *\n   * <Table\n   * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n   * {...rest}\n   * />\n   * ```\n   */\n  selecting?: {\n    state: [\n      ReadonlySet<RowIdType>,\n      React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n    ];\n  } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n       */\n      controlBlock?: {\n        domMetadata?: DomMetadata;\n      };\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n       */\n      sidebar?: {\n        domMetadata?: DomMetadata;\n      };\n    };\n  /**\n   * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n   *\n   * columnConfig=[{editingCell: {...}}]\n   */\n  editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n  /**\n   * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n   *\n   * columnConfig=[{subRow: {...}}]\n   */\n  subRows?: SubRows<RowType, RowIdType>;\n  rowsGrouping?: RowsGrouping<RowType>;\n\n  /**\n   * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации -  resizableColumn: true. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={resizableColumn: true}\n   *\n   * columnConfig=[{resizable: true}]\n   */\n  resizableColumn?: boolean;\n  /**\n   * style - inline-стили. Для стилей самой таблицы (без вложенности).\n   *\n   * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n   */\n  style?: Omit<\n    CSSProperties,\n    'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n  >;\n  /**\n   * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n   *\n   * Пример:\n   *\n   * ```css\n   * & > .rdg-header-row > .rdgCell {\n   * background-color: red;\n   * }\n   * ```\n   *\n   */\n  css?: string | CSSObject;\n\n  summaryRows?: SummaryRowsConfig;\n  /**\n   * controlBlock - пропс для активации, кастомизации контролблока.\n   */\n  controlBlock?: ControlBlockConfig;\n  /**\n     * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n     * Пример:\n     *\n     * ```tsx\n        tableConfig={{ containerStyle: { height: '70vh' } }}\n     * ```\n     */\n  containerStyle?: CSSProperties | undefined;\n  /**\n   * containerCss - стили для контейнера таблицы и контролблока.\n   * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n   */\n  containerCss?: string | CSSObject | undefined;\n  /**\n   * containerId - html-атрибут id контейнера таблицы.\n   */\n  containerId?: string | undefined;\n\n  /**\n   * infinityScroll - бесконечная подгрузка данных при скролле.\n   *\n   *  Условие активации - наличие самого пропса infinityScroll.\n   *\n   * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n   * (Предполагается, что если есть infinityScroll,\n   * то в таблице представлен не весь объем данных,\n   * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n   *\n   */\n  infinityScroll?: {\n    onTrigger: (rows: RowType[]) => Promise<void> | void;\n    isLoading: boolean;\n    /**\n     * @default true\n     */\n    hasMore?: boolean;\n    /**\n     * @default 100   (px)\n     */\n    scrollThreshold?: number;\n  };\n  /**\n   * @isLoading - состояние загрузки данных для таблицы.\n   */\n  isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n  /**\n   * loadingOverlay - конфигурация для отображения оверлея загрузки.\n   * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n   */\n  loadingOverlay?: {\n    /**\n     * Активен ли оверлей загрузки\n     * @default true\n     */\n    active?: boolean;\n    /**\n     * Кастомный компонент спиннера\n     * @default <Spinner view=\"secondary\" size=\"36\" /> (внутренний компонент)\n     */\n    spinner?: ReactNode;\n    /**\n     * Основной заголовок оверлея\n     * @default \"Загрузка таблицы\"\n     */\n    title?: string;\n    /**\n     * Подзаголовок, который появится после задержки, пустая строка - значит он не появится\n     * @default \"\"\n     */\n    subtitle?: string;\n    /**\n     * Задержка перед показом подзаголовка (мс)\n     * @default 10000 (10 секунд)\n     */\n    showSubtitleDelay?: number;\n  };\n  noRowsFallback?: boolean | { custom: ReactNode };\n  columnsControl?: ColumnsControlConfig;\n  rowDetailPanel?: RowDetailConfig<RowType>;\n  rowInstruments?: {\n    getRowDropdownConfig: RowInstrumentsType<RowType>;\n    /**\n     * @default false\n     */\n    defaultOpened?: boolean;\n    /**\n     * @default true\n     */\n    showInControl?: boolean;\n    /**\n     * Внешний стейт видимости\n     */\n    openedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  };\n  fullScreenEnabled?: FullScreen;\n  keyText?: boolean | KeyTextConfig;\n  /**\n   * pagination - пропс для пагинации.\n   *\n   * Условие активации - наличие самого пропса pagination.\n   *\n   * При активации pagination отключается дефолтные поиск, сортировка и фильтрация.\n   * (поиск работает на уровне с фильтрацией и сортировкой, сначала поиск, затем фильтрация, затем сортировка)\n   *\n   */\n  pagination?: PaginationProps;\n  /**\n   * searching - пропс для поиска по таблицу.\n   *\n   * Условие активации - наличие searching.enabled: true\n   *\n   */\n  /**\n   * Конфигурация табов в сайдбаре\n   */\n  sidebarConfig?: SidebarConfig;\n  searching?: SearchingProps;\n  /**\n   * onHeaderContextMenu - пропс для активации открытия контекстного меню.\n   *\n   */\n  onHeaderContextMenu?: HeaderContextMenuProps;\n  onHeaderContextMenuDropDown?: HeaderContextMenuDropDownProps;\n  onCellContextMenuDropDown?: CellContextMenuDropDownProps<\n    RowType,\n    SummaryRowType\n  >;\n} & Pick<\n  DataGridPropsDefault<RowType, SummaryRowType, RowIdType>,\n  | 'summaryRowHeight'\n  | 'onFill'\n  | 'onCopy'\n  | 'onPaste'\n  | 'onCellClick'\n  | 'onCellDoubleClick'\n  | 'onCellContextMenu'\n  | 'onCellKeyDown'\n  | 'onSelectedCellChange'\n  | 'onScroll'\n  | 'onColumnResize'\n  | 'onColumnsReorder'\n  | 'enableVirtualization'\n  | 'rowClass'\n  | 'data-testid'\n  | 'headerRowHeight'\n>;\n```\n\n## ColumnConfig\n\n`sortingType` настраивается в конфигурации колонки.\n\n```typescript\ntype ColumnConfig<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n  /**\n   * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n   */\n  nameAsString?: string;\n  sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n  searching?: {\n    valueInRow: (row: Row) => string | number;\n  };\n  filtering?: {\n    keyInFilterState: string;\n    /**\n     * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n     */\n    valueInRow?: (row: Row) => string | number;\n    /**\n     * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n     */\n  } & (\n    | {\n        component: 'input';\n        filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n      }\n    | {\n        component: 'select';\n        /**\n         * Произвольное содержимое над списком опций фильтра.\n         *\n         * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n         * фильтров. Рендерится как компонент, поэтому внутри можно\n         * использовать хуки и локальное состояние.\n         *\n         * @example\n         * beforeList: ({ headerContextState }) => (\n         *   <TableFilterSelectListItem $size={headerContextState.rowSize}>\n         *     Подсказка над списком\n         *   </TableFilterSelectListItem>\n         * )\n         */\n        beforeList?: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        /**\n         * Произвольное содержимое под списком опций фильтра.\n         *\n         * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n         * фильтров. Рендерится как компонент, поэтому внутри можно\n         * использовать хуки и локальное состояние — например, чтобы держать\n         * черновик выбора и применять его по кнопке.\n         *\n         * @example\n         * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n         *   <TableFilterSelectListItem $size={headerContextState.rowSize}>\n         *     Подсказка под списком\n         *   </TableFilterSelectListItem>\n         * )\n         */\n        afterList?: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        filter:\n          | {\n              typeOfValue: 'single';\n              /**\n               * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n               */\n              filteringType?: FilterCb<'single'>;\n            }\n          | {\n              typeOfValue: 'multiple';\n              /**\n               * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n               */\n              filteringType?: FilterCb<'multiple'>;\n            };\n        selectOptions:\n          | {\n              type: 'constant';\n              options: SelectOptions[];\n            }\n          | {\n              type: 'stateInHeaderContext';\n              /**\n               * тип optionsState, который будет в HeaderContext:\n               * ```ts\n               * {\n               * value: string | number;\n               * text: string | number;\n               * }[];\n               * ```\n               */\n              optionsKeyInHeaderContext: string;\n            };\n        /**\n         * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n         * @default \"360px\"\n         */\n        listMaxHeight?: string;\n      }\n    | {\n        component: 'custom';\n        customRender: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n        compareWithClearedValue?: (\n          clearedValue: unknown,\n          currV: unknown,\n        ) => boolean;\n      }\n  );\n\n  contentFormat?: ContentFormat;\n\n  editingCell?: Editing<Row>;\n\n  subRow?: {\n    /**\n     * @default false\n     */\n    isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n    /**\n     * @default false\n     */\n    hideHeaderExpandAllArrow?: boolean;\n    /**\n     * @default false\n     */\n    parentKeyAsDefault?: boolean;\n    /**\n     * @default undefined\n     */\n    contentFormat?: ContentFormat;\n\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    renderSubRowCell?: RenderSubRowCell<any>;\n  } & (\n    | {\n        keyOfColumnInSubRow:\n          | string\n          | number\n          | ((lvl: number) => string | number);\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        editingCell: Editing<any>;\n      }\n    | {\n        editingCell?: undefined;\n        keyOfColumnInSubRow?:\n          | string\n          | number\n          | ((lvl: number) => string | number);\n      }\n  );\n  rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n  keyText?: KeyTextColumnConfig<Row, SummRow>;\n};\n```",
      "api": [
        {
          "typeName": "Comparator",
          "source": "type Comparator<Row extends ObjectForExtending> = (\n  a: Row,\n  b: Row,\n) => number;"
        },
        {
          "typeName": "TableConfig",
          "source": "type TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *"
        },
        {
          "typeName": "ColumnConfig",
          "source": "type ColumnConfig<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n  /**\n   * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n   */\n  nameAsString?: string;\n  sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n  searching?: {\n    valueInRow: (row: Row) => string | number;\n  };\n  filtering?: {\n    keyInFilterState: string;\n    /**\n     * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n     */\n    valueInRow?: (row: Row) => string | number;\n    /**\n     *"
        }
      ],
      "stories": [
        {
          "exportName": "ManualSorting",
          "displayName": "ID",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const rows = useMemo(() => createRows(), []);\n    const [sortedRows, setSortedRows] = useState(rows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          sortingType: 'numberSort',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          sortingType: 'stringSort',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          sortingType: 'stringSort',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          sortingType: 'stringSort',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n          sortingType: 'numberSort',\n        },\n      ],\n      [],\n    );\n\n    const sortingStateAndSetter = useState<readonly SortColumn[]>([]);\n\n    const [state] = sortingStateAndSetter;\n\n    useEffect(() => {\n      const sortColState = state[0];\n      if (!sortColState) {\n        setSortedRows(rows);\n        return;\n      }\n      const sortRows = [...rows].sort((a, b) => {\n        const aValue = a[sortColState.columnKey as keyof Row];\n        const bValue = b[sortColState.columnKey as keyof Row];\n\n        if (typeof aValue === 'number' && typeof bValue === 'number') {\n          return sortColState.direction === 'ASC'\n            ? aValue - bValue\n            : bValue - aValue;\n        }\n\n        if (\n          typeof aValue === 'string' &&\n          typeof bValue === 'string' &&\n          aValue[0] &&\n          bValue[0]\n        ) {\n          return sortColState.direction === 'ASC'\n            ? aValue.localeCompare(bValue)\n            : bValue.localeCompare(aValue);\n        }\n\n        return 0;\n      });\n\n      setSortedRows(sortRows);\n      // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [state]);\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          sorting: {\n            state: sortingStateAndSetter,\n            manualSorting: true,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={sortedRows}\n      />\n    );\n  }"
        },
        {
          "exportName": "Sorting",
          "displayName": "ID",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n\n          sortingType: 'numberSort',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          sortingType: 'stringSort',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          // custom sorting\n          sortingType: (a: Row, b: Row) => {\n            const values = {\n              Critical: 2,\n              High: 3,\n              Medium: 4,\n              Low: 5,\n            };\n            const aValue = values[a.priority as keyof typeof values] ?? 0;\n            const bValue = values[b.priority as keyof typeof values] ?? 0;\n            return aValue - bValue;\n          },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n          sortingType: 'stringSort',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n\n          sortingType: 'numberSort',\n        },\n      ],\n      [],\n    );\n\n    const sortingStateAndSetter = useState<readonly SortColumn[]>([]);\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          sorting: {\n            state: sortingStateAndSetter,\n          },\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "subRows",
      "legacy": true,
      "summary": "Иерархичные строки legacy `Table`.",
      "docs": "# SubRows\n\nИерархичные строки legacy `Table`.\n\n## Ключевые особенности\n\n- Вложенные строки подключаются через `tableConfig.subRows`\n- `getSubRows` возвращает дочерние строки\n- `rowKeyGetter` задает уникальный ключ строки\n- `columnConfig.subRow` управляет отображением данных дочерних строк\n- Можно показать chevron раскрытия и кастомный render дочерней ячейки\n\n## Особенности\n\nДля вложенных строк важно иметь стабильный `rowKeyGetter`. Если нужно группировать плоский набор данных, используйте `rowsGrouping`, а не `subRows`.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-subrows-api--docs).",
      "apiDocs": "# SubRows API\n\n## SubRows\n\n```typescript\ntype SubRows<RowType, RowIdType> = {\n  getSubRows: (row: RowType) => RowType[] | undefined;\n  rowKeyGetter: (row: RowType) => RowIdType;\n  expandedIdsState?: [\n    Set<string | number>,\n    (\n      newV:\n        | Set<string | number>\n        | ((prev: Set<string | number>) => Set<string | number>),\n    ) => void,\n  ];\n};\n```\n\n## RenderSubRowCell\n\n```typescript\ntype RenderSubRowCell<SubRowType extends ObjectForExtending> = (\n  renderCellProps: RenderCellProps<SubRowType>,\n  lvl: number,\n) => ReactNode;\n```\n\n## RenderSubRowEditCell\n\n```typescript\ntype RenderSubRowEditCell<SubRowType extends ObjectForExtending> = (\n  renderCellProps: RenderEditCellProps<SubRowType>,\n  lvl: number,\n) => ReactNode;\n```",
      "api": [
        {
          "typeName": "SubRows",
          "source": "type SubRows<RowType, RowIdType> = {\n  getSubRows: (row: RowType) => RowType[] | undefined;\n  rowKeyGetter: (row: RowType) => RowIdType;\n  expandedIdsState?: [\n    Set<string | number>,\n    (\n      newV:\n        | Set<string | number>\n        | ((prev: Set<string | number>) => Set<string | number>),\n    ) => void,\n  ];\n};"
        },
        {
          "typeName": "RenderSubRowCell",
          "source": "type RenderSubRowCell<SubRowType extends ObjectForExtending> = (\n  renderCellProps: RenderCellProps<SubRowType>,\n  lvl: number,\n) => ReactNode;"
        },
        {
          "typeName": "RenderSubRowEditCell",
          "source": "type RenderSubRowEditCell<SubRowType extends ObjectForExtending> = (\n  renderCellProps: RenderEditCellProps<SubRowType>,\n  lvl: number,\n) => ReactNode;"
        }
      ],
      "stories": [
        {
          "exportName": "SubRows",
          "displayName": "Иерархичный вид",
          "type": "full-code",
          "code": "import React, { useMemo, useState } from 'react';\nimport { Badge, ColumnConfig, Table } from '@daisforge/ui';\n\n() => {\n    const [rows] = useState(() => createRowsTree());\n\n    const columns = useMemo(\n      (): readonly ColumnConfig<TreeRow>[] => [\n        {\n          key: 'block',\n          name: 'Блок / Трайб / Продукт',\n\n          subRow: {\n            keyOfColumnInSubRow: (lvl) => {\n              switch (lvl) {\n                case 0:\n                  return 'block';\n                case 1:\n                  return 'tribe';\n                case 2:\n                  return 'product';\n                default:\n                  return 'block';\n              }\n            },\n\n            isColumnWithArrow: true,\n            hideHeaderExpandAllArrow: false,\n          },\n          resizable: true,\n        },\n        {\n          key: 'blockActivity',\n          name: 'Активность блока',\n        },\n        {\n          key: '',\n          minWidth: 170,\n\n          name: 'Локация трайба',\n          subRow: {\n            renderSubRowCell: (props, lvl) => {\n              if (lvl === 1) {\n                return (\n                  <Badge view=\"accent\" size=\"m\">\n                    {props.row?.tribeZone}\n                  </Badge>\n                );\n              }\n              return null;\n            },\n          },\n        },\n        {\n          key: 'q1',\n          name: 'Q1',\n\n          subRow: {\n            parentKeyAsDefault: true,\n          },\n        },\n\n        {\n          key: 'q2',\n          name: 'Q2',\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n        {\n          key: 'q3',\n          name: 'Q3',\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n        {\n          key: 'q4',\n          name: 'Q4',\n          subRow: {\n            keyOfColumnInSubRow: 'q1',\n          },\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          subRows: {\n            getSubRows: (row) => row?.subRows,\n            rowKeyGetter: (row) => row.id,\n          },\n          resizableColumn: true,\n        }}\n        columnConfig={columns}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "virtualization",
      "legacy": true,
      "summary": "Виртуализация строк и колонок legacy `Table`.",
      "docs": "# Virtualization\n\nВиртуализация строк и колонок legacy `Table`.\n\n## Ключевые особенности\n\n- Используется для больших списков строк\n- Управляется настройками underlying `DataGrid`\n- Может быть отключена через `enableVirtualization`\n- Работает вместе с высотой контейнера таблицы\n\n## Особенности\n\nОтключение виртуализации полезно только для небольших таблиц или специальных тестовых сценариев. Для больших наборов данных оставляйте виртуализацию включенной.\n\nОписание типов - в разделе [API](?path=/docs/локальные-компоненты-table-virtualization-api--docs).",
      "apiDocs": "# Virtualization API\n\n## DataGridPropsDefault\n\n```typescript\ninterface DataGridPropsDefault<R, SR = unknown, K extends Key = Key>\n  extends SharedDivProps {\n  /**\n   * Grid and data Props\n   */\n  /** An array of objects representing each column on the grid */\n  columns: readonly ColumnOrColumnGroup<R, SR>[];\n  /** A function called for each rendered row that should return a plain key/value pair object */\n  rows: readonly R[];\n  /**\n   * Rows to be pinned at the top of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  topSummaryRows?: Maybe<readonly SR[]>;\n  /**\n   * Rows to be pinned at the bottom of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  bottomSummaryRows?: Maybe<readonly SR[]>;\n  /** The getter should return a unique key for each row */\n  rowKeyGetter?: Maybe<(row: R) => K>;\n  onRowsChange?: Maybe<(rows: R[], data: RowsChangeData<R, SR>) => void>;\n  /**\n   * Dimensions props\n   */\n  /**\n   * The height of each row in pixels\n   * @default 35\n   */\n  rowHeight?: Maybe<number | ((row: R) => number)>;\n  /**\n   * The height of the header row in pixels\n   * @default 35\n   */\n  headerRowHeight?: Maybe<number>;\n  /**\n   * The height of each summary row in pixels\n   * @default 35\n   */\n  summaryRowHeight?: Maybe<number>;\n  /**\n   * Feature props\n   */\n  /** Set of selected row keys */\n  selectedRows?: Maybe<ReadonlySet<K>>;\n  /** Function called whenever row selection is changed */\n  onSelectedRowsChange?: Maybe<(selectedRows: Set<K>) => void>;\n  /** Used for multi column sorting */\n  sortColumns?: Maybe<readonly SortColumn[]>;\n  onSortColumnsChange?: Maybe<(sortColumns: SortColumn[]) => void>;\n  defaultColumnOptions?: Maybe<DefaultColumnOptions<R, SR>>;\n  onFill?: Maybe<(event: FillEvent<R>) => R>;\n  onCopy?: Maybe<(event: CopyEvent<R>) => void>;\n  onPaste?: Maybe<(event: PasteEvent<R>) => R>;\n  /**\n   * Event props\n   */\n  /** Function called whenever a cell is clicked */\n  onCellClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is double clicked */\n  onCellDoubleClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is right clicked */\n  onCellContextMenu?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  onCellKeyDown?: Maybe<\n    (args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) => void\n  >;\n  /** Function called whenever cell selection is changed */\n  onSelectedCellChange?: Maybe<(args: CellSelectArgs<R, SR>) => void>;\n  /** Called when the grid is scrolled */\n  onScroll?: Maybe<(event: React.UIEvent<HTMLDivElement>) => void>;\n  /** Called when a column is resized */\n  onColumnResize?: Maybe<(idx: number, width: number) => void>;\n  /** Called when a column is reordered */\n  onColumnsReorder?: Maybe<\n    (sourceColumnKey: string, targetColumnKey: string) => void\n  >;\n  /**\n   * Toggles and modes\n   */\n  /** @default true */\n  enableVirtualization?: Maybe<boolean>;\n  /**\n   * Miscellaneous\n   */\n  renderers?: Maybe<Renderers<R, SR>>;\n  rowClass?: Maybe<(row: R, rowIdx: number) => Maybe<string>>;\n  /** @default 'ltr' */\n  direction?: Maybe<Direction>;\n  'data-testid'?: Maybe<string>;\n}\n```",
      "api": [
        {
          "typeName": "DataGridPropsDefault",
          "source": "interface DataGridPropsDefault<R, SR = unknown, K extends Key = Key>\n  extends SharedDivProps {\n  /**\n   * Grid and data Props\n   */\n  /** An array of objects representing each column on the grid */\n  columns: readonly ColumnOrColumnGroup<R, SR>[];\n  /** A function called for each rendered row that should return a plain key/value pair object */\n  rows: readonly R[];\n  /**\n   * Rows to be pinned at the top of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  topSummaryRows?: Maybe<readonly SR[]>;\n  /**\n   * Rows to be pinned at the bottom of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  bottomSummaryRows?: Maybe<readonly SR[]>;\n  /** The getter should return a unique key for each row */\n  rowKeyGetter?: Maybe<(row: R) => K>;\n  onRowsChange?: Maybe<(rows: R[], data: RowsChangeData<R, SR>) => void>;\n  /**\n   * Dimensions props\n   */\n  /**\n   * The height of each row in pixels\n   * @default 35\n   */\n  rowHeight?: Maybe<number | ((row: R) => number)>;\n  /**\n   * The height of the header row in pixels\n   * @default 35\n   */\n  headerRowHeight?: Maybe<number>;\n  /**\n   * The height of each summary row in pixels\n   * @default 35\n   */\n  summaryRowHeight?: Maybe<number>;\n  /**\n   * Feature props\n   */\n  /** Set of selected row keys */\n  selectedRows?: Maybe<ReadonlySet<K>>;\n  /** Function called whenever row selection is changed */\n  onSelectedRowsChange?: Maybe<(selectedRows: Set<K>) => void>;\n  /** Used for multi column sorting */\n  sortColumns?: Maybe<readonly SortColumn[]>;\n  onSortColumnsChange?: Maybe<(sortColumns: SortColumn[]) => void>;\n  defaultColumnOptions?: Maybe<DefaultColumnOptions<R, SR>>;\n  onFill?: Maybe<(event: FillEvent<R>) => R>;\n  onCopy?: Maybe<(event: CopyEvent<R>) => void>;\n  onPaste?: Maybe<(event: PasteEvent<R>) => R>;\n  /**\n   * Event props\n   */\n  /** Function called whenever a cell is clicked */\n  onCellClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is double clicked */\n  onCellDoubleClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is right clicked */\n  onCellContextMenu?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  onCellKeyDown?: Maybe<\n    (args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) => void\n  >;\n  /** Function called whenever cell selection is changed */\n  onSelectedCellChange?: Maybe<(args: CellSelectArgs<R, SR>) => void>;\n  /** Called when the grid is scrolled */\n  onScroll?: Maybe<(event: React.UIEvent<HTMLDivElement>) => void>;\n  /** Called when a column is resized */\n  onColumnResize?: Maybe<(idx: number, width: number) => void>;\n  /** Called when a column is reordered */\n  onColumnsReorder?: Maybe<\n    (sourceColumnKey: string, targetColumnKey: string) => void\n  >;\n  /**\n   * Toggles and modes\n   */\n  /** @default true */\n  enableVirtualization?: Maybe<boolean>;\n  /**\n   * Miscellaneous\n   */\n  renderers?: Maybe<Renderers<R, SR>>;\n  rowClass?: Maybe<(row: R, rowIdx: number) => Maybe<string>>;\n  /** @default 'ltr' */\n  direction?: Maybe<Direction>;\n  'data-testid'?: Maybe<string>;\n}"
        }
      ],
      "stories": [
        {
          "exportName": "Virtualization",
          "displayName": "ID",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n        },\n        {\n          key: 'task',\n          name: 'Title',\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'developer',\n          name: 'Developer',\n        },\n        {\n          key: 'tr1',\n          name: 'TR',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          enableVirtualization: false,\n        }}\n        columnConfig={columnConfig}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    },
    {
      "component": "Table",
      "feature": "summaryRows",
      "legacy": true,
      "summary": "*tableConfig.summaryRows**",
      "docs": "# Summary Rows\n\n**tableConfig.summaryRows**\n\nИтоговые строки в верхней и/или нижней части таблицы.\n\n## Ключевые особенности\n\n- Отображение итогов через `topSummaryRows` и `bottomSummaryRows` пропсы\n- Кнопка переключения видимости в control block (`showInControl: true`)\n- Кастомный рендер через `renderSummaryCell` в `columnConfig`\n\n## Особенности\n\n- Количество элементов массива = количество итоговых строк\n- Пустой массив — итоговые строки не отображаются\n- `renderSummaryCell` получает `RenderSummaryCellProps` с данными итоговой строки\n\n> Подробнее о типах и пропсах — [Summary Rows API](?path=/docs/локальные-компоненты-table-summaryrows-api--docs)",
      "apiDocs": "# Summary Rows API\n\n## SummaryRowsConfig\n\n```typescript\ntype SummaryRowsConfig = {\n  showDefault: boolean;\n  showInControl: boolean;\n} & {\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};\n```\n\n## TableProps\n\n```typescript\ntype TableProps<\n  FilterStateType extends ObjectForExtending,\n  RowIdType extends string | number,\n  HeaderContextValueType extends ObjectForExtending,\n  RowContextValueType extends ObjectForExtending,\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n> = {\n  /**\n   * columnConfig - Конфигурация колонок.\n   *\n   * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n   */\n  columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n  /**\n   * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n   */\n  rows: RowType[];\n  /**\n   * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n   */\n  topSummaryRows?: SummaryRowType[];\n  /**\n   * rows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n   */\n  bottomSummaryRows?: SummaryRowType[];\n  /**\n   * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n   */\n  tableConfig?: Prettify<\n    TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n  >;\n  /**\n   * headerContextValue:  любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью useHeaderContext.\n   */\n  headerContextValue?: HeaderContextValueType;\n  /**\n   * rowContextValue:  любые стейты, которые нужны в cell - кладем в rowContextValue.  И получаем доступ с помощью useRowContext.\n   */\n  rowContextValue?: RowContextValueType;\n  refTable?: Ref<DataGridHandle>;\n  refTableContainer?: React.Ref<HTMLDivElement>;\n};\n```",
      "api": [
        {
          "typeName": "SummaryRowsConfig",
          "source": "type SummaryRowsConfig = {\n  showDefault: boolean;\n  showInControl: boolean;\n} & {\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};"
        },
        {
          "typeName": "TableProps",
          "source": "type TableProps<\n  FilterStateType extends ObjectForExtending,\n  RowIdType extends string | number,\n  HeaderContextValueType extends ObjectForExtending,\n  RowContextValueType extends ObjectForExtending,\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n> = {\n  /**\n   * columnConfig - Конфигурация колонок.\n   *\n   * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n   */\n  columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n  /**\n   * rows - данные для таблицы."
        }
      ],
      "stories": [
        {
          "exportName": "SummaryRows",
          "displayName": "ID",
          "type": "full-code",
          "code": "import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  Badge,\n  Box,\n  Button,\n  ColumnConfig,\n  ColumnOrColumnGroupConfig,\n  RenderCellProps,\n  RowHeightFunc,\n  SIZES,\n  Select,\n  Switch,\n  Table,\n  TextField,\n} from '@daisforge/ui';\nimport { IconAddOutline, IconBoxOutline, IconSber } from '@daisforge/ui/icons';\n\n() => {\n    const [rows] = useState(createRows);\n\n    const topSummaryRowsData: TSummaryRowData[] = [\n      {\n        type: 'top',\n        values: [\n          {\n            columnId: 'id',\n            value: 'Итого',\n          },\n          {\n            columnId: 'priority',\n            value: `Критичных приоритетов ${\n              rows.filter((el) => el.priority === 'Critical').length\n            }`,\n          },\n        ],\n      },\n      {\n        type: 'top',\n        values: [\n          {\n            columnId: 'id',\n            value: 'Итого',\n          },\n          {\n            columnId: 'priority',\n            value: `Высоких приоритетов ${\n              rows.filter((el) => el.priority === 'High').length\n            }`,\n          },\n        ],\n      },\n    ];\n\n    const bottomSummaryRowsData: TSummaryRowData[] = [\n      {\n        type: 'bottom',\n        values: [\n          { columnId: 'id', value: 'Итого' },\n          { columnId: 'task', value: `Всего тасков ${rows.length}` },\n          {\n            columnId: 'priority',\n            value: `Средних приоритетов ${\n              rows.filter((el) => el.priority === 'Medium').length\n            }`,\n          },\n        ],\n      },\n    ];\n\n    const renderCommonSummaryCell = useCallback(\n      (props: RenderSummaryCellProps<unknown, Row>) =>\n        (props.row as TSummaryRowData).values.find(\n          (el) => el.columnId === props.column.key,\n        )?.value,\n      [],\n    );\n\n    const columnConfig = useMemo<readonly ColumnConfig<Row>[]>(\n      () => [\n        {\n          key: 'id',\n          name: 'ID',\n          renderSummaryCell: renderCommonSummaryCell,\n        },\n        {\n          key: 'task',\n          name: 'Title',\n          renderSummaryCell: renderCommonSummaryCell,\n        },\n        {\n          key: 'priority',\n          name: 'Priority',\n          renderSummaryCell: (props) => {\n            const rowData = props.row as TSummaryRowData;\n            return (\n              <div\n                style={{\n                  color: rowData.type === 'top' ? textNegative : textWarning,\n                }}\n              >\n                {renderCommonSummaryCell(props)}\n              </div>\n            );\n          },\n        },\n        {\n          key: 'issueType',\n          name: 'Issue Type',\n        },\n        {\n          key: 'complete',\n          name: '% Complete',\n        },\n      ],\n      [renderCommonSummaryCell],\n    );\n\n    return (\n      <Table\n        tableConfig={{\n          containerStyle: { height: '700px' },\n          summaryRows: {\n            showDefault: true,\n            showInControl: true,\n          },\n        }}\n        columnConfig={columnConfig}\n        topSummaryRows={topSummaryRowsData}\n        bottomSummaryRows={bottomSummaryRowsData}\n        rows={rows}\n      />\n    );\n  }"
        }
      ]
    }
  ],
  "types": {
    "AiAgentPopoverPlacement": {
      "name": "AiAgentPopoverPlacement",
      "definition": "export type AiAgentPopoverPlacement =\n  | PopoverProps['placement']\n  | AiAgentPopoverCustomPlacement;",
      "internal": true,
      "importNotice": "Тип \"AiAgentPopoverPlacement\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/AiAgentPopover/AiAgentPopover.types.ts"
    },
    "AiAgentPopoverPositionState": {
      "name": "AiAgentPopoverPositionState",
      "definition": "export type AiAgentPopoverPositionState = [\n  AiAgentPopoverPosition,\n  Dispatch<SetStateAction<AiAgentPopoverPosition>>,\n];",
      "internal": true,
      "importNotice": "Тип \"AiAgentPopoverPositionState\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/AiAgentPopover/AiAgentPopover.types.ts"
    },
    "AiAgentPopoverPosition": {
      "name": "AiAgentPopoverPosition",
      "definition": "export type AiAgentPopoverPosition = { x: number; y: number };",
      "internal": true,
      "importNotice": "Тип \"AiAgentPopoverPosition\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/AiAgentPopover/AiAgentPopover.types.ts"
    },
    "AiAgentPopoverDragBoundary": {
      "name": "AiAgentPopoverDragBoundary",
      "definition": "export type AiAgentPopoverDragBoundary = {\n  top?: number;\n  right?: number;\n  bottom?: number;\n  left?: number;\n};",
      "internal": true,
      "importNotice": "Тип \"AiAgentPopoverDragBoundary\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/AiAgentPopover/AiAgentPopover.types.ts"
    },
    "AiAgentPopover.DataAttributes": {
      "name": "DataAttributes",
      "definition": "type DataAttributes = {\n  [K in `data-${string}`]?: string;\n};",
      "internal": true,
      "importNotice": "Тип \"DataAttributes\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/AiAgentPopover/AiAgentPopover.types.ts"
    },
    "TableCanvas.DataAttributes": {
      "name": "DataAttributes",
      "definition": "export type DataAttributes = {\n  [K in `data-${string}`]?: string;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { DataAttributes } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/utils.type.ts"
    },
    "Table.DataAttributes": {
      "name": "DataAttributes",
      "definition": "export type DataAttributes = {\n  [K in `data-${string}`]?: string;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { DataAttributes } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/utils.type.ts"
    },
    "AnalyticalWidgetSize": {
      "name": "AnalyticalWidgetSize",
      "definition": "export type AnalyticalWidgetSize = 'l' | 'm' | 's';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { AnalyticalWidgetSize } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/AnalyticalWidget/AnalyticalWidget.types.ts"
    },
    "AnalyticalWidgetClasses": {
      "name": "AnalyticalWidgetClasses",
      "definition": "export type AnalyticalWidgetClasses = {\n  /**\n   * Кастомный класс для root элемента\n   */\n  root?: string;\n  /**\n   * Кастомный класс для topSlot элемента\n   */\n  topSlot?: string;\n  /**\n   * Кастомный класс для middleSlot элемента\n   */\n  middleSlot?: string;\n  /**\n   * Кастомный класс для contentSlot элемента\n   */\n  contentSlot?: string;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { AnalyticalWidgetClasses } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/AnalyticalWidget/AnalyticalWidget.types.ts"
    },
    "AnalyticalWidgetFixedChipProps": {
      "name": "AnalyticalWidgetFixedChipProps",
      "definition": "export type AnalyticalWidgetFixedChipProps = ChipCompProps & {\n  key?: string | number;\n};",
      "internal": true,
      "importNotice": "Тип \"AnalyticalWidgetFixedChipProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/AnalyticalWidget/components/AnalyticalWidgetChips/AnalyticalWidgetChipsGroup.types.ts"
    },
    "ApprovalCenterPreview": {
      "name": "ApprovalCenterPreview",
      "definition": "export type ApprovalCenterPreview = {\n  /**\n   * Параметры кнопки превью\n   */\n  button?: PreviewButton;\n  /**\n   * Переключить превью в режим загрузки\n   */\n  loading?: boolean;\n};",
      "internal": true,
      "importNotice": "Тип \"ApprovalCenterPreview\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/ApprovalCenter/ApprovalCenter.types.ts"
    },
    "ApprovalCenterTabs": {
      "name": "ApprovalCenterTabs",
      "definition": "export type ApprovalCenterTabs = {\n  /**\n   * Текущая открытая вкладка\n   */\n  active: 'LIFE_CYCLE';\n  /**\n   * Список доступных вкладок\n   */\n  available:\n    | ['LIFE_CYCLE', 'HISTORY']\n    | ['HISTORY', 'LIFE_CYCLE']\n    | ['HISTORY']\n    | ['LIFE_CYCLE'];\n};",
      "internal": true,
      "importNotice": "Тип \"ApprovalCenterTabs\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/ApprovalCenter/ApprovalCenter.types.ts"
    },
    "LifeCycleItem": {
      "name": "LifeCycleItem",
      "definition": "export type LifeCycleItem = {\n  /**\n   * Статус\n   */\n  status: LifeCycleStatus;\n  /**\n   * Заголовок\n   */\n  title: string;\n  /**\n   * Заголовок выполненного действия\n   */\n  actionTitle?: string;\n  /**\n   * Дата выполненного действия\n   */\n  actionDate?: string;\n  /**\n   * Этапы (аккордеон)\n   */\n  stages?: StageItem[];\n  /**\n   * Вспомогательные кнопки\n   */\n  buttons?: LifeCycleButton[];\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LifeCycleItem } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/ApprovalCenter/ApprovalCenter.types.ts"
    },
    "HistoryItem": {
      "name": "HistoryItem",
      "definition": "export type HistoryItem = {\n  /**\n   * Статус\n   */\n  status: HistoryItemStatus;\n  /**\n   * Заголовок действия\n   */\n  actionTitle: string;\n  /**\n   * Дата действия\n   */\n  actionDate: string;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { HistoryItem } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/ApprovalCenter/ApprovalCenter.types.ts"
    },
    "BlockTitleAdaptiveSlot": {
      "name": "BlockTitleAdaptiveSlot",
      "definition": "export type BlockTitleAdaptiveSlot =\n  | ReactNode\n  | ((props: BlockTitleSlotSizesProps) => ReactNode);",
      "importPath": "@daisforge/ui",
      "importStatement": "import { BlockTitleAdaptiveSlot } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/BlockTitle/BlockTitle.types.ts"
    },
    "EmptyStateButtonProps": {
      "name": "EmptyStateButtonProps",
      "definition": "export type EmptyStateButtonProps = ButtonVariant | LinkButtonVariant;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { EmptyStateButtonProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/EmptyState/EmptyState.types.ts"
    },
    "ButtonVariant": {
      "name": "ButtonVariant",
      "definition": "type ButtonVariant = {\n  type: 'button';\n  props: Omit<ButtonCompProps, 'size'>;\n};",
      "internal": true,
      "importNotice": "Тип \"ButtonVariant\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/EmptyState/EmptyState.types.ts"
    },
    "LinkButtonVariant": {
      "name": "LinkButtonVariant",
      "definition": "type LinkButtonVariant = {\n  type: 'link';\n  props: Omit<LinkButtonCompProps, 'size'>;\n};",
      "internal": true,
      "importNotice": "Тип \"LinkButtonVariant\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/EmptyState/EmptyState.types.ts"
    },
    "EmptyStateClasses": {
      "name": "EmptyStateClasses",
      "definition": "export type EmptyStateClasses = {\n  root?: string;\n  icon?: string;\n  title?: string;\n  subtitle?: string;\n  buttons?: string;\n  extraButton?: string;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { EmptyStateClasses } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/EmptyState/EmptyState.types.ts"
    },
    "GridDNDItems": {
      "name": "GridDNDItems",
      "definition": "export type GridDNDItems = {\n  id: string;\n  /** Размер по типу: s(1x1), m(2x1), l(2x2) */\n  type: 's' | 'm' | 'l';\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { GridDNDItems } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/GridDND/GridDND.types.ts"
    },
    "GridDNDItemConfig": {
      "name": "GridDNDItemConfig",
      "definition": "export type GridDNDItemConfig = {\n  id: string;\n  type: 's' | 'm' | 'l';\n  position: { x: number; y: number; w: number; h: number };\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { GridDNDItemConfig } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/GridDND/GridDND.types.ts"
    },
    "PanelCollapsedContentProps": {
      "name": "PanelCollapsedContentProps",
      "definition": "type PanelCollapsedContentProps = Omit<\n  ComponentProps<typeof PanelCollapsedContent>,\n  '$isAdaptive1280' | 'showResizeable' | '$active'\n>;",
      "internal": true,
      "importNotice": "Тип \"PanelCollapsedContentProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/LeftPanel/LeftPanel.types.ts"
    },
    "LeftPanelAdaptiveSlot": {
      "name": "LeftPanelAdaptiveSlot",
      "definition": "export type LeftPanelAdaptiveSlot =\n  | ReactNode\n  | ((props: LeftPanelSlotSizesProps) => ReactNode);",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LeftPanelAdaptiveSlot } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/LeftPanel/LeftPanel.types.ts"
    },
    "ItemOrGroup": {
      "name": "ItemOrGroup",
      "definition": "export type ItemOrGroup = Item | Group;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ItemOrGroup } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/ListOfFilters/types.ts"
    },
    "MassActionsButtonProps": {
      "name": "MassActionsButtonProps",
      "definition": "export type MassActionsButtonProps =\n  | MassActionsButtonPropsButton\n  | MassActionsButtonPropsLinkButton;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { MassActionsButtonProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/MassActions/types.ts"
    },
    "MassActionsSidebarConfig": {
      "name": "MassActionsSidebarConfig",
      "definition": "export type MassActionsSidebarConfig = {\n  /** Открыт ли сайдбар */\n  isOpen: boolean;\n  /** Ширина сайдбара */\n  width: number;\n  /** Ширина тогл-панели сайдбара (по умолчанию 44px) */\n  togglePanelWidth?: number;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { MassActionsSidebarConfig } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/MassActions/types.ts"
    },
    "Table.TableDropdownConfigProps": {
      "name": "TableDropdownConfigProps",
      "definition": "export type TableDropdownConfigProps = Omit<\n  TableDropdownProps,\n  'onItemSelect' | 'items' | 'onToggle' | 'size' | 'portal'\n>;",
      "internal": true,
      "importNotice": "Тип \"TableDropdownConfigProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/components/TableDropdown/types.ts"
    },
    "TableCanvas.TableDropdownConfigProps": {
      "name": "TableDropdownConfigProps",
      "definition": "export type TableDropdownConfigProps = Omit<\n  TableDropdownProps,\n  'onItemSelect' | 'items' | 'onToggle' | 'size' | 'portal'\n>;",
      "internal": true,
      "importNotice": "Тип \"TableDropdownConfigProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/components/TableDropdown/types.ts"
    },
    "ModalDFConfirmationContent": {
      "name": "ModalDFConfirmationContent",
      "definition": "export type ModalDFConfirmationContent = {\n  /**\n   * заголовок\n   */\n  header?: ReactNode;\n  /**\n   * информационный текст\n   */\n  body?: ReactNode;\n  /**\n   * отступы сверху и снизу информационного текста (по умолчанию: `bodyMarginBlock ?? (typeof body === 'string' ? s.x4 : undefined);`)\n   */\n  bodyMarginBlock?: string;\n  /**\n   * пропсы для самой правой главной кнопки, по умолчанию `view=\"accent\"`\n   */\n  mainButton?: ButtonCompProps;\n  /**\n   * пропсы для вторичной кнопки, по умолчанию `view=\"secondary\"`\n   */\n  secondaryButton?: ButtonCompProps;\n  /**\n   * если `mainButton` или `secondaryButton` не подходят, то можно полностью заменить footer на кастомный\n   */\n  footer?: ReactNode;\n};",
      "internal": true,
      "importNotice": "Тип \"ModalDFConfirmationContent\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/ModalDFConfirmation/ModalDFConfirmation.tsx"
    },
    "PageTitleAdaptiveSlot": {
      "name": "PageTitleAdaptiveSlot",
      "definition": "export type PageTitleAdaptiveSlot =\n  | ReactNode\n  | ((props: PageTitleSlotSizesProps) => ReactNode);",
      "importPath": "@daisforge/ui",
      "importStatement": "import { PageTitleAdaptiveSlot } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/PageTitle/PageTitle.types.ts"
    },
    "StorySlide": {
      "name": "StorySlide",
      "definition": "export interface StorySlide {\n  /** Стабильный идентификатор сегмента (ключи, внешняя адресация). */\n  id?: string;\n  /** URL ассета (картинка или GIF). */\n  src: string;\n  /** Тип ассета. По умолчанию `image` (video пока не реализован). */\n  type?: StoryAssetType;\n  /** Длительность показа сегмента, мс. Переопределяет дефолт группы и компонента. */\n  duration?: number;\n  /** Способ вписывания ассета. По умолчанию `cover`. */\n  objectFit?: StoriesObjectFit;\n  /** Слот внизу баннера (любой ReactNode). Может отличаться на каждом сегменте. */\n  footer?: ReactNode;\n}",
      "importPath": "@daisforge/ui",
      "importStatement": "import { StorySlide } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Stories/Stories.types.ts"
    },
    "Table.ColumnConfig": {
      "name": "ColumnConfig",
      "definition": "export type ColumnConfig<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> = ColumnDefaultOmitted<Row, SummRow> & {\n  /**\n   * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n   */\n  nameAsString?: string;\n  sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n  searching?: {\n    valueInRow: (row: Row) => string | number;\n  };\n  filtering?: {\n    keyInFilterState: string;\n    /**\n     * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n     */\n    valueInRow?: (row: Row) => string | number;\n    /**\n     * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n     */\n  } & (\n    | {\n        component: 'input';\n        filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n      }\n    | {\n        component: 'select';\n        /**\n         * Произвольное содержимое над списком опций фильтра.\n         *\n         * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n         * фильтров. Рендерится как компонент, поэтому внутри можно\n         * использовать хуки и локальное состояние.\n         *\n         * @example\n         * beforeList: ({ headerContextState }) => (\n         *   <TableFilterSelectListItem $size={headerContextState.rowSize}>\n         *     Подсказка над списком\n         *   </TableFilterSelectListItem>\n         * )\n         */\n        beforeList?: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        /**\n         * Произвольное содержимое под списком опций фильтра.\n         *\n         * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n         * фильтров. Рендерится как компонент, поэтому внутри можно\n         * использовать хуки и локальное состояние — например, чтобы держать\n         * черновик выбора и применять его по кнопке.\n         *\n         * @example\n         * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n         *   <TableFilterSelectListItem $size={headerContextState.rowSize}>\n         *     Подсказка под списком\n         *   </TableFilterSelectListItem>\n         * )\n         */\n        afterList?: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        filter:\n          | {\n              typeOfValue: 'single';\n              /**\n               * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n               */\n              filteringType?: FilterCb<'single'>;\n            }\n          | {\n              typeOfValue: 'multiple';\n              /**\n               * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n               */\n              filteringType?: FilterCb<'multiple'>;\n            };\n        selectOptions:\n          | {\n              type: 'constant';\n              options: SelectOptions[];\n            }\n          | {\n              type: 'stateInHeaderContext';\n              /**\n               * тип optionsState, который будет в HeaderContext:\n               * ```ts\n               * {\n               * value: string | number;\n               * text: string | number;\n               * }[];\n               * ```\n               */\n              optionsKeyInHeaderContext: string;\n            };\n        /**\n         * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n         * @default \"360px\"\n         */\n        listMaxHeight?: string;\n      }\n    | {\n        component: 'custom';\n        customRender: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n        compareWithClearedValue?: (\n          clearedValue: unknown,\n          currV: unknown,\n        ) => boolean;\n      }\n  );\n\n  contentFormat?: ContentFormat;\n\n  editingCell?: Editing<Row>;\n\n  subRow?: {\n    /**\n     * @default false\n     */\n    isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n    /**\n     * @default false\n     */\n    hideHeaderExpandAllArrow?: boolean;\n    /**\n     * @default false\n     */\n    parentKeyAsDefault?: boolean;\n    /**\n     * @default undefined\n     */\n    contentFormat?: ContentFormat;\n\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    renderSubRowCell?: RenderSubRowCell<any>;\n  } & (\n    | {\n        keyOfColumnInSubRow:\n          | string\n          | number\n          | ((lvl: number) => string | number);\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        editingCell: Editing<any>;\n      }\n    | {\n        editingCell?: undefined;\n        keyOfColumnInSubRow?:\n          | string\n          | number\n          | ((lvl: number) => string | number);\n      }\n  );\n  rowsGrouping?: ColumnRowsGrouping<Row, SummRow>;\n  keyText?: KeyTextColumnConfig<Row, SummRow>;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ColumnConfig } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
    },
    "TableCanvas.ColumnConfig": {
      "name": "ColumnConfig",
      "definition": "export type ColumnConfig<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = ColumnDefaultOmitted<Row, SummRow, CustomCtxs> & {\n  renderCell?: (cellInfo: CellInfo<Row, SummRow, CustomCtxs>) => CellContent;\n  renderCellPreview?: RenderCellPreview<Row, SummRow, CustomCtxs>;\n  /**\n   * Если в поле name был передан jsx, то нужно заполнить nameAsString для указания label в разделе Настройки столбцов, либо для отображения label в фильтрах в правом сайдбаре (но приоритет для фильтро будет ниже, чем то, что указали в filtering.sidebarConfig.items, там отдельно можно перезаписать label для фильтров сайдабара)\n   */\n  nameAsString?: string;\n  /**\n   * Текстовое представление ячейки для копирования в clipboard (Ctrl+C).\n   * Если не задан, используется `row[column.key]?.toString()`.\n   * Для кастомных canvas-ячеек (бейджи, кнопки) рекомендуется указывать явно.\n   */\n  copyData?: string | ((row: Row) => string);\n  sortingType?: 'stringSort' | 'numberSort' | Comparator<Row>;\n  searching?: {\n    valueInRow: (row: Row) => string | number;\n  };\n  filtering?: {\n    keyInFilterState: string;\n    /**\n     * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n     */\n    valueInRow?: (row: Row) => string | number;\n    /**\n     * ```FilterCb - (filterValue: string, rowValue: string) => boolean```\n     */\n  } & (\n    | {\n        component: 'input';\n        filter: 'includes' | 'startWith' | 'equal' | FilterCb<'single'>;\n      }\n    | {\n        component: 'select';\n        /**\n         * Произвольное содержимое над списком опций фильтра.\n         *\n         * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n         * фильтров. Рендерится как компонент, поэтому внутри можно\n         * использовать хуки и локальное состояние.\n         *\n         * @example\n         * beforeList: ({ headerContextState }) => (\n         *   <TableFilterSelectListItem $size={headerContextState.rowSize}>\n         *     Подсказка над списком\n         *   </TableFilterSelectListItem>\n         * )\n         */\n        beforeList?: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        /**\n         * Произвольное содержимое под списком опций фильтра.\n         *\n         * Рендерится и в поповере фильтра в шапке колонки, и в сайдбаре\n         * фильтров. Рендерится как компонент, поэтому внутри можно\n         * использовать хуки и локальное состояние — например, чтобы держать\n         * черновик выбора и применять его по кнопке.\n         *\n         * @example\n         * afterList: ({ headerContextState, setPopoverIsOpen }) => (\n         *   <TableFilterSelectListItem $size={headerContextState.rowSize}>\n         *     Подсказка под списком\n         *   </TableFilterSelectListItem>\n         * )\n         */\n        afterList?: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        filter:\n          | {\n              typeOfValue: 'single';\n              /**\n               * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n               */\n              filteringType?: FilterCb<'single'>;\n            }\n          | {\n              typeOfValue: 'multiple';\n              /**\n               * Обязательно передать в случае НЕ ручной фильтрации. Если на уровне tableConfig.manualFiltering = false или не задан. Иначе фильтрация не отработает.\n               */\n              filteringType?: FilterCb<'multiple'>;\n            };\n        selectOptions:\n          | {\n              type: 'constant';\n              options: SelectOptions[];\n            }\n          | {\n              type: 'stateInHeaderContext';\n              /**\n               * тип optionsState, который будет в HeaderContext:\n               * ```ts\n               * {\n               * value: string | number;\n               * text: string | number;\n               * }[];\n               * ```\n               */\n              optionsKeyInHeaderContext: string;\n            };\n        /**\n         * Максимальна высота выпадающего списка в фильтрах колонок / правом сайдбаре.\n         * @default \"360px\"\n         */\n        listMaxHeight?: string;\n      }\n    | {\n        component: 'custom';\n        customRender: (\n          props: FilterComponentInPopoverProps<\n            ObjectForExtending,\n            ColumnConfig<Row, SummRow>\n          >,\n        ) => ReactNode;\n        filter?: (filterValue: unknown, rowValue: unknown) => boolean;\n        compareWithClearedValue?: (\n          clearedValue: unknown,\n          currV: unknown,\n        ) => boolean;\n      }\n  );\n\n  contentFormat?: ContentFormat;\n\n  editingCell?: Editing<Row, SummRow>;\n\n  /**\n   * Настройки колонки для дерева subRows (шеврон, свой контент и редактор на\n   * вложенных уровнях). Работает только в виде дерева. При\n   * `subRows.view: 'merged'` не действует: там листья рисуются как обычные\n   * строки, вложенных уровней нет.\n   */\n  subRow?: {\n    /**\n     * @default false\n     */\n    isColumnWithArrow?: boolean | ((props: { keyText: KeyText }) => boolean);\n    /**\n     * @default false\n     */\n    hideHeaderExpandAllArrow?: boolean;\n    /**\n     * @default false\n     */\n    parentKeyAsDefault?: boolean;\n    /**\n     * @default undefined\n     */\n    contentFormat?: ContentFormat;\n\n    renderSubRowCell?: RenderSubRowCell<ObjectForExtending>;\n  } & (\n    | {\n        keyOfColumnInSubRow:\n          | string\n          | number\n          | ((lvl: number) => string | number);\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        editingCell: Editing<any, any>;\n      }\n    | {\n        editingCell?: undefined;\n        keyOfColumnInSubRow?:\n    …",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { ColumnConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
    },
    "TableGlide.ObjectForExtending": {
      "name": "ObjectForExtending",
      "definition": "export type ObjectForExtending = Record<string, any>;",
      "internal": true,
      "importNotice": "Тип \"ObjectForExtending\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "Table.ObjectForExtending": {
      "name": "ObjectForExtending",
      "definition": "export type ObjectForExtending = Record<string | number, any>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ObjectForExtending } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/utils.type.ts"
    },
    "TableCanvas.ObjectForExtending": {
      "name": "ObjectForExtending",
      "definition": "export type ObjectForExtending = Record<string | number, any>;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { ObjectForExtending } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/utils.type.ts"
    },
    "HoverEffectsConfig": {
      "name": "HoverEffectsConfig",
      "definition": "export type HoverEffectsConfig = {\n  /**\n   * Подсветка строки под курсором. По умолчанию выключена.\n   * - не задано или `false` — выключена;\n   * - `true` — включена, цвета из темы.\n   *\n   * Цвета по зонам строки берутся из темы:\n   * - data-ячейки — `bgRowHovered`;\n   * - служебные колонки (нумерация, чекбокс) — `bgServiceRowHovered`, тот же\n   *   цвет, что у сервис-зоны при выделении;\n   * - строка, отмеченная чекбоксом, темнеет целиком `bgSelectedRowHovered`.\n   *\n   * Hover — самый нижний слой: выделение ячеек, строк, колонок и залипшая\n   * активная строка (`highlightActiveType: 'row'`) рисуются поверх и\n   * перекрывают его; после сброса выделения он снова виден. Summary-строки\n   * hover не получают.\n   */\n  row?: boolean;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { HoverEffectsConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "ColumnGlideInstance": {
      "name": "ColumnGlideInstance",
      "definition": "export type ColumnGlideInstance<\n  R extends ObjectForExtending,\n  SR,\n  CustomCtxs extends ObjectForExtending = {},\n> = {\n  key: string;\n  name: string | CanvasEl;\n  nameAsString?: string;\n  readonly width?: number;\n  isServiceColumn?: boolean;\n  isErrorCell?: (row: R) => boolean;\n  frozen?: boolean;\n  /** Минимальная ширина колонки (px). Ограничивает ресайз и начальную ширину снизу. */\n  minWidth?: number;\n  /** Максимальная ширина колонки (px). Ограничивает ресайз и начальную ширину сверху. */\n  maxWidth?: number;\n  /** Максимальная ширина колонки при auto-sizing и grow-распределении (px). Не ограничивает ручной ресайз. */\n  maxAutoWidth?: number;\n  renderHeaderCell?: (\n    cellInfo: HeaderCellInfoGlideInstance<R, SR, CustomCtxs>,\n  ) => CanvasContent;\n  renderCell?: (\n    cellInfo: CellInfoGlideInstance<R, SR, CustomCtxs>,\n  ) => CellContent;\n  contentAlign?: 'left' | 'right' | 'center';\n  copyData?: string | ((row: R) => string);\n  editable?: boolean | ((row: R) => boolean);\n  renderEditCell?: (\n    cellInfo: EditingCellInfoGlideInstance<R, SR, CustomCtxs>,\n  ) => ReactNode;\n  /**\n   * Кастомный рендер preview-ячейки (при двойном клике на readonly-ячейку).\n   * 'none' — отключает превью. 'cellEditorAsPreview' — стандартный текстовый превью.\n   * Функция — полностью кастомный рендер.\n   */\n  renderCellPreview?:\n    | 'none'\n    | 'cellEditorAsPreview'\n    | ((\n        cellInfo: PreviewCellInfoGlideInstance<R, SR, CustomCtxs>,\n      ) => ReactNode);\n  renderSummaryCell?: (\n    cellInfo: SummaryCellInfoGlideInstance<R, SR, CustomCtxs>,\n  ) => CellContent;\n  colSpan?:\n    | number\n    | ((cellInfo: CellInfoGlideInstance<R, SR, CustomCtxs>) => number);\n  /** Объединение строк: (cellInfo) => [перваяСтрока, последняяСтрока] | null (см. TableGlide RowSpan). */\n  rowSpan?: (\n    cellInfo: CellInfoGlideInstance<R, SR, CustomCtxs>,\n  ) => readonly [number, number] | null;\n  /** Выравнивание контента в объединённой ячейке тела; в adaptColumn идёт в glide как `spanAlign`. */\n  spanAlign?:\n    | SpanCellAlign\n    | ((\n        cellInfo: CellInfoGlideInstance<R, SR, CustomCtxs>,\n      ) => SpanCellAlign | undefined);\n  /** Выравнивание в объединённой шапке; в adaptColumn идёт в glide как `spanGroupHeaderAlign`. */\n  squashedHeaderAlign?: HeaderAlignment;\n  /** Тултип для ячеек этой колонки. Строка, объект или функция (context) => config | null. */\n  cellTooltip?:\n    | CanvasNodeTooltipConfig\n    | ((context: {\n        row: R;\n        column: ColumnGlideInstance<R, SR, CustomCtxs>;\n        ctxs: CtxsType<CustomCtxs>;\n        refTable?: React.Ref<DataEditorRef>;\n        colInd?: number;\n        rowInd?: number;\n        theme?: Theme;\n      }) => CanvasNodeTooltipConfig | null);\n  /** Тултип для шапки колонки. Строка, объект или функция (context) => config | null. */\n  headerCellTooltip?:\n    | CanvasNodeTooltipConfig\n    | ((context: {\n        column: ColumnGlideInstance<R, SR, CustomCtxs>;\n        ctxs: CtxsType<CustomCtxs>;\n        refTable?: React.Ref<DataEditorRef>;\n        colInd?: number;\n        theme?: Theme;\n      }) => CanvasNodeTooltipConfig | null);\n  columnThemeOverride?: (\n    cellInfo: CellInfoGlideInstance<R, SR, CustomCtxs>,\n  ) => CellThemeOverrideResult | undefined;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { ColumnGlideInstance } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "HeaderContextMenuDropdownProps": {
      "name": "HeaderContextMenuDropdownProps",
      "definition": "export type HeaderContextMenuDropdownProps<\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n  CustomCtxs extends ObjectForExtending = ObjectForExtending,\n> = ContextMenuDropdownProps & {\n  /** Тип конфигурации (всегда 'dropdown') */\n  type: 'dropdown';\n  /**\n   * Функция, возвращающая массив пунктов меню для конкретного заголовка.\n   * В асинхронном режиме (задан onOpen) перечитывается реактивно, пока меню\n   * открыто: верните скелетон-пункты во время загрузки и реальные — после.\n   */\n  getDropdownItems: (\n    params: TableInfoBase<RowType, SummaryRowType, CustomCtxs>,\n  ) => DropdownProps['items'];\n  /**\n   * Колбэк открытия меню для асинхронной подгрузки. Если getDropdownItems\n   * вернул пусто, но onOpen задан — меню всё равно открывается, а потребитель\n   * здесь стартует запрос и хранит своё состояние (loading/error/items).\n   */\n  onOpen?: (params: TableInfoBase<RowType, SummaryRowType, CustomCtxs>) => void;\n  /** Обработчик выбора пункта меню */\n  onItemSelect?: (\n    item: ContextMenuDropdownItem,\n    context: TableInfoBase<RowType, SummaryRowType, CustomCtxs>,\n    event?: React.SyntheticEvent,\n  ) => void;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { HeaderContextMenuDropdownProps } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "CellContextMenuDropdownProps": {
      "name": "CellContextMenuDropdownProps",
      "definition": "export type CellContextMenuDropdownProps<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  CustomCtxs extends ObjectForExtending = ObjectForExtending,\n> = ContextMenuDropdownProps & {\n  /** Тип конфигурации (всегда 'dropdown') */\n  type: 'dropdown';\n  /**\n   * Функция, возвращающая массив пунктов меню для конкретной ячейки.\n   * В асинхронном режиме (задан onOpen) перечитывается реактивно, пока меню\n   * открыто: верните скелетон-пункты во время загрузки и реальные — после.\n   */\n  getDropdownItems: (\n    params: TableInfoWithRow<RowType, SummaryRowType, CustomCtxs>,\n  ) => DropdownProps['items'];\n  /**\n   * Колбэк открытия меню для асинхронной подгрузки. Если getDropdownItems\n   * вернул пусто, но onOpen задан — меню всё равно открывается, а потребитель\n   * здесь стартует запрос и хранит своё состояние (loading/error/items).\n   */\n  onOpen?: (\n    params: TableInfoWithRow<RowType, SummaryRowType, CustomCtxs>,\n  ) => void;\n  /** Обработчик выбора пункта меню */\n  onItemSelect?: (\n    item: ContextMenuDropdownItem,\n    context: TableInfoWithRow<RowType, SummaryRowType, CustomCtxs>,\n    event?: React.SyntheticEvent,\n  ) => void;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellContextMenuDropdownProps } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "TableContentStateEmptyOverlay": {
      "name": "TableContentStateEmptyOverlay",
      "definition": "export type TableContentStateEmptyOverlay = {\n  kind: 'empty';\n} & TableContentStateFrame &\n  Partial<EmptyStateProps>;",
      "internal": true,
      "importNotice": "Тип \"TableContentStateEmptyOverlay\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-content-state/types.ts"
    },
    "TableContentStateErrorOverlay": {
      "name": "TableContentStateErrorOverlay",
      "definition": "export type TableContentStateErrorOverlay = {\n  kind: 'error';\n  errorPageProps?: Partial<ErrorPageProps>;\n} & TableContentStateFrame;",
      "internal": true,
      "importNotice": "Тип \"TableContentStateErrorOverlay\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-content-state/types.ts"
    },
    "Table.TableDropdownProps": {
      "name": "TableDropdownProps",
      "definition": "export type TableDropdownProps = DropdownProps & { $css?: CSSObject };",
      "internal": true,
      "importNotice": "Тип \"TableDropdownProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/components/TableDropdown/types.ts"
    },
    "TableCanvas.TableDropdownProps": {
      "name": "TableDropdownProps",
      "definition": "export type TableDropdownProps = DropdownProps & { $css?: CSSObject };",
      "internal": true,
      "importNotice": "Тип \"TableDropdownProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/components/TableDropdown/types.ts"
    },
    "ColumnGlideLast": {
      "name": "ColumnGlideLast",
      "definition": "export type ColumnGlideLast<R extends ObjectForExtending, SR> = СolumnGlide &\n  ColumnGlideCustoms<R, SR>;",
      "internal": true,
      "importNotice": "Тип \"ColumnGlideLast\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "CanvasInteractionOptions": {
      "name": "CanvasInteractionOptions",
      "definition": "export interface CanvasInteractionOptions {\n  /**\n   * Как клик по этой зоне влияет на выделение таблицы.\n   *\n   * `normal` — таблица ведет себя обычно: клик может сделать ячейку активной.\n   *\n   * `keep` — текущее выделение сохраняется: клик по этой зоне не переключает\n   * active cell. Это основной режим для кнопок действия внутри ячейки.\n   */\n  selection?: 'normal' | 'keep';\n\n  /**\n   * Дойдет ли клик до `tableConfig.onCellClicked`.\n   *\n   * `normal` — после canvas `onClick` таблица получит обычный `onCellClicked`.\n   *\n   * `stop` — клик остается внутри canvas-элемента, внешний\n   * `tableConfig.onCellClicked` не вызывается.\n   */\n  cellClick?: 'normal' | 'stop';\n\n  /**\n   * Как клик по этой зоне влияет на editor ячейки.\n   *\n   * `normal` — не вмешиваться: таблица ведет себя как обычно для этой ячейки.\n   *\n   * `never` — клик по этой зоне не должен открывать editor.\n   *\n   * `open-on-click` — клик по этой зоне должен открыть editor этой же ячейки.\n   * В текущей реализации поддерживается только текущая ячейка, потому что\n   * editor открывается через штатный click-путь таблицы.\n   */\n  editor?: 'normal' | 'never' | 'open-on-click';\n\n  /**\n   * Как правый клик / context menu ведет себя на этой зоне.\n   *\n   * `normal` — обычное поведение таблицы.\n   *\n   * `keep-selection` — context menu разрешен, но текущее выделение не меняется.\n   *\n   * `none` — context menu для этой зоны не открывается.\n   */\n  contextMenu?: 'normal' | 'keep-selection' | 'none';\n}",
      "internal": true,
      "importNotice": "Тип \"CanvasInteractionOptions\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/core/canvasInteraction.ts"
    },
    "ButtonIcon": {
      "name": "ButtonIcon",
      "definition": "export type ButtonIcon =\n  | string\n  | HTMLImageElement\n  | ReactElement\n  | null\n  | undefined;",
      "internal": true,
      "importNotice": "Тип \"ButtonIcon\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/cells/iconSprites/types.ts"
    },
    "TCustomOrNotTab": {
      "name": "TCustomOrNotTab",
      "definition": "export type TCustomOrNotTab<T extends TabId> = TTabItem<T> | TCustomTabItem<T>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TCustomOrNotTab } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/TableTabs/TableTabs.types.ts"
    },
    "TTabsContainerOptions": {
      "name": "TTabsContainerOptions",
      "definition": "export type TTabsContainerOptions = {\n  /**\n   * Максимальная ширина контейнера табов.\n   * Если установлено, контейнер будет иметь ограничение ширины и стрелки прокрутки при переполнении.\n   * Может быть числом (пиксели) или строкой (CSS значение, например '250px', '50%').\n   * Если не указано, ограничения ширины не будет.\n   */\n  maxWidth?: number | string;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TTabsContainerOptions } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/TableTabs/TableTabs.types.ts"
    },
    "TableTabsCollapseConfig": {
      "name": "TableTabsCollapseConfig",
      "definition": "export type TableTabsCollapseConfig = Pick<\n  TableCollapseConfig,\n  | 'defaultCollapsed'\n  | 'collapseText'\n  | 'expandText'\n  | 'onToggleCollapse'\n  | 'collapsedState'\n  | 'domMetadata'\n> & {\n  /** Включить коллапсинг над табами (аналог enableCollapse в TableCollapseConfig) */\n  enabled?: boolean;\n  /** Кастомный слот справа от кнопки коллапсинга */\n  rightSlot?: ReactNode;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TableTabsCollapseConfig } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/TableTabs/TableTabs.types.ts"
    },
    "THandleChange": {
      "name": "THandleChange",
      "definition": "export type THandleChange<T> = (\n  newValue: T,\n  formCtx: TReturnUseChangedFormContext,\n) => void;",
      "internal": true,
      "importNotice": "Тип \"THandleChange\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/types.ts"
    },
    "StatusCode": {
      "name": "StatusCode",
      "definition": "export type StatusCode = number | 'unknown' | undefined;",
      "internal": true,
      "importNotice": "Тип \"StatusCode\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/layouts/ErrorPage/ErrorPage.tsx"
    },
    "CustomStatusObj": {
      "name": "CustomStatusObj",
      "definition": "export type CustomStatusObj = {\n  title: ReactNode;\n  description: ReactNode;\n  button?: StatusButton;\n  buttons?: StatusButton[];\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { CustomStatusObj } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/layouts/ErrorPage/ErrorPage.tsx"
    },
    "BoxProps": {
      "name": "BoxProps",
      "definition": "export type BoxProps = ComponentProps<typeof Box> & BoxBaseProps;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { BoxProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Box/Box.tsx"
    },
    "LayoutSpacing": {
      "name": "LayoutSpacing",
      "definition": "export type LayoutSpacing = {\n  horizontal?: string;\n  vertical?: string | { top?: string; bottom?: string };\n  gutter?: string;\n  headerHeight?: string;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LayoutSpacing } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/layouts/Layout/Layout.types.ts"
    },
    "LayoutClasses": {
      "name": "LayoutClasses",
      "definition": "export type LayoutClasses = {\n  root?: string;\n  header?: string;\n  main?: string;\n  item?: string;\n  centeredItem?: string;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LayoutClasses } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/layouts/Layout/Layout.types.ts"
    },
    "AiAgentPopoverCustomPlacement": {
      "name": "AiAgentPopoverCustomPlacement",
      "definition": "export type AiAgentPopoverCustomPlacement =\n  | 'top-right'\n  | 'top-left'\n  | 'bottom-right'\n  | 'bottom-left';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { AiAgentPopoverCustomPlacement } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/AiAgentPopover/AiAgentPopover.types.ts"
    },
    "ChipCompProps": {
      "name": "ChipCompProps",
      "definition": "export type ChipCompProps = ComponentProps<typeof Chip>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ChipCompProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Chip/index.ts"
    },
    "PreviewButton": {
      "name": "PreviewButton",
      "definition": "export type PreviewButton = {\n  /**\n   * Колбэк, вызываемый по клику\n   */\n  onClick: () => void;\n  /**\n   * Текстовая надпись\n   */\n  text: string;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { PreviewButton } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/ApprovalCenter/ApprovalCenter.types.ts"
    },
    "LifeCycleStatus": {
      "name": "LifeCycleStatus",
      "definition": "export type LifeCycleStatus = 'DEFAULT' | 'WAIT' | 'SUCCESSFUL' | 'FAILURE';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LifeCycleStatus } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/ApprovalCenter/ApprovalCenter.types.ts"
    },
    "StageItem": {
      "name": "StageItem",
      "definition": "export type StageItem = {\n  /**\n   * Статус\n   */\n  status: StageStatus;\n  /**\n   * Заголовок\n   */\n  title: string;\n  /**\n   * Открыт ли элемент аккордеона\n   */\n  open?: boolean;\n  /**\n   * Комментарий\n   */\n  comment?: string;\n  /**\n   * Тултип на иконке статуса\n   */\n  tooltip?: { text: string };\n  /**\n   * Пометка (обычно звёздочка)\n   */\n  mark?: { tooltip: { text: string }; icon: ReactNode };\n  /**\n   * Заголовок действия\n   */\n  actionTitle?: string;\n  /**\n   * Заголовок даты\n   */\n  actionDate?: string;\n  /**\n   * ФИО людей, отвечающих за согласование\n   */\n  assignee?: [string, ...string[]];\n  /**\n   * Вспомогательные кнопки\n   */\n  buttons?: LifeCycleButton[];\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { StageItem } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/ApprovalCenter/ApprovalCenter.types.ts"
    },
    "LifeCycleButton": {
      "name": "LifeCycleButton",
      "definition": "export type LifeCycleButton = {\n  /**\n   * Слот для контента слева\n   */\n  contentLeft: ReactNode;\n  /**\n   * Колбэк, вызываемый по клику\n   */\n  onClick: () => void;\n  /**\n   * Текстовая надпись\n   */\n  text: string;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LifeCycleButton } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/ApprovalCenter/ApprovalCenter.types.ts"
    },
    "HistoryItemStatus": {
      "name": "HistoryItemStatus",
      "definition": "export type HistoryItemStatus = 'DEFAULT' | 'WAIT' | 'SUCCESSFUL' | 'FAILURE';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { HistoryItemStatus } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/ApprovalCenter/ApprovalCenter.types.ts"
    },
    "BlockTitleSlotSizesProps": {
      "name": "BlockTitleSlotSizesProps",
      "definition": "export type BlockTitleSlotSizesProps = {\n  /**\n   * Размер иконки рядом с заголовком\n   */\n  titleIconSize: 's' | 'xs';\n  /**\n   * Размер Badge рядом с заголовком\n   */\n  titleBadgeSize: 'm' | 's';\n  /**\n   * Размер кнопок в правом слоте\n   */\n  buttonSize: 's' | 'xs';\n  /**\n   * Размер иконок внутри кнопок в правом слоте\n   */\n  actionIconSize: 's' | 'xs';\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { BlockTitleSlotSizesProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/BlockTitle/BlockTitle.types.ts"
    },
    "ButtonCompProps": {
      "name": "ButtonCompProps",
      "definition": "type ButtonCompProps = ComponentProps<typeof Button>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ButtonCompProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Button/index.ts"
    },
    "LinkButtonCompProps": {
      "name": "LinkButtonCompProps",
      "definition": "export type LinkButtonCompProps = ComponentProps<typeof LinkButton>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LinkButtonCompProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/LinkButton/index.ts"
    },
    "LeftPanelSlotSizesProps": {
      "name": "LeftPanelSlotSizesProps",
      "definition": "export type LeftPanelSlotSizesProps = {\n  /**\n   * Размер кнопок, поиска и сегментов в кастомных слотах\n   */\n  buttonSize: 's' | 'xs';\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LeftPanelSlotSizesProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/LeftPanel/LeftPanel.types.ts"
    },
    "Item": {
      "name": "Item",
      "definition": "export type Item = {\n  id: string | number;\n  label: string | number;\n  onClick: () => void;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Item } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/ListOfFilters/types.ts"
    },
    "Group": {
      "name": "Group",
      "definition": "export type Group = { groupLabel: string; groupId: string; items: Item[] };",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Group } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/ListOfFilters/types.ts"
    },
    "MassActionsButtonPropsButton": {
      "name": "MassActionsButtonPropsButton",
      "definition": "export type MassActionsButtonPropsButton = DataAttributes &\n  Partial<ButtonCompProps> & {\n    type: 'button';\n    view?: ButtonCompProps['view'];\n    /**\n     * Dropdown для кнопки.\n     * Используется универсальный DropdownProps, который работает и с обычным Dropdown, и с TableDropdown\n     */\n    dropdown?: DropdownProps & { $css?: CSSObject };\n    disabledTooltipProps?: TooltipProps;\n  };",
      "importPath": "@daisforge/ui",
      "importStatement": "import { MassActionsButtonPropsButton } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/MassActions/types.ts"
    },
    "MassActionsButtonPropsLinkButton": {
      "name": "MassActionsButtonPropsLinkButton",
      "definition": "export type MassActionsButtonPropsLinkButton = DataAttributes &\n  Partial<LinkButtonProps> & {\n    type?: 'linkButton';\n    view?: LinkView<LinkButtonView>;\n    /**\n     * Dropdown для кнопки.\n     * Используется универсальный DropdownProps, который работает и с обычным Dropdown, и с TableDropdown\n     */\n    dropdown?: DropdownProps & { $css?: CSSObject };\n    disabledTooltipProps?: TooltipProps;\n  };",
      "importPath": "@daisforge/ui",
      "importStatement": "import { MassActionsButtonPropsLinkButton } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/MassActions/types.ts"
    },
    "PageTitleSlotSizesProps": {
      "name": "PageTitleSlotSizesProps",
      "definition": "export type PageTitleSlotSizesProps = {\n  /**\n   * Размер кнопок в кастомных слотах\n   */\n  buttonSize: 's' | 'xs';\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { PageTitleSlotSizesProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/PageTitle/PageTitle.types.ts"
    },
    "StoryAssetType": {
      "name": "StoryAssetType",
      "definition": "export type StoryAssetType = 'image' | 'gif' | 'video';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { StoryAssetType } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Stories/Stories.types.ts"
    },
    "StoriesObjectFit": {
      "name": "StoriesObjectFit",
      "definition": "export type StoriesObjectFit =\n  | 'cover'\n  | 'contain'\n  | 'fill'\n  | 'none'\n  | 'scale-down';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { StoriesObjectFit } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Stories/Stories.types.ts"
    },
    "Table.ColumnDefaultOmitted": {
      "name": "ColumnDefaultOmitted",
      "definition": "export type ColumnDefaultOmitted<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> = Omit<ColumnDefault<Row, SummRow>, DefaultOmittedKeys>;",
      "internal": true,
      "importNotice": "Тип \"ColumnDefaultOmitted\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/types/data-grid.type.ts"
    },
    "TableCanvas.ColumnDefaultOmitted": {
      "name": "ColumnDefaultOmitted",
      "definition": "export type ColumnDefaultOmitted<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<ColumnGlideInstance<Row, SummRow, CustomCtxs>, DefaultOmittedKeys>;",
      "internal": true,
      "importNotice": "Тип \"ColumnDefaultOmitted\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/glide-type.ts"
    },
    "Table.Comparator": {
      "name": "Comparator",
      "definition": "export type Comparator<Row extends ObjectForExtending> = (\n  a: Row,\n  b: Row,\n) => number;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Comparator } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
    },
    "TableCanvas.Comparator": {
      "name": "Comparator",
      "definition": "export type Comparator<Row extends ObjectForExtending> = (\n  a: Row,\n  b: Row,\n) => number;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { Comparator } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
    },
    "Table.FilterCb": {
      "name": "FilterCb",
      "definition": "type FilterCb<Mode extends 'multiple' | 'single' | void = 'single'> = (\n  filterV: Mode extends 'multiple' ? string[] : string,\n  rowValue: string,\n) => boolean;",
      "internal": true,
      "importNotice": "Тип \"FilterCb\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
    },
    "TableCanvas.FilterCb": {
      "name": "FilterCb",
      "definition": "type FilterCb<Mode extends 'multiple' | 'single' | void = 'single'> = (\n  filterV: Mode extends 'multiple' ? string[] : string,\n  rowValue: string,\n) => boolean;",
      "internal": true,
      "importNotice": "Тип \"FilterCb\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
    },
    "Table.FilterComponentInPopoverProps": {
      "name": "FilterComponentInPopoverProps",
      "definition": "export type FilterComponentInPopoverProps<\n  FilterStateType extends ObjectForExtending,\n  ColumnConfig,\n> = {\n  popoverIsOpen: boolean;\n  setPopoverIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n  columnConfig: ColumnConfig;\n  tabIndex: number;\n  headerContextState: HeaderContextValueTypeInstance<FilterStateType> &\n    FiltersVariables &\n    HeaderContextValueTypeInstance<ObjectForExtending>;\n  /**\n   * Источник открытия фильтра: из шапки таблицы или из сайдбара\n   * Полезно для условной логики в customRender (например, alwaysOpened для combobox)\n   */\n  filterSource?: 'header' | 'sidebar';\n};",
      "internal": true,
      "importNotice": "Тип \"FilterComponentInPopoverProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-filtering/header-filter-button/types.ts"
    },
    "TableCanvas.FilterComponentInPopoverProps": {
      "name": "FilterComponentInPopoverProps",
      "definition": "export type FilterComponentInPopoverProps<\n  FilterStateType extends ObjectForExtending,\n  ColumnConfig,\n> = {\n  popoverIsOpen: boolean;\n  setPopoverIsOpen: React.Dispatch<React.SetStateAction<boolean>>;\n  columnConfig: ColumnConfig;\n  tabIndex: number;\n  headerContextState: HeaderContextValueTypeInstance<FilterStateType> &\n    FiltersVariables &\n    HeaderContextValueTypeInstance<ObjectForExtending>;\n  /**\n   * Источник открытия фильтра: из шапки таблицы или из сайдбара\n   * Полезно для условной логики в customRender (например, alwaysOpened для combobox)\n   */\n  filterSource?: 'header' | 'sidebar';\n};",
      "internal": true,
      "importNotice": "Тип \"FilterComponentInPopoverProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/header-filter-button/types.ts"
    },
    "Table.SelectOptions": {
      "name": "SelectOptions",
      "definition": "export type SelectOptions = {\n  value: string | number;\n  text: string | number;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { SelectOptions } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
    },
    "TableCanvas.SelectOptions": {
      "name": "SelectOptions",
      "definition": "export type SelectOptions = {\n  value: string | number;\n  text: string | number;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { SelectOptions } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
    },
    "Table.ContentFormat": {
      "name": "ContentFormat",
      "definition": "export type ContentFormat =\n  | 'number' // Стандартное числовое форматирование с локалью ru-RU (разделитель тысяч: пробел, дробная часть: запятая)\n  | CustomFormat\n  | NumberFormatOptions;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ContentFormat } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
    },
    "TableCanvas.ContentFormat": {
      "name": "ContentFormat",
      "definition": "export type ContentFormat =\n  | 'number' // Стандартное числовое форматирование с локалью ru-RU (разделитель тысяч: пробел, дробная часть: запятая)\n  | CustomFormat\n  | NumberFormatOptions;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { ContentFormat } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "Table.Editing": {
      "name": "Editing",
      "definition": "export type Editing<RowType extends ObjectForExtending> = {\n  /**\n   * Если `error.value(row) === true`, то у ячейки появляется красная рамка\n   */\n  error?: { value: (row: RowType, treeLevel: number) => boolean };\n  editedSuccessfully?: { value: (row: RowType, treeLevel: number) => boolean };\n  /**\n   * Функция для определения возможности редактирования  ячейки на основе данных строки (приоритетнее, чем rowEditable в tableConfig.editing)\n   */\n  editable?: ((row: RowType) => boolean) | boolean;\n} & (\n  | {\n      component: 'inputString';\n      /**\n       * Дополнительные пропсы для компонента TextField в редактировании\n       * @example { placeholder: \"Введите текст\"}\n       */\n      inputProps?: Partial<\n        Omit<TextFieldProps, 'value' | 'onChange' | 'onBlur' | 'ref' | 'size'>\n      >;\n    }\n  | {\n      component: 'inputNumber';\n      /**\n       * Дополнительные пропсы для компонента NumberFormat в редактировании\n       * @example { placeholder: \"Введите текст\"}\n       */\n      inputProps?: Partial<\n        Omit<\n          ComponentProps<typeof NumberFormat>,\n          'value' | 'onChange' | 'onBlur' | 'ref' | 'size'\n        >\n      >;\n    }\n  | {\n      component: 'select';\n      options: {\n        type: 'constant';\n        options: SelectOptions[];\n      };\n      /**\n       * Дополнительные пропсы для компонента Combobox в редактировании\n       * @example { listMaxHeight: \"100px\"}\n       */\n      selectProps?: Partial<\n        Omit<\n          ComponentProps<typeof Combobox>,\n          'value' | 'onChange' | 'items' | 'ref' | 'size' | 'portal'\n        >\n      >;\n    }\n  | {\n      component: 'select';\n\n      options: {\n        type: 'stateInRowContext';\n        /**\n         * тип optionsState, который будет в RowContext:\n         * ```ts\n         * options: {\n         * value: string | number;\n         * text: string | number;\n         * }[];\n         * ```\n         */\n        optionsKeyInRowContext: string;\n      };\n    }\n  | {\n      /**\n       * Кастомный рендер ячейки редактирования\n       */\n      component: RenderSubRowEditCell<RowType>;\n    }\n);",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Editing } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
    },
    "TableCanvas.Editing": {
      "name": "Editing",
      "definition": "export type Editing<RowType extends ObjectForExtending, SummaryRowType> = {\n  /**\n   * Если `error.value(row) === true`, то у ячейки появляется красная рамка\n   */\n  error?: { value: (row: RowType, treeLevel: number) => boolean };\n  editedSuccessfully?: { value: (row: RowType, treeLevel: number) => boolean };\n  /**\n   * Функция для определения возможности редактирования  ячейки на основе данных строки (приоритетнее, чем rowEditable в tableConfig.editing)\n   */\n  editable?: ((row: RowType) => boolean) | boolean;\n} & (\n  | {\n      component: 'inputString';\n      /**\n       * Дополнительные пропсы для компонента TextField в редактировании\n       * @example { placeholder: \"Введите текст\"}\n       */\n      inputProps?: Partial<\n        Omit<\n          CellEditorTextAreaProps,\n          'value' | 'onChange' | 'onBlur' | 'ref' | 'size'\n        >\n      >;\n    }\n  | {\n      component: 'inputNumber';\n      /**\n       * Дополнительные пропсы для компонента NumberFormat в редактировании\n       * @example { placeholder: \"Введите текст\"}\n       */\n      inputProps?: Partial<\n        Omit<\n          CellEditorNumberFormatProps,\n          'value' | 'onChange' | 'onBlur' | 'ref' | 'size'\n        >\n      >;\n    }\n  | {\n      component: 'select';\n      options: {\n        type: 'constant';\n        options: SelectOptions[];\n      };\n      /**\n       * Дополнительные пропсы для компонента Combobox в редактировании\n       * @example { listMaxHeight: \"100px\"}\n       */\n      selectProps?: Partial<\n        Omit<\n          CellEditorComboboxProps<ComboboxItemOption>,\n          'value' | 'onChange' | 'items' | 'ref' | 'size' | 'portal'\n        >\n      >;\n    }\n  | {\n      component: 'select';\n\n      options: {\n        type: 'stateInRowContext';\n        /**\n         * тип optionsState, который будет в RowContext:\n         * ```ts\n         * options: {\n         * value: string | number;\n         * text: string | number;\n         * }[];\n         * ```\n         */\n        optionsKeyInRowContext: string;\n      };\n    }\n  | {\n      /**\n       * Кастомный рендер ячейки редактирования\n       */\n      component: RenderRowCustomEditCell<RowType, SummaryRowType>;\n    }\n);",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { Editing } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
    },
    "Table.KeyText": {
      "name": "KeyText",
      "definition": "export type KeyText = 'key' | 'text' | 'keyText' | 'textKey';",
      "internal": true,
      "importNotice": "Тип \"KeyText\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-key-text/types.ts"
    },
    "TableCanvas.KeyText": {
      "name": "KeyText",
      "definition": "export type KeyText = 'key' | 'text' | 'keyText' | 'textKey';",
      "internal": true,
      "importNotice": "Тип \"KeyText\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-key-text/types.ts"
    },
    "Table.RenderSubRowCell": {
      "name": "RenderSubRowCell",
      "definition": "export type RenderSubRowCell<SubRowType extends ObjectForExtending> = (\n  renderCellProps: RenderCellProps<SubRowType>,\n  lvl: number,\n) => ReactNode;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { RenderSubRowCell } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
    },
    "TableCanvas.RenderSubRowCell": {
      "name": "RenderSubRowCell",
      "definition": "export type RenderSubRowCell<\n  SubRowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = (\n  renderCellProps: CellInfo<SubRowType, SummaryRowType, CustomCtxs>,\n  lvl: number,\n) => CellContent;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { RenderSubRowCell } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
    },
    "Table.ColumnRowsGrouping": {
      "name": "ColumnRowsGrouping",
      "definition": "export type ColumnRowsGrouping<RowType, SummaryRowType = unknown> = {\n  /**\n   * @default true - при наличии ColumnConfig.rowsGrouping\n   */\n  groupByColumn?: boolean;\n  /**\n   * @default ColumnConfig.key\n   */\n  columnGroupLabel?: string;\n  renderGroupCell?: (\n    props: RenderGroupCellProps<RowType, SummaryRowType>,\n  ) => ReactNode;\n};",
      "internal": true,
      "importNotice": "Тип \"ColumnRowsGrouping\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-rows-grouping/types.ts"
    },
    "TableCanvas.ColumnRowsGrouping": {
      "name": "ColumnRowsGrouping",
      "definition": "export type ColumnRowsGrouping<\n  RowType extends ObjectForExtending,\n  ColumnConfig extends LocalColumnInstance,\n> = {\n  /**\n   * @default true - при наличии ColumnConfig.rowsGrouping\n   */\n  groupByColumn?: boolean;\n  /**\n   * @default ColumnConfig.key\n   */\n  columnGroupLabel?: string;\n  /**\n   * Свой контент ячейки строки-группы. Работает только в виде дерева: при\n   * view: 'merged' строк-групп нет (группы показаны объединёнными ячейками),\n   * поэтому этот рендер не вызывается.\n   */\n  renderGroupCell?: (\n    props: RenderGroupCellProps<RowType, ColumnConfig>,\n  ) => CanvasContent;\n};",
      "internal": true,
      "importNotice": "Тип \"ColumnRowsGrouping\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-rows-grouping/types.ts"
    },
    "Table.KeyTextColumnConfig": {
      "name": "KeyTextColumnConfig",
      "definition": "export type KeyTextColumnConfig<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> =\n  | ((props: { keyText: KeyText }) => ColumnConfig<Row, SummRow>)\n  | ColumnConfig<Row, SummRow>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { KeyTextColumnConfig } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
    },
    "TableCanvas.KeyTextColumnConfig": {
      "name": "KeyTextColumnConfig",
      "definition": "export type KeyTextColumnConfig<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n> =\n  | ((props: { keyText: KeyText }) => ColumnConfig<Row, SummRow>)\n  | ColumnConfig<Row, SummRow>;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { KeyTextColumnConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
    },
    "TableCanvas.CellInfo": {
      "name": "CellInfo",
      "definition": "export type CellInfo<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<\n  CellInfoGlideInstance<R, SR, CustomCtxs>,\n  'column' | 'ctxs' | 'hovered' | 'active'\n> & {\n  column: ColumnConfig<R, SR, CustomCtxs>;\n  ctxs: CtxsType<CustomCtxs>;\n  /**\n   * Состояние наведения для текущей ячейки, которую рендерит renderCell.\n   * `cellHover` равно true только у ячейки под курсором, `rowHover` — у всех ячеек ее строки.\n   */\n  hovered: CellHoverState;\n  /**\n   * Состояние активного выделения для текущей ячейки, которую рендерит renderCell.\n   * `cellActive` равно true у активной ячейки или диапазона, `rowActive` — у строк с активной ячейкой или диапазоном.\n   */\n  active: CellActiveState;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellInfo } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
    },
    "TableGlide.CellInfo": {
      "name": "CellInfo",
      "definition": "export type CellInfo<R extends ObjectForExtending, SR = unknown> = {\n  row: R;\n  column: ColumnGlideLast<R, SR>;\n  colInd: number;\n  rowInd: number;\n  ctxs: ObjectForExtending;\n  theme: Theme;\n  /** Состояние наведения для ячейки, которую сейчас рендерит renderCell. */\n  hovered: CellHoverState;\n  /** Состояние активного выделения для ячейки, которую сейчас рендерит renderCell. */\n  active: CellActiveState;\n  // Есть только у верхней-левой ячейки объединённого блока. align — выравнивание\n  // блока (пусто = по центру). По нему ячейка-select расставляет контент и\n  // уголок по высоте всего блока.\n  __mergedCell?: { align?: SpanCellAlign };\n};",
      "internal": true,
      "importNotice": "Тип \"CellInfo\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "CellContent": {
      "name": "CellContent",
      "definition": "export type CellContent = CanvasContent | GridCell;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellContent } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "RenderCellPreview": {
      "name": "RenderCellPreview",
      "definition": "export type RenderCellPreview<\n  Row extends ObjectForExtending,\n  SummRow = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> =\n  | 'none'\n  | 'cellEditorAsPreview'\n  | ((cellInfo: PreviewCellInfo<Row, SummRow, CustomCtxs>) => ReactNode);",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { RenderCellPreview } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
    },
    "CellThemeOverrideResult": {
      "name": "CellThemeOverrideResult",
      "definition": "export type CellThemeOverrideResult = Partial<{\n  bgCell: string;\n  cellHorizontalPadding: number;\n  cellVerticalPadding: number;\n}>;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellThemeOverrideResult } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "HeaderAlignment": {
      "name": "HeaderAlignment",
      "definition": "export type HeaderAlignment = {\n  /** По горизонтали. @default 'left' */\n  horizontal?: 'left' | 'center' | 'right';\n  /** По вертикали. @default 'center' */\n  vertical?: 'top' | 'center' | 'bottom';\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { HeaderAlignment } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/columns-grouping.type.ts"
    },
    "MergedCellsAlign": {
      "name": "MergedCellsAlign",
      "definition": "export type MergedCellsAlign = {\n  /** По горизонтали. @default из `contentFormat.alignContent` колонки, иначе 'left' */\n  horizontal?: 'left' | 'center' | 'right';\n  /** По вертикали. @default 'center' */\n  vertical?: 'top' | 'center' | 'bottom';\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { MergedCellsAlign } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/merged-cells.type.ts"
    },
    "CanvasEl": {
      "name": "CanvasEl",
      "definition": "export type CanvasEl = ReactElement;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CanvasEl } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "HeaderCellInfoGlideInstance": {
      "name": "HeaderCellInfoGlideInstance",
      "definition": "export type HeaderCellInfoGlideInstance<\n  R extends ObjectForExtending,\n  SR,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<HeaderCellInfoGlide<R, SR>, 'column' | 'ctxs'> & {\n  column: ColumnGlideInstance<R, SR, CustomCtxs>;\n  ctxs: CtxsType<CustomCtxs>;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { HeaderCellInfoGlideInstance } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "CanvasContent": {
      "name": "CanvasContent",
      "definition": "export type CanvasContent = ReactElement | string;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CanvasContent } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "CellInfoGlideInstance": {
      "name": "CellInfoGlideInstance",
      "definition": "export type CellInfoGlideInstance<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<CellInfo<R, SR>, 'column' | 'ctxs'> & {\n  column: ColumnGlideInstance<R, SR, CustomCtxs>;\n  ctxs: CtxsType<CustomCtxs>;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellInfoGlideInstance } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "EditingCellInfoGlideInstance": {
      "name": "EditingCellInfoGlideInstance",
      "definition": "export type EditingCellInfoGlideInstance<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<CellInfoGlideInstance<R, SR, CustomCtxs>, 'hovered' | 'active'> & {\n  onRowChange: (newV: R, closeEditor?: boolean) => void;\n  /** initialValue - введенное значение, если редактор ячейки откроется не по двойному клику а при попытке ввода любой буквы */\n  initialValue: string | undefined;\n  portalElementRef: React.RefObject<HTMLElement> | undefined;\n  activation: CellActivatedEventArgs | undefined;\n  cellWidth: number;\n  cellHeight: number;\n  /** readOnly=true - будет значить, что активен не режим редактирования, а режим превью */\n  readOnly: boolean | undefined;\n  // onClose: (commitChanges?: boolean, shouldFocusCell?: boolean) => void;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { EditingCellInfoGlideInstance } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "PreviewCellInfoGlideInstance": {
      "name": "PreviewCellInfoGlideInstance",
      "definition": "export type PreviewCellInfoGlideInstance<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<EditingCellInfoGlideInstance<R, SR, CustomCtxs>, 'onRowChange'>;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { PreviewCellInfoGlideInstance } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "SummaryCellInfoGlideInstance": {
      "name": "SummaryCellInfoGlideInstance",
      "definition": "export type SummaryCellInfoGlideInstance<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<SummaryCellInfo<R, SR>, 'column' | 'ctxs'> & {\n  column: ColumnGlideInstance<R, SR, CustomCtxs>;\n  ctxs: CtxsType<CustomCtxs>;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { SummaryCellInfoGlideInstance } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "SpanCellAlign": {
      "name": "SpanCellAlign",
      "definition": "export type SpanCellAlign = {\n  /** По горизонтали. @default из contentAlign колонки, иначе 'left' */\n  horizontal?: 'left' | 'center' | 'right';\n  /** По вертикали. @default 'center' */\n  vertical?: 'top' | 'center' | 'bottom';\n};",
      "internal": true,
      "importNotice": "Тип \"SpanCellAlign\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "CanvasNodeTooltipConfig": {
      "name": "CanvasNodeTooltipConfig",
      "definition": "export type CanvasNodeTooltipConfig =\n  | string\n  | (CanvasNodeTooltipProps & {\n      /** Текст тултипа (только string, не ReactNode). */\n      text: string;\n      /** Задержка перед показом (мс). По умолчанию 0. */\n      mouseEnterDelay?: number;\n      /** Задержка перед скрытием после ухода мыши (мс). По умолчанию 0. */\n      mouseLeaveDelay?: number;\n    });",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CanvasNodeTooltipConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/utils/portalHoverEvents.ts"
    },
    "CtxsType": {
      "name": "CtxsType",
      "definition": "export type CtxsType<Customs extends ObjectForExtending | void = {}> = {\n  selectingRowCtx: SelectingContextType;\n  headerCtx: HeaderContextValueTypeInstance<ObjectForExtending>;\n  expandedRowsCtx: {\n    expandedRowsIds: ExpandedRowsContextV | null;\n    setExpandedRowsIds: ExpandedRowsChangeContextV | null;\n    handleExpandRowDetail: HandleExpandDetail<ObjectForExtending>;\n    expandButtonColumnKey: string | undefined;\n  };\n  rowCtx: ObjectForExtending;\n  /**\n   * Высота ОДНОГО header-ряда (листового и каждого групп-уровня — они равны).\n   * Нужна рендерам шапки, чтобы позиционировать контент в ПОСЛЕДНЕМ (листовом)\n   * уровне слитой многоуровневой шапки (напр. общий чекбокс прижимается к низу).\n   */\n  headerHeight: number;\n  /** Число групп-уровней шапки (0 — одноуровневая шапка). */\n  groupHeaderLevels: number;\n} & Customs;",
      "internal": true,
      "importNotice": "Тип \"CtxsType\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/ctxs.type.ts"
    },
    "Theme": {
      "name": "Theme",
      "definition": "export type Theme = ThemeGlide & ThemeCustoms & ThemeDynamicCustoms;",
      "internal": true,
      "importNotice": "Тип \"Theme\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/theming/types.ts"
    },
    "ContextMenuDropdownProps": {
      "name": "ContextMenuDropdownProps",
      "definition": "export type ContextMenuDropdownProps = Omit<\n  DropdownProps,\n  | 'children'\n  | 'items'\n  | 'placement'\n  | 'closeOnOverlayClick'\n  | 'portal'\n  | 'openByRightClick'\n  | 'onItemClick'\n  | 'hoverIndex'\n  | 'alwaysOpened'\n  | 'trigger'\n  | 'hasArrow'\n  | 'onItemSelect'\n>;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { ContextMenuDropdownProps } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "TableInfoBase": {
      "name": "TableInfoBase",
      "definition": "export type TableInfoBase<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = {\n  column: ColumnOrColumnGroupGlideInstance<R, SR, CustomCtxs>;\n  ctxs: CustomCtxs;\n  refTable?: React.Ref<DataEditorRef>;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableInfoBase } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "DropdownProps": {
      "name": "DropdownProps",
      "definition": "type DropdownProps = ComponentProps<typeof Dropdown>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { DropdownProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Dropdown/index.ts"
    },
    "TableCanvas.ContextMenuDropdownItem": {
      "name": "ContextMenuDropdownItem",
      "definition": "export type ContextMenuDropdownItem = NonNullable<\n  DropdownProps['items']\n>[number];",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { ContextMenuDropdownItem } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "Table.ContextMenuDropdownItem": {
      "name": "ContextMenuDropdownItem",
      "definition": "export type ContextMenuDropdownItem = NonNullable<\n  DropdownProps['items']\n>[number];",
      "internal": true,
      "importNotice": "Тип \"ContextMenuDropdownItem\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-context-menu/types.ts"
    },
    "TableInfoWithRow": {
      "name": "TableInfoWithRow",
      "definition": "export type TableInfoWithRow<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = TableInfoBase<R, SR, CustomCtxs> & { row: R };",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableInfoWithRow } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "TableContentStateFrame": {
      "name": "TableContentStateFrame",
      "definition": "type TableContentStateFrame = {\n  displayMode?: 'body-overlay' | 'full-content';\n  borderLeftTopRadiusRounded?: boolean;\n  borderRightTopRadiusRounded?: boolean;\n  borderLeftBottomRadiusRounded?: boolean;\n  borderRightBottomRadiusRounded?: boolean;\n  custom?: ReactNode;\n};",
      "internal": true,
      "importNotice": "Тип \"TableContentStateFrame\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-content-state/types.ts"
    },
    "EmptyStateProps": {
      "name": "EmptyStateProps",
      "definition": "export type EmptyStateProps = {\n  /**\n   * Размер компонента (small, medium, large)\n   *   */\n  size: 's' | 'm' | 'l';\n  /**\n   * Основной заголовок состояния\n   *   */\n  title?: ReactNode;\n  /**\n   * Дополнительный поясняющий текст\n   *   */\n  subtitle?: ReactNode;\n  /**\n   * Вариант изображения для отображения\n   * Поддерживаются варианты EmptyState (loading, life-circle, need-access, no-access, no-content, not-found, not-result)\n   * и варианты ErrorPage (400, 401, 403, 404, 500, 502, 503, unidentified)\n   */\n  variant?: EmptyStateImageVariant;\n  /**\n   * @deprecated Используйте prop `variant` для отображения изображений.\n   * Компонент иконки (только для size='m' или для size='s')\n   * Оставлено для обратной совместимости.\n   */\n  icon?: React.FC<IconProps>;\n  /**\n   * @deprecated Используйте prop `variant` для отображения изображений.\n   * Дополнительные пропсы для иконки\n   * Оставлено для обратной совместимости.\n   */\n  iconProps?: Omit<IconProps, 'size'>;\n  /**\n   * Массив кнопок (до 2 для size='l', до 1 для других размеров)\n   */\n  buttons?: EmptyStateButtonProps[];\n  /**\n   * Дополнительная кнопка (только для size='l')\n   */\n  extraButton?: EmptyStateButtonProps;\n  /**\n   * Дополнительный класс для корневого элемента\n   */\n  className?: string;\n  /**\n   * Объект с классами для внутренних элементов\n   */\n  classes?: EmptyStateClasses;\n  /**\n   * Центрировать контент по вертикали и горизонтали\n   */\n  centered?: boolean;\n  /**\n   * Кастомные CSS-стили для контейнера\n   */\n  $css?: string | CSSObject | FlattenSimpleInterpolation;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { EmptyStateProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/EmptyState/EmptyState.types.ts"
    },
    "ErrorPageProps": {
      "name": "ErrorPageProps",
      "definition": "export type ErrorPageProps = {\n  /**\n   * `statusCode` - статус-код ошибки. Поддерживаются по умолчанию: 400 | 403 | 404 | 409 | 500 | 502 | 503\n   */\n  statusCode?: StatusCode;\n  /**\n   * `buttonHandler` - обработка клика по кнопке при разных ошибках\n   */\n  buttonHandler?: (\n    statusCode: StatusCode,\n    statusObj: CustomStatusObj,\n    e: React.MouseEvent<HTMLElement, MouseEvent>,\n  ) => void;\n  /**\n   * `customStatuses` - кастомные статусы и содержимое для их отображения.\n   * Если переданы статусы, которые компонентом по умолчанию поддерживаются, то кастомный перезапишет дефолтный.\n   */\n  customStatuses?: Record<number, CustomStatusObj>;\n  /**\n   * `unknownStatus` - содержимое для отображения, если статус не передан или статуса нет среди известных.\n   *\n   * Если данное свойство не передано, то при неизвестных статусах будет выбрано отображение по умолчанию.\n   */\n  unknownStatus?: CustomStatusObj;\n  /**\n   * `containerProps` - Пропсы для контейнера компонента. Например, `$css`, `style`.\n   */\n  containerProps?: BoxProps;\n  /**\n   * Показывать код ошибки перед заголовком. Например, \"503: Сервис временно недоступен\"\n   * @default false\n   */\n  showStatusCode?: boolean;\n  /**\n   * Идентификатор ошибки. Отображается под кнопками (или под subtitle, если кнопок нет).\n   * Формат отображения: \"Идентификатор ошибки: {значение}\"\n   */\n  errorId?: string;\n  /**\n   * Размер страницы ошибки. Влияет на изображение, типографику и отступы\n   * (размерная сетка та же, что у `EmptyState`).\n   * @default 'l'\n   */\n  size?: 's' | 'm' | 'l';\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ErrorPageProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/layouts/ErrorPage/ErrorPage.tsx"
    },
    "СolumnGlide": {
      "name": "СolumnGlide",
      "definition": "export type СolumnGlide = GlideProps['columns'][number];",
      "internal": true,
      "importNotice": "Тип \"СolumnGlide\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "ColumnGlideCustoms": {
      "name": "ColumnGlideCustoms",
      "definition": "export type ColumnGlideCustoms<R extends ObjectForExtending, SR = unknown> = {\n  id: string;\n  /** Служебные колонки (marker / checkbox / row instruments) живут по отдельным правилам подсветки. */\n  isServiceColumn?: boolean;\n  /** Внутренний helper для cell-level error outline, совпадающий по семантике с Table editing error. */\n  isErrorCell?: (row: R) => boolean;\n  renderHeaderCell?: (cellInfo: HeaderCellInfo<R, SR>) => CanvasContent;\n  /** Текстовое представление ячейки для копирования в clipboard (Ctrl+C). */\n  copyData?: string | ((row: R) => string);\n  editable?: boolean | ((row: R) => boolean);\n  contentAlign?: 'right' | 'left' | 'center';\n  renderCell?: ColumnGlideGetCellContent<R, SR>;\n  renderEditCell?: (cellInfo: EditingCellInfoGlide<R, SR>) => CellContent;\n  renderSummaryCell?: (summaryCellInfo: SummaryCellInfo<R, SR>) => CellContent;\n  colSpan?: ColSpan<R, SR>;\n  rowSpan?: RowSpan<R, SR>;\n  /** Выравнивание контента в объединённых ячейках колонки; функция — если нужно задавать для каждого блока отдельно. */\n  spanAlign?: SpanCellAlign | ((cellInfo: CellInfo<R, SR>) => SpanCellAlign | undefined);\n  /** Тултип для ячеек этой колонки. Строка, объект или функция (context) => config | null. */\n  cellTooltip?:\n    | CanvasNodeTooltipConfig\n    | ((context: {\n        row: R;\n        column: ColumnGlideLast<R, SR>;\n        ctxs: ObjectForExtending;\n        refTable?: Ref<DataEditorRef>;\n        colInd?: number;\n        rowInd?: number;\n        theme?: Theme;\n      }) => CanvasNodeTooltipConfig | null);\n  /** Тултип для шапки этой колонки. Строка, объект или функция (context) => config | null. */\n  headerCellTooltip?:\n    | CanvasNodeTooltipConfig\n    | ((context: {\n        column: ColumnGlideLast<R, SR>;\n        ctxs: ObjectForExtending;\n        refTable?: Ref<DataEditorRef>;\n        colInd?: number;\n        theme?: Theme;\n      }) => CanvasNodeTooltipConfig | null);\n  columnThemeOverride?: (\n    cellInfo: CellInfo<R, SR>\n  ) => CellThemeOverrideResult | undefined;\n  /** Управление preview для колонки. true — включить overlay, 'none' — отключить (в т.ч. стандартный). */\n  hasPreview?: boolean | 'none';\n  /** Минимальная ширина колонки (px). Ограничивает ресайз и начальную ширину снизу. */\n  minWidth?: number;\n  /** Максимальная ширина колонки (px). Ограничивает ресайз и начальную ширину сверху. */\n  maxWidth?: number;\n};",
      "internal": true,
      "importNotice": "Тип \"ColumnGlideCustoms\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "TabId": {
      "name": "TabId",
      "definition": "export type TabId = string | number;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TabId } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/TableTabs/TableTabs.types.ts"
    },
    "TTabItem": {
      "name": "TTabItem",
      "definition": "export type TTabItem<T extends TabId> = {\n  tabId: T;\n  label: ReactNode;\n} & ComponentProps<typeof TabItem>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TTabItem } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/TableTabs/TableTabs.types.ts"
    },
    "TCustomTabItem": {
      "name": "TCustomTabItem",
      "definition": "export type TCustomTabItem<T extends TabId> = { tabId: T; custom: ReactNode };",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TCustomTabItem } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/TableTabs/TableTabs.types.ts"
    },
    "TableCanvas.TableCollapseConfig": {
      "name": "TableCollapseConfig",
      "definition": "export type TableCollapseConfig = {\n  /**\n   * Обязательный флаг для активации\n   * @default false\n   */\n  enableCollapse?: boolean;\n  /**\n   * Начальное состояние (опционально)\n   *  @default false\n   */\n  defaultCollapsed?: boolean;\n  /**\n   * Текст для кнопки при раскрытом состоянии (опционально)\n   * @default \"Свернуть\"\n   */\n  collapseText?: string;\n  /**\n   * Текст для кнопки при закрытом состоянии (опционально)\n   * @default \"Развернуть\"\n   */\n  expandText?: string;\n  /**\n   * callback при изменении состояния\n   */\n  onToggleCollapse?: (isCollapsed: boolean) => void;\n  /** Внешнее состояние [isCollapsed, setIsCollapsed] */\n  collapsedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n  /**\n   * Размещение кнопки коллапсинга / заголовка\n   * - 'inside' - внутри контрол-блока (по умолчанию, участвует в компрессии)\n   * - 'above' - в отдельном блоке сверху контрол-блока (не участвует в компрессии)\n   * @default 'inside'\n   */\n  collapseButtonPlacement?: 'inside' | 'above';\n  /**\n   * Кастомный рендер правого слота кнопки коллапсинга, который используется при collapseButtonPlacement='above'\n   */\n  collapseButtonAboveRightSlot?: React.ReactNode;\n  /**\n   * Текст заголовка таблицы. Только строка, оформляется нашей типографикой.\n   * Рендерится в блоке above или inline в зависимости от collapseButtonPlacement.\n   * При 'above' — показывается вместе с кнопкой коллапсинга (или без неё если enableCollapse=false).\n   * При 'inline' — показывается внутри контрол-блока слева.\n   * Для произвольной разметки заголовка используйте titleRender.\n   */\n  titleText?: string;\n  /**\n   * Полностью кастомный рендер заголовка (заменяет titleText).\n   */\n  titleRender?: React.ReactNode;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableCollapseConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "Table.TableCollapseConfig": {
      "name": "TableCollapseConfig",
      "definition": "export type TableCollapseConfig = {\n  /**\n   * Обязательный флаг для активации\n   * @default false\n   */\n  enableCollapse?: boolean;\n  /**\n   * Начальное состояние (опционально)\n   *  @default false\n   */\n  defaultCollapsed?: boolean;\n  /**\n   * Текст для кнопки при раскрытом состоянии (опционально)\n   * @default \"Свернуть\"\n   */\n  collapseText?: string;\n  /**\n   * Текст для кнопки при закрытом состоянии (опционально)\n   * @default \"Развернуть\"\n   */\n  expandText?: string;\n  /**\n   * callback при изменении состояния\n   */\n  onToggleCollapse?: (isCollapsed: boolean) => void;\n  /** Внешнее состояние [isCollapsed, setIsCollapsed] */\n  collapsedState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n  /**\n   * Размещение кнопки коллапсинга\n   * - 'inside' - внутри контрол-блока (по умолчанию, участвует в компрессии)\n   * - 'above' - в отдельном блоке сверху контрол-блока (не участвует в компрессии)\n   * @default 'inside'\n   */\n  collapseButtonPlacement?: 'inside' | 'above';\n  /**\n   * Кастомный рендер правого слота кнопки коллапсинга, который используется при collapseButtonPlacement='above'\n   */\n  collapseButtonAboveRightSlot?: React.ReactNode;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TableCollapseConfig } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "TReturnUseChangedFormContext": {
      "name": "TReturnUseChangedFormContext",
      "definition": "export type TReturnUseChangedFormContext = UseFormReturn<FieldValues> &\n  TRules &\n  TOptions;",
      "internal": true,
      "importNotice": "Тип \"TReturnUseChangedFormContext\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/utils/types.ts"
    },
    "StatusButton": {
      "name": "StatusButton",
      "definition": "export type StatusButton = {\n  label: ReactNode;\n  view?: NonNullable<ButtonCompProps['view']>;\n};",
      "internal": true,
      "importNotice": "Тип \"StatusButton\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/layouts/ErrorPage/ErrorPage.tsx"
    },
    "BoxBaseProps": {
      "name": "BoxBaseProps",
      "definition": "type BoxBaseProps = BoxCSSProperties & {\n  /**\n   * Кастомные стили styled-components для Box-контейнера\n   */\n  $css?: string | CSSObject | FlattenSimpleInterpolation;\n  /**\n   * Скрытие элемента\n   */\n  hidden?: boolean;\n  /**\n   * Компонент, используемый для корневого узла. Либо строка для использования элемента HTML, либо компонента. (Например: `li`, `p`, `button` и т.д.)\n   */\n  as?: React.ElementType | keyof JSX.IntrinsicElements;\n};",
      "internal": true,
      "importNotice": "Тип \"BoxBaseProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Box/Box.tsx"
    },
    "AiAgentPopoverResizableConfig": {
      "name": "AiAgentPopoverResizableConfig",
      "definition": "export type AiAgentPopoverResizableConfig = Exclude<\n  PopoverProps['resizable'],\n  boolean | undefined\n>;",
      "internal": true,
      "importNotice": "Тип \"AiAgentPopoverResizableConfig\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/AiAgentPopover/AiAgentPopover.types.ts"
    },
    "AutocompleteBaseProps": {
      "name": "AutocompleteBaseProps",
      "definition": "type AutocompleteBaseProps = ComponentProps<typeof BaseAutocomplete>;",
      "internal": true,
      "importNotice": "Тип \"AutocompleteBaseProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Autocomplete/Autocomplete.types.ts"
    },
    "BaseAutocompliteSearchProps": {
      "name": "BaseAutocompliteSearchProps",
      "definition": "type BaseAutocompliteSearchProps = {\n  /**\n   * Размер Поля ввода\n   */\n  size?: 'xs' | 's';\n  /**\n   * Показать/Скрыть count значение в начале выпадающего листа. Или указать собственное число\n   */\n  beforeListTotal?: number | boolean;\n  /**\n   * Добавление названия сущности в начале выпадающего списка\n   */\n  beforeListTotalEntity?: string;\n  /**\n   * Действие при выполнении нажатия на кнопку очистки поля ввода\n   * @deprecated Используйте onClear\n   */\n  handlerClear?: () => void;\n  /**\n   * Действие при выполнении нажатия на кнопку очистки поля ввода\n   */\n  onClear?: () => void;\n};",
      "internal": true,
      "importNotice": "Тип \"BaseAutocompliteSearchProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/AutocompleteSearch/AutocompleteSearch.types.ts"
    },
    "BlockGradientScrollVariant": {
      "name": "BlockGradientScrollVariant",
      "definition": "export type BlockGradientScrollVariant = 'white' | 'gray';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { BlockGradientScrollVariant } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/mixins/blockGradientScroll/types.ts"
    },
    "TypographyWithAutoTooltipProps": {
      "name": "TypographyWithAutoTooltipProps",
      "definition": "export type TypographyWithAutoTooltipProps<T extends TypographyVariant> = {\n  tooltipText?: React.ReactNode;\n  tooltipProps?: Omit<TooltipProps, 'text' | 'target' | 'trigger' | 'opened'>;\n  lines?: number;\n} & Omit<TypographyProps<T>, 'frame'>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TypographyWithAutoTooltipProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Typography/TypographyWithAutoTooltip.types.ts"
    },
    "DrawerProps": {
      "name": "DrawerProps",
      "definition": "export type DrawerProps = ComponentProps<typeof Drawer>;",
      "internal": true,
      "importNotice": "Тип \"DrawerProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/DrawerDF/types.ts"
    },
    "DrawerDFContentProps": {
      "name": "DrawerDFContentProps",
      "definition": "export type DrawerDFContentProps = BoxProps & {\n  fixedWidth?: string;\n  refEl?: Ref<HTMLDivElement>;\n  $isFirstSingleContent?: boolean;\n  $isLastSingleContent?: boolean;\n};",
      "internal": true,
      "importNotice": "Тип \"DrawerDFContentProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/DrawerDF/types.ts"
    },
    "DrawerDFFooterProps": {
      "name": "DrawerDFFooterProps",
      "definition": "export type DrawerDFFooterProps = BoxProps & {\n  refEl?: LegacyRef<HTMLDivElement>;\n};",
      "internal": true,
      "importNotice": "Тип \"DrawerDFFooterProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/DrawerDF/types.ts"
    },
    "DrawerDFHeaderProps": {
      "name": "DrawerDFHeaderProps",
      "definition": "export type DrawerDFHeaderProps = BoxProps & {\n  refEl?: LegacyRef<HTMLDivElement>;\n  title?: ReactNode;\n  subTitle?: ReactNode;\n  badge?: (BadgeCompProps & { text: string }) | undefined;\n  rightBlock?: ReactNode;\n  footerBlock?: ReactNode;\n};",
      "internal": true,
      "importNotice": "Тип \"DrawerDFHeaderProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/DrawerDF/types.ts"
    },
    "EmptyStateImageVariant": {
      "name": "EmptyStateImageVariant",
      "definition": "export type EmptyStateImageVariant = EmptyStateVariant | ErrorPageVariant;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { EmptyStateImageVariant } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/EmptyState/EmptyState.types.ts"
    },
    "GridDNDLayout": {
      "name": "GridDNDLayout",
      "definition": "export type GridDNDLayout = {\n  breakpoint: string;\n  cols: number;\n  rowHeight: number;\n  items: GridDNDItemConfig[];\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { GridDNDLayout } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/GridDND/GridDND.types.ts"
    },
    "GridDNDMeta": {
      "name": "GridDNDMeta",
      "definition": "export type GridDNDMeta = {\n  /** Текущий канонический порядок id после раскладки */\n  itemsOrder: string[];\n  itemsOrderTyped?: GridDNDItems[];\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { GridDNDMeta } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/GridDND/GridDND.types.ts"
    },
    "IconButtonProps": {
      "name": "IconButtonProps",
      "definition": "type IconButtonProps = ComponentProps<typeof IconButton>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { IconButtonProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/IconButton/IconButton.ts"
    },
    "ToggleButtonProps": {
      "name": "ToggleButtonProps",
      "definition": "export type ToggleButtonProps = ToggleButtonBaseProps & {\n  collapsed?: boolean;\n  isAbsolute?: boolean;\n  isAdaptive1280?: boolean;\n  onClick?: () => void;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ToggleButtonProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/LeftPanel/LeftPanel.types.ts"
    },
    "MassActionsSize": {
      "name": "MassActionsSize",
      "definition": "export type MassActionsSize = 'm' | 's' | 'xs';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { MassActionsSize } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/MassActions/types.ts"
    },
    "MassActionsStaticProps": {
      "name": "MassActionsStaticProps",
      "definition": "export type MassActionsStaticProps = {\n  children: ReactNode;\n  className?: string;\n  style?: CSSProperties;\n  /**\n   * Позиционирование компонента\n   * - 'absolute' - абсолютное позиционирование (по умолчанию)\n   * - 'static' - обычный блок без абсолютного позиционирования\n   * - 'relative' - относительное позиционирование\n   */\n  position?: 'absolute' | 'static' | 'relative';\n  /**\n   * Явный контроль видимости компонента\n   * Если не указан, компонент всегда виден\n   * Если указан, компонент отображается только при show === true\n   */\n  show?: boolean;\n  /**\n   * Включить/отключить анимацию появления/исчезновения\n   * @default true\n   */\n  animate?: boolean;\n};",
      "internal": true,
      "importNotice": "Тип \"MassActionsStaticProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/MassActionsStatic/types.ts"
    },
    "ModalDFBackIconButtonProps": {
      "name": "ModalDFBackIconButtonProps",
      "definition": "export type ModalDFBackIconButtonProps = ComponentProps<typeof IconButton> & {\n  iconSize?: ComponentProps<typeof IconArrowLeft>['size'];\n};",
      "internal": true,
      "importNotice": "Тип \"ModalDFBackIconButtonProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/types.ts"
    },
    "ModalDFDotsIconButtonProps": {
      "name": "ModalDFDotsIconButtonProps",
      "definition": "export type ModalDFDotsIconButtonProps = ComponentProps<typeof IconButton> & {\n  dropdownProps?: ComponentProps<typeof Dropdown>;\n  iconSize?: ComponentProps<typeof IconDotsVerticalCenteredOutline>['size'];\n};",
      "internal": true,
      "importNotice": "Тип \"ModalDFDotsIconButtonProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/types.ts"
    },
    "ModalDFFooterProps": {
      "name": "ModalDFFooterProps",
      "definition": "export type ModalDFFooterProps = Omit<BoxProps, 'children'> & {\n  leftBlock?: ReactNode;\n  rightBlock?: ReactNode;\n};",
      "internal": true,
      "importNotice": "Тип \"ModalDFFooterProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/types.ts"
    },
    "ModalDFHeaderProps": {
      "name": "ModalDFHeaderProps",
      "definition": "export type ModalDFHeaderProps = Omit<BoxProps, 'children'> & {\n  title?: ReactNode;\n  badge?: ComponentProps<typeof Badge>;\n  subTitle?: ReactNode;\n  rightBlock?: ReactNode;\n  onBackClick?: () => void;\n  showBackButton?: boolean;\n};",
      "internal": true,
      "importNotice": "Тип \"ModalDFHeaderProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/types.ts"
    },
    "ContainerProps": {
      "name": "ContainerProps",
      "definition": "export type ContainerProps = ISplitContainerProps | INotSplitContainerProps;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ContainerProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/layouts/Container/Container.types.ts"
    },
    "ModalCompProps": {
      "name": "ModalCompProps",
      "definition": "type ModalCompProps = ComponentProps<typeof Modal>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalCompProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Modal/index.ts"
    },
    "ModalDFProps": {
      "name": "ModalDFProps",
      "definition": "export type ModalDFProps = {\n  fullScreen?:\n    | {\n        defaultEnabled?: boolean;\n        saveStateAfterClosing?: boolean;\n        onFullScreen?: () => void;\n        onExitFullScreen?: () => void;\n      }\n    | undefined\n    | boolean;\n  contentContainerProps?: Partial<ContainerProps>;\n  zIndexOverlay?: string;\n} & Omit<ModalCompProps, 'hasBody'>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ModalDFProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/ModalDF/types.ts"
    },
    "NumberFormatBaseProps": {
      "name": "NumberFormatBaseProps",
      "definition": "type NumberFormatBaseProps = ComponentProps<typeof BaseNumberFormat>;",
      "internal": true,
      "importNotice": "Тип \"NumberFormatBaseProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/NumberFormat/NumberFormat.tsx"
    },
    "NumberFormatCompProps": {
      "name": "NumberFormatCompProps",
      "definition": "export type NumberFormatCompProps = NumberFormatBaseProps & {\n  onClear?: () => void;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { NumberFormatCompProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/NumberFormat/NumberFormat.tsx"
    },
    "BreadcrumbsPropsComp": {
      "name": "BreadcrumbsPropsComp",
      "definition": "export type BreadcrumbsPropsComp = ComponentProps<typeof Breadcrumbs>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { BreadcrumbsPropsComp } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Breadcrumbs/index.ts"
    },
    "PopoverDFBaseProps": {
      "name": "PopoverDFBaseProps",
      "definition": "type PopoverDFBaseProps = {\n  /**\n   * Содержимое popover.\n   * Обычно используется композиция из `PopoverDF.Header`, `PopoverDF.Body` и `PopoverDF.Footer`.\n   */\n  children?: ReactNode;\n  /**\n   * Размер PopoverDF.\n   * Влияет на внутренние отступы и типографику header.\n   * @default 'm'\n   */\n  size?: PopoverDFSize;\n};",
      "internal": true,
      "importNotice": "Тип \"PopoverDFBaseProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/PopoverDF/types.ts"
    },
    "PopupDFSize": {
      "name": "PopupDFSize",
      "definition": "export type PopupDFSize = 's' | 'm' | 'l';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { PopupDFSize } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/PopupDF/types.ts"
    },
    "SplitViewAdaptiveContent": {
      "name": "SplitViewAdaptiveContent",
      "definition": "export type SplitViewAdaptiveContent =\n  | ReactNode\n  | ((props: SplitViewSlotSizesProps) => ReactNode);",
      "importPath": "@daisforge/ui",
      "importStatement": "import { SplitViewAdaptiveContent } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/SplitView/SplitView.type.ts"
    },
    "SplVSizes": {
      "name": "SplVSizes",
      "definition": "export type SplVSizes = {\n  /**\n   * Ширина main content в процентах\n   */\n  main: number;\n  /**\n   * Ширина main content в пикселях\n   */\n  mainPx?: number;\n  /**\n   * Ширина sidebar content в процентах\n   */\n  sidebar: number;\n  /**\n   * Ширина sidebar content в пикселях\n   */\n  sidebarPx?: number;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { SplVSizes } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/SplitView/SplitView.type.ts"
    },
    "StoriesShape": {
      "name": "StoriesShape",
      "definition": "export type StoriesShape = 'circle' | 'rect';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { StoriesShape } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Stories/Stories.types.ts"
    },
    "StoriesTitleProps": {
      "name": "StoriesTitleProps",
      "definition": "export type StoriesTitleProps = Partial<\n  TypographyWithAutoTooltipProps<TypographyVariant>\n>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { StoriesTitleProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Stories/Stories.types.ts"
    },
    "StoriesTriggerState": {
      "name": "StoriesTriggerState",
      "definition": "export interface StoriesTriggerState {\n  /** Порядковый индекс группы. */\n  index: number;\n  /** Просмотрена ли группа (значение пропа `viewed`). */\n  viewed: boolean;\n  /** Открыт ли сейчас вьюер на этой группе. */\n  isActive: boolean;\n}",
      "importPath": "@daisforge/ui",
      "importStatement": "import { StoriesTriggerState } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Stories/Stories.types.ts"
    },
    "StoryErrorContext": {
      "name": "StoryErrorContext",
      "definition": "export interface StoryErrorContext {\n  groupIndex: number;\n  slideIndex: number;\n  slide: StorySlide;\n  /** Повторить загрузку ассета. */\n  retry: () => void;\n}",
      "importPath": "@daisforge/ui",
      "importStatement": "import { StoryErrorContext } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Stories/Stories.types.ts"
    },
    "StoriesGroupTransition": {
      "name": "StoriesGroupTransition",
      "definition": "export type StoriesGroupTransition = 'slide' | 'fade' | 'none';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { StoriesGroupTransition } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Stories/Stories.types.ts"
    },
    "StoriesArrows": {
      "name": "StoriesArrows",
      "definition": "export type StoriesArrows = 'auto' | 'always' | 'never';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { StoriesArrows } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Stories/Stories.types.ts"
    },
    "StoriesMode": {
      "name": "StoriesMode",
      "definition": "export type StoriesMode = 'light' | 'dark';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { StoriesMode } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Stories/Stories.types.ts"
    },
    "BaseSwitchProps": {
      "name": "BaseSwitchProps",
      "definition": "export type BaseSwitchProps = ComponentProps<typeof Switch> & {\n  /**\n   * Отображение подложки у switch\n   */\n  hasBackground?: boolean;\n};",
      "internal": true,
      "importNotice": "Тип \"BaseSwitchProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Switch/types.ts"
    },
    "Table.Single": {
      "name": "Single",
      "definition": "type Single = {\n  mode?: 'single';\n  value: string;\n  onChange: (v: string) => void;\n};",
      "internal": true,
      "importNotice": "Тип \"Single\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-filtering/combobox/combobox.tsx"
    },
    "TableCanvas.Single": {
      "name": "Single",
      "definition": "type Single = {\n  mode?: 'single';\n  value: string;\n  onChange: (v: string) => void;\n};",
      "internal": true,
      "importNotice": "Тип \"Single\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/combobox.tsx"
    },
    "Table.Multiple": {
      "name": "Multiple",
      "definition": "type Multiple = {\n  mode?: 'multiple';\n  value: string[];\n  onChange: (v: string[]) => void;\n};",
      "internal": true,
      "importNotice": "Тип \"Multiple\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-filtering/combobox/combobox.tsx"
    },
    "TableCanvas.Multiple": {
      "name": "Multiple",
      "definition": "type Multiple = {\n  mode?: 'multiple';\n  value: string[];\n  onChange: (v: string[]) => void;\n};",
      "internal": true,
      "importNotice": "Тип \"Multiple\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/combobox/combobox.tsx"
    },
    "Table.SIZE": {
      "name": "SIZE",
      "definition": "export type SIZE = keyof typeof SIZES;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { SIZE } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/styles/styles.constants.ts"
    },
    "TableGlide.SIZE": {
      "name": "SIZE",
      "definition": "export type SIZE = keyof GlideSizes;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { SIZE } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/constants.ts"
    },
    "Table.Prettify": {
      "name": "Prettify",
      "definition": "export type Prettify<T> = {\n  [K in keyof T]: T[K];\n  // eslint-disable-next-line @typescript-eslint/ban-types\n} & {};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Prettify } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/utils.type.ts"
    },
    "TableCanvas.Prettify": {
      "name": "Prettify",
      "definition": "export type Prettify<T> = {\n  [K in keyof T]: T[K];\n  // eslint-disable-next-line @typescript-eslint/ban-types\n} & {};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { Prettify } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/utils.type.ts"
    },
    "Table.TableConfig": {
      "name": "TableConfig",
      "definition": "export type TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Тип выделения активной (кликнутой) сущности `'cell' | 'row'`\n   * @default 'cell'\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *```jsx\n   * import { Table } from '@daisforge/ui';\n   *\n   * <Table\n   * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n   * {...rest}\n   * />\n   * ```\n   */\n  selecting?: {\n    state: [\n      ReadonlySet<RowIdType>,\n      React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n    ];\n  } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n       */\n      controlBlock?: {\n        domMetadata?: DomMetadata;\n      };\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n       */\n      sidebar?: {\n        domMetadata?: DomMetadata;\n      };\n    };\n  /**\n   * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n   *\n   * columnConfig=[{editingCell: {...}}]\n   */\n  editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n  /**\n   * subRows - активация иерархии, отображения вложенных строк. Условие активации - наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={subRows: {getSubRows, rowKeyGetter}}\n   *\n   * columnConfig=[{subRow: {...}}]\n   */\n  subRows?: SubRows<RowType, RowIdType>;\n  rowsGrouping?: RowsGrouping<RowType>;\n\n  /**\n   * resizableColumn - активация изменения ширины колонки с помощью курсора. Условие активации -  resizableColumn: true. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={resizableColumn: true}\n   *\n   * columnConfig=[{resizable: true}]\n   */\n  resizableColumn?: boolean;\n  /**\n   * style - inline-стили. Для стилей самой таблицы (без вложенности).\n   *\n   * Исключены свойства 'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'. Их следует стилизовать через свойства containerStyle.\n   */\n  style?: Omit<\n    CSSProperties,\n    'width' | 'height' | 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight'\n  >;\n  /**\n   * css - для стилей простых и сложных(например, для стилизации cell, headerCell, ...).\n   *\n   * Пример:\n   *\n   * ```css\n   * & > .rdg-header-row > .rdgCell {\n   * background-color: red;\n   * }\n   * ```\n   *\n   */\n  css?: string | CSSObject;\n\n  summaryRows?: SummaryRowsConfig;\n  /**\n   * controlBlock - пропс для активации, кастомизации контролблока.\n   */\n  controlBlock?: ControlBlockConfig;\n  /**\n     * containerStyle - инлайновые стили контейнера таблицы и контролблока. высоту и ширину для таблицы рекомендуется задавать в этом пропсе.\n     * Пример:\n     *\n     * ```tsx\n        tableConfig={{ containerStyle: { height: '70vh' } }}\n     * ```\n     */\n  containerStyle?: CSSProperties | undefined;\n  /**\n   * containerCss - стили для контейнера таблицы и контролблока.\n   * Через этот пропс можно дополнительно кастомизировать контейнер и все его дочерние элементы.\n   */\n  containerCss?: string | CSSObject | undefined;\n  /**\n   * containerId - html-атрибут id контейнера таблицы.\n   */\n  containerId?: string | undefined;\n\n  /**\n   * infinityScroll - бесконечная подгрузка данных при скролле.\n   *\n   *  Условие активации - наличие самого пропса infinityScroll.\n   *\n   * При активации infinityScroll отключается дефолтная сортировка и фильтрация.\n   * (Предполагается, что если есть infinityScroll,\n   * то в таблице представлен не весь объем данных,\n   * по этой причине дефолтная сортировка и фильтрация не подходят и будут отображать некорректные данные)\n   *\n   */\n  infinityScroll?: {\n    onTrigger: (rows: RowType[]) => Promise<void> | void;\n    isLoading: boolean;\n    /**\n     * @default true\n     */\n    hasMore?: boolean;\n    /**\n     * @default 100   (px)\n     */\n    scrollThreshold?: number;\n  };\n  /**\n   * @isLoading - состояние загрузки данных для таблицы.\n   */\n  isLoading?: boolean | { boolean: boolean; skeletonRowsCount: number };\n  /**\n   * loadingOverlay - конфигурация для отображения оверлея загрузки.\n   * Показывает индикатор загрузки поверх таблицы с возможностью кастомизации.\n   */\n  loadingOverlay?: {\n    /**\n     * Активен ли оверлей з…",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TableConfig } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "TableCanvas.TableConfig": {
      "name": "TableConfig",
      "definition": "export type TableConfig<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n  RowIdType extends string | number,\n  FilterStateType extends ObjectForExtending,\n  // SubRowType\n> = {\n  /**\n   * Группировка колонок (многоуровневая шапка через `columnConfig.children`):\n   * объединение пустых ячеек шапки (`squashEmptyCells`, по умолчанию включено) и\n   * дефолт выравнивания в объединённых ячейках (`squashedHeaderAlign`).\n   */\n  columnsGrouping?: ColumnsGroupingConfig;\n  /**\n   * Подсветка активной сущности в canvas-таблице.\n   * @deprecated Значения `'cell'`/`'range-cell'` устарели — используйте\n   * `cellsSelection.mode`. Актуальны `'row'` (подсветка строки) и `'disabled'`.\n   */\n  highlightActiveType?: HighlightActiveType;\n  /**\n   * Единый конфиг выделения ячеек: режим (`mode`), оси\n   * (`enableColumnSelection`/`enableRowSelection`/`enableSelectAll`) и controlled\n   * (`state`). См. {@link CellsSelectionConfig}.\n   */\n  cellsSelection?: CellsSelectionConfig;\n  /**\n   * Подсвеченная строка (`highlightActiveType='row'`).\n   * `state` (опционально) — controlled-кортеж `[value, setter]`: задан — значением\n   * владеешь снаружи (сброс `setter(undefined)`); не задан — таблица крутит\n   * подсветку внутренним стейтом, а `onChange` всё равно срабатывает (подписка\n   * без владения значением).\n   */\n  highlightActiveRow?: {\n    state?: [\n      number | undefined,\n      React.Dispatch<React.SetStateAction<number | undefined>>,\n    ];\n    /**\n     * Колбэк смены подсвеченной строки: отдаёт её флэт-индекс и сам объект\n     * строки (`rows[index]`). Позволяет открывать данные подсвеченной строки\n     * (например, в SplitView) без `onCellClicked`.\n     */\n    onChange?: (params: {\n      index: number | undefined;\n      row: RowType | undefined;\n    }) => void;\n  };\n  /**\n   * Эффекты при наведении (hover)\n   * `row` — подсветка строки под курсором.\n   * Независимая визуальная ось: селектинг (`cellsSelection`) и `highlightActiveType='row'`\n   * рисуются ПОВЕРХ hover-подсветки и визуально перекрывают её (hover\n   * «остаётся под ними» и снова виден после сброса выделения).\n   *\n   * `{ row: true }` — включить с цветами из темы;\n   * `{ row: { color: '#F7F9FB' } }` — переопределить цвет data-ячеек.\n   * @default undefined (выключено)\n   */\n  hoverEffects?: HoverEffectsConfig;\n  /**\n   * Включает компенсацию тонких canvas-линий при browser zoom ниже 100%, когда devicePixelRatio меньше 1.\n   * Влияет только на grid/header/sticky hairline borders.\n   * @default false\n   */\n  enableLowDprHairline?: boolean;\n  /**\n   * Управление рамками (линиями) таблицы: включение и выключение.\n   *\n   * Уровни, от слабого к сильному: общие настройки (vertical, horizontal),\n   * затем колонка (getVerticalBorder) и строка (getHorizontalBorder), затем\n   * ячейка (getCellBorder).\n   *\n   * `vertical: false` и `horizontal: false` убирают все вертикальные или\n   * горизонтальные линии тела. `getCellBorder` включает и выключает стороны\n   * рамки конкретной ячейки; при его использовании линии рисуются с разбивкой\n   * по ячейкам.\n   */\n  borders?: BordersConfig<RowType>;\n  /**\n   * rowSize - размеры строк таблицы\n   */\n  rowSize?: Prettify<RowSize>;\n  /**\n   * rowHeight - размер высоты строк таблицы\n   */\n  rowHeight?: Maybe<number | RowHeightFunc<RowType>>;\n  /**\n   * sorting - активация сортировки. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={sorting: {sortingState}}\n   *\n   * columnConfig=[{sortingType: 'numberSort'}]\n   */\n  sorting?: {\n    state: [\n      readonly SortColumn[],\n      React.Dispatch<React.SetStateAction<readonly SortColumn[]>>,\n    ];\n    /**\n     * manualSorting - пропс, активирующий ручную-кастомную (или на стороне бэкенда) сортировку\n     */\n    manualSorting?: boolean;\n  };\n  /** @deprecated Свойство view не используется и будет удалено в следующей мажорной версии. */\n  view?: View;\n  /**\n   * filtering - активация фильтрации. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={filtering: {stateAndSetter, ...}}\n   *\n   * columnConfig=[{filtering: {...}}]\n   */\n  filtering?: FilteringConfig<FilterStateType>;\n  /**\n   * Сворачивание / разворачивание таблицы\n   */\n  collapsing?: TableCollapseConfig;\n  /**\n   * selecting - активация выбора строк. Условие активации - это наличие данного свойства.\n   * Есть поддержка выбора строк с многоуровневой вложенностью.\n   *\n   * Пример:\n   *\n   *```jsx\n   * import { Table } from '@daisforge/ui';\n   *\n   * <Table\n   * tableConfig={{selecting: {stateAndSetter, rowKeyGetter}}}\n   * {...rest}\n   * />\n   * ```\n   */\n  selecting?: {\n    state: [\n      ReadonlySet<RowIdType>,\n      React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>,\n    ];\n    rowKeyGetter: (row: RowType) => RowIdType;\n  } & Prettify<SelectingRowConfig<RowType, RowIdType>> & {\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n       */\n      controlBlock?: {\n        domMetadata?: DomMetadata;\n      };\n      /**\n       * Метки для автоматизированного тестирования и аналитики\n       * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n       */\n      sidebar?: {\n        domMetadata?: DomMetadata;\n      };\n    };\n  /**\n   * editing - активация редактирования. Условие активации - это наличие данного свойства. Нужно также сконфигурировать колонки.\n   *\n   * Пример:\n   *\n   * tableConfig={editing: {onRowsChange, rowKeyGetter}}\n   *\n   * columnConfig=[{editingCell: {...}}]\n   */\n  editing?: EditingConfig<RowType, RowIdType, SummaryRowType>;\n\n  /**\n   * cellTransfer — конфигурация копирования, вставки и fill handle.\n   * По умолчанию копирование (Ctrl+C) работает в режиме редактирования.\n   * Данные копируются в формате TSV (tab-separated values), совместимом с Excel.\n   *\n   * Пример:\n   *\n   * tableConfig={{ cellTransfer: { enabled: true,…",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "SwitchProps": {
      "name": "SwitchProps",
      "definition": "export type SwitchProps = BaseSwitchProps;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { SwitchProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Switch/index.tsx"
    },
    "ComboboxCompProps": {
      "name": "ComboboxCompProps",
      "definition": "type ComboboxCompProps<T extends ComboboxItemOption> = ComponentProps<\n  ComboboxType<T>\n>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ComboboxCompProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Combobox/index.ts"
    },
    "CustomCellStyleProps": {
      "name": "CustomCellStyleProps",
      "definition": "export type CustomCellStyleProps = {\n  cellWidth: number;\n  cellHeight: number;\n  disableLeftOffset?: boolean | undefined;\n};",
      "internal": true,
      "importNotice": "Тип \"CustomCellStyleProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-edit/types.ts"
    },
    "CustomCellStyleNumberFormatProps": {
      "name": "CustomCellStyleNumberFormatProps",
      "definition": "export type CustomCellStyleNumberFormatProps = {\n  align?: 'left' | 'center' | 'right';\n  autoFocusType: 'autoFocus' | 'autoFocusAndSelect' | 'none';\n} & CustomCellStyleProps;",
      "internal": true,
      "importNotice": "Тип \"CustomCellStyleNumberFormatProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-edit/types.ts"
    },
    "TableProps": {
      "name": "TableProps",
      "definition": "export type TableProps<\n  FilterStateType extends ObjectForExtending,\n  RowIdType extends string | number,\n  HeaderContextValueType extends ObjectForExtending,\n  RowContextValueType extends ObjectForExtending,\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n> = {\n  /**\n   * columnConfig - Конфигурация колонок.\n   *\n   * (рекомендуется минимальное количество зависимостей для данной сущности - в идеале, чтобы не пересоздавался)\n   */\n  columnConfig: readonly ColumnConfig<RowType, SummaryRowType>[];\n  /**\n   * rows - данные для таблицы. ```RowType extends Record<string | number, any>```\n   */\n  rows: RowType[];\n  /**\n   * topSummaryRows - данные для итоговой строки в верхней части таблицы. ```SummaryRowType[]```\n   * topSummaryRows?: SummaryRowType[];\n   */\n  /**\n   * bottomSummaryRows - данные для итоговой строки в нижней части таблицы. ```SummaryRowType[]```\n   */\n  bottomSummaryRows?: SummaryRowType[];\n  /**\n   * tableConfig - Конфигурация фичей таблицы (их активация и отключение)\n   */\n  tableConfig?: Prettify<\n    TableConfig<RowType, SummaryRowType, RowIdType, FilterStateType>\n  >;\n  /**\n   * headerContextValue:  любые стейты, которые нужны в headerCell - кладем в headerContextValue. И получаем доступ с помощью cellInfo.ctxs из args.\n   */\n  headerContextValue?: HeaderContextValueType;\n  /**\n   * rowContextValue:  любые стейты, которые нужны в cell - кладем в rowContextValue.  И получаем доступ с помощью cellInfo.ctxs из args.\n   */\n  rowContextValue?: RowContextValueType;\n  refTable?: Ref<DataEditorRef>;\n  refTableContainer?: React.Ref<HTMLDivElement>;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableProps } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table.type.ts"
    },
    "TableGlideProps": {
      "name": "TableGlideProps",
      "definition": "export type TableGlideProps<R extends ObjectForExtending, SR> = Omit<\n  GlideProps,\n  | keyof TableGlideCustomProps<R, SR>\n  | 'getCellContent'\n  | 'drawGroupHeader'\n  | 'ref'\n  | 'groupHeaderHeight'\n> &\n  TableGlideCustomProps<R, SR>;",
      "internal": true,
      "importNotice": "Тип \"TableGlideProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "TableContentStateOverlay": {
      "name": "TableContentStateOverlay",
      "definition": "export type TableContentStateOverlay =\n  | TableContentStateEmptyOverlay\n  | TableContentStateErrorOverlay;",
      "internal": true,
      "importNotice": "Тип \"TableContentStateOverlay\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-content-state/types.ts"
    },
    "CellReadOnlyEditorGlideInstanceProps": {
      "name": "CellReadOnlyEditorGlideInstanceProps",
      "definition": "export type CellReadOnlyEditorGlideInstanceProps<\n  R extends ObjectForExtending,\n  SR,\n> = EditingCellInfoGlideInstance<R, SR> &\n  CellReadOnlyEditorGlideInstanceStaticProps;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellReadOnlyEditorGlideInstanceProps } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "RowsChangeDataGlideInstance": {
      "name": "RowsChangeDataGlideInstance",
      "definition": "export interface RowsChangeDataGlideInstance<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> {\n  indexes: number[];\n  column: ColumnGlideInstance<R, SR, CustomCtxs>;\n  /** Источник изменения: `'edit'` — ручное редактирование, `'paste'` — вставка, `'fill'` — fill handle */\n  type: RowsChangeType;\n  /** Метаданные fill handle (только при `type === 'fill'`) */\n  fillMeta?: FillMeta;\n  /** Результат `onBeforeFill` (только при `type === 'fill'`, если `onBeforeFill` задан) */\n  fillResult?: string[][];\n}",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { RowsChangeDataGlideInstance } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "TableGlideInstanceContextMenu": {
      "name": "TableGlideInstanceContextMenu",
      "definition": "export type TableGlideInstanceContextMenu<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = {\n  onHeaderContextMenu?: (\n    ...args: [\n      ...Parameters<NonNullable<TableGlideProps<R, SR>['onHeaderContextMenu']>>,\n      TableInfoBase<R, SR, CustomCtxs>,\n    ]\n  ) => void;\n  onCellContextMenu?: (\n    ...args: [\n      ...Parameters<NonNullable<TableGlideProps<R, SR>['onCellContextMenu']>>,\n      TableInfoWithRow<R, SR, CustomCtxs>,\n    ]\n  ) => void;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableGlideInstanceContextMenu } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "ButtonProps": {
      "name": "ButtonProps",
      "definition": "export type ButtonProps = ComponentProps<typeof Button>;",
      "internal": true,
      "importNotice": "Тип \"ButtonProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/widgets/control-block/control-block-button.types.tsx"
    },
    "DefPropsKeys": {
      "name": "DefPropsKeys",
      "definition": "type DefPropsKeys = keyof typeof controlButtonDefaultProps;",
      "internal": true,
      "importNotice": "Тип \"DefPropsKeys\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/widgets/control-block/control-block-button.types.tsx"
    },
    "Table.LinkView": {
      "name": "LinkView",
      "definition": "type LinkView<V extends string | undefined> = V extends string\n  ? `link${Capitalize<V>}`\n  : undefined;",
      "internal": true,
      "importNotice": "Тип \"LinkView\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/widgets/control-block/control-block-button.types.tsx"
    },
    "TableGlide.LinkView": {
      "name": "LinkView",
      "definition": "export type LinkView = Extract<LinkAllProps['view'], string>;",
      "internal": true,
      "importNotice": "Тип \"LinkView\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasLink.ts"
    },
    "MassActions.LinkView": {
      "name": "LinkView",
      "definition": "export type LinkView<V extends string | undefined> = V extends string\n  ? `link${Capitalize<V>}`\n  : undefined;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LinkView } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/MassActions/types.ts"
    },
    "Table.LinkButtonView": {
      "name": "LinkButtonView",
      "definition": "export type LinkButtonView = LinkButtonProps['view'];",
      "internal": true,
      "importNotice": "Тип \"LinkButtonView\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/widgets/control-block/control-block-button.types.tsx"
    },
    "MassActions.LinkButtonView": {
      "name": "LinkButtonView",
      "definition": "export type LinkButtonView = LinkButtonProps['view'];",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LinkButtonView } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/MassActions/types.ts"
    },
    "GlideProps": {
      "name": "GlideProps",
      "definition": "export type GlideProps = ComponentProps<typeof DataEditor>;",
      "internal": true,
      "importNotice": "Тип \"GlideProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "TableGlideCustomProps": {
      "name": "TableGlideCustomProps",
      "definition": "export type TableGlideCustomProps<\n  R extends ObjectForExtending,\n  SR = unknown\n> = {\n  columns: ColumnGlideLast<R, SR>[];\n  rows: readonly R[];\n  bottomSummaryRows?: readonly SR[];\n  rowSize?: SIZE;\n  rowHeight?:\n    | ((\n        row: R,\n        currentRowSize: {\n          rowSizeName: SIZE;\n          rowSizeValue: number;\n        },\n        rowIndex: number\n      ) => number)\n    | number\n    | undefined\n    | null;\n  ctxs?: ObjectForExtending;\n  renderGroupHeader?: (\n    args: RenderGroupHeaderArgs\n  ) => 'default' | { defaultWithCustomGroupName: string } | CanvasEl;\n  /** Выравнивание текста в объединённой шапке по ключу группы (ColumnGroupConfig.key). */\n  groupAlignMap?: Map<string, SpanAlignment>;\n  refTable?: Ref<DataEditorRef>;\n  onColumnsReorder?: (sourceKey: string, targetKey: string) => void;\n  /** Ref на контейнер таблицы — события portal hover диспатчатся на него, чтобы несколько таблиц не перехватывали чужие тултипы */\n  portalEventTargetRef?: RefObject<HTMLElement | null>;\n  /** Откреплённая шапка — header уезжает вместе со скроллом */\n  unstickyHeader?: boolean;\n  // отключает resize колонок (по умолчанию true)\n  resizableColumn?: boolean;\n  /** Внешний ref на wrapper-div (для TableCanvas - refTableContainer) */\n  containerRef?: Ref<HTMLDivElement>;\n  /** className для wrapper-div */\n  containerClassName?: string;\n  /** inline-style для wrapper-div */\n  containerStyle?: CSSProperties;\n  /** Рендер overlay-фич (tooltip, contextMenu, popover) внутри wrapper-div когда DOM готов */\n  renderOverlayFeatures?: (ctx: {\n    containerElement: HTMLDivElement;\n    renderInContainer: (children: ReactNode) => ReactPortal | null;\n  }) => ReactNode;\n  /** Не рендерить canvas-grid, оставив только overlay-content внутри wrapper. */\n  hideGrid?: boolean;\n  /** DOM-узел content-state (empty/error), рендерится как прямой child контейнера. */\n  contentStateNode?: ReactNode;\n  /** Флаг fullscreen - пересканирование DOM при переключении */\n  fullScreened?: boolean;\n  /** Переносит editor overlay внутрь контейнера (вместо document.body). Для модалок с CSS transform. */\n  editorOverlayPortal?: 'inside';\n  groupHeaderHeight?: number[];\n  /** Управляет canvas-подсветкой активной сущности поверх glide selection. */\n  highlightActiveType?: HighlightActiveType;\n  /** Режим выделения ячеек (нативный glide selection). По умолчанию 'range-cell'. */\n  cellsSelectionMode?: CellsSelectionMode;\n  /** Канал для copy/paste (selectionRef потребителя), отдельно от controlled gridSelection. */\n  onSelectionEmit?: (selection: GridSelection) => void;\n  /**\n   * Ключи выделенных КОЛОНОК (объединение: одиночный клик/Shift/select-all +\n   * Ctrl-мультивыбор), без сервисных колонок. Канал наверх для контрл-блока\n   * (например «Закрепить столбцы»). Обычное выделение ячеек сюда не попадает.\n   */\n  onColumnSelectionChange?: (selectedColumnKeys: string[]) => void;\n  /**\n   * Follow-выделение: после реордера (закрепление колонок) заново выделить эти\n   * ключи. Пустой массив → снять выделение. null/undefined → не трогать.\n   */\n  pendingColumnSelectionKeys?: string[] | null;\n  /** Вызывается после применения pendingColumnSelectionKeys (сброс pending). */\n  onColumnSelectionApplied?: () => void;\n  /** Controlled-значение подсвеченной строки (highlightActiveType='row'). */\n  highlightActiveRow?: number;\n  /**\n   * Controlled-сеттер подсвеченной строки. Вторым аргументом отдаёт сам объект\n   * строки (`rows[index]`) — чтобы потребитель получал узел без onCellClicked.\n   */\n  onHighlightActiveRowChange?: (\n    row: number | undefined,\n    rowData?: R | undefined\n  ) => void;\n  /**\n   * Режим подсветки строки controlled (значением владеют снаружи). Если не\n   * задан — таблица крутит подсветку внутренним стейтом, но колбэк всё равно\n   * вызывается (подписка без владения).\n   */\n  highlightActiveRowControlled?: boolean;\n  /** Выделение колонок по клику на шапку (независимо от highlightActiveType). По умолчанию true. */\n  enableColumnSelection?: boolean;\n  /** Выделение строк по клику/драгу на колонке нумерации. По умолчанию true. */\n  enableRowSelection?: boolean;\n  /** Выделение всей таблицы кликом по шапке колонки нумерации. По умолчанию true. */\n  enableSelectAll?: boolean;\n  /** Индексы строк, выбранных через checkbox selection. */\n  checkboxSelectedRowIndexes?: ReadonlySet<number>;\n  /** Индексы строк, у которых ЕСТЬ (виден) чекбокс — для тёмной подсветки highlightActiveType='row'. */\n  checkboxVisibleRowIndexes?: ReadonlySet<number>;\n  /**\n   * Эффекты при наведении. `hoverEffects.row` — подсветка строки под курсором:\n   * рисуется через bgCell (getRowThemeOverride), т.е. лежит ПОД селектингом и\n   * highlightActiveType — они рисуются поверх (highlightRegions) и визуально\n   * перекрывают hover. По умолчанию выключено.\n   */\n  hoverEffects?: HoverEffectsConfig;\n  /** Включает компенсацию тонких canvas-линий при browser zoom ниже 100% / DPR < 1. */\n  enableLowDprHairline?: boolean;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableGlideCustomProps } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "FlexBoxOptions": {
      "name": "FlexBoxOptions",
      "definition": "export interface FlexBoxOptions {\n  id?: string;\n  direction?: Direction;\n  wrap?: 'nowrap' | 'wrap' | 'wrap-reverse';\n  columnGap?: number;\n  rowGap?: number;\n  justifyContent?: Justify;\n  alignItems?: Align;\n  alignContent?: AlignContent;\n  padding?:\n    | {\n        top?: number;\n        right?: number;\n        bottom?: number;\n        left?: number;\n      }\n    | number;\n}",
      "internal": true,
      "importNotice": "Тип \"FlexBoxOptions\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/miniflex/types.ts"
    },
    "CanvasFlexStyle": {
      "name": "CanvasFlexStyle",
      "definition": "export type CanvasFlexStyle = Omit<\n  Partial<FlexStyle>,\n  'width' | 'height' | 'crossAxisSizing'\n> & {\n  width?: DimensionValue;\n  height?: DimensionValue;\n  cursor?: string;\n  marginRight?: number;\n};",
      "internal": true,
      "importNotice": "Тип \"CanvasFlexStyle\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/core/CanvasNode.type.ts"
    },
    "PositionValue": {
      "name": "PositionValue",
      "definition": "export type PositionValue = number | string;",
      "internal": true,
      "importNotice": "Тип \"PositionValue\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/core/CanvasNode.type.ts"
    },
    "CanvasEvent": {
      "name": "CanvasEvent",
      "definition": "export interface CanvasEvent<T = any> {\n  type: string;\n  x: number;\n  y: number;\n  originalEvent: MouseEvent | any;\n  target?: any;\n  currentTarget?: T;\n  stopPropagation: () => void;\n  preventDefault: () => void;\n  cellBounds?: Rect | null;\n}",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CanvasEvent } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/core/CanvasNode.type.ts"
    },
    "BadgeView": {
      "name": "BadgeView",
      "definition": "export type BadgeView =\n  | 'default'\n  | 'accent'\n  | 'positive'\n  | 'warning'\n  | 'negative'\n  | 'dark'\n  | 'light';",
      "internal": true,
      "importNotice": "Тип \"BadgeView\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasBadge.ts"
    },
    "BadgeSize": {
      "name": "BadgeSize",
      "definition": "export type BadgeSize = 'xs' | 's' | 'm' | 'l';",
      "internal": true,
      "importNotice": "Тип \"BadgeSize\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasBadge.ts"
    },
    "ButtonView": {
      "name": "ButtonView",
      "definition": "export type ButtonView =\n  | 'default'\n  | 'primary'\n  | 'accent'\n  | 'secondary'\n  | 'clear'\n  | 'success'\n  | 'warning'\n  | 'critical'\n  | 'dark'\n  | 'black'\n  | 'white';",
      "internal": true,
      "importNotice": "Тип \"ButtonView\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/cells/buttons/types.ts"
    },
    "ButtonSize": {
      "name": "ButtonSize",
      "definition": "export type ButtonSize = 'xs' | 's' | 'm' | 'l';",
      "internal": true,
      "importNotice": "Тип \"ButtonSize\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/cells/buttons/types.ts"
    },
    "EmbedIconButtonSize": {
      "name": "EmbedIconButtonSize",
      "definition": "export type EmbedIconButtonSize = ButtonSize;",
      "internal": true,
      "importNotice": "Тип \"EmbedIconButtonSize\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/cells/buttons/types.ts"
    },
    "CanvasTextOptions": {
      "name": "CanvasTextOptions",
      "definition": "export interface CanvasTextOptions {\n  font?: string;\n  fontSize?: number;\n  lineHeightPx?: number;\n  color?: string;\n  wordWrap?: boolean;\n  lineHeight?: number;\n  overflow?: CanvasTextOverflowMode;\n  textOverflow?: CanvasTextOverflow;\n  ellipsis?: string;\n  maxLines?: number;\n  autoTooltip?: CanvasTextAutoTooltip;\n}",
      "internal": true,
      "importNotice": "Тип \"CanvasTextOptions\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasText.ts"
    },
    "TTabsProps": {
      "name": "TTabsProps",
      "definition": "export type TTabsProps = ComponentProps<typeof Tabs>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TTabsProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/TableTabs/TableTabs.types.ts"
    },
    "TableTabsSize": {
      "name": "TableTabsSize",
      "definition": "export type TableTabsSize = 'm' | 's' | 'xs';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TableTabsSize } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/TableTabs/TableTabs.types.ts"
    },
    "TextAreaBaseProps": {
      "name": "TextAreaBaseProps",
      "definition": "type TextAreaBaseProps = ComponentProps<typeof BaseTextArea>;",
      "internal": true,
      "importNotice": "Тип \"TextAreaBaseProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TextArea/TextArea.types.ts"
    },
    "TextFieldBaseProps": {
      "name": "TextFieldBaseProps",
      "definition": "type TextFieldBaseProps = ComponentProps<typeof BaseTextField>;",
      "internal": true,
      "importNotice": "Тип \"TextFieldBaseProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TextField/TextField.tsx"
    },
    "TextFieldSearchBaseProps": {
      "name": "TextFieldSearchBaseProps",
      "definition": "export type TextFieldSearchBaseProps = {\n  /**\n   * Размер Поля ввода\n   */\n  size?: 'xs' | 's';\n  /**\n   * Действие при выполнении нажатия на кнопку очистки поля ввода\n   * @deprecated Используйте onClear\n   */\n  handlerClear?: () => void;\n  /**\n   * Действие при выполнении нажатия на кнопку очистки поля ввода\n   */\n  onClear?: () => void;\n};",
      "internal": true,
      "importNotice": "Тип \"TextFieldSearchBaseProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TextField/TextFieldSearch.tsx"
    },
    "TourWidgetCss": {
      "name": "TourWidgetCss",
      "definition": "export type TourWidgetCss = string | CSSObject | FlattenSimpleInterpolation;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TourWidgetCss } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/TourWidget/types.ts"
    },
    "TourWidgetOrientation": {
      "name": "TourWidgetOrientation",
      "definition": "export type TourWidgetOrientation = 'vertical' | 'horizontal';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TourWidgetOrientation } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/TourWidget/types.ts"
    },
    "TypographyVariant": {
      "name": "TypographyVariant",
      "definition": "export type TypographyVariant = keyof typeof typographyComponents;",
      "internal": true,
      "importNotice": "Тип \"TypographyVariant\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Typography/Typography.tsx"
    },
    "PropsForVariant": {
      "name": "PropsForVariant",
      "definition": "export type PropsForVariant<T extends TypographyVariant> = ComponentProps<\n  (typeof typographyComponents)[T]\n>;",
      "internal": true,
      "importNotice": "Тип \"PropsForVariant\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Typography/Typography.tsx"
    },
    "TypographyProps": {
      "name": "TypographyProps",
      "definition": "export type TypographyProps<T extends TypographyVariant> = {\n  variant: T;\n  children: React.ReactNode;\n  refTypography?: LegacyRef<HTMLDivElement> | undefined;\n} & PropsForVariant<T>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TypographyProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Typography/Typography.tsx"
    },
    "TMutationRegister": {
      "name": "TMutationRegister",
      "definition": "export type TMutationRegister<TFieldValues extends FieldValues> = {\n  name: Path<TFieldValues>;\n  options?: RegisterOptions<FieldValues, Path<TFieldValues>> | undefined;\n};",
      "internal": true,
      "importNotice": "Тип \"TMutationRegister\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/types.ts"
    },
    "TPropsFromAutocomplete": {
      "name": "TPropsFromAutocomplete",
      "definition": "type TPropsFromAutocomplete = Omit<\n  TAutocompleteProps,\n  | keyof Required<TProps>\n  | keyof Required<TMutationRegister<object>>\n  | 'value'\n  | 'onSuggestionSelect'\n>;",
      "internal": true,
      "importNotice": "Тип \"TPropsFromAutocomplete\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormAutocomplete/types.ts"
    },
    "FormAutocomplete.TProps": {
      "name": "TProps",
      "definition": "type TProps = {\n  onChange?: THandleChange<string>;\n  onChangeInput?: THandleChange<string>;\n};",
      "internal": true,
      "importNotice": "Тип \"TProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormAutocomplete/types.ts"
    },
    "FormCheckbox.TProps": {
      "name": "TProps",
      "definition": "type TProps = {\n  onChange?: THandleChange<boolean>;\n};",
      "internal": true,
      "importNotice": "Тип \"TProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormCheckbox/types.ts"
    },
    "FormCombobox.TProps": {
      "name": "TProps",
      "definition": "type TProps =\n  | {\n      multiselect: true;\n      onChange?: THandleChange<string[]>;\n    }\n  | {\n      multiselect?: false | undefined;\n      onChange?: THandleChange<string>;\n    };",
      "internal": true,
      "importNotice": "Тип \"TProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormCombobox/types.ts"
    },
    "FormDatePickers.TProps": {
      "name": "TProps",
      "definition": "type TProps = {\n  portal?: TDatePickerRangeProps['frame'];\n  onChange?: (newValue: string) => void;\n  textHint?: string;\n  format?: TDatePickerFormat;\n  invalidFormatMessage?: string;\n};",
      "internal": true,
      "importNotice": "Тип \"TProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormDatePickers/FormDatePickerRange/types.ts"
    },
    "FormMask.TProps": {
      "name": "TProps",
      "definition": "type TProps = {\n  onChange?: THandleChange<string>;\n  mask: string;\n};",
      "internal": true,
      "importNotice": "Тип \"TProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormMask/types.ts"
    },
    "FormNumberFormat.TProps": {
      "name": "TProps",
      "definition": "type TProps = {\n  onChange?: THandleChange<string>;\n};",
      "internal": true,
      "importNotice": "Тип \"TProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormNumberFormat/types.ts"
    },
    "FormSegments.TProps": {
      "name": "TProps",
      "definition": "type TProps = {\n  selectionMode?: 'multiple' | 'single';\n  onChange?: THandleChange<string[]>;\n};",
      "internal": true,
      "importNotice": "Тип \"TProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormSegments/types.ts"
    },
    "FormSelect.TProps": {
      "name": "TProps",
      "definition": "type TProps =\n  | {\n      multiselect: true;\n      onChange?: THandleChange<string[]>;\n    }\n  | {\n      multiselect?: false | undefined;\n      onChange?: THandleChange<string>;\n    };",
      "internal": true,
      "importNotice": "Тип \"TProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormSelect/types.ts"
    },
    "FormSwitch.TProps": {
      "name": "TProps",
      "definition": "type TProps = {\n  onChange?: THandleChange<boolean>;\n};",
      "internal": true,
      "importNotice": "Тип \"TProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormSwitch/types.ts"
    },
    "FormTextArea.TProps": {
      "name": "TProps",
      "definition": "type TProps = {\n  onChange?: THandleChange<string>;\n};",
      "internal": true,
      "importNotice": "Тип \"TProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormTextArea/types.ts"
    },
    "FormTextField.TProps": {
      "name": "TProps",
      "definition": "type TProps = {\n  onChange?: THandleChange<string>;\n};",
      "internal": true,
      "importNotice": "Тип \"TProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormTextField/types.ts"
    },
    "TPropsFromCheckbox": {
      "name": "TPropsFromCheckbox",
      "definition": "type TPropsFromCheckbox = Omit<\n  TCheckboxProps,\n  | keyof Required<TProps>\n  | keyof Required<TMutationRegister<object>>\n  | 'checked'\n  | 'value'\n>;",
      "internal": true,
      "importNotice": "Тип \"TPropsFromCheckbox\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormCheckbox/types.ts"
    },
    "TPropsFromCombobox": {
      "name": "TPropsFromCombobox",
      "definition": "type TPropsFromCombobox = Omit<\n  TComboboxProps,\n  keyof Required<TProps> | keyof Required<TMutationRegister<object>> | 'value'\n>;",
      "internal": true,
      "importNotice": "Тип \"TPropsFromCombobox\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormCombobox/types.ts"
    },
    "TPropsFromDatePicker": {
      "name": "TPropsFromDatePicker",
      "definition": "type TPropsFromDatePicker = Omit<\n  TDatePickerProps,\n  keyof Required<TProps> | keyof Required<TMutationRegister<object>> | 'value'\n>;",
      "internal": true,
      "importNotice": "Тип \"TPropsFromDatePicker\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormDatePickers/FormDatePicker/types.ts"
    },
    "TMutationDatePickerRangeProps": {
      "name": "TMutationDatePickerRangeProps",
      "definition": "export type TMutationDatePickerRangeProps<TFieldValues extends FieldValues> =\n  TMutationRegister<TFieldValues> & TPropsFromDatePickerRange & TProps;",
      "internal": true,
      "importNotice": "Тип \"TMutationDatePickerRangeProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormDatePickers/FormDatePickerRange/types.ts"
    },
    "TPropsFromMask": {
      "name": "TPropsFromMask",
      "definition": "type TPropsFromMask = Omit<\n  TMaskProps,\n  | 'mask'\n  | keyof Required<TProps>\n  | keyof Required<TMutationRegister<object>>\n  | 'value'\n>;",
      "internal": true,
      "importNotice": "Тип \"TPropsFromMask\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormMask/types.ts"
    },
    "TPropsFromNumberFormat": {
      "name": "TPropsFromNumberFormat",
      "definition": "type TPropsFromNumberFormat = Omit<\n  TNumberFormatProps,\n  keyof Required<TProps> | keyof Required<TMutationRegister<object>> | 'value'\n>;",
      "internal": true,
      "importNotice": "Тип \"TPropsFromNumberFormat\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormNumberFormat/types.ts"
    },
    "NativeRadioboxProps": {
      "name": "NativeRadioboxProps",
      "definition": "export type NativeRadioboxProps = ComponentProps<typeof Radiobox>;",
      "internal": true,
      "importNotice": "Тип \"NativeRadioboxProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormRadioGroupBox/types.ts"
    },
    "NativeRadioGroupProps": {
      "name": "NativeRadioGroupProps",
      "definition": "export type NativeRadioGroupProps = ComponentProps<typeof RadioGroup>;",
      "internal": true,
      "importNotice": "Тип \"NativeRadioGroupProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormRadioGroupBox/types.ts"
    },
    "TextFieldProps": {
      "name": "TextFieldProps",
      "definition": "export type TextFieldProps = TextFieldBaseProps & {\n  /**\n   * Callback при нажатии на кнопку очистки поля ввода.\n   * При наличии value и onClear справа отображается крестик.\n   */\n  onClear?: () => void;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TextFieldProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/TextField/TextField.tsx"
    },
    "TPropsFromSegmentGroup": {
      "name": "TPropsFromSegmentGroup",
      "definition": "type TPropsFromSegmentGroup = Omit<\n  TSegmentGroupNativeProps,\n  | 'children'\n  | 'onChange'\n  | keyof Required<TPropsBase>\n  | keyof Required<TMutationRegister<object>>\n>;",
      "internal": true,
      "importNotice": "Тип \"TPropsFromSegmentGroup\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormSegments/types.ts"
    },
    "TLabelBlockProps": {
      "name": "TLabelBlockProps",
      "definition": "export type TLabelBlockProps = Pick<\n  TextFieldProps,\n  'label' | 'titleCaption' | 'hintText' | 'hintTrigger' | 'hintHasArrow'\n>;",
      "internal": true,
      "importNotice": "Тип \"TLabelBlockProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormSegments/types.ts"
    },
    "TSegmentItemNativeProps": {
      "name": "TSegmentItemNativeProps",
      "definition": "export type TSegmentItemNativeProps = ComponentProps<typeof SegmentItem>;",
      "internal": true,
      "importNotice": "Тип \"TSegmentItemNativeProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormSegments/types.ts"
    },
    "TPropsFromSelect": {
      "name": "TPropsFromSelect",
      "definition": "type TPropsFromSelect = Omit<\n  TSelectProps,\n  keyof Required<TProps> | keyof Required<TMutationRegister<object>> | 'value'\n>;",
      "internal": true,
      "importNotice": "Тип \"TPropsFromSelect\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormSelect/types.ts"
    },
    "TPropsFromSwitch": {
      "name": "TPropsFromSwitch",
      "definition": "type TPropsFromSwitch = Omit<\n  TSwitchProps,\n  | keyof Required<TProps>\n  | keyof Required<TMutationRegister<object>>\n  | 'checked'\n  | 'value'\n>;",
      "internal": true,
      "importNotice": "Тип \"TPropsFromSwitch\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormSwitch/types.ts"
    },
    "TPropsFromTextArea": {
      "name": "TPropsFromTextArea",
      "definition": "type TPropsFromTextArea = Omit<\n  TTextAreaProps,\n  keyof Required<TProps> | keyof Required<TMutationRegister<object>> | 'value'\n>;",
      "internal": true,
      "importNotice": "Тип \"TPropsFromTextArea\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormTextArea/types.ts"
    },
    "TPropsFromTextField": {
      "name": "TPropsFromTextField",
      "definition": "type TPropsFromTextField = Omit<\n  TTextFieldProps,\n  keyof Required<TProps> | keyof Required<TMutationRegister<object>> | 'value'\n>;",
      "internal": true,
      "importNotice": "Тип \"TPropsFromTextField\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormTextField/types.ts"
    },
    "ISplitContainerProps": {
      "name": "ISplitContainerProps",
      "definition": "export interface ISplitContainerProps extends IContainerBaseProps {\n  split: true;\n  children?:\n    | [ReactElement, ReactElement]\n    | [ReactElement, ReactElement, ReactElement];\n  /**\n   * @default '30/70'\n   */\n  view?: TContainerView;\n  /**\n   * Минимальная ширина колонок\n   * @default '360px'\n   */\n  minColWidth?: string;\n  /**\n   * Отступ между колонками\n   * @default '24px'\n   */\n  gap?: string;\n  /**\n   * Ширина фиксированной колонки (для view='fixed-fluid')\n   * @default '288px'\n   */\n  fixedWidth?: string;\n}",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ISplitContainerProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/layouts/Container/Container.types.ts"
    },
    "INotSplitContainerProps": {
      "name": "INotSplitContainerProps",
      "definition": "export interface INotSplitContainerProps extends IContainerBaseProps {\n  split?: false;\n  children?: ReactNode;\n}",
      "importPath": "@daisforge/ui",
      "importStatement": "import { INotSplitContainerProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/layouts/Container/Container.types.ts"
    },
    "CompPopoverProps": {
      "name": "CompPopoverProps",
      "definition": "type CompPopoverProps = PopoverCompProps;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { CompPopoverProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Popover/index.ts"
    },
    "FiltersActionsFiltersButtonProps": {
      "name": "FiltersActionsFiltersButtonProps",
      "definition": "export type FiltersActionsFiltersButtonProps = ButtonCompProps & {\n  redSquare?: boolean;\n  hideLabel?: boolean;\n  iconSize?: ComponentProps<typeof Icon>['size'];\n};",
      "internal": true,
      "importNotice": "Тип \"FiltersActionsFiltersButtonProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/layouts/FiltersActions/components/FiltersButton.tsx"
    },
    "FilterTargetRenderApi": {
      "name": "FilterTargetRenderApi",
      "definition": "export type FilterTargetRenderApi = {\n  /**\n   * Обработчик открытия/закрытия Popover. Повесьте его на `onClick` корневого\n   * кликабельного элемента вашего таргета — иначе Popover не будет открываться.\n   */\n  onClick: (event?: React.MouseEvent) => void;\n  /** Открыт ли Popover сейчас — удобно для смены вида таргета в активном состоянии. */\n  isOpen: boolean;\n  /**\n   * Нужно ли показывать красную точку-индикатор (значение пропа `redSquare`).\n   * Передайте в `<RedDot visible={isRedDotVisible} />`.\n   */\n  isRedDotVisible: boolean;\n  /**\n   * Компонент красной точки-индикатора. Позиционируется абсолютно в правый\n   * верхний угол ближайшего контейнера с `position: relative`.\n   */\n  RedDot: typeof RedDot;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FilterTargetRenderApi } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/layouts/FiltersActions/components/FiltersButtonWithPopover.tsx"
    },
    "FiltersActionsResizeDimensions": {
      "name": "FiltersActionsResizeDimensions",
      "definition": "export interface FiltersActionsResizeDimensions {\n  /** Полная ширина контейнера */\n  containerWidth: number;\n  /** Ширина левого блока (mainBlock) - вычисляется как containerWidth - buttonsBlockWidth - gap */\n  mainBlockWidth: number;\n  /** Ширина правого блока (activeButtonsBlock), 0 если блок отсутствует */\n  buttonsBlockWidth: number;\n  /** Доступная ширина для элементов mainBlock (за вычетом padding и gap) */\n  availableMainBlockWidth: number;\n}",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FiltersActionsResizeDimensions } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/layouts/FiltersActions/FiltersActions.tsx"
    },
    "LayoutVariant": {
      "name": "LayoutVariant",
      "definition": "export type LayoutVariant = keyof typeof LAYOUT_VARIANTS;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LayoutVariant } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/layouts/Layout/Layout.types.ts"
    },
    "CSSValue": {
      "name": "CSSValue",
      "definition": "export type CSSValue = string | number;",
      "internal": true,
      "importNotice": "Тип \"CSSValue\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/layouts/PageLayout/PageLayout.types.ts"
    },
    "StageStatus": {
      "name": "StageStatus",
      "definition": "export type StageStatus = 'DEFAULT' | 'WAIT' | 'SUCCESSFUL' | 'FAILURE';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { StageStatus } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/ApprovalCenter/ApprovalCenter.types.ts"
    },
    "MassActions.LinkButtonProps": {
      "name": "LinkButtonProps",
      "definition": "export type LinkButtonProps = ComponentProps<typeof LinkButton>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { LinkButtonProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/MassActions/types.ts"
    },
    "Table.LinkButtonProps": {
      "name": "LinkButtonProps",
      "definition": "export type LinkButtonProps = ComponentProps<typeof LinkButton>;",
      "internal": true,
      "importNotice": "Тип \"LinkButtonProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/widgets/control-block/control-block-button.types.tsx"
    },
    "ColumnDefault": {
      "name": "ColumnDefault",
      "definition": "export type ColumnDefault<TRow, TSummaryRow = unknown> = {\n  /** The name of the column. By default it will be displayed in the header cell */\n  readonly name: string | ReactElement;\n  /** A unique key to distinguish each column */\n  readonly key: string;\n  /** Column width. If not specified, it will be determined automatically based on grid width and specified widths of other columns */\n  readonly width?: Maybe<number | string>;\n  /** Minimum column width in px. */\n  readonly minWidth?: Maybe<number>;\n  /** Maximum column width in px. */\n  readonly maxWidth?: Maybe<number>;\n  readonly cellClass?: Maybe<string | ((row: TRow) => Maybe<string>)>;\n  readonly headerCellClass?: Maybe<string>;\n  readonly summaryCellClass?: Maybe<\n    string | ((row: TSummaryRow) => Maybe<string>)\n  >;\n  /** Render function used to render the content of the column's header cell */\n  readonly renderHeaderCell?: Maybe<\n    (props: RenderHeaderCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of cells */\n  readonly renderCell?: Maybe<\n    (props: RenderCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of summary cells */\n  readonly renderSummaryCell?: Maybe<\n    (props: RenderSummaryCellProps<TSummaryRow, TRow>) => ReactNode\n  >;\n  /** Render function used to render the content of group cells */\n  readonly renderGroupCell?: Maybe<\n    (props: RenderGroupCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Render function used to render the content of edit cells. When set, the column is automatically set to be editable */\n  readonly renderEditCell?: Maybe<\n    (props: RenderEditCellProps<TRow, TSummaryRow>) => ReactNode\n  >;\n  /** Enables cell editing. If set and no editor property specified, then a textInput will be used as the cell editor */\n  readonly editable?: Maybe<boolean | ((row: TRow) => boolean)>;\n  readonly colSpan?: Maybe<\n    (args: ColSpanArgs<TRow, TSummaryRow>) => Maybe<number>\n  >;\n  /** Determines whether column is frozen or not */\n  readonly frozen?: Maybe<boolean>;\n  /** Enable resizing of a column */\n  readonly resizable?: Maybe<boolean>;\n  /** Enable sorting of a column */\n  readonly sortable?: Maybe<boolean>;\n  /** Enable dragging of a column */\n  readonly draggable?: Maybe<boolean>;\n  /** Sets the column sort order to be descending instead of ascending the first time the column is sorted */\n  readonly sortDescendingFirst?: Maybe<boolean>;\n  readonly editorOptions?: Maybe<{\n    /**\n     * Render the cell content in addition to the edit cell.\n     * Enable this option when the editor is rendered outside the grid, like a modal for example.\n     * By default, the cell content is not rendered when the edit cell is open.\n     * @default false\n     */\n    readonly displayCellContent?: Maybe<boolean>;\n    /** @default true */\n    readonly commitOnOutsideClick?: Maybe<boolean>;\n  }>;\n};",
      "internal": true,
      "importNotice": "Тип \"ColumnDefault\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/types/data-grid.type.ts"
    },
    "Table.DefaultOmittedKeys": {
      "name": "DefaultOmittedKeys",
      "definition": "export type DefaultOmittedKeys =\n  | 'editable'\n  | 'sortable'\n  | 'sortDescendingFirst'\n  | 'renderGroupCell'\n  | 'renderEditCell'\n  | 'frozen'\n  | 'draggable';",
      "internal": true,
      "importNotice": "Тип \"DefaultOmittedKeys\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/types/data-grid.type.ts"
    },
    "TableCanvas.DefaultOmittedKeys": {
      "name": "DefaultOmittedKeys",
      "definition": "export type DefaultOmittedKeys = Extract<\n  keyof ColumnGlideInstance<ObjectForExtending, unknown, ObjectForExtending>,\n  | 'editable'\n  | 'frozen'\n  | 'isServiceColumn'\n  | 'isErrorCell'\n  | 'renderEditCell'\n  | 'renderCellPreview'\n  | 'renderCell'\n  | 'columnThemeOverride'\n  // Объединение ячеек тела задаётся только через tableConfig.mergeCells\n  // (mergeByCellValues / mergedCellsRegions). Колоночные colSpan/rowSpan убраны:\n  // они позиционные и небезопасны при реордере. Внутри (ColumnConfigInternal)\n  // остаются как труба, в которую mergeCells синтезирует объединения.\n  | 'colSpan'\n  | 'rowSpan'\n  // Выравнивание блока публично задаётся через mergedCellsAlign / mergeCells.align.\n  | 'spanAlign'\n>;",
      "internal": true,
      "importNotice": "Тип \"DefaultOmittedKeys\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/glide-type.ts"
    },
    "Table.HeaderContextValueTypeInstance": {
      "name": "HeaderContextValueTypeInstance",
      "definition": "export type HeaderContextValueTypeInstance<\n  FilterStateType extends Record<string | number, unknown>,\n> = {\n  filters: FilterStateType | undefined;\n  setFilters: React.Dispatch<React.SetStateAction<FilterStateType>> | undefined;\n  clearedFiltersValue: FilterStateType | undefined;\n  sortState: readonly SortColumn[] | undefined;\n  setSortState:\n    | React.Dispatch<React.SetStateAction<readonly SortColumn[]>>\n    | undefined;\n  sortIsVisible: boolean;\n  setSortIsVisible: React.Dispatch<React.SetStateAction<boolean>>;\n\n  rowSize: SIZE;\n  setRowSize: React.Dispatch<React.SetStateAction<SIZE>>;\n  onRowSizeChange?: (size: SIZE) => void;\n\n  isExpandedAllRows: boolean;\n  toggleExpandAllButton: () => void;\n  activeView: ActiveViewModsType;\n  setActiveView: React.Dispatch<React.SetStateAction<ActiveViewModsType>>;\n};",
      "internal": true,
      "importNotice": "Тип \"HeaderContextValueTypeInstance\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/contexts.tsx"
    },
    "TableCanvas.HeaderContextValueTypeInstance": {
      "name": "HeaderContextValueTypeInstance",
      "definition": "export type HeaderContextValueTypeInstance<\n  FilterStateType extends Record<string | number, unknown>,\n> = {\n  filters: FilterStateType | undefined;\n  setFilters: React.Dispatch<React.SetStateAction<FilterStateType>> | undefined;\n  clearedFiltersValue: FilterStateType | undefined;\n  sortState: readonly SortColumn[] | undefined;\n  setSortState:\n    | React.Dispatch<React.SetStateAction<readonly SortColumn[]>>\n    | undefined;\n  sortIsVisible: boolean;\n  setSortIsVisible: React.Dispatch<React.SetStateAction<boolean>>;\n\n  rowSize: SIZE;\n  setRowSize: React.Dispatch<React.SetStateAction<SIZE>>;\n  onRowSizeChange?: (size: SIZE) => void;\n\n  isExpandedAllRows: boolean;\n  toggleExpandAllButton: () => void;\n  activeView: ActiveViewModsType;\n  setActiveView: React.Dispatch<React.SetStateAction<ActiveViewModsType>>;\n};",
      "internal": true,
      "importNotice": "Тип \"HeaderContextValueTypeInstance\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/contexts.tsx"
    },
    "Table.FiltersVariables": {
      "name": "FiltersVariables",
      "definition": "export type FiltersVariables = {\n  filtersAreVisible: boolean;\n  toggleFiltersAreVisible: () => void;\n};",
      "internal": true,
      "importNotice": "Тип \"FiltersVariables\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-filtering/filtering.type.ts"
    },
    "TableCanvas.FiltersVariables": {
      "name": "FiltersVariables",
      "definition": "export type FiltersVariables = {\n  filtersAreVisible: boolean;\n  toggleFiltersAreVisible: () => void;\n};",
      "internal": true,
      "importNotice": "Тип \"FiltersVariables\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-filtering/filtering.type.ts"
    },
    "Table.CustomFormat": {
      "name": "CustomFormat",
      "definition": "export type CustomFormat = CommonFormat & {\n  customFormat: (value: string) => React.ReactNode;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { CustomFormat } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
    },
    "TableCanvas.CustomFormat": {
      "name": "CustomFormat",
      "definition": "export type CustomFormat = CommonFormat & {\n  customFormat: (value: string) => React.ReactNode;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CustomFormat } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "Table.NumberFormatOptions": {
      "name": "NumberFormatOptions",
      "definition": "export type NumberFormatOptions = CommonFormat & {\n  type: 'number';\n  /** Кастомный разделитель дробной части (по умолчанию ',') */\n  decimalSeparator?: string;\n  /** Кастомный разделитель тысяч (по умолчанию ' ') */\n  thousandSeparator?: string;\n  /** Минимальное число знаков после запятой (по умолчанию 0) */\n  minimumFractionDigits?: number;\n  /** Максимальное число знаков после запятой (по умолчанию 2) */\n  maximumFractionDigits?: number;\n  /** Включить/отключить группировку разрядов (по умолчанию true) */\n  useGrouping?: boolean;\n  /** Локаль для Intl.NumberFormat (по умолчанию 'ru-RU') */\n  locales?: string | string[];\n  alignContent?: 'right' | 'left' | 'center';\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { NumberFormatOptions } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
    },
    "TableCanvas.NumberFormatOptions": {
      "name": "NumberFormatOptions",
      "definition": "export type NumberFormatOptions = CommonFormat & {\n  type: 'number';\n  /** Кастомный разделитель дробной части (по умолчанию ',') */\n  decimalSeparator?: string;\n  /** Кастомный разделитель тысяч (по умолчанию ' ') */\n  thousandSeparator?: string;\n  /** Минимальное число знаков после запятой (по умолчанию 0) */\n  minimumFractionDigits?: number;\n  /** Максимальное число знаков после запятой (по умолчанию 2) */\n  maximumFractionDigits?: number;\n  /** Включить/отключить группировку разрядов (по умолчанию true) */\n  useGrouping?: boolean;\n  /** Локаль для Intl.NumberFormat (по умолчанию 'ru-RU') */\n  locales?: string | string[];\n  alignContent?: 'right' | 'left' | 'center';\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { NumberFormatOptions } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "RenderSubRowEditCell": {
      "name": "RenderSubRowEditCell",
      "definition": "export type RenderSubRowEditCell<SubRowType extends ObjectForExtending> = (\n  renderCellProps: RenderEditCellProps<SubRowType>,\n  lvl: number,\n) => ReactNode;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { RenderSubRowEditCell } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
    },
    "Table.RenderGroupCellProps": {
      "name": "RenderGroupCellProps",
      "definition": "export type RenderGroupCellProps<RowType, SummaryRowType = unknown> = {\n  column: CalculatedColumn<RowType, SummaryRowType>;\n  tabIndex: number;\n  // TODO isExpanded: boolean;\n  // TODO toggleGroup: () => void;\n} & GroupRow<RowType>;",
      "internal": true,
      "importNotice": "Тип \"RenderGroupCellProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-rows-grouping/types.ts"
    },
    "TableCanvas.RenderGroupCellProps": {
      "name": "RenderGroupCellProps",
      "definition": "export type RenderGroupCellProps<\n  RowType extends ObjectForExtending,\n  ColumnConfig extends LocalColumnInstance = LocalColumnInstance,\n> = {\n  column: ColumnConfig;\n  tabIndex: number;\n  theme?: Theme;\n  // TODO isExpanded: boolean;\n  // TODO toggleGroup: () => void;\n} & GroupRow<RowType>;",
      "internal": true,
      "importNotice": "Тип \"RenderGroupCellProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-rows-grouping/types.ts"
    },
    "CellHoverState": {
      "name": "CellHoverState",
      "definition": "export type CellHoverState = {\n  /** Равно true только для ячейки с данными, над которой сейчас находится курсор. */\n  cellHover: boolean;\n  /** Равно true для всех ячеек с данными в строке, над которой сейчас находится курсор. */\n  rowHover: boolean;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellHoverState } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "CellActiveState": {
      "name": "CellActiveState",
      "definition": "export type CellActiveState = {\n  /** Равно true, если текущая ячейка с данными входит в активную область выделения таблицы. */\n  cellActive: boolean;\n  /** Равно true, если строка текущей ячейки с данными содержит активную ячейку или активный диапазон. */\n  rowActive: boolean;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellActiveState } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "PreviewCellInfo": {
      "name": "PreviewCellInfo",
      "definition": "export type PreviewCellInfo<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = ObjectForExtending,\n> = Omit<PreviewCellInfoGlideInstance<R, SR, CustomCtxs>, 'column'> & {\n  column: ColumnConfig<R, SR, CustomCtxs>;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { PreviewCellInfo } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
    },
    "CellEditorTextAreaProps": {
      "name": "CellEditorTextAreaProps",
      "definition": "export type CellEditorTextAreaProps = Omit<\n  ComponentProps<typeof TextCellEntry>,\n  'highlight'\n> & {\n  autoFocusType?: 'autoFocus' | 'autoFocusAndSelect' | 'none';\n  paddingInline: number;\n  containerClassName?: string;\n} & CustomCellStyleProps;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellEditorTextAreaProps } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-edit/types.ts"
    },
    "CellEditorNumberFormatProps": {
      "name": "CellEditorNumberFormatProps",
      "definition": "export type CellEditorNumberFormatProps = Omit<\n  NumberFormatCompProps,\n  'view' | 'size'\n> &\n  CustomCellStyleNumberFormatProps;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellEditorNumberFormatProps } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-edit/types.ts"
    },
    "CellEditorComboboxProps": {
      "name": "CellEditorComboboxProps",
      "definition": "export type CellEditorComboboxProps<T extends ComboboxItemOption> =\n  ComboboxCompProps<T> &\n    CustomCellStyleProps & {\n      autoFocusType: 'autoFocus' | 'none';\n      paddingInline: number;\n    };",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellEditorComboboxProps } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-edit/types.ts"
    },
    "RenderRowCustomEditCell": {
      "name": "RenderRowCustomEditCell",
      "definition": "export type RenderRowCustomEditCell<\n  SubRowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = (\n  renderCellProps: EditingCellInfo<SubRowType, SummaryRowType, CustomCtxs>,\n  lvl: number,\n  disableLeftOffset: boolean | undefined,\n) => ReactNode;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { RenderRowCustomEditCell } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
    },
    "LocalColumnInstance": {
      "name": "LocalColumnInstance",
      "definition": "type LocalColumnInstance = Record<'key' | 'name' | 'width' | string, unknown>;",
      "internal": true,
      "importNotice": "Тип \"LocalColumnInstance\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-rows-grouping/types.ts"
    },
    "HeaderCellInfo": {
      "name": "HeaderCellInfo",
      "definition": "export type HeaderCellInfo<R extends ObjectForExtending, SR> = {\n  column: ColumnGlideLast<R, SR>;\n  drawArgs: DrawHeaderArgs;\n  ctxs: ObjectForExtending;\n  theme: Theme;\n};",
      "internal": true,
      "importNotice": "Тип \"HeaderCellInfo\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "SummaryCellInfo": {
      "name": "SummaryCellInfo",
      "definition": "export type SummaryCellInfo<R extends ObjectForExtending, SR> = {\n  row: SR;\n  column: ColumnGlideLast<R, SR>;\n  colInd: number;\n  rowInd: number;\n  ctxs: ObjectForExtending;\n  theme: Theme;\n};",
      "internal": true,
      "importNotice": "Тип \"SummaryCellInfo\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "CanvasNodeTooltipProps": {
      "name": "CanvasNodeTooltipProps",
      "definition": "export type CanvasNodeTooltipProps = Pick<\n  TooltipProps,\n  'placement' | 'view' | 'minWidth' | 'maxWidth'\n> & {\n  /** Сохранять переносы строк (\\n) в тексте тултипа через white-space: pre-line. @default false */\n  preserveLineBreaks?: boolean;\n  /**\n   * Сдвиг тултипа по X (px) относительно центра ноды. Нужен, когда видимая\n   * часть ноды смещена внутри неё (например, иконка прижата к краю кнопки).\n   * @default 0\n   */\n  offsetX?: number;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CanvasNodeTooltipProps } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/utils/portalHoverEvents.ts"
    },
    "SelectingContextType": {
      "name": "SelectingContextType",
      "definition": "export type SelectingContextType<\n  RowType extends ObjectForExtending = ObjectForExtending,\n  RowIdType extends RowIdTypeInstance = RowIdTypeInstance,\n> = {\n  rows: RowType[];\n  selectingRowConfig: SelectingRowConfig<RowType, RowIdType> & {\n    selectingRowsIsActive: boolean;\n  };\n  flattenedRowsArrAndMap: FlattenedRowsArrAndMap<RowType, RowIdType> | null;\n  selectedRows: ReadonlySet<string | number> | undefined;\n  setSelectedRows:\n    | React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>\n    | undefined;\n  rowKeyGetter: undefined | ((row: RowType) => RowIdType);\n  rowsGroupingIsActive: boolean;\n  isRowsGroupingLabelVisible: boolean;\n  setIsRowsGroupingLabelVisible: React.Dispatch<React.SetStateAction<boolean>>;\n  isRowsGroupingCounterVisible: boolean;\n  setIsRowsGroupingCounterVisible: React.Dispatch<\n    React.SetStateAction<boolean>\n  >;\n  isSelectingRowLabelVisible: boolean;\n  setIsSelectingRowLabelVisible: React.Dispatch<React.SetStateAction<boolean>>;\n  isSelectingRowCounterVisible: boolean;\n  setIsSelectingRowCounterVisible: React.Dispatch<\n    React.SetStateAction<boolean>\n  >;\n  controlBlock?: {\n    domMetadata?: DomMetadata;\n  };\n  sidebar?: {\n    domMetadata?: DomMetadata;\n  };\n};",
      "internal": true,
      "importNotice": "Тип \"SelectingContextType\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-select-row/selecting-contexts.tsx"
    },
    "ExpandedRowsContextV": {
      "name": "ExpandedRowsContextV",
      "definition": "export type ExpandedRowsContextV = Set<string | number>;",
      "internal": true,
      "importNotice": "Тип \"ExpandedRowsContextV\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/contexts.tsx"
    },
    "ExpandedRowsChangeContextV": {
      "name": "ExpandedRowsChangeContextV",
      "definition": "export type ExpandedRowsChangeContextV = React.Dispatch<\n  React.SetStateAction<ExpandedRowsContextV>\n>;",
      "internal": true,
      "importNotice": "Тип \"ExpandedRowsChangeContextV\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/contexts.tsx"
    },
    "HandleExpandDetail": {
      "name": "HandleExpandDetail",
      "definition": "export type HandleExpandDetail<RowType extends ObjectForExtending> = (\n  row: RowType,\n) => void;",
      "internal": true,
      "importNotice": "Тип \"HandleExpandDetail\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/feature-row-detail/types.ts"
    },
    "ThemeCustoms": {
      "name": "ThemeCustoms",
      "definition": "export type ThemeCustoms = ReturnType<typeof getCustomColors> & {\n  rowSize: SIZE;\n  activeSizes: GlideSizeConfig;\n};",
      "internal": true,
      "importNotice": "Тип \"ThemeCustoms\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/theming/custom-colors.ts"
    },
    "ThemeDynamicCustoms": {
      "name": "ThemeDynamicCustoms",
      "definition": "export type ThemeDynamicCustoms = {\n  rowSize: SIZE;\n  activeSizes: GlideSizeConfig;\n};",
      "internal": true,
      "importNotice": "Тип \"ThemeDynamicCustoms\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/theming/types.ts"
    },
    "ColumnOrColumnGroupGlideInstance": {
      "name": "ColumnOrColumnGroupGlideInstance",
      "definition": "export type ColumnOrColumnGroupGlideInstance<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> =\n  | ColumnGlideInstance<R, SR, CustomCtxs>\n  | ColumnGroupGlideInstance<R, SR, CustomCtxs>;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { ColumnOrColumnGroupGlideInstance } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "ColumnGlideGetCellContent": {
      "name": "ColumnGlideGetCellContent",
      "definition": "export type ColumnGlideGetCellContent<R extends ObjectForExtending, SR> = (\n  cellInfo: CellInfo<R, SR>\n) => CellContent;",
      "internal": true,
      "importNotice": "Тип \"ColumnGlideGetCellContent\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "EditingCellInfoGlide": {
      "name": "EditingCellInfoGlide",
      "definition": "export type EditingCellInfoGlide<\n  R extends ObjectForExtending,\n  SR = unknown\n> = Omit<CellInfo<R, SR>, 'hovered' | 'active'> & {\n  onRowChange: (row: R, commitChanges?: boolean) => void;\n  onClose: (commitChanges?: boolean, shouldFocusCell?: boolean) => void;\n};",
      "internal": true,
      "importNotice": "Тип \"EditingCellInfoGlide\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "ColSpan": {
      "name": "ColSpan",
      "definition": "export type ColSpan<R extends ObjectForExtending, SR> =\n  | number\n  | ((cellInfo: CellInfo<R, SR>) => number);",
      "internal": true,
      "importNotice": "Тип \"ColSpan\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "RowSpan": {
      "name": "RowSpan",
      "definition": "export type RowSpan<R extends ObjectForExtending, SR> = (\n  cellInfo: CellInfo<R, SR>\n) => readonly [number, number] | null;",
      "internal": true,
      "importNotice": "Тип \"RowSpan\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "TableCanvas.DomMetadata": {
      "name": "DomMetadata",
      "definition": "export type DomMetadata = {\n  /**\n   * CSS класс для стилизации и поиска элемента\n   *\n   * @example 'user-profile-card'\n   * @example 'onboarding-step-1'\n   */\n  className?: string;\n  /**\n   * Data-атрибуты для тестирования, аналитики и онбординга\n   *\n   * @example { 'data-testid': 'submit-button', 'data-analytics': 'click-event' }\n   */\n  dataAttributes?: DataAttributes;\n  /**\n   * Обработчик клика для аналитики и трекинга\n   *\n   * Вызывается вместе с основным обработчиком элемента (не заменяет его).\n   * Не вызывает stopPropagation — оригинальная логика кнопки сохраняется.\n   *\n   * @param e - MouseEvent (может быть undefined для элементов внутри Dropdown)\n   * @param detail - контекст действия: action, columnKey, size и др.\n   *\n   * @example onClick: (e, detail) => analytics.track(detail?.action, detail)\n   */\n  onClick?: (\n    e?: React.MouseEvent<HTMLElement>,\n    detail?: Record<string, unknown>,\n  ) => void;\n};",
      "internal": true,
      "importNotice": "Тип \"DomMetadata\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/additional.type.ts"
    },
    "Table.DomMetadata": {
      "name": "DomMetadata",
      "definition": "export type DomMetadata = {\n  /**\n   * CSS класс для стилизации и поиска элемента\n   *\n   * @example 'user-profile-card'\n   * @example 'onboarding-step-1'\n   */\n  className?: string;\n  /**\n   * Data-атрибуты для тестирования, аналитики и онбординга\n   *\n   * @example { 'data-testid': 'submit-button', 'data-analytics': 'click-event' }\n   */\n  dataAttributes?: DataAttributes;\n  /**\n   * Обработчик клика для аналитики и трекинга\n   *\n   * Вызывается вместе с основным обработчиком элемента (не заменяет его).\n   * Не вызывает stopPropagation — оригинальная логика кнопки сохраняется.\n   *\n   * @param e - MouseEvent (может быть undefined для элементов внутри Dropdown)\n   * @param detail - контекст действия: action, columnKey, size и др.\n   *\n   * @example onClick: (e, detail) => analytics.track(detail?.action, detail)\n   */\n  onClick?: (\n    e?: React.MouseEvent<HTMLElement>,\n    detail?: Record<string, unknown>,\n  ) => void;\n};",
      "internal": true,
      "importNotice": "Тип \"DomMetadata\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/types/additional.type.ts"
    },
    "TRules": {
      "name": "TRules",
      "definition": "type TRules = {\n  rules: Omit<\n    RegisterOptions<FieldValues, Path<FieldValues>>,\n    'disabled' | 'setValueAs' | 'valueAsNumber' | 'valueAsDate'\n  >;\n};",
      "internal": true,
      "importNotice": "Тип \"TRules\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/utils/types.ts"
    },
    "TOptions": {
      "name": "TOptions",
      "definition": "type TOptions = {\n  remOptions: Pick<\n    RegisterOptions<FieldValues, Path<FieldValues>>,\n    'disabled' | 'setValueAs' | 'valueAsNumber' | 'valueAsDate'\n  >;\n};",
      "internal": true,
      "importNotice": "Тип \"TOptions\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/utils/types.ts"
    },
    "BoxCSSProperties": {
      "name": "BoxCSSProperties",
      "definition": "export type BoxCSSProperties = Pick<\n  CSSProperties,\n  | 'width'\n  | 'maxWidth'\n  | 'minWidth'\n  | 'height'\n  | 'maxHeight'\n  | 'minHeight'\n  | 'margin'\n  | 'marginLeft'\n  | 'marginRight'\n  | 'marginTop'\n  | 'marginBottom'\n  | 'padding'\n  | 'paddingLeft'\n  | 'paddingRight'\n  | 'paddingTop'\n  | 'paddingBottom'\n  | 'display'\n  | 'flexDirection'\n  | 'justifyContent'\n  | 'justifyItems'\n  | 'justifySelf'\n  | 'flexGrow'\n  | 'flexWrap'\n  | 'flexShrink'\n  | 'gap'\n  | 'position'\n  | 'top'\n  | 'left'\n  | 'right'\n  | 'bottom'\n  | 'zIndex'\n  | 'boxSizing'\n  | 'overflow'\n  | 'cursor'\n  | 'background'\n  | 'backgroundColor'\n  | 'opacity'\n  | 'border'\n  | 'borderWidth'\n  | 'borderColor'\n  | 'borderStyle'\n  | 'borderRadius'\n>;",
      "internal": true,
      "importNotice": "Тип \"BoxCSSProperties\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Box/typeKeys.ts"
    },
    "BadgeCompProps": {
      "name": "BadgeCompProps",
      "definition": "export type BadgeCompProps = ComponentProps<typeof Badge>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { BadgeCompProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Badge/index.ts"
    },
    "EmptyStateVariant": {
      "name": "EmptyStateVariant",
      "definition": "export type EmptyStateVariant =\n  | 'loading'\n  | 'life-circle'\n  | 'need-access'\n  | 'no-access'\n  | 'no-content'\n  | 'not-found'\n  /** @deprecated Используйте `'not-found'` */\n  | 'not-result'\n  | 'success';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { EmptyStateVariant } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/EmptyState/EmptyState.types.ts"
    },
    "ErrorPageVariant": {
      "name": "ErrorPageVariant",
      "definition": "export type ErrorPageVariant =\n  | '400'\n  | '401'\n  | '403'\n  | '404'\n  | '409'\n  | '500'\n  | '502'\n  | '503'\n  | 'unidentified';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ErrorPageVariant } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/EmptyState/EmptyState.types.ts"
    },
    "ToggleButtonBaseProps": {
      "name": "ToggleButtonBaseProps",
      "definition": "type ToggleButtonBaseProps = ComponentProps<typeof IconButton>;",
      "internal": true,
      "importNotice": "Тип \"ToggleButtonBaseProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/LeftPanel/LeftPanel.types.ts"
    },
    "PopoverDFSize": {
      "name": "PopoverDFSize",
      "definition": "export type PopoverDFSize = 's' | 'm';",
      "internal": true,
      "importNotice": "Тип \"PopoverDFSize\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/PopoverDF/types.ts"
    },
    "SplitViewSlotSizesProps": {
      "name": "SplitViewSlotSizesProps",
      "definition": "export type SplitViewSlotSizesProps = {\n  /**\n   * Размер Avatar в кастомном контенте sidebar\n   */\n  avatarSize: 'l' | 'm';\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { SplitViewSlotSizesProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/SplitView/SplitView.type.ts"
    },
    "Table.HighlightActiveType": {
      "name": "HighlightActiveType",
      "definition": "export type HighlightActiveType = 'cell' | 'row' | 'disabled';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { HighlightActiveType } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "TableGlide.HighlightActiveType": {
      "name": "HighlightActiveType",
      "definition": "export type HighlightActiveType = 'cell' | 'row' | 'range-cell' | 'disabled';",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { HighlightActiveType } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "Table.RowSize": {
      "name": "RowSize",
      "definition": "export type RowSize = {\n  /**\n   * Показывать кнопку в блоке управления\n   */\n  showInControl: boolean;\n  /**\n   * Значение по умолчанию\n   */\n  default?: SIZE;\n  /**\n   * Список доступных значений размера\n   */\n  available?: SIZE[];\n  /**\n   * Обработчик изменения rowSize\n   * @param size\n   * @returns\n   */\n  onRowSizeChange?: (size: SIZE) => void;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { RowSize } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "TableCanvas.RowSize": {
      "name": "RowSize",
      "definition": "export type RowSize = {\n  /**\n   * Показывать кнопку в блоке управления\n   */\n  showInControl: boolean;\n  /**\n   * Значение по умолчанию\n   */\n  default?: SIZE;\n  /**\n   * Список доступных значений размера\n   */\n  available?: SIZE[];\n  /**\n   * Обработчик изменения rowSize\n   * @param size\n   * @returns\n   */\n  onRowSizeChange?: (size: SIZE) => void;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { RowSize } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "Table.Maybe": {
      "name": "Maybe",
      "definition": "export type Maybe<T> = T | undefined | null;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Maybe } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/utils.type.ts"
    },
    "TableCanvas.Maybe": {
      "name": "Maybe",
      "definition": "export type Maybe<T> = T | undefined | null;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { Maybe } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/utils.type.ts"
    },
    "Table.RowHeightFunc": {
      "name": "RowHeightFunc",
      "definition": "export type RowHeightFunc<RowType> = (\n  row: RowType,\n  currentRowSize: { rowSizeName: SIZE; rowSizeValue: number },\n) => number;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { RowHeightFunc } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "TableCanvas.RowHeightFunc": {
      "name": "RowHeightFunc",
      "definition": "export type RowHeightFunc<RowType> = (\n  row: RowType,\n  currentRowSize: { rowSizeName: SIZE; rowSizeValue: number },\n  rowIndex: number,\n) => number;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { RowHeightFunc } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "Table.View": {
      "name": "View",
      "definition": "export type View = ViewMods['rows' | 'bothTypes' | 'cards'];",
      "importPath": "@daisforge/ui",
      "importStatement": "import { View } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "TableCanvas.View": {
      "name": "View",
      "definition": "export type View = ViewMods['rows' | 'bothTypes' | 'cards'];",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { View } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "Table.FilteringConfig": {
      "name": "FilteringConfig",
      "definition": "export type FilteringConfig<T> = {\n  state: [T, React.Dispatch<React.SetStateAction<T>>];\n  /**\n   * @deprecated Использовать filtersInfo\n   *\n   * clearedValue - состояние фильтров после очистки. Используется для сравнения:\n   * Например, был ли фильтр конкретной колонки изменен рассчитывается посредством сравнения текущего значения фильтра и значения фильтра в clearedValue.\n   * Если они равны, то фильтр считается не измененным.\n   */\n  clearedValue?: T;\n  /**\n   * Информация о фильтрах для каждой колонки.\n   * Используется для:\n   * 1. Хранения меток (label) фильтров для отображения в UI\n   * 2. Хранения значений по умолчанию (clearedValue) для каждого фильтра\n   * 3. Определения, был ли фильтр изменен (сравнение текущего значения с clearedValue)\n   */\n  filtersInfo?: Record<\n    keyof T,\n    {\n      label: string;\n      clearedValue: T[keyof T];\n    }\n  >;\n  /**\n   * manualFiltering - пропс, активирующий ручную-кастомную (или на стороне бэка) фильтрацию.\n   * @remarks\n   * Для автоматической фильтрации (когда не используется manualFiltering в tableConfig):\n   * - Для всех типов фильтров обязательно должен быть указан `valueInRow`\n   * - Для component: 'select' дополнительно должен быть указан `filteringType`\n   * - Для component: 'input' с кастомным фильтром (когда filter - функция)\n   *   функция фильтрации должна быть передана явно\n   *\n   * Если используется manualFiltering, эти параметры не обязательны,\n   * так как вся логика фильтрации реализуется извне.\n   */\n  manualFiltering?: boolean;\n  /**\n   * Конфигурация для отображения фильтров в правом сайдбаре.\n   *\n   * Позволяет:\n   * 1. Добавлять глобальные фильтры (не привязанные к конкретной колонке)\n   * 2. Управлять порядком отображения фильтров\n   * 3. Переопределять рендер и заголовки колоночных фильтров\n   *\n   * Логика работы:\n   * - По умолчанию в сайдбаре отображаются все колоночные фильтры (из columnConfig)\n   * - Ключом фильтра считается `key` колонки, если его нет, то пытаемся взять `keyInFilterState` (если указан), иначе это не будет работать\n   * - Заголовком фильтра по умолчанию является `name` колонки или ключ фильтра (name || key)\n   * - Глобальные фильтры добавляются через `items` с уникальными ключами\n   *\n   * Особенности:\n   * 1. Порядок отображения:\n   *    - Сначала фильтры из `order` (в указанной последовательности)\n   *    - Затем остальные колоночные фильтры (в порядке columnConfig)\n   *    - В конце - глобальные фильтры (в алфавитном порядке ключей)\n   *\n   * 2. Переопределение колоночных фильтров:\n   *    - Чтобы изменить заголовок: укажите ключ колонки в `items` с новым `label`\n   *    - Чтобы заменить рендер: укажите ключ колонки с `customRenderFn`\n   *    - Оригинальный фильтр из колонки будет проигнорирован\n   *\n   * 3. Глобальные фильтры:\n   *    - Ключ не должен совпадать с ключами колонок\n   *    - Обязательно указать `label` и `customRenderFn`\n   *    - Отображаются после всех колоночных фильтров, если не переопределены в order\n   *\n   * @example\n   * // Добавление глобального фильтра и изменение порядка\n   * sidebarConfig: {\n   *   order: ['status', 'tasks', 'type'], // Сначала статус, затем глобальный поиск\n   *   items: {\n   *     tasks: { // Уникальный ключ\n   *       label: 'Поиск по всем полям',\n   *       customRenderFn: () => <TaskComponent />\n   *     },\n   *     status: { // Переопределение колоночного фильтра\n   *       label: 'Статус заявки', // Новый заголовок\n   *       customRenderFn: () => <CustomStatusFilter /> // Кастомный рендер\n   *     }\n   *     type: { // Переопределение только Label колоночного фильтра\n   *       label: 'Тип', // Новый заголовок\n   *     }\n   *   }\n   * }\n   */\n  sidebarConfig?: {\n    /**\n     * Определяет порядок отображения фильтров.\n     * - Указываются ключи фильтров (колоночных или глобальных)\n     * - Не указанные в order фильтры отображаются после\n     * - Если order пуст, сохраняется порядок: глобальные фильтры + columnConfig фильтры в конце\n     */\n    order?: string[];\n    /**\n     * Конфигурация фильтров для сайдбара.\n     * Ключом может быть:\n     * - Ключ колонки (для переопределения колоночного фильтра)\n     * - Уникальный ключ (для добавления глобального фильтра)\n     */\n    items: Partial<\n      Record<\n        keyof T,\n        {\n          /** Заголовок фильтра (обязателен для глобальных фильтров), можно использовать для переопределения для локальных фильтров */\n          label: string;\n          /**\n           * Функция рендера компонента фильтра.\n           * Для колоночных фильтров переопределяет оригинальный рендер.\n           * Для глобальных фильтров обязательна.\n           */\n          customRenderFn?: (\n            filters: T,\n            setFilters: React.Dispatch<React.SetStateAction<T>>,\n          ) => React.ReactNode;\n        }\n      >\n    >;\n  };\n  /**\n   * Callback для кастомизации стилей чипсов (фильтров) в списке\n   *\n   * @param {ItemOrGroup} itemOrGroup - Текущий элемент или группа фильтров\n   * @param {Item | undefined} item - Конкретный элемент фильтра (если есть)\n   * @returns {CSSObject} Объект стилей, который будет применен к чипсу\n   *\n   * @description\n   * Позволяет динамически задавать стили для каждого чипса в зависимости от его типа и содержимого.\n   * Вызывается для каждого отображаемого чипса (как для отдельных элементов, так и для элементов внутри групп).\n   *\n   * @example\n   * // Пример 1: Стилизация чипсов по типу\n   * chipStyle: (itemOrGroup, item) => {\n   *   if (isGroup(itemOrGroup)) {\n   *     return { backgroundColor: '#f0f0f0' };\n   *   }\n   *   return { backgroundColor: '#e0e0e0' };\n   * }\n   *\n   * @example\n   * // Пример 2: Стилизация по значению фильтра\n   * chipStyle: (itemOrGroup, item) => {\n   *   if (item?.label === 'Высокий приоритет') {\n   *     return {\n   *       backgroundColor: '#ffebee',\n   *       color: '#d32f2f'\n   *     };\n   *   }\n   *   return {};\n   * }\n   *\n   * @example\n   * // Пример 3: Разные стили для элементов в группе и одиночных\n   * chipStyle: (itemOrGroup, item) => {…",
      "importPath": "@daisforge/ui",
      "importStatement": "import { FilteringConfig } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "TableCanvas.FilteringConfig": {
      "name": "FilteringConfig",
      "definition": "export type FilteringConfig<T> = {\n  state: [T, React.Dispatch<React.SetStateAction<T>>];\n  /**\n   * @deprecated Использовать filtersInfo\n   *\n   * clearedValue - состояние фильтров после очистки. Используется для сравнения:\n   * Например, был ли фильтр конкретной колонки изменен рассчитывается посредством сравнения текущего значения фильтра и значения фильтра в clearedValue.\n   * Если они равны, то фильтр считается не измененным.\n   */\n  clearedValue?: T;\n  /**\n   * Информация о фильтрах для каждой колонки.\n   * Используется для:\n   * 1. Хранения меток (label) фильтров для отображения в UI\n   * 2. Хранения значений по умолчанию (clearedValue) для каждого фильтра\n   * 3. Определения, был ли фильтр изменен (сравнение текущего значения с clearedValue)\n   */\n  filtersInfo?: Record<\n    keyof T,\n    {\n      label: string;\n      clearedValue: T[keyof T];\n    }\n  >;\n  /**\n   * manualFiltering - пропс, активирующий ручную-кастомную (или на стороне бэка) фильтрацию.\n   * @remarks\n   * Для автоматической фильтрации (когда не используется manualFiltering в tableConfig):\n   * - Для всех типов фильтров обязательно должен быть указан `valueInRow`\n   * - Для component: 'select' дополнительно должен быть указан `filteringType`\n   * - Для component: 'input' с кастомным фильтром (когда filter - функция)\n   *   функция фильтрации должна быть передана явно\n   *\n   * Если используется manualFiltering, эти параметры не обязательны,\n   * так как вся логика фильтрации реализуется извне.\n   */\n  manualFiltering?: boolean;\n  /**\n   * Конфигурация для отображения фильтров в правом сайдбаре.\n   *\n   * Позволяет:\n   * 1. Добавлять глобальные фильтры (не привязанные к конкретной колонке)\n   * 2. Управлять порядком отображения фильтров\n   * 3. Переопределять рендер и заголовки колоночных фильтров\n   *\n   * Логика работы:\n   * - По умолчанию в сайдбаре отображаются все колоночные фильтры (из columnConfig)\n   * - Ключом фильтра считается `key` колонки, если его нет, то пытаемся взять `keyInFilterState` (если указан), иначе это не будет работать\n   * - Заголовком фильтра по умолчанию является `name` колонки или ключ фильтра (name || key)\n   * - Глобальные фильтры добавляются через `items` с уникальными ключами\n   *\n   * Особенности:\n   * 1. Порядок отображения:\n   *    - Сначала фильтры из `order` (в указанной последовательности)\n   *    - Затем остальные колоночные фильтры (в порядке columnConfig)\n   *    - В конце - глобальные фильтры (в алфавитном порядке ключей)\n   *\n   * 2. Переопределение колоночных фильтров:\n   *    - Чтобы изменить заголовок: укажите ключ колонки в `items` с новым `label`\n   *    - Чтобы заменить рендер: укажите ключ колонки с `customRenderFn`\n   *    - Оригинальный фильтр из колонки будет проигнорирован\n   *\n   * 3. Глобальные фильтры:\n   *    - Ключ не должен совпадать с ключами колонок\n   *    - Обязательно указать `label` и `customRenderFn`\n   *    - Отображаются после всех колоночных фильтров, если не переопределены в order\n   *\n   * @example\n   * // Добавление глобального фильтра и изменение порядка\n   * sidebarConfig: {\n   *   order: ['status', 'tasks', 'type'], // Сначала статус, затем глобальный поиск\n   *   items: {\n   *     tasks: { // Уникальный ключ\n   *       label: 'Поиск по всем полям',\n   *       customRenderFn: () => <TaskComponent />\n   *     },\n   *     status: { // Переопределение колоночного фильтра\n   *       label: 'Статус заявки', // Новый заголовок\n   *       customRenderFn: () => <CustomStatusFilter /> // Кастомный рендер\n   *     }\n   *     type: { // Переопределение только Label колоночного фильтра\n   *       label: 'Тип', // Новый заголовок\n   *     }\n   *   }\n   * }\n   */\n  sidebarConfig?: {\n    /**\n     * Определяет порядок отображения фильтров.\n     * - Указываются ключи фильтров (колоночных или глобальных)\n     * - Не указанные в order фильтры отображаются после\n     * - Если order пуст, сохраняется порядок: глобальные фильтры + columnConfig фильтры в конце\n     */\n    order?: string[];\n    /**\n     * Конфигурация фильтров для сайдбара.\n     * Ключом может быть:\n     * - Ключ колонки (для переопределения колоночного фильтра)\n     * - Уникальный ключ (для добавления глобального фильтра)\n     */\n    items: Partial<\n      Record<\n        keyof T,\n        {\n          /** Заголовок фильтра (обязателен для глобальных фильтров), можно использовать для переопределения для локальных фильтров */\n          label: string;\n          /**\n           * Функция рендера компонента фильтра.\n           * Для колоночных фильтров переопределяет оригинальный рендер.\n           * Для глобальных фильтров обязательна.\n           */\n          customRenderFn?: (\n            filters: T,\n            setFilters: React.Dispatch<React.SetStateAction<T>>,\n          ) => React.ReactNode;\n        }\n      >\n    >;\n  };\n  /**\n   * Callback для кастомизации стилей чипсов (фильтров) в списке\n   *\n   * @param {ItemOrGroup} itemOrGroup - Текущий элемент или группа фильтров\n   * @param {Item | undefined} item - Конкретный элемент фильтра (если есть)\n   * @returns {CSSObject} Объект стилей, который будет применен к чипсу\n   *\n   * @description\n   * Позволяет динамически задавать стили для каждого чипса в зависимости от его типа и содержимого.\n   * Вызывается для каждого отображаемого чипса (как для отдельных элементов, так и для элементов внутри групп).\n   *\n   * @example\n   * // Пример 1: Стилизация чипсов по типу\n   * chipStyle: (itemOrGroup, item) => {\n   *   if (isGroup(itemOrGroup)) {\n   *     return { backgroundColor: '#f0f0f0' };\n   *   }\n   *   return { backgroundColor: '#e0e0e0' };\n   * }\n   *\n   * @example\n   * // Пример 2: Стилизация по значению фильтра\n   * chipStyle: (itemOrGroup, item) => {\n   *   if (item?.label === 'Высокий приоритет') {\n   *     return {\n   *       backgroundColor: '#ffebee',\n   *       color: '#d32f2f'\n   *     };\n   *   }\n   *   return {};\n   * }\n   *\n   * @example\n   * // Пример 3: Разные стили для элементов в группе и одиночных\n   * chipStyle: (itemOrGroup, item) => {…",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { FilteringConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "Table.SelectingRowConfig": {
      "name": "SelectingRowConfig",
      "definition": "export type SelectingRowConfig<\n  RowType,\n  RowIdType extends string | number = string | number,\n> = {\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n   */\n  showDefault?: boolean;\n  /**\n   * showState - состояние, отвечающее за то, видны ли чекбоксы.\n   */\n  showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n   */\n  showInControl?: boolean;\n  /**\n   * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n   */\n  selectingRules?: {\n    /**\n     * изменять ли скрытые строки при клике на чекбокс-ы родительских строк\n     * @default true\n     */\n    // changeableOfRowWithoutCheckbox?: boolean;\n    /**\n     * изменять ли задизейбленные строки при клике на чекбокс-ы родительских строк\n     * @default true\n     */\n    // changeableDisabledRow?: boolean;\n    /**\n     * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n     */\n    levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n  };\n  disableSummaryCheckboxInHeader?: boolean;\n  hideSummaryCheckboxInHeader?: boolean;\n  /**\n   * hideSummaryCheckbox - в островке  массовых действий\n   */\n  hideSummaryCheckbox?: boolean;\n  /**\n   * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n   */\n  summaryChecked?: {\n    checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n    indeterminate:\n      | boolean\n      | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n    getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n    onChange: SummaryCheckedFunc<\n      RowType,\n      void,\n      {\n        checkedAll: boolean;\n        clearButtonClicked?: boolean;\n        setSelectedRowsIds: React.Dispatch<\n          React.SetStateAction<ReadonlySet<string | number>>\n        >;\n      }\n    >;\n  };\n\n  /**\n   * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n   */\n  summaryCheckedUncontrolled?: {\n    onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n  };\n\n  /**\n   * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n   */\n  rowShowCheckbox?: RowShowCheckbox<RowType>;\n  /**\n   * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n   */\n  rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n\n  /**\n   * Функция для переопределения checked, indeterminate для каждой строки.\n   * Что будет возвращено функцией в объекте, то будет переопределено.\n   */\n  rowGetStates?: (\n    p: RowGetStatesProps<RowType, RowIdType>,\n  ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n\n  groupedRow?: {\n    /**\n     * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n     * Что будет возвращено функцией в объекте, то будет переопределено.\n     */\n    getStates: (p: {\n      checkedCalculated: boolean;\n      indeterminateCalculated: boolean;\n      row: GroupRow<RowType>;\n      selectedRows: ReadonlySet<string | number>;\n      selectedChildCount: number;\n      childCount: number;\n    }) => {\n      checked?: boolean | null;\n      indeterminate?: boolean | null;\n      showCheckbox?: boolean | null;\n      checkboxDisabled?: boolean | null;\n    } | null;\n    onChange?: (p: {\n      row: GroupRow<RowType>;\n\n      setSelectedRows: React.Dispatch<\n        React.SetStateAction<ReadonlySet<string | number>>\n      >;\n      checked: boolean;\n      indeterminate: boolean;\n      checkboxDisabled: boolean;\n      showCheckbox: boolean;\n      defaultSetter: () => void;\n    }) => void;\n  };\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { SelectingRowConfig } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "TableCanvas.SelectingRowConfig": {
      "name": "SelectingRowConfig",
      "definition": "export type SelectingRowConfig<RowType, RowIdType extends string | number> = {\n  /**\n   * showDefault - состояние, отвечающее за то, видно ли по дефолту чекбоксы.\n   */\n  showDefault?: boolean;\n  /**\n   * showState - состояние, отвечающее за то, видны ли чекбоксы.\n   */\n  showState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * showInControl - состояние, отвечающее за то, добавлять ли выбор строк как фичу, которую можно скрывать и раскрывать в правой части контролблока.\n   */\n  showInControl?: boolean;\n  /**\n   * selectingRules - пропс, отвечающий за кастомизацию логики выбора строк.\n   */\n  selectingRules?: {\n    // TODO доработать логику\n    // changeableOfRowWithoutCheckbox?: boolean;\n    // changeableDisabledRow?: boolean;\n    /**\n     * levels - логика активации чекбоксов у строк с определенным уровнем вложенности.\n     */\n    levels?: number | 'all' | number[] | ((lvl: number) => boolean);\n  };\n  disableSummaryCheckboxInHeader?: boolean;\n  hideSummaryCheckboxInHeader?: boolean;\n  /**\n   * hideSummaryCheckbox - в островке  массовых действий\n   */\n  hideSummaryCheckbox?: boolean;\n  /**\n   * summaryChecked - пропс, отвечающий за логику состояния checked у итогового чекбокса в левой части контролблока.\n   */\n  summaryChecked?: {\n    checked: boolean | SummaryCheckedFunc<RowType, boolean>;\n    indeterminate:\n      | boolean\n      | SummaryCheckedFunc<RowType, boolean, { checkedAll: boolean }>;\n    getCountOfChecked: SummaryCheckedFunc<RowType, number>;\n    onChange: SummaryCheckedFunc<\n      RowType,\n      void,\n      {\n        checkedAll: boolean;\n        clearButtonClicked?: boolean;\n        setSelectedRowsIds: React.Dispatch<\n          React.SetStateAction<ReadonlySet<string | number>>\n        >;\n      }\n    >;\n  };\n\n  /**\n   * summaryCheckedUncontrolled - пропс отвечающий за колбеки в неконтролируемом режиме\n   */\n  summaryCheckedUncontrolled?: {\n    onChange: (event: ChangeEvent<HTMLInputElement>) => void;\n  };\n\n  /**\n   * rowShowCheckbox - пропс, отвечающий за то, будет ли у конкретной строки отрендерен чекбокс.\n   */\n  rowShowCheckbox?: RowShowCheckbox<RowType>;\n  /**\n   * rowCheckboxDisabled - пропс, отвечающий за то, будет ли у конкретной строки чекбокс задизейблен.\n   */\n  rowCheckboxDisabled?: RowCheckboxDisabled<RowType>;\n  /**\n   * Функция для переопределения checked, indeterminate для каждой строки.\n   * Что будет возвращено функцией в объекте, то будет переопределено.\n   */\n  rowGetStates?: (\n    p: RowGetStatesProps<RowType, RowIdType>,\n  ) => RowGetStatesReturnType<RowType, RowIdType> | null;\n  groupedRow?: {\n    /**\n     * Функция для переопределения checked, indeterminate, showCheckbox, checkboxDisabled для группированных строк.\n     * Что будет возвращено функцией в объекте, то будет переопределено.\n     */\n    getStates: (p: {\n      checkedCalculated: boolean;\n      indeterminateCalculated: boolean;\n      row: GroupRow<RowType>;\n      selectedRows: ReadonlySet<string | number>;\n      selectedChildCount: number;\n      childCount: number;\n    }) => {\n      checked?: boolean | null;\n      indeterminate?: boolean | null;\n      showCheckbox?: boolean | null;\n      checkboxDisabled?: boolean | null;\n    } | null;\n    onChange?: (p: {\n      row: GroupRow<RowType>;\n\n      setSelectedRows: React.Dispatch<\n        React.SetStateAction<ReadonlySet<string | number>>\n      >;\n      checked: boolean;\n      indeterminate: boolean;\n      checkboxDisabled: boolean;\n      showCheckbox: boolean;\n      defaultSetter: () => void;\n    }) => void;\n  };\n};",
      "internal": true,
      "importNotice": "Тип \"SelectingRowConfig\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-select-row/types.ts"
    },
    "Table.EditingConfig": {
      "name": "EditingConfig",
      "definition": "export type EditingConfig<RowType, RowIdType, SummaryRowType> = {\n  /**\n   * Функция обработки изменений в редактируемой строке\n   */\n  onRowsChange: Maybe<\n    (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n  >;\n  /**\n   * свойство, необходимое для корректного изменения дочерних строк.\n   * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n   *\n   * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n   * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n   *\n   * @example \"child\" или \"uvh367.children\"\n   */\n  subRowsKey?: string;\n  /**\n   * Функция определения уникального id строки\n   * @param row\n   * @returns\n   */\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * Функция определения возможности редактирования строки\n   * @param row\n   * @returns\n   */\n  rowEditable?: (row: RowType) => boolean;\n  /**\n   * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n   * @default false\n   */\n  defaultEnabled?: boolean;\n  /**\n   * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n   * По умолчанию, управление происходит в компоненте.\n   * Приоритетнее, чем defaultEnabled.\n   *\n   * @type boolean - если НЕ нужно переключение в самой таблице\n   * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n   *\n   */\n  enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n   * @default true\n   */\n  showToggleEnabledButton?: boolean;\n  /**\n   * Функция, вызывающаяся при включении/выключении фичи\n   * @param editingIsActive\n   * @returns\n   */\n  onToggleEnableEditing?: (editingIsActive: boolean) => void;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { EditingConfig } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "TableCanvas.EditingConfig": {
      "name": "EditingConfig",
      "definition": "export type EditingConfig<\n  RowType extends ObjectForExtending,\n  RowIdType,\n  SummaryRowType,\n> = {\n  /**\n   * Функция обработки изменений в редактируемой строке\n   */\n  onRowsChange: Maybe<\n    (rows: RowType[], data: RowsChangeData<RowType, SummaryRowType>) => void\n  >;\n  /**\n   * свойство, необходимое для корректного изменения дочерних строк.\n   * Данное свойство обязательно, если ваши дочерние строки установлены не под ключом \"subRows\" внутри строки.\n   *\n   * Как дочерние строки можно указывать свойство, которые вложено в другое свойство.\n   * В таком случае \".\" будет знаком для обозначения сл. уровня вложенности.\n   *\n   * @example \"child\" или \"uvh367.children\"\n   */\n  subRowsKey?: string;\n  /**\n   * Глубокое копирование строк перед применением правки в режиме редактирования.\n   *\n   * Включите, если строки, передаваемые в таблицу, иммутабельны/заморожены\n   * (напр. стейт под управлением Redux Toolkit или Immer — они вызывают\n   * Object.freeze в dev). При редактировании дочерней строки таблица записывает\n   * изменение ВНУТРЬ объекта родителя; на замороженном объекте это падает с\n   * `TypeError: Cannot assign to read only property`.\n   *\n   * Когда флаг включён, таблица сама делает structuredClone редактируемой строки\n   * перед записью — ваш иммутабельный стейт не мутируется, и редактирование\n   * дочерних строк работает без действий с вашей стороны.\n   *\n   * ⚠️ Данные строки должны быть сериализуемыми. Где доступен structuredClone —\n   * Date/Map/Set и вложенные структуры копируются корректно; на старых средах\n   * без structuredClone используется JSON-фоллбэк (теряет Date/Map/Set, undefined\n   * и функции). Не включайте без необходимости — глубокое копирование добавляет\n   * накладные расходы.\n   *\n   * @default false\n   */\n  deepCloneRows?: boolean;\n  /**\n   * Функция определения уникального id строки\n   * @param row\n   * @returns\n   */\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * Функция определения возможности редактирования строки\n   * @param row\n   * @returns\n   */\n  rowEditable?: (row: RowType) => boolean;\n  /**\n   * defaultEnabled - пропс, отвечающий за то, будет ли активен режим редактирования или нет. По умолчанию - не активно.\n   * @default false\n   */\n  defaultEnabled?: boolean;\n  /**\n   * enabled - необходим для управления режимом редактирования снаружи компонента Таблицы.\n   * По умолчанию, управление происходит в компоненте.\n   * Приоритетнее, чем defaultEnabled.\n   *\n   * @type boolean - если НЕ нужно переключение в самой таблице\n   * @type [boolean, React.Dispatch<React.SetStateAction<boolean>>] - если нужно переключение в самой таблице\n   *\n   */\n  enabled?: boolean | [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * Cостояние скрытия/раскрытия кнопки включения/выключения фичи\n   * @default true\n   */\n  showButtons?: boolean;\n  /**\n   * Функция, вызывающаяся при включении фичи.\n   * @param enableEditorMode - функция включающая режим редактирования\n   */\n  onEnableEditing?: (enableEditorMode: () => void) => void;\n  /**\n   * Функция, вызывающаяся при сохранении отредактированного.\n   * @param disableEditorMode - функция выключающая режим редактирования\n   */\n  onSave?: (disableEditorMode: () => void) => void;\n  /**\n   * Функция, вызывающаяся при отмене отредактированного.\n   * @param disableEditorMode - функция выключающая режим редактирования\n   */\n  onCancel?: (disableEditorMode: () => void) => void;\n  /** Пропсы кнопок в controlBlock. */\n  buttons?: {\n    save?: EditingButtonProps;\n    cancel?: EditingButtonProps;\n    edit?: EditingButtonProps;\n  };\n  /**\n   * Кастомный слот, отображаемый левее кнопок «Отменить» / «Сохранить».\n   * Виден только когда режим редактирования активен (editMode = true).\n   * Зона ответственности разработчика — размерная сетка controlBlock не влияет на этот слот.\n   */\n  editModeLeftSlot?: React.ReactNode;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: {\n    enableButton?: DomMetadata;\n    saveButton?: DomMetadata;\n    cancelButton?: DomMetadata;\n  };\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { EditingConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "Table.SubRows": {
      "name": "SubRows",
      "definition": "export type SubRows<RowType, RowIdType> = {\n  getSubRows: (row: RowType) => RowType[] | undefined;\n  rowKeyGetter: (row: RowType) => RowIdType;\n  expandedIdsState?: [\n    Set<string | number>,\n    (\n      newV:\n        | Set<string | number>\n        | ((prev: Set<string | number>) => Set<string | number>),\n    ) => void,\n  ];\n};",
      "internal": true,
      "importNotice": "Тип \"SubRows\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-tree/types.ts"
    },
    "TableCanvas.SubRows": {
      "name": "SubRows",
      "definition": "export type SubRows<RowType, RowIdType> = {\n  /**\n   * Возвращает дочерние строки узла (или undefined, если их нет).\n   *\n   * Функция должна быть стабильной — не менять поведение между рендерами.\n   * Если она зависит от чего-то меняющегося, оберните её в useCallback.\n   */\n  getSubRows: (row: RowType) => RowType[] | undefined;\n  /**\n   * Возвращает уникальный ключ строки.\n   *\n   * Функция должна быть стабильной — не менять поведение между рендерами.\n   * Если она зависит от чего-то меняющегося, оберните её в useCallback.\n   */\n  rowKeyGetter: (row: RowType) => RowIdType;\n  /**\n   * Внешний стейт развёрнутых строк.\n   * Если не задан — используется внутренний useState.\n   * При view: 'merged' не используется: сворачивания в этом виде нет.\n   */\n  expandedIdsState?: [\n    Set<string | number>,\n    (\n      newV:\n        | Set<string | number>\n        | ((prev: Set<string | number>) => Set<string | number>),\n    ) => void,\n  ];\n  /**\n   * Как показывать дерево.\n   * 'tree' (по умолчанию) — узлы с раскрытием (шевроны) и отступом по уровню.\n   * 'merged' — дерево разворачивается в листья, а колонки-предки показаны\n   * объединёнными ячейками. Структуру задаёт потребитель через getSubRows;\n   * данные (пагинация, сортировка, поиск) остаются на его стороне.\n   */\n  view?: 'tree' | 'merged';\n  /**\n   * Только для view: 'merged'. Колонки-предки по порядку уровней:\n   * mergedColumns[0] — верхний уровень, дальше глубже. Каждая такая колонка\n   * показывает значение своего узла-предка (узел должен нести поле с этим именем)\n   * и объединяется по его границам. Верхний уровень задаёт чекбокс и номер блока.\n   */\n  mergedColumns?: string[];\n};",
      "internal": true,
      "importNotice": "Тип \"SubRows\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-tree/types.ts"
    },
    "Table.RowsGrouping": {
      "name": "RowsGrouping",
      "definition": "export type RowsGrouping<RowType extends ObjectForExtending> = {\n  /**\n   * массив группированных колонок и его setter\n   */\n  groupByState: [string[], React.Dispatch<React.SetStateAction<string[]>>];\n  /**\n   * Функция определения уникального id строки\n   */\n  rowKeyGetter: (row: RowType) => string | number;\n  /**\n   * Показывать ли кнопку «Группировать» в controlBlock.\n   * При `false` кнопка скрыта и не участвует в компрессии,\n   * но группировка строк продолжает работать от внешнего `groupByState`.\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * @default 'Группировка'\n   */\n  groupedColumnProps?: Partial<\n    Pick<\n      ColumnConfig<RowType>,\n      | 'name'\n      | 'resizable'\n      | 'width'\n      | 'minWidth'\n      | 'maxWidth'\n      | 'renderSummaryCell'\n    >\n  > & {\n    renderCell?: (\n      props: RenderCellProps<RowType> & {\n        parentGroupKey: string | undefined;\n        groupByArr: string[];\n      },\n    ) => ReactNode;\n    rowsGrouping?: Pick<ColumnRowsGrouping<RowType>, 'renderGroupCell'>;\n  };\n  expandAllBtn?: {\n    /**\n     * Функция для расчета состояния открытости всех раскрываемых строк. Функция должна быть чистой.\n     * @returns boolean\n     */\n    expandedAll: (p: {\n      /**\n       * allRowsIds - уникальные идентификаторы всех строк (группировок и обычных)\n       */\n      allRowsIds: Set<string | number> | null;\n      /**\n       * shownRows - представленные прямо сейчас строки (группировки и обычные). Или видимые строки - видимые не во viewport-е, а которые должны быть показаны из-за раскрытий)\n       */\n      shownRows: readonly RowType[];\n      expandedRowsIds: Set<string | number>;\n    }) => boolean;\n  };\n  /**\n   * `groupButton` - свойство для кастомизации кнопки с выпадающим списком\n   */\n  groupButton?: {\n    getGroupedCount?: (props: {\n      /**\n       * высчитанное автоматически количество активных группировок.\n       */\n      currCount: number;\n      /**\n       * активные группировки.\n       */\n      groupedCols: string[];\n      columns: {\n        /**\n         * `visible` - видимые в выпадающем списке колонки-группировки.\n         */\n        visible: string[];\n        /**\n         * `hidden` - невидимые  или не участвующие в группировке колонки\n         *\n         * (columnConfig.rowsGrouping=undefined ||\n         *  columnConfig.rowsGrouping.groupByColumn=false).\n         */\n        hidden: string[];\n      };\n    }) => number;\n    /**\n     * `defaultCustomItems` - свойство для добавления ключей группировки, которых нет в таблице.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    defaultCustomItems?: DropdownItemOption[];\n    /**\n     * `onItemSelect` - свойство для полного контроля над изменением группировки при выборе опций.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    onItemSelect?: (props: {\n      item: DropdownItemOption;\n      setGroupedCols: React.Dispatch<React.SetStateAction<string[]>>;\n      columns: {\n        visible: string[];\n        hidden: string[];\n      };\n    }) => void;\n  };\n  /**\n   * `groupRowReplaceTo` - свойство для изменения данных сгруппированных строк. Может понадобиться в редких случаях.\n   *\n   * @param groupRow данные сгруппированной строки\n   * @returns измененная группировка или строка без группировки — строка, которые заменит groupRow\n   */\n  groupRowReplaceTo?: (\n    groupRow: GroupRow<RowType>,\n  ) => GroupRow<RowType> | RowType;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};",
      "internal": true,
      "importNotice": "Тип \"RowsGrouping\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-rows-grouping/types.ts"
    },
    "TableCanvas.RowsGrouping": {
      "name": "RowsGrouping",
      "definition": "export type RowsGrouping<\n  RowType extends ObjectForExtending,\n  SummaryRowType = unknown,\n  ColumnConfig extends LocalColumnInstance = LocalColumnInstance,\n> = {\n  /**\n   * массив группированных колонок и его setter\n   */\n  groupByState: [string[], React.Dispatch<React.SetStateAction<string[]>>];\n  /**\n   * Как показывать группировку.\n   * 'tree' (по умолчанию) — дерево с раскрытием (шевроны) и колонкой группировки.\n   * 'merged' — плоский вид: строки идут по группам, а группирующие колонки\n   * показаны объединёнными ячейками. Раскрытия нет; чекбокс и номер — на всю\n   * группу верхнего уровня.\n   * @default 'tree'\n   */\n  view?: 'tree' | 'merged';\n  /**\n   * Только для view: 'merged'. Выравнивание по умолчанию в объединённых ячейках\n   * группирующих колонок. Колоночный mergedCellsAlign важнее.\n   */\n  mergedCellsAlign?: MergedCellsAlign;\n  /**\n   * Только для view: 'merged'. Запретить сортировку по группирующим колонкам\n   * (как в дереве). По остальным колонкам сортировка остаётся.\n   * @default false\n   */\n  disableGroupColumnsSort?: boolean;\n  /**\n   * Функция определения уникального id строки\n   */\n  rowKeyGetter: (row: RowType) => string | number;\n  /**\n   * Показывать ли кнопку «Группировать» в controlBlock.\n   * При `false` кнопка скрыта и не участвует в компрессии,\n   * но группировка строк продолжает работать от внешнего `groupByState`.\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * Настройки колонки «Группировка» (имя, ширина, свои рендеры). Работает только\n   * в виде дерева: при view: 'merged' эта колонка не создаётся, а сгруппированные\n   * колонки остаются на своих местах.\n   * @default 'Группировка'\n   */\n  groupedColumnProps?: Partial<Pick<ColumnConfig, 'name' | 'width'>> & {\n    renderCell?: (\n      props: CellInfoGlideInstance<RowType, SummaryRowType> & {\n        parentGroupKey: string | undefined;\n        groupByArr: string[];\n      },\n    ) => CanvasContent;\n    rowsGrouping?: Pick<\n      ColumnRowsGrouping<RowType, ColumnConfig>,\n      'renderGroupCell'\n    >;\n  };\n  /** Кнопка «развернуть всё». Работает только в виде дерева: при view: 'merged' шевронов нет. */\n  expandAllBtn?: {\n    /**\n     * Функция для расчета состояния открытости всех раскрываемых строк. Функция должна быть чистой.\n     * @returns boolean\n     */\n    expandedAll: (p: {\n      /**\n       * allRowsIds - уникальные идентификаторы всех строк (группировок и обычных)\n       */\n      allRowsIds: Set<string | number> | null;\n      /**\n       * shownRows - представленные прямо сейчас строки (группировки и обычные). Или видимые строки - видимые не во viewport-е, а которые должны быть показаны из-за раскрытий)\n       */\n      shownRows: readonly RowType[];\n      expandedRowsIds: Set<string | number>;\n    }) => boolean;\n  };\n  /**\n   * `groupButton` - свойство для кастомизации кнопки с выпадающим списком\n   */\n  groupButton?: {\n    getGroupedCount?: (props: {\n      /**\n       * высчитанное автоматически количество активных группировок.\n       */\n      currCount: number;\n      /**\n       * активные группировки.\n       */\n      groupedCols: string[];\n      columns: {\n        /**\n         * `visible` - видимые в выпадающем списке колонки-группировки.\n         */\n        visible: string[];\n        /**\n         * `hidden` - невидимые  или не участвующие в группировке колонки\n         *\n         * (columnConfig.rowsGrouping=undefined ||\n         *  columnConfig.rowsGrouping.groupByColumn=false).\n         */\n        hidden: string[];\n      };\n    }) => number;\n    /**\n     * `defaultCustomItems` - свойство для добавления ключей группировки, которых нет в таблице.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    defaultCustomItems?: DropdownItemOption[];\n    /**\n     * `onItemSelect` - свойство для полного контроля над изменением группировки при выборе опций.\n     *\n     * `DropdownItemOption.value` - необходимо заполнять ключом, который существует в данных.\n     */\n    onItemSelect?: (props: {\n      item: DropdownItemOption;\n      setGroupedCols: React.Dispatch<React.SetStateAction<string[]>>;\n      columns: {\n        visible: string[];\n        hidden: string[];\n      };\n    }) => void;\n  };\n  /**\n   * `groupRowReplaceTo` - свойство для изменения данных сгруппированных строк. Может понадобиться в редких случаях.\n   *\n   * @param groupRow данные сгруппированной строки\n   * @returns измененная группировка или строка без группировки — строка, которые заменит groupRow\n   */\n  groupRowReplaceTo?: (\n    groupRow: GroupRow<RowType>,\n  ) => GroupRow<RowType> | RowType;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};",
      "internal": true,
      "importNotice": "Тип \"RowsGrouping\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-rows-grouping/types.ts"
    },
    "Table.SummaryRowsConfig": {
      "name": "SummaryRowsConfig",
      "definition": "export type SummaryRowsConfig = {\n  showDefault: boolean;\n  showInControl: boolean;\n} & {\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { SummaryRowsConfig } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "TableCanvas.SummaryRowsConfig": {
      "name": "SummaryRowsConfig",
      "definition": "export type SummaryRowsConfig = {\n  showDefault: boolean;\n  showInControl: boolean;\n} & {\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { SummaryRowsConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "Table.ControlBlockConfig": {
      "name": "ControlBlockConfig",
      "definition": "export type ControlBlockConfig = {\n  /**\n   * show - наличие controlBlock-а\n   * @default true\n   */\n  show?: boolean;\n  /**\n   * leftSideInner - пропс для добавления кнопок в левую часть контролблока\n   */\n  leftSideInner?: ControlBlockButtonProps[];\n  /**\n   * rightSideInner - пропс для добавления кнопок в в правую часть контролблока\n   */\n  rightSideInner?: ControlBlockButtonProps[];\n  /**\n   * rightSideInner - пропс для добавления кастомные фичей (кнопки-иконки)\n   */\n  customFeatures?: FeatureItem[];\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n   */\n  leftSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n   */\n  rightSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n   * @default true\n   */\n  enableAdaptiveCompress?: boolean;\n  /**\n   * Панель массовых действий\n   */\n  massActionPanel?: {\n    /**\n     * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n     * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n     */\n    buttons: MassActionsButtonProps[];\n    /**\n     * Пропсы для Dropdown, в который сжались кнопки\n     */\n    collapsedDropdownProps?: TableDropdownConfigProps;\n    /**\n     * Отступ панели снизу от контейнера (px)\n     * @default 24\n     */\n    bottom?: number;\n    /**\n     * Управление отображением панели массовых действий.\n     * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n     * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n     * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n     */\n    show?: boolean;\n    /**\n     * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n     * Viewport-логика (1280) в таблице не используется.\n     * @default 's'\n     */\n    size?: MassActionsSize;\n  };\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ControlBlockConfig } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "TableCanvas.ControlBlockConfig": {
      "name": "ControlBlockConfig",
      "definition": "export type ControlBlockConfig = {\n  /**\n   * show - наличие controlBlock-а\n   * @default true\n   */\n  show?: boolean;\n  /**\n   * Размер controlBlock и его элементов (кнопки, иконки, поиск, отступы).\n   * 'm' и 's' — стандартные стили, 'xs' — компактный режим.\n   * Не влияет на customFeatures и кастомные слоты — они контролируются разработчиком.\n   * @default 'm'\n   */\n  size?: ControlBlockSize;\n  /**\n   * @deprecated Используйте кастомные кнопки через rightSideInner или customFeatures.\n   * leftSideInner - пропс для добавления кнопок в левую часть контролблока.\n   * Продолжает работать для обратной совместимости.\n   */\n  leftSideInner?: ControlBlockButtonProps[];\n  /**\n   * rightSideInner - пропс для добавления кнопок в правую часть контролблока\n   */\n  rightSideInner?: ControlBlockButtonProps[];\n  /**\n   * customFeatures - пропс для добавления кастомных фичей (кнопки-иконки)\n   */\n  customFeatures?: FeatureItem[];\n  /**\n   * pinningMenu - нативная фича закрепления столбцов (SplitIconButton с\n   * дропдауном) в правой зоне иконок. Появляется, когда активировано\n   * закрепление колонок (columnsControl.pinning). Продукт может донастроить\n   * и дополнить пункты меню (см. PinningMenuConfig).\n   */\n  pinningMenu?: PinningMenuConfig;\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты левые фичи при адаптивной компрессии\n   */\n  leftSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Пропсы для компонента dropdown в котором будут скрыты правые фичи при адаптивной компрессии\n   */\n  rightSideDropdownProps?: TableDropdownConfigProps;\n  /**\n   * Активна ли фича компрессии (сжатие ToolsMenu при адаптиве)\n   * @default true\n   */\n  enableAdaptiveCompress?: boolean;\n  /**\n   * Панель массовых действий\n   */\n  massActionPanel?: {\n    /**\n     * Кнопки панели. Размеры кнопок/дропдаунов панель подбирает сама (по `size` панели и компактности) —\n     * передавать `size` кнопкам не нужно. Если `size` на кнопке всё же задан — он используется как есть.\n     */\n    buttons: MassActionButtonProps[];\n    /**\n     * Пропсы для Dropdown, в который сжались кнопки\n     */\n    collapsedDropdownProps?: TableDropdownConfigProps;\n    /**\n     * Отступ панели снизу от контейнера (px)\n     * @default 24\n     */\n    bottom?: number;\n    /**\n     * Управление отображением панели массовых действий.\n     * - `undefined` (по умолчанию) — стандартное поведение (показывается при selecting + выбранных строках)\n     * - `false` — панель не рендерится, разработчик управляет действиями самостоятельно\n     * - `true` — панель показывается всегда, даже без активного selecting и выбранных строк\n     */\n    show?: boolean;\n    /**\n     * Размерная сетка панели внутри таблицы: `m`/`s` — обычный размер, `xs` — уменьшенный (кнопки `xxs`, «ещё» `xs`, счётчик Body XS).\n     * Viewport-логика (1280) в таблице не используется.\n     * @default 's'\n     */\n    size?: MassActionsSize;\n  };\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { ControlBlockConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "Table.ColumnsControlConfig": {
      "name": "ColumnsControlConfig",
      "definition": "export type ColumnsControlConfig = {\n  enable: boolean;\n  /**\n   * @default enable\n   */\n  hiding?: boolean;\n  /**\n   * @default enable\n   */\n  pinning?: boolean;\n  /**\n   * @default enable\n   */\n  reorderingAside?: boolean;\n  /**\n   * reorderingHeader  - активация изменения порядка колонок  посредством перемещения шапок колонок таблицы\n   */\n  /**\n   * @default enable\n   */\n  reorderingHeader?: boolean;\n  onReorderingHeader?: (params: {\n    newOrder: string[];\n    sourceKey: string;\n    targetKey: string;\n  }) => void;\n\n  columnsLabel?: Record<\n    string,\n    ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n  >;\n\n  orderDefault?: string[];\n\n  pinnedDefault?: string[];\n  disablePinning?: string[];\n\n  hiddenDefault?: string[];\n  disableHiding?: string[];\n\n  onConfirm?: (\n    params: {\n      pinned: string[];\n      order: string[];\n      hidden: string[];\n      changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n    },\n    setters: {\n      setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n      setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n      setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n    },\n  ) => void;\n  /**\n   * DomMetadata для кнопок закрепления столбцов\n   */\n  pinDomMetadata?: DomMetadata;\n  /**\n   * DomMetadata для свитчеров скрытия/показа столбцов\n   */\n  switchDomMetadata?: DomMetadata;\n};",
      "internal": true,
      "importNotice": "Тип \"ColumnsControlConfig\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-column-control/types.ts"
    },
    "TableCanvas.ColumnsControlConfig": {
      "name": "ColumnsControlConfig",
      "definition": "export type ColumnsControlConfig = {\n  enable: boolean;\n  /**\n   * @default enable\n   */\n  hiding?: boolean;\n  /**\n   * @default enable\n   */\n  pinning?: boolean;\n  /**\n   * @default enable\n   */\n  reorderingAside?: boolean;\n  /**\n   * reorderingHeader  - активация изменения порядка колонок  посредством перемещения шапок колонок таблицы\n   */\n  /**\n   * @default enable\n   */\n  reorderingHeader?: boolean;\n  onReorderingHeader?: (params: {\n    newOrder: string[];\n    sourceKey: string;\n    targetKey: string;\n  }) => void;\n\n  columnsLabel?: Record<\n    string,\n    ReactNode | ((isHidden: boolean, isPinned: boolean) => ReactNode)\n  >;\n\n  /**\n   * Виртуализация списка колонок в правом сайдбаре: в DOM держатся только\n   * видимые строки списка. false — отключить полностью; { minCount } —\n   * включать, когда строк в списке не меньше порога.\n   * @default { minCount: 30 }\n   */\n  virtualization?: boolean | { minCount?: number };\n\n  orderDefault?: string[];\n\n  pinnedDefault?: string[];\n  disablePinning?: string[];\n\n  hiddenDefault?: string[];\n  disableHiding?: string[];\n  /**\n   * Индикатор скрытых столбцов: синяя полосатая линия в шапке на границе, за\n   * которой скрыты столбцы. Двойной клик по линии раскрывает весь промежуток,\n   * ресайз на этой границе работает как обычно.\n   * @default hiding\n   */\n  hiddenColumnsIndicator?: boolean;\n  /**\n   * Уведомление о раскрытии промежутка двойным кликом по индикатору скрытых\n   * столбцов. Само раскрытие (снятие скрытия) обёртка делает сама; колбэк нужен,\n   * чтобы внешний потребитель мог подписаться на это событие и узнать, какие\n   * столбцы раскрылись и между какими видимыми колонками стояла линия.\n   */\n  onHiddenColumnsIndicatorExpand?: (\n    info: HiddenColumnsIndicatorExpandInfo,\n  ) => void;\n\n  onConfirm?: (\n    params: {\n      pinned: string[];\n      order: string[];\n      hidden: string[];\n      changed: { pinned?: 'pinned'; order?: 'order'; hidden?: 'hidden' };\n    },\n    setters: {\n      setColumnsOrder: (value: React.SetStateAction<string[]>) => void;\n      setPinnedCols: (value: React.SetStateAction<string[]>) => void;\n      setHiddenCols: (value: React.SetStateAction<string[]>) => void;\n    },\n  ) => void;\n  /**\n   * DomMetadata для кнопок закрепления столбцов\n   */\n  pinDomMetadata?: DomMetadata;\n  /**\n   * DomMetadata для свитчеров скрытия/показа столбцов\n   */\n  switchDomMetadata?: DomMetadata;\n};",
      "internal": true,
      "importNotice": "Тип \"ColumnsControlConfig\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-column-control/types.ts"
    },
    "RowDetailConfig": {
      "name": "RowDetailConfig",
      "definition": "export type RowDetailConfig<RowType> = {\n  rowKeyGetter: (row: RowType) => string | number;\n  isRowWithDetail: (r: RowType) => boolean;\n  renderRowDetail: (props: {\n    row: RowType;\n    tabIndex: number;\n    onRowChange: (row: RowType) => void;\n    rowIdx: number;\n    colIdx: number;\n  }) => ReactNode;\n\n  detailHeight: number | ((r: RowType) => number);\n  expandButtonColumnKey: string;\n  icons?: Prettify<IconsPropType>;\n\n  // TODO  режим редактирования detailPanel  - выключен и убран из типов, если будет потребность, нужно доработать\n  // renderRowDetailEditing?: (props: {\n  //     row: RowType;\n  //     onRowChange: (row: RowType, commitChanges?: boolean) => void;\n  //     onClose: (commitChanges?: boolean, shouldFocusCell?: boolean) => void;\n  // }) => ReactNode;\n  // rowDetailIsEditable?: boolean | ((row: RowType) => boolean);\n};",
      "internal": true,
      "importNotice": "Тип \"RowDetailConfig\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-row-detail/types.ts"
    },
    "RowInstrumentsType": {
      "name": "RowInstrumentsType",
      "definition": "export type RowInstrumentsType<RowType extends ObjectForExtending> =\n  (rowProps: {\n    row: RowType;\n    rowIdx: number;\n    onRowChange: (r: RowType) => void;\n    additional: HeaderContextValueTypeInstance<RowType>;\n  }) => {\n    items: (DropdownItemOption & {\n      onItemSelect?: (item: DropdownItemOption, event: SyntheticEvent) => void;\n    })[];\n    dropdownProps?: Partial<DropdownProps> & {\n      /**\n       * При количестве item-ов = 1:  использовать ли contentLeft ?? contentRight\n       * как иконку для основной кнопки и onItemSelect item-а как onClick основной кнопки\n       */\n      useItemContentAsButtonContent?: boolean;\n    };\n  };",
      "importPath": "@daisforge/ui",
      "importStatement": "import { RowInstrumentsType } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-row-instruments/types.ts"
    },
    "Table.FullScreen": {
      "name": "FullScreen",
      "definition": "export type FullScreen = boolean | FullScreenObj;",
      "internal": true,
      "importNotice": "Тип \"FullScreen\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-full-screen/types.ts"
    },
    "TableCanvas.FullScreen": {
      "name": "FullScreen",
      "definition": "export type FullScreen = boolean | FullScreenObj;",
      "internal": true,
      "importNotice": "Тип \"FullScreen\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-full-screen/types.ts"
    },
    "Table.KeyTextConfig": {
      "name": "KeyTextConfig",
      "definition": "export type KeyTextConfig = {\n  showInControl?: boolean;\n  defaultActiveOption?: KeyText;\n  controlBlock: {\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n     */\n    domMetadata?: DomMetadata;\n  };\n  sidebar: {\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n     */\n    domMetadata?: DomMetadata;\n  };\n};",
      "internal": true,
      "importNotice": "Тип \"KeyTextConfig\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-key-text/types.ts"
    },
    "TableCanvas.KeyTextConfig": {
      "name": "KeyTextConfig",
      "definition": "export type KeyTextConfig = {\n  showInControl?: boolean;\n  defaultActiveOption?: KeyText;\n  controlBlock: {\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n     */\n    domMetadata?: DomMetadata;\n  };\n  sidebar: {\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам RightSidebar\n     */\n    domMetadata?: DomMetadata;\n  };\n};",
      "internal": true,
      "importNotice": "Тип \"KeyTextConfig\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-key-text/types.ts"
    },
    "Table.PaginationProps": {
      "name": "PaginationProps",
      "definition": "export type PaginationProps = Omit<\n  ComponentProps<typeof Pagination>,\n  'onChangePageValue' | 'onChange'\n> & {\n  onChangePageValue?: (\n    page: number | undefined,\n    scrollToTop: () => void,\n  ) => void;\n  onChange?: (\n    newPage: number | undefined,\n    perPage: number | undefined,\n    scrollToTop: () => void,\n  ) => void;\n  /**\n   * Нужно ли активировать умную адаптацию изменения количества слотов в зависимости от ширины блока пагинации и от size\n   * @default false\n   */\n  responsiveSlots?: boolean;\n  /**\n   * Callback при ресайзе блока с пагинацией таблицы\n   */\n  onResize?: (width: number) => void;\n};",
      "internal": true,
      "importNotice": "Тип \"PaginationProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-pagination/types.ts"
    },
    "TableCanvas.PaginationProps": {
      "name": "PaginationProps",
      "definition": "export type PaginationProps = Omit<\n  ComponentProps<typeof Pagination>,\n  'onChangePageValue' | 'onChange'\n> & {\n  onChangePageValue?: (\n    page: number | undefined,\n    scrollToTop: () => void,\n  ) => void;\n  onChange?: (\n    newPage: number | undefined,\n    perPage: number | undefined,\n    scrollToTop: () => void,\n  ) => void;\n  /**\n   * Нужно ли активировать умную адаптацию изменения количества слотов в зависимости от ширины блока пагинации и от size\n   * @default false\n   */\n  responsiveSlots?: boolean;\n  /**\n   * Callback при ресайзе блока с пагинацией таблицы\n   */\n  onResize?: (width: number) => void;\n};",
      "internal": true,
      "importNotice": "Тип \"PaginationProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-pagination/types.ts"
    },
    "Table.SidebarConfig": {
      "name": "SidebarConfig",
      "definition": "type SidebarConfig = {\n  /**\n   * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n   * @default true\n   */\n  enabled?: boolean;\n  /**\n   * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n   * Игнорируется, если передан openState.\n   * @default false\n   */\n  defaultOpen?: boolean;\n  /**\n   * Внешний контроль открытия/закрытия sidebar.\n   * Если передан — источник истины, defaultOpen игнорируется.\n   */\n  openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n   * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n   */\n  defaultActiveTabId?: string;\n  /**\n   * Внешний контроль активной вкладки (controlled-режим).\n   * Если передан — источник истины, defaultActiveTabId игнорируется.\n   */\n  activeTabState?: [\n    string | null,\n    React.Dispatch<React.SetStateAction<string | null>>,\n  ];\n  /**\n   * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n   * При закрытии сайдбара приходит null.\n   */\n  onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n  /**\n   * Кастомные табы\n   */\n  customTabs?: Array<\n    Omit<SidebarTab, 'id'> & {\n      id: Exclude<string, DefaultSidebarTabIds>;\n    }\n  >;\n  /**\n   * Порядок отображения кастомных вкладок\n   */\n  customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n  defaultTabs?: Array<\n    | {\n        id: 'filtering' | 'columns';\n        label?: string;\n        title?: string;\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n      }\n    | {\n        id: 'tableSettings';\n        label?: string;\n        title?: string;\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n         * Только дл id: 'tableSettings'\n         */\n        customGeneralSettingsSlot?: React.ReactNode;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n      }\n  >;\n};",
      "internal": true,
      "importNotice": "Тип \"SidebarConfig\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "TableCanvas.SidebarConfig": {
      "name": "SidebarConfig",
      "definition": "export type SidebarConfig = {\n  /**\n   * Включен ли sidebar. Отвечает только за UI. Не влияет на перерасчёт фичей.\n   * @default true\n   */\n  enabled?: boolean;\n  /**\n   * Открыт ли sidebar при первом рендере (uncontrolled-режим).\n   * Игнорируется, если передан openState.\n   * @default false\n   */\n  defaultOpen?: boolean;\n  /**\n   * Внешний контроль открытия/закрытия sidebar.\n   * Если передан — источник истины, defaultOpen игнорируется.\n   */\n  openState?: [boolean, React.Dispatch<React.SetStateAction<boolean>>];\n  /**\n   * id вкладки, выбранной по умолчанию (актуально при открытом сайдбаре).\n   * Если id не найден или у вкладки showInSidebar=false — используется первая доступная.\n   */\n  defaultActiveTabId?: string;\n  /**\n   * Внешний контроль активной вкладки (controlled-режим).\n   * Если передан — источник истины, defaultActiveTabId игнорируется.\n   */\n  activeTabState?: [\n    string | null,\n    React.Dispatch<React.SetStateAction<string | null>>,\n  ];\n  /**\n   * Колбэк смены активной вкладки. Вызывается и в uncontrolled-режиме.\n   * При закрытии сайдбара приходит null.\n   */\n  onActiveTabChange?: (tabId: string | null, tab?: SidebarTab) => void;\n  /**\n   * Кастомные табы\n   */\n  customTabs?: Array<\n    Omit<SidebarTab, 'id'> & {\n      id: Exclude<string, DefaultSidebarTabIds>;\n    }\n  >;\n  /**\n   * Порядок отображения кастомных вкладок\n   */\n  customTabsOrder?: Array<Exclude<string, DefaultSidebarTabIds>>;\n  defaultTabs?: Array<\n    | {\n        id: 'filtering' | 'columns';\n        /** название таба в рамках горизонтального табов внутри таба настройки */\n        label?: string;\n        /** название таба в рамках вертикальных табов сайдбара (если данный таб окажется единственным табом в настройках) */\n        title?: string;\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n        /** @default true */\n        showInSidebar?: boolean;\n        /** тултип иконки шестеренки (для табов с id = filtering и columns - недоступен. Настраивается через таб с id='tableSettings') */\n        iconTooltipText?: undefined;\n      }\n    | {\n        id: 'tableSettings';\n        /** название таба в рамках горизонтального табов внутри таба настройки */\n        label?: string;\n        /** название таба в рамках вертикальных табов сайдбара */\n        title?: string;\n\n        /**\n         * Метки для автоматизированного тестирования и аналитики\n         * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n         */\n        domMetadata?: DomMetadata;\n        /**\n         * Кастомный слот для вкладки tableSettings (рендерится после общих настроек)\n         * Только дл id: 'tableSettings'\n         */\n        customGeneralSettingsSlot?: React.ReactNode;\n        /**\n         * Кастомный элемент справа от title в шапке сайдбара\n         */\n        titleRightSlot?: React.ReactNode;\n        /** @default true */\n        showInSidebar?: boolean;\n        /** тултип иконки шестеренки @default 'Настройки' */\n        iconTooltipText?: string;\n      }\n  >;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { SidebarConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "Table.SearchingProps": {
      "name": "SearchingProps",
      "definition": "export type SearchingProps = {\n  /**\n   * Активация функционала поиска (обязательный параметр)\n   */\n  enabled: boolean;\n\n  /**\n   * Если true - поиск НЕ будет работать на фронте (ручное управление)\n   * Полезно когда поисковая логика полностью управляется на бэкенде\n   */\n  manualSearching?: boolean;\n\n  /**\n   * Начальное значение поискового запроса\n   */\n  defaultSearchQuery?: string;\n\n  /**\n   * Видимость UI блока поиска\n   */\n  showSearchBlock?: boolean;\n\n  /**\n   * Состояние и сеттер для контролируемого режима\n   * [текущее значение, функция установки значения]\n   */\n  searchQueryState?: [string, React.Dispatch<React.SetStateAction<string>>];\n\n  /**\n   * Обработчик изменения с debounce\n   * Вызывается с задержкой после окончания ввода\n   * @param value - текущее значение поискового запроса\n   */\n  onDebouncedChange?: (value: string) => void;\n\n  /**\n   * Мгновенный обработчик изменений\n   * Вызывается при каждом изменении input\n   * @param value - текущее значение поискового запроса\n   */\n  onChange?: (value: string) => void;\n\n  /**\n   * Задержка для debounce (в миллисекундах)\n   * @default 300\n   */\n  debounceDelay?: number;\n\n  /**\n   * Активация debounce механизма\n   * @default true\n   */\n  isDebounceActive?: boolean;\n\n  /**\n   * Дополнительные классы для контейнера поиска\n   */\n  searchClasses?: string;\n\n  /**\n   * Placeholder для поискового input\n   * @default \"Поиск\"\n   */\n  placeholder?: string;\n\n  /**\n   * DOM метаданные для аналитики и онбординга\n   */\n  domMetadata?: DomMetadata;\n\n  /**\n   * Режим запуска поиска\n   * - true: поиск запускается автоматически при вводе текста (по умолчанию)\n   * - false: поиск запускается только по клику на иконку поиска или нажатию Enter\n   */\n  searchOnType?: boolean;\n\n  /**\n   * Конфигурация автокомплита для поиска.\n   * При передаче поле поиска заменяется на Autocomplete с подсказками.\n   */\n  autocomplete?: SearchAutocompleteConfig;\n};",
      "internal": true,
      "importNotice": "Тип \"SearchingProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-searching/types.ts"
    },
    "TableCanvas.SearchingProps": {
      "name": "SearchingProps",
      "definition": "export type SearchingProps = {\n  /**\n   * Активация функционала поиска (обязательный параметр)\n   */\n  enabled: boolean;\n\n  /**\n   * Если true - поиск НЕ будет работать на фронте (ручное управление)\n   * Полезно когда поисковая логика полностью управляется на бэкенде\n   */\n  manualSearching?: boolean;\n\n  /**\n   * Начальное значение поискового запроса\n   */\n  defaultSearchQuery?: string;\n\n  /**\n   * Видимость UI блока поиска\n   */\n  showSearchBlock?: boolean;\n\n  /**\n   * Состояние и сеттер для контролируемого режима\n   * [текущее значение, функция установки значения]\n   */\n  searchQueryState?: [string, React.Dispatch<React.SetStateAction<string>>];\n\n  /**\n   * Обработчик изменения с debounce\n   * Вызывается с задержкой после окончания ввода\n   * @param value - текущее значение поискового запроса\n   */\n  onDebouncedChange?: (value: string) => void;\n\n  /**\n   * Мгновенный обработчик изменений\n   * Вызывается при каждом изменении input\n   * @param value - текущее значение поискового запроса\n   */\n  onChange?: (value: string) => void;\n\n  /**\n   * Задержка для debounce (в миллисекундах)\n   * @default 300\n   */\n  debounceDelay?: number;\n\n  /**\n   * Активация debounce механизма\n   * @default true\n   */\n  isDebounceActive?: boolean;\n\n  /**\n   * Дополнительные классы для контейнера поиска\n   */\n  searchClasses?: string;\n\n  /**\n   * Placeholder для поискового input\n   * @default \"Поиск\"\n   */\n  placeholder?: string;\n\n  /**\n   * DOM метаданные для аналитики и онбординга\n   */\n  domMetadata?: DomMetadata;\n\n  /**\n   * Режим запуска поиска\n   * - true: поиск запускается автоматически при вводе текста (по умолчанию)\n   * - false: поиск запускается только по клику на иконку поиска или нажатию Enter\n   */\n  searchOnType?: boolean;\n\n  /**\n   * Конфигурация автокомплита для поиска.\n   * При передаче поле поиска заменяется на Autocomplete с подсказками.\n   */\n  autocomplete?: SearchAutocompleteConfig;\n};",
      "internal": true,
      "importNotice": "Тип \"SearchingProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-searching/types.ts"
    },
    "HeaderContextMenuProps": {
      "name": "HeaderContextMenuProps",
      "definition": "export type HeaderContextMenuProps = (\n  event: React.MouseEvent,\n  columnLabel: string | undefined,\n  closestTargetElement: HTMLElement | undefined,\n) => void;",
      "internal": true,
      "importNotice": "Тип \"HeaderContextMenuProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-context-menu/types.ts"
    },
    "HeaderContextMenuDropDownProps": {
      "name": "HeaderContextMenuDropDownProps",
      "definition": "export type HeaderContextMenuDropDownProps = {\n  type: 'dropdown';\n  getDropDownItems: (params: {\n    columnLabel: string | undefined;\n  }) => DropdownProps['items'];\n  /**\n   * Колбэк открытия меню для асинхронной подгрузки. Если getDropDownItems вернул\n   * пусто, но onOpen задан — меню открывается, а getDropDownItems перечитывается\n   * реактивно, пока меню открыто. Здесь потребитель стартует запрос.\n   */\n  onOpen?: (params: { columnLabel: string | undefined }) => void;\n  onItemSelect?: (\n    item: ContextMenuDropdownItem,\n    context: { columnLabel: string | undefined },\n    event?: React.SyntheticEvent,\n  ) => void;\n} & ContextMenuDropDownProps;",
      "internal": true,
      "importNotice": "Тип \"HeaderContextMenuDropDownProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-context-menu/types.ts"
    },
    "CellContextMenuDropDownProps": {
      "name": "CellContextMenuDropDownProps",
      "definition": "export type CellContextMenuDropDownProps<RowType, SummaryRowType> = {\n  type: 'dropdown';\n  getDropDownItems: (params: {\n    row: RowType;\n    column: CalculatedColumn<RowType, SummaryRowType>;\n  }) => DropdownProps['items'];\n  /**\n   * Колбэк открытия меню для асинхронной подгрузки. Если getDropDownItems вернул\n   * пусто, но onOpen задан — меню открывается, а getDropDownItems перечитывается\n   * реактивно, пока меню открыто. Здесь потребитель стартует запрос.\n   */\n  onOpen?: (params: {\n    row: RowType;\n    column: CalculatedColumn<RowType, SummaryRowType>;\n  }) => void;\n  onItemSelect?: (\n    item: ContextMenuDropdownItem,\n    context: {\n      row: RowType;\n      column: CalculatedColumn<RowType, SummaryRowType>;\n      selectCell: (enableEditor?: boolean) => void;\n    },\n    event?: React.SyntheticEvent,\n  ) => void;\n} & ContextMenuDropDownProps;",
      "internal": true,
      "importNotice": "Тип \"CellContextMenuDropDownProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-context-menu/types.ts"
    },
    "DataGridPropsDefault": {
      "name": "DataGridPropsDefault",
      "definition": "export interface DataGridPropsDefault<R, SR = unknown, K extends Key = Key>\n  extends SharedDivProps {\n  /**\n   * Grid and data Props\n   */\n  /** An array of objects representing each column on the grid */\n  columns: readonly ColumnOrColumnGroup<R, SR>[];\n  /** A function called for each rendered row that should return a plain key/value pair object */\n  rows: readonly R[];\n  /**\n   * Rows to be pinned at the top of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  topSummaryRows?: Maybe<readonly SR[]>;\n  /**\n   * Rows to be pinned at the bottom of the rows view for summary, the vertical scroll bar will not scroll these rows.\n   */\n  bottomSummaryRows?: Maybe<readonly SR[]>;\n  /** The getter should return a unique key for each row */\n  rowKeyGetter?: Maybe<(row: R) => K>;\n  onRowsChange?: Maybe<(rows: R[], data: RowsChangeData<R, SR>) => void>;\n  /**\n   * Dimensions props\n   */\n  /**\n   * The height of each row in pixels\n   * @default 35\n   */\n  rowHeight?: Maybe<number | ((row: R) => number)>;\n  /**\n   * The height of the header row in pixels\n   * @default 35\n   */\n  headerRowHeight?: Maybe<number>;\n  /**\n   * The height of each summary row in pixels\n   * @default 35\n   */\n  summaryRowHeight?: Maybe<number>;\n  /**\n   * Feature props\n   */\n  /** Set of selected row keys */\n  selectedRows?: Maybe<ReadonlySet<K>>;\n  /** Function called whenever row selection is changed */\n  onSelectedRowsChange?: Maybe<(selectedRows: Set<K>) => void>;\n  /** Used for multi column sorting */\n  sortColumns?: Maybe<readonly SortColumn[]>;\n  onSortColumnsChange?: Maybe<(sortColumns: SortColumn[]) => void>;\n  defaultColumnOptions?: Maybe<DefaultColumnOptions<R, SR>>;\n  onFill?: Maybe<(event: FillEvent<R>) => R>;\n  onCopy?: Maybe<(event: CopyEvent<R>) => void>;\n  onPaste?: Maybe<(event: PasteEvent<R>) => R>;\n  /**\n   * Event props\n   */\n  /** Function called whenever a cell is clicked */\n  onCellClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is double clicked */\n  onCellDoubleClick?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  /** Function called whenever a cell is right clicked */\n  onCellContextMenu?: Maybe<\n    (args: CellClickArgs<R, SR>, event: CellMouseEvent) => void\n  >;\n  onCellKeyDown?: Maybe<\n    (args: CellKeyDownArgs<R, SR>, event: CellKeyboardEvent) => void\n  >;\n  /** Function called whenever cell selection is changed */\n  onSelectedCellChange?: Maybe<(args: CellSelectArgs<R, SR>) => void>;\n  /** Called when the grid is scrolled */\n  onScroll?: Maybe<(event: React.UIEvent<HTMLDivElement>) => void>;\n  /** Called when a column is resized */\n  onColumnResize?: Maybe<(idx: number, width: number) => void>;\n  /** Called when a column is reordered */\n  onColumnsReorder?: Maybe<\n    (sourceColumnKey: string, targetColumnKey: string) => void\n  >;\n  /**\n   * Toggles and modes\n   */\n  /** @default true */\n  enableVirtualization?: Maybe<boolean>;\n  /**\n   * Miscellaneous\n   */\n  renderers?: Maybe<Renderers<R, SR>>;\n  rowClass?: Maybe<(row: R, rowIdx: number) => Maybe<string>>;\n  /** @default 'ltr' */\n  direction?: Maybe<Direction>;\n  'data-testid'?: Maybe<string>;\n}",
      "internal": true,
      "importNotice": "Тип \"DataGridPropsDefault\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/types/data-grid.type.ts"
    },
    "ComboboxType": {
      "name": "ComboboxType",
      "definition": "type ComboboxType<T extends ComboboxItemOption> = typeof ComboboxSDDS<T>;",
      "internal": true,
      "importNotice": "Тип \"ComboboxType\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Combobox/index.ts"
    },
    "GlideSizes": {
      "name": "GlideSizes",
      "definition": "export type GlideSizes = typeof SIZES;",
      "internal": true,
      "importNotice": "Тип \"GlideSizes\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/constants.ts"
    },
    "CellReadOnlyEditorGlideInstanceStaticProps": {
      "name": "CellReadOnlyEditorGlideInstanceStaticProps",
      "definition": "export type CellReadOnlyEditorGlideInstanceStaticProps = {\n  formatOptions: ContentFormat | undefined;\n  disableLeftOffset: boolean | undefined;\n  contentAlign: 'right' | 'left' | 'center';\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellReadOnlyEditorGlideInstanceStaticProps } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "RowsChangeType": {
      "name": "RowsChangeType",
      "definition": "export type RowsChangeType = 'edit' | 'paste' | 'fill';",
      "internal": true,
      "importNotice": "Тип \"RowsChangeType\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-cell-transfer/types.ts"
    },
    "FillMeta": {
      "name": "FillMeta",
      "definition": "export type FillMeta = {\n  /** Исходный диапазон (откуда тянули) */\n  sourceRange: Rectangle;\n  /** Целевой диапазон (куда заполнили) */\n  destinationRange: Rectangle;\n  /** Двумерный массив информации об исходных ячейках */\n  sourceCells: CellTransferCellInfo[][];\n  /** Двумерный массив информации о целевых ячейках (до заполнения) */\n  targetCells: CellTransferCellInfo[][];\n};",
      "internal": true,
      "importNotice": "Тип \"FillMeta\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-cell-transfer/types.ts"
    },
    "RenderGroupHeaderArgs": {
      "name": "RenderGroupHeaderArgs",
      "definition": "export type RenderGroupHeaderArgs = Parameters<\n  NonNullable<GlideProps['drawGroupHeader']>\n>[0];",
      "internal": true,
      "importNotice": "Тип \"RenderGroupHeaderArgs\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "CellsSelectionMode": {
      "name": "CellsSelectionMode",
      "definition": "export type CellsSelectionMode =\n  | 'cell'\n  | 'range-cell'\n  | 'multi-range-cell'\n  | 'disabled';",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellsSelectionMode } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "TableGlide.Direction": {
      "name": "Direction",
      "definition": "export type Direction = 'row' | 'row-reverse' | 'column' | 'column-reverse';",
      "internal": true,
      "importNotice": "Тип \"Direction\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/miniflex/types.ts"
    },
    "Table.Direction": {
      "name": "Direction",
      "definition": "type Direction = 'ltr' | 'rtl';",
      "internal": true,
      "importNotice": "Тип \"Direction\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/types/data-grid.type.ts"
    },
    "Justify": {
      "name": "Justify",
      "definition": "export type Justify =\n  | 'flex-start'\n  | 'flex-end'\n  | 'center'\n  | 'space-between'\n  | 'space-around'\n  | 'space-evenly';",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { Justify } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/miniflex/types.ts"
    },
    "Align": {
      "name": "Align",
      "definition": "export type Align = 'flex-start' | 'flex-end' | 'center' | 'stretch';",
      "internal": true,
      "importNotice": "Тип \"Align\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/miniflex/types.ts"
    },
    "AlignContent": {
      "name": "AlignContent",
      "definition": "export type AlignContent =\n  | 'flex-start'\n  | 'flex-end'\n  | 'center'\n  | 'space-between'\n  | 'space-around'\n  | 'space-evenly'\n  | 'stretch';",
      "internal": true,
      "importNotice": "Тип \"AlignContent\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/miniflex/types.ts"
    },
    "FlexStyle": {
      "name": "FlexStyle",
      "definition": "export interface FlexStyle {\n  id?: string;\n  flexGrow: number;\n  flexShrink: number;\n  flexBasis: number;\n  alignSelf?: Align | 'auto';\n  width?: number;\n  height?: number;\n  crossAxisSizing?: CrossAxisSizing;\n  metadata?: unknown;\n}",
      "internal": true,
      "importNotice": "Тип \"FlexStyle\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/miniflex/types.ts"
    },
    "DimensionValue": {
      "name": "DimensionValue",
      "definition": "export type DimensionValue = number | '100%';",
      "internal": true,
      "importNotice": "Тип \"DimensionValue\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/core/CanvasNode.type.ts"
    },
    "Rect": {
      "name": "Rect",
      "definition": "export interface Rect {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n}",
      "internal": true,
      "importNotice": "Тип \"Rect\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/core/CanvasNode.type.ts"
    },
    "CanvasTextOverflowMode": {
      "name": "CanvasTextOverflowMode",
      "definition": "export type CanvasTextOverflowMode = 'visible' | 'hidden';",
      "internal": true,
      "importNotice": "Тип \"CanvasTextOverflowMode\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasText.ts"
    },
    "CanvasTextOverflow": {
      "name": "CanvasTextOverflow",
      "definition": "export type CanvasTextOverflow = 'clip' | 'ellipsis';",
      "internal": true,
      "importNotice": "Тип \"CanvasTextOverflow\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/utils/textOverflow.ts"
    },
    "CanvasTextAutoTooltip": {
      "name": "CanvasTextAutoTooltip",
      "definition": "export type CanvasTextAutoTooltip =\n  | boolean\n  | (CanvasNodeTooltipProps & {\n      /** @default true — скрыть можно через false */\n      enabled?: boolean;\n      /**\n       * Переопределение/трансформация текста тултипа. По умолчанию — собственный\n       * текст ноды. Вернуть `null` — не показывать.\n       */\n      text?: string | ((fullText: string) => string | null);\n      mouseEnterDelay?: number;\n      mouseLeaveDelay?: number;\n    });",
      "internal": true,
      "importNotice": "Тип \"CanvasTextAutoTooltip\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasText.ts"
    },
    "LinkAllProps": {
      "name": "LinkAllProps",
      "definition": "type LinkAllProps = ComponentProps<typeof Link>;",
      "internal": true,
      "importNotice": "Тип \"LinkAllProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/primitives/CanvasLink.ts"
    },
    "TAutocompleteProps": {
      "name": "TAutocompleteProps",
      "definition": "type TAutocompleteProps = ComponentProps<typeof Autocomplete>;",
      "internal": true,
      "importNotice": "Тип \"TAutocompleteProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormAutocomplete/types.ts"
    },
    "TCheckboxProps": {
      "name": "TCheckboxProps",
      "definition": "type TCheckboxProps = ComponentProps<typeof Checkbox>;",
      "internal": true,
      "importNotice": "Тип \"TCheckboxProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormCheckbox/types.ts"
    },
    "TComboboxProps": {
      "name": "TComboboxProps",
      "definition": "export type TComboboxProps = ComponentProps<typeof Combobox>;",
      "internal": true,
      "importNotice": "Тип \"TComboboxProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormCombobox/types.ts"
    },
    "TDatePickerProps": {
      "name": "TDatePickerProps",
      "definition": "type TDatePickerProps = DatePickerCompProps;",
      "internal": true,
      "importNotice": "Тип \"TDatePickerProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormDatePickers/FormDatePicker/types.ts"
    },
    "TDatePickerFormat": {
      "name": "TDatePickerFormat",
      "definition": "export type TDatePickerFormat = DayMonthYear | DayMonth | MonthYear;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { TDatePickerFormat } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/formComponents/FormDatePickers/types.ts"
    },
    "TPropsFromDatePickerRange": {
      "name": "TPropsFromDatePickerRange",
      "definition": "type TPropsFromDatePickerRange = Omit<\n  TDatePickerRangeProps,\n  keyof Required<TProps> | keyof Required<TMutationRegister<object>> | 'value'\n>;",
      "internal": true,
      "importNotice": "Тип \"TPropsFromDatePickerRange\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormDatePickers/FormDatePickerRange/types.ts"
    },
    "TMaskProps": {
      "name": "TMaskProps",
      "definition": "type TMaskProps = ComponentProps<typeof Mask>;",
      "internal": true,
      "importNotice": "Тип \"TMaskProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormMask/types.ts"
    },
    "TNumberFormatProps": {
      "name": "TNumberFormatProps",
      "definition": "type TNumberFormatProps = ComponentProps<typeof NumberFormat>;",
      "internal": true,
      "importNotice": "Тип \"TNumberFormatProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormNumberFormat/types.ts"
    },
    "TSegmentGroupNativeProps": {
      "name": "TSegmentGroupNativeProps",
      "definition": "export type TSegmentGroupNativeProps = ComponentProps<typeof SegmentGroup>;",
      "internal": true,
      "importNotice": "Тип \"TSegmentGroupNativeProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormSegments/types.ts"
    },
    "TPropsBase": {
      "name": "TPropsBase",
      "definition": "type TPropsBase = {\n  singleSelectedRequired?: boolean;\n  selectionMode?: 'single' | 'multiple';\n};",
      "internal": true,
      "importNotice": "Тип \"TPropsBase\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormSegments/types.ts"
    },
    "TSelectProps": {
      "name": "TSelectProps",
      "definition": "type TSelectProps = ComponentProps<typeof Select>;",
      "internal": true,
      "importNotice": "Тип \"TSelectProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormSelect/types.ts"
    },
    "TSwitchProps": {
      "name": "TSwitchProps",
      "definition": "type TSwitchProps = ComponentProps<typeof Switch>;",
      "internal": true,
      "importNotice": "Тип \"TSwitchProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormSwitch/types.ts"
    },
    "TTextAreaProps": {
      "name": "TTextAreaProps",
      "definition": "type TTextAreaProps = ComponentProps<typeof TextArea> & {\n  showClearButton?: boolean;\n};",
      "internal": true,
      "importNotice": "Тип \"TTextAreaProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormTextArea/types.ts"
    },
    "TTextFieldProps": {
      "name": "TTextFieldProps",
      "definition": "type TTextFieldProps = ComponentProps<typeof TextField>;",
      "internal": true,
      "importNotice": "Тип \"TTextFieldProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormTextField/types.ts"
    },
    "TContainerView": {
      "name": "TContainerView",
      "definition": "export type TContainerView =\n  | '30/70'\n  | '20/80'\n  | '70/30'\n  | '80/20'\n  | '1/1'\n  | '1/1/1'\n  | '1/3/1'\n  | 'fixed-fluid';",
      "internal": true,
      "importNotice": "Тип \"TContainerView\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/layouts/Container/Container.types.ts"
    },
    "PopoverCompProps": {
      "name": "PopoverCompProps",
      "definition": "type PopoverCompProps = ComponentProps<typeof Popover>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { PopoverCompProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Popover/index.ts"
    },
    "Table.ActiveViewModsType": {
      "name": "ActiveViewModsType",
      "definition": "export type ActiveViewModsType = Exclude<keyof ViewMods, 'bothTypes'>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ActiveViewModsType } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "TableCanvas.ActiveViewModsType": {
      "name": "ActiveViewModsType",
      "definition": "export type ActiveViewModsType = Exclude<keyof ViewMods, 'bothTypes'>;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { ActiveViewModsType } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "Table.CommonFormat": {
      "name": "CommonFormat",
      "definition": "export type CommonFormat = {\n  alignContent?: 'right' | 'left' | 'center';\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { CommonFormat } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/column-config.type.ts"
    },
    "TableCanvas.CommonFormat": {
      "name": "CommonFormat",
      "definition": "export type CommonFormat = {\n  alignContent?: 'right' | 'left' | 'center';\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CommonFormat } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "Table.GroupRow": {
      "name": "GroupRow",
      "definition": "export type GroupRow<RowType> = {\n  readonly childRows: readonly RowType[];\n  readonly childGroups: readonly RowType[] | Readonly<GroupRowsOrRows<RowType>>;\n  groupKey: string;\n  groupByKey: string;\n  groupParents: string;\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { GroupRow } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-rows-grouping/types.ts"
    },
    "TableCanvas.GroupRow": {
      "name": "GroupRow",
      "definition": "export type GroupRow<RowType> = {\n  readonly childRows: readonly RowType[];\n  readonly childGroups: readonly RowType[] | Readonly<GroupRowsOrRows<RowType>>;\n  groupKey: string;\n  groupByKey: string;\n  groupParents: string;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { GroupRow } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-rows-grouping/types.ts"
    },
    "SortColumn": {
      "name": "SortColumn",
      "definition": "export interface SortColumn {\n  readonly columnKey: string;\n  readonly direction: SortDirection;\n}",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { SortColumn } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-sorting/types.ts"
    },
    "EditingCellInfo": {
      "name": "EditingCellInfo",
      "definition": "export type EditingCellInfo<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = ObjectForExtending,\n> = Omit<EditingCellInfoGlideInstance<R, SR, CustomCtxs>, 'column'> & {\n  column: ColumnConfig<R, SR, CustomCtxs>;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { EditingCellInfo } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/column-config.type.ts"
    },
    "DrawHeaderArgs": {
      "name": "DrawHeaderArgs",
      "definition": "type DrawHeaderArgs = Parameters<NonNullable<GlideProps['drawHeader']>>[0];",
      "internal": true,
      "importNotice": "Тип \"DrawHeaderArgs\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/types.ts"
    },
    "RowIdTypeInstance": {
      "name": "RowIdTypeInstance",
      "definition": "type RowIdTypeInstance = string | number;",
      "internal": true,
      "importNotice": "Тип \"RowIdTypeInstance\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-select-row/selecting-contexts.tsx"
    },
    "FlattenedRowsArrAndMap": {
      "name": "FlattenedRowsArrAndMap",
      "definition": "export type FlattenedRowsArrAndMap<RowType, RowIdType> = {\n  flattenedRows: (RowType & {\n    [SELECTING_KEYS.level]?: number;\n    [SELECTING_KEYS.parent]?: RowType | null;\n  })[];\n\n  flattenedRowsMap: Map<\n    RowIdType,\n    RowType & {\n      [SELECTING_KEYS.level]?: number;\n      [SELECTING_KEYS.parent]?: RowType | null;\n    }\n  >;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { FlattenedRowsArrAndMap } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-select-row/types.ts"
    },
    "GlideSizeConfig": {
      "name": "GlideSizeConfig",
      "definition": "export type GlideSizeConfig = GlideSizes[SIZE];",
      "internal": true,
      "importNotice": "Тип \"GlideSizeConfig\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/constants.ts"
    },
    "ColumnGroupGlideInstance": {
      "name": "ColumnGroupGlideInstance",
      "definition": "export type ColumnGroupGlideInstance<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = {\n  readonly key: string;\n  readonly name: CanvasEl;\n  readonly children: readonly ColumnOrColumnGroupGlideInstance<\n    R,\n    SR,\n    CustomCtxs\n  >[];\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { ColumnGroupGlideInstance } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "ViewMods": {
      "name": "ViewMods",
      "definition": "export type ViewMods = {\n  rows: {\n    type: 'rows';\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n     */\n    domMetadata?: DomMetadata;\n  };\n  cards: {\n    type: 'cards';\n    typeCardsRender: ReactNode;\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n     */\n    domMetadata?: DomMetadata;\n  };\n  bothTypes: {\n    type: 'both-types';\n    typeCardsRender: ReactNode;\n    default?: 'cards' | 'rows';\n    /**\n     * Метки для автоматизированного тестирования и аналитики\n     * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n     */\n    domMetadata?: DomMetadata;\n  };\n};",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ViewMods } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "SummaryCheckedFunc": {
      "name": "SummaryCheckedFunc",
      "definition": "type SummaryCheckedFunc<\n  RowType,\n  ReturnType,\n  AdditionalPropsObj extends ObjectForExtending | void = void,\n  RowIdType extends string | number = string | number,\n> = (\n  props: {\n    rows: RowType[];\n    flattenedRows: (RowType & {\n      level?: number;\n      parent?: RowType | null;\n    })[];\n    selectedRowsIds: ReadonlySet<string | number>;\n    rowKeyGetter: (row: RowType) => string | number;\n    rowCheckboxDisabled: SelectingRowConfig<\n      RowType,\n      RowIdType\n    >['rowCheckboxDisabled'];\n    rowShowCheckbox: SelectingRowConfig<RowType, RowIdType>['rowShowCheckbox'];\n    allRowsInLevels: (RowType & {\n      level?: number;\n      parent?: RowType | null;\n    })[];\n    getAllRowsInfo: () => ChildrenInfo<RowType, RowIdType>;\n  } & (AdditionalPropsObj extends ObjectForExtending\n    ? AdditionalPropsObj\n    : // eslint-disable-next-line @typescript-eslint/ban-types\n      {}),\n) => ReturnType;",
      "internal": true,
      "importNotice": "Тип \"SummaryCheckedFunc\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "RowShowCheckbox": {
      "name": "RowShowCheckbox",
      "definition": "export type RowShowCheckbox<RowType> = (\n  row: RowType,\n  lvl?: number,\n  parent?: RowType | null,\n) => boolean;",
      "internal": true,
      "importNotice": "Тип \"RowShowCheckbox\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-select-row/types.ts"
    },
    "RowCheckboxDisabled": {
      "name": "RowCheckboxDisabled",
      "definition": "export type RowCheckboxDisabled<RowType> = (\n  row: RowType,\n  lvl?: number,\n  parent?: RowType | null,\n) => boolean;",
      "internal": true,
      "importNotice": "Тип \"RowCheckboxDisabled\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-select-row/types.ts"
    },
    "RowGetStatesProps": {
      "name": "RowGetStatesProps",
      "definition": "export type RowGetStatesProps<RowType, RowIdType> = {\n  /**\n   * просчитанное по умолчанию значение наличия чекбокса у строки\n   */\n  isHaveCheckboxCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение checked у строки\n   */\n  isRowSelectedCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение indeterminate у строки\n   */\n  isIndeterminateCalculated: boolean;\n  /**\n   * просчитанное по умолчанию значение disabled у строки\n   */\n  isRowSelectionDisabled: boolean;\n\n  rowKeyGetter: RowKeyGetter<RowType, RowIdType>;\n  row: RowType;\n  /**\n   * Все строки таблицы в плоском виде с информацией об уровне и родительской строке\n   */\n  flattenedRowsMap: Map<\n    RowIdType,\n    RowType & {\n      level?: number;\n      parent?: RowType | null | undefined;\n    }\n  >;\n  /**\n   * стейт всех выбранных строк (Set)\n   */\n  selectedRows: ReadonlySet<RowIdType>;\n  /**\n   * сеттер стейта всех выбранных строк\n   */\n  setSelectedRows: React.Dispatch<React.SetStateAction<ReadonlySet<RowIdType>>>;\n  /**\n   * уровень вложенности текущей строки\n   */\n  level: number;\n  /**\n   * родительская строка для текущей строки\n   */\n  parent: RowType | null;\n  /**\n   * хендлер для получения детальных данных о дочерних строках текущей строки\n   */\n  getRowChildrenInfo: () => ChildrenInfo<RowType, RowIdType>;\n  rowShowCheckbox: RowShowCheckbox<RowType> | undefined;\n  rowCheckboxDisabled: RowCheckboxDisabled<RowType> | undefined;\n};",
      "internal": true,
      "importNotice": "Тип \"RowGetStatesProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-select-row/types.ts"
    },
    "RowGetStatesReturnType": {
      "name": "RowGetStatesReturnType",
      "definition": "export type RowGetStatesReturnType<RowType, RowIdType> = {\n  /**\n   * состояние checked, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  checked?: boolean | null;\n  /**\n   * состояние indeterminate, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  indeterminate?: boolean | null;\n  /**\n   * состояние showCheckbox, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  showCheckbox?: boolean | null;\n  /**\n   * состояние checkboxDisabled, которое будет окончательным. Если не передано, то будет взято из расчетов по умолчанию\n   */\n  checkboxDisabled?: boolean | null;\n  /**\n   * onChange у чекбокса, который будет окончательным. Если не передан, то будет взят из расчетов по умолчанию\n   */\n  onChange?:\n    | ((p: {\n        allParentsMap: Map<RowIdType, RowType>;\n        isRowInLevels: (row: RowType) => boolean;\n        defaultSetter: () => void;\n        getRowParentsInfo: () => {\n          all: RowType[];\n          getShouldBeSelectedInfo: (\n            actualSelecteds: ReadonlySet<RowIdType>,\n          ) => {\n            shouldBeSelected: RowIdType[];\n            shouldNotBeSelected: RowIdType[];\n          };\n        };\n      }) => void)\n    | null;\n};",
      "internal": true,
      "importNotice": "Тип \"RowGetStatesReturnType\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-select-row/types.ts"
    },
    "RowsChangeData": {
      "name": "RowsChangeData",
      "definition": "export interface RowsChangeData<R, SR = unknown> {\n  indexes: number[];\n  column: CalculatedColumn<R, SR>;\n  rows: { before: R; after: R }[];\n}",
      "importPath": "@daisforge/ui",
      "importStatement": "import { RowsChangeData } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "DropdownItemOption": {
      "name": "DropdownItemOption",
      "definition": "export type DropdownItemOption = {\n  /**\n   *  Значение у item\n   */\n  value: string | number;\n  /**\n   * Метка-подпись к item\n   */\n  label: string;\n  /**\n   * Список дочерних items.\n   */\n  items?: Array<DropdownItemOption>;\n  /**\n   * Item не активен\n   */\n  disabled?: boolean;\n  /**\n   * Слот для контента слева\n   */\n  contentLeft?: ReactNode;\n  /**\n   * Слот для контента справа\n   */\n  contentRight?: ReactNode;\n  /**\n   * Отобразить ли разделитель до элемента\n   */\n  dividerBefore?: boolean;\n  /**\n   * Отобразить ли разделитель после элемента\n   */\n  dividerAfter?: boolean;\n  /**\n   * Выбранный item.\n   * @deprecated использовать ContentLeft || ContentRight\n   */\n  isActive?: boolean;\n  /**\n   * Кастомный цвет текста\n   * @deprecated\n   */\n  color?: string;\n  /**\n   * Item не активен\n   * @deprecated использовать disabled\n   */\n  isDisabled?: boolean;\n};",
      "internal": true,
      "importNotice": "Тип \"DropdownItemOption\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/types/additional.type.ts"
    },
    "ControlBlockButtonProps": {
      "name": "ControlBlockButtonProps",
      "definition": "export type ControlBlockButtonProps = DataAttributes &\n  Omit<Partial<ButtonProps>, DefPropsKeys> & {\n    view?: LinkView<LinkButtonView> | ButtonProps['view'];\n    dropdown?: TableDropdownProps;\n    isTargetAction?: boolean;\n  };",
      "importPath": "@daisforge/ui",
      "importStatement": "import { ControlBlockButtonProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/widgets/control-block/control-block-button.types.tsx"
    },
    "FeatureItem": {
      "name": "FeatureItem",
      "definition": "export type FeatureItem = FeatureItemWithIcon | FeatureItemWithCustomIcon;",
      "internal": true,
      "importNotice": "Тип \"FeatureItem\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/widgets/control-block/types.ts"
    },
    "IconsPropType": {
      "name": "IconsPropType",
      "definition": "export type IconsPropType = {\n  closed?: ReactNode;\n  opened?: ReactNode;\n  iconButtonProps?: IconButtonProps;\n};",
      "internal": true,
      "importNotice": "Тип \"IconsPropType\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-row-detail/types.ts"
    },
    "FullScreenObj": {
      "name": "FullScreenObj",
      "definition": "export type FullScreenObj = {\n  /**\n   * @default false\n   */\n  defaultOpened?: boolean;\n  state?: [boolean, (arg: (prev: boolean) => typeof prev) => void];\n  /**\n   * @default true\n   */\n  showInControl?: boolean;\n  /**\n   * @default document.body\n   */\n  portal?: Element | DocumentFragment | false;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};",
      "internal": true,
      "importNotice": "Тип \"FullScreenObj\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-full-screen/types.ts"
    },
    "SidebarTab": {
      "name": "SidebarTab",
      "definition": "export type SidebarTab = {\n  /**\n   * Уникальный идентификатор таба\n   */\n  id: DefaultSidebarTabIds | string;\n  /**\n   * title таба (для Tooltip)\n   */\n  label: string;\n  /**\n   * Иконка таба\n   */\n  icon: ReactNode;\n  /**\n   * Контентная часть сайдбара\n   */\n  content: React.ReactNode;\n  /**\n   * Показывать ли в сайдбаре\n   * @default true\n   */\n  showInSidebar?: boolean;\n  /**\n   * Заголовок контентной части сайдбара\n   */\n  title?: string;\n  /**\n   * Кастомный элемент справа от title в шапке сайдбара\n   */\n  titleRightSlot?: React.ReactNode;\n  /**\n   * Метки для автоматизированного тестирования и аналитики\n   * Добавляет data-атрибуты и CSS-классы к элементам controlBlock\n   */\n  domMetadata?: DomMetadata;\n};",
      "internal": true,
      "importNotice": "Тип \"SidebarTab\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/widgets/control-block/types.ts"
    },
    "DefaultSidebarTabIds": {
      "name": "DefaultSidebarTabIds",
      "definition": "export type DefaultSidebarTabIds = 'columns' | 'tableSettings' | 'filtering';",
      "importPath": "@daisforge/ui",
      "importStatement": "import { DefaultSidebarTabIds } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/table-config.type.ts"
    },
    "SearchAutocompleteConfig": {
      "name": "SearchAutocompleteConfig",
      "definition": "export type SearchAutocompleteConfig = Pick<\n  AutocompleteProps,\n  | 'suggestions'\n  | 'onSuggestionSelect'\n  | 'threshold'\n  | 'renderList'\n  | 'renderListEnd'\n  | 'beforeList'\n  | 'listMaxHeight'\n  | 'listWidth'\n  | 'portal'\n  | 'hasDivider'\n  | 'beforeList'\n  | 'afterList'\n  | 'virtual'\n  | 'hasDivider'\n  | 'onScroll'\n  | 'zIndex'\n  | 'filter'\n  | 'renderItem'\n>;",
      "internal": true,
      "importNotice": "Тип \"SearchAutocompleteConfig\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-searching/types.ts"
    },
    "ContextMenuDropDownProps": {
      "name": "ContextMenuDropDownProps",
      "definition": "export type ContextMenuDropDownProps = Omit<\n  DropdownProps,\n  | 'children'\n  | 'items'\n  | 'placement'\n  | 'closeOnOverlayClick'\n  | 'portal'\n  | 'openByRightClick'\n  | 'onItemClick'\n  | 'hoverIndex'\n  | 'size'\n  | 'alwaysOpened'\n  | 'trigger'\n  | 'hasArrow'\n  | 'onItemSelect'\n>;",
      "internal": true,
      "importNotice": "Тип \"ContextMenuDropDownProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/feature-context-menu/types.ts"
    },
    "Key": {
      "name": "Key",
      "definition": "export type Key = string | number | bigint;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { Key } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/Table/types/utils.type.ts"
    },
    "DefaultColumnOptions": {
      "name": "DefaultColumnOptions",
      "definition": "declare type DefaultColumnOptions<R, SR> = Pick<\n  Column<R, SR>,\n  | 'renderCell'\n  | 'width'\n  | 'minWidth'\n  | 'maxWidth'\n  | 'resizable'\n  | 'sortable'\n  | 'draggable'\n>;",
      "internal": true,
      "importNotice": "Тип \"DefaultColumnOptions\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/Table/types/data-grid.type.ts"
    },
    "ColumnsGroupingConfig": {
      "name": "ColumnsGroupingConfig",
      "definition": "export type ColumnsGroupingConfig = {\n  /**\n   * Объединять пустые ячейки шапки: колонка без группы (конечная, без вложенных\n   * подколонок) растягивается вверх на всю высоту шапки, а «мелкая» группа (без более\n   * глубоких подгрупп) — вниз. Убирает пустые полосы в многоуровневой шапке.\n   * Включает/выключает поведение сразу для всей таблицы.\n   * @default true\n   */\n  squashEmptyCells?: boolean;\n  /**\n   * Дефолт выравнивания текста в объединённых ячейках шапки. Влияет только на\n   * объединённые ячейки, обычные (не объединённые) ячейки не затрагивает. Точечно\n   * перекрывается на колонке или группе через их собственный `squashedHeaderAlign`.\n   */\n  squashedHeaderAlign?: HeaderAlignment;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { ColumnsGroupingConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/columns-grouping.type.ts"
    },
    "CellsSelectionConfig": {
      "name": "CellsSelectionConfig",
      "definition": "export type CellsSelectionConfig = {\n  /**\n   * Режим фактического выделения ячеек (нативный glide selection). По нему\n   * работают copy/paste, рамка, fill-handle и затемнение шапки/нумерации.\n   * @default \"range-cell\"\n   */\n  mode?: CellsSelectionMode;\n  /**\n   * Выделение колонок по клику на шапку. Ctrl/Cmd — добавить/убрать колонку,\n   * Shift — диапазон колонок. Клик по иконкам сортировки/фильтрации в шапке\n   * выделение НЕ вызывает. Поддерживает copy/paste по выделенным колонкам.\n   * @default true\n   */\n  enableColumnSelection?: boolean;\n  /**\n   * Выделение строк по клику/драгу на колонке нумерации (`rowMarkers`).\n   * Ctrl/Cmd — несмежный выбор отдельных строк, драг — смежный диапазон.\n   * Поддерживает copy/paste по выделенным строкам. Требует включённой колонки\n   * нумерации (`rowMarkers`). При `false` клик по нумерации ничего не выделяет.\n   * @default true\n   */\n  enableRowSelection?: boolean;\n  /**\n   * Выделение всей таблицы кликом по «нулевой» ячейке — шапке колонки нумерации\n   * (левый верхний угол). Выделяет все строки данных по всем колонкам одним\n   * диапазоном; поддерживает copy/paste. Требует включённой колонки нумерации\n   * (`rowMarkers`) и активного `mode` (≠ `disabled`).\n   * @default true\n   */\n  enableSelectAll?: boolean;\n  /**\n   * Внешний (controlled) контроль НАТИВНОГО выделения (ячейки/диапазон/смежные\n   * строки и колонки). `state` — кортеж `[value, setter]` как у `selecting.state`.\n   * Сброс: `setter({ current: undefined, rows: empty, columns: empty })`.\n   * Несмежный Ctrl-выбор колонок/строк (own-state) сюда не входит — он внутренний.\n   */\n  state?: [GridSelection, React.Dispatch<React.SetStateAction<GridSelection>>];\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellsSelectionConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "BordersConfig": {
      "name": "BordersConfig",
      "definition": "export type BordersConfig<RowType = ObjectForExtending> = {\n  /** Рисовать ли вертикальные линии между колонками. @default true */\n  vertical?: boolean;\n  /** Рисовать ли горизонтальные линии между строками тела. @default true */\n  horizontal?: boolean;\n  /**\n   * Точечное управление вертикальной линией справа от колонки (разделитель\n   * после неё). Вернуть true или false, чтобы переопределить общую настройку\n   * vertical, или undefined, чтобы оставить её. Зовётся на каждую видимую\n   * колонку при перерисовке, поэтому функция должна быть быстрой.\n   */\n  getVerticalBorder?: (params: {\n    /** Ключ колонки, справа от которой рисуется линия. */\n    columnKey: string;\n    /** Индекс колонки в порядке отрисовки (закреплённые в начале). */\n    columnIndex: number;\n  }) => boolean | undefined;\n  /**\n   * Точечное управление горизонтальной линией сверху строки. Вернуть true или\n   * false, чтобы переопределить общую настройку horizontal, или undefined,\n   * чтобы оставить её. Для summary-строк не вызывается. Зовётся на каждую\n   * видимую строку при перерисовке, поэтому функция должна быть быстрой.\n   */\n  getHorizontalBorder?: (params: {\n    /** Строка под линией (линия рисуется сверху этой строки). */\n    row: RowType;\n    /** Индекс строки среди отображаемых. При раскрытии subRows индексы сдвигаются. */\n    rowIndex: number;\n    /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n    treeLvl: number;\n  }) => boolean | undefined;\n  /**\n   * Стороны рамки конкретной ячейки, вкл и выкл. Для ячеек без переопределений\n   * возвращать undefined. Включает отрисовку линий с разбивкой по ячейкам,\n   * поэтому функция должна быть быстрой: без тяжёлых вычислений и с готовыми\n   * объектами-константами вместо новых на каждый вызов. Для summary-строк не\n   * вызывается.\n   */\n  getCellBorder?: (params: {\n    /** Индекс колонки среди отображаемых (без служебных). */\n    col: number;\n    /** Ключ колонки. */\n    columnKey: string | undefined;\n    /** Строка ячейки. */\n    row: RowType;\n    /** Индекс строки среди отображаемых. */\n    rowIndex: number;\n    /** Уровень вложенности subRows: 0 корень, 1 и больше дочерние. */\n    treeLvl: number;\n  }) => CellBorderVisibility | undefined;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { BordersConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "CellTransferConfig": {
      "name": "CellTransferConfig",
      "definition": "export type CellTransferConfig = {\n  /**\n   * Явное включение/выключение всей фичи.\n   * По умолчанию copy работает всегда, а paste и fill handle следуют\n   * за `editModeEnabled`. При `false` отключается всё.\n   */\n  enabled?: boolean;\n  /**\n   * Переопределение хоткеев.\n   * Можно передать один `HotkeyConfig` или массив альтернативных комбинаций.\n   * По умолчанию: copy = Ctrl+C / Cmd+C, paste = Ctrl+V / Cmd+V.\n   */\n  hotkeys?: {\n    /** Хоткей(и) для копирования */\n    copy?: HotkeyConfig | HotkeyConfig[];\n    /** Хоткей(и) для вставки */\n    paste?: HotkeyConfig | HotkeyConfig[];\n  };\n  /** Настройки paste (readonly, overflow, broadcast, validation) */\n  paste?: PasteConfig;\n  /** Настройки fill handle. `true/false` — быстрое вкл/выкл без деталей */\n  fillHandle?: boolean | FillHandleConfig;\n  /**\n   * Колбэк перед копированием.\n   * Можно модифицировать данные (вернуть новый `string[][]`) или отменить\n   * операцию (вернуть `false`).\n   * Если onBeforeCopy нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n   */\n  onBeforeCopy?: (data: string[][], meta: CopyMeta) => string[][] | false;\n  /**\n   * Колбэк перед вставкой.\n   * Можно модифицировать данные (вернуть новый `string[][]`) или отменить\n   * операцию (вернуть `false`).\n   * Если onBeforePaste нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n   */\n  onBeforePaste?: (data: string[][], meta: PasteMeta) => string[][] | false;\n  /**\n   * Колбэк перед fill handle (drag-to-fill).\n   * Вызывается перед применением значений. Можно модифицировать данные\n   * (вернуть новый `string[][]`) или отменить операцию (вернуть `false`).\n   *\n   * `meta.sourceCells` содержит полную информацию об исходных ячейках,\n   * включая объекты строк (`row`) — позволяет получить source row\n   * и использовать данные из соседних колонок.\n   * Если onBeforeFill нужен для side-эффектов, то функция должна вернуть data из первого аргумента без изменений.\n   */\n  onBeforeFill?: (data: string[][], meta: FillMeta) => string[][] | false;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { CellTransferConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-cell-transfer/types.ts"
    },
    "MergedCellsRegion": {
      "name": "MergedCellsRegion",
      "definition": "export type MergedCellsRegion = {\n  rowKeys: Array<string | number>;\n  colKeys: string[];\n  /** Выравнивание контента этого блока. Важнее колоночного и общего. */\n  mergedCellsAlign?: MergedCellsAlign;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { MergedCellsRegion } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "TableNotificationsConfig": {
      "name": "TableNotificationsConfig",
      "definition": "export interface TableNotificationsConfig {\n  /** Вызывается на каждое событие таблицы (ошибки copy/paste и т.д.). */\n  onNotification: (event: TableNotification) => void;\n}",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableNotificationsConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-notifications/types.ts"
    },
    "RowMarkersTableConfig": {
      "name": "RowMarkersTableConfig",
      "definition": "export type RowMarkersTableConfig<\n  RowType extends ObjectForExtending = ObjectForExtending,\n> = {\n  /**\n   * Стартовый индекс нумерации (для дефолтной логики без `getRowMarker`).\n   * @default 1\n   */\n  startIndex?: number;\n\n  /**\n   * Ширина столбца с нумерацией (в px).\n   * Если задан `size` — он приоритетнее.\n+  * Если ни `size`, ни `width` не заданы — ширина подстраивается\n+  * под глобальный `tableConfig.rowSize` (small=20, medium=32, big=48).\n   * @default 32\n   */\n  width?: number;\n  /**\n   * Размер столбца. Приоритетнее `width`.\n   * - `xs` = 20px\n   * - `s` = 32px\n   * - `m` = 48px\n   */\n  size?: 'xs' | 's' | 'm';\n  /**\n   * Кастомная функция нумерации. Полностью переопределяет дефолтную root-only логику.\n   * Вызывается при рендере каждой ячейки столбца нумерации.\n   *\n   * ⚠️ Вызывается не только при полной отрисовке таблицы, но и при ховере/скролле —\n   * для **одной** ячейки. Не используйте внешние переменные-счётчики —\n   * используйте аргументы (`siblingPath`, `flatIndex` и др.), они всегда актуальны.\n   *\n   * @example\n   * // Сквозная стабильная нумерация (все строки, номера не прыгают при сворачивании)\n   * getRowMarker: ({ flatIndex }) => flatIndex + 1\n   *\n   * @example\n   * // Корневые — номер, дочерние — прочерк\n   * getRowMarker: ({ isSubRow, flatIndex }) => isSubRow ? '—' : flatIndex + 1\n   *\n   * @example\n   * // Иерархическая нумерация любой глубины: 1, 1.1, 1.1.1, 1.2, 2\n   * getRowMarker: ({ siblingPath }) => siblingPath.map(i => i + 1).join('.')\n   */\n  getRowMarker?: (args: {\n    /** Данные текущей строки. */\n    row: RowType;\n    /** Уровень строки в дереве: `0` — корневая, `1` — дочерняя, `2` — внучка, и т.д. */\n    level: number;\n    /** `true`, если строка дочерняя (`level > 0`). */\n    isSubRow: boolean;\n    /**\n     * Индекс строки в **видимых** строках.\n     * **Нестабильный** — меняется при сворачивании и разворачивании веток.\n     */\n    rowIndex: number;\n    /**\n     * Стабильный 0-based индекс строки в **полном** дереве (включая скрытые/свёрнутые).\n     * Не меняется при collapse/expand — подходит для сквозной нумерации.\n     */\n    flatIndex: number;\n    /**\n     * Порядковый номер среди siblings одного родителя (0-based).\n     * Для корневых строк — порядковый номер среди всех корневых.\n     * Для дочерних — порядковый номер среди children одного `parentKey`.\n     */\n    siblingIndex: number;\n    /**\n     * Путь siblingIndex-ов от корня до текущей строки (каждый элемент 0-based).\n     *\n     * Примеры:\n     * - корневая строка (2-я): `[1]`\n     * - дочерняя (3-й ребёнок 2-го корня): `[1, 2]`\n     * - внучка (1-й ребёнок 1-го ребёнка 1-го корня): `[0, 0, 0]`\n     *\n     * Для иерархической нумерации: `siblingPath.map(i => i + 1).join('.')` → `\"1.1.1\"`\n     *\n     * Для плоской таблицы (без subRows): всегда `[siblingIndex]` (один элемент).\n     */\n    siblingPath: number[];\n    /**\n     * Ключ родительской строки (`rowKeyGetter(parent)`).\n     * `null` для корневых строк. Работает для **любой** глубины вложенности.\n     */\n    parentKey: string | number | null;\n    /** Текущий видимый `flattened` массив строк. */\n    rows: readonly RowType[];\n  }) => string | number;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { RowMarkersTableConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "TableConfigTooltip": {
      "name": "TableConfigTooltip",
      "definition": "export type TableConfigTooltip = {\n  /**\n   * Включить/выключить колоночные и кастомные тултипы (cellTooltip, headerCellTooltip).\n   * Внутренние тултипы (drag-иконка в шапке и другие по nodeId) работают всегда.\n   * @default false\n   */\n  enabled?: boolean;\n  /** Глобальная задержка перед показом тултипа (мс). Per-node переопределяет. @default 500 */\n  mouseEnterDelay?: number;\n  /** Глобальная задержка перед скрытием тултипа (мс). Per-node переопределяет. @default 0 */\n  mouseLeaveDelay?: number;\n  /**\n   * Минимальная ширина тултипа. Число трактуется как px, строка с единицей\n   * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n   * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n   * (per-node), приоритет у неё.\n   */\n  minWidth?: number | string;\n  /**\n   * Максимальная ширина тултипа. Число трактуется как px, строка с единицей\n   * (например '20rem', '50%') отдаётся как есть. Действует на все canvas-тултипы,\n   * включая авто-тултип Canvas.Text. Если ширина задана на самом тултипе\n   * (per-node), приоритет у неё.\n   */\n  maxWidth?: number | string;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableConfigTooltip } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "InfinityScrollConfig": {
      "name": "InfinityScrollConfig",
      "definition": "export type InfinityScrollConfig<RowType extends ObjectForExtending> = {\n  /** Триггер достижения скроллом зоны подгрузки данных. */\n  onTrigger: (rows: RowType[]) => Promise<void> | void;\n  /** Состояние загрузки (скелетоны) новых строк. */\n  isLoading: boolean;\n  /**\n   * Флаг, когда все данные загружены — false.\n   * @default true\n   */\n  hasMore?: boolean;\n  /**\n   * Для mode='region': за сколько строк до конца триггерить загрузку.\n   * @default 5\n   */\n  rowThreshold?: number;\n};",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { InfinityScrollConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "TableCanvasEmptyStateConfig": {
      "name": "TableCanvasEmptyStateConfig",
      "definition": "export type TableCanvasEmptyStateConfig = TableCanvasContentStateBase &\n  Partial<EmptyStateProps>;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableCanvasEmptyStateConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-content-state/types.ts"
    },
    "TableCanvasErrorStateConfig": {
      "name": "TableCanvasErrorStateConfig",
      "definition": "export type TableCanvasErrorStateConfig = TableCanvasContentStateBase &\n  Partial<ErrorPageProps>;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableCanvasErrorStateConfig } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-content-state/types.ts"
    },
    "TableGlideInstanceProps": {
      "name": "TableGlideInstanceProps",
      "definition": "export type TableGlideInstanceProps<\n  R extends ObjectForExtending,\n  SR = unknown,\n  CustomCtxs extends ObjectForExtending = {},\n> = Omit<\n  TableGlideProps<R, SR>,\n  'columns' | 'onHeaderContextMenu' | 'onCellContextMenu'\n> & {\n  columns: readonly ColumnGlideInstance<R, SR, CustomCtxs>[];\n  onHeaderContextMenuDropdown?: HeaderContextMenuDropdownProps<\n    R,\n    SR,\n    CustomCtxs\n  >;\n  onCellContextMenuDropdown?: CellContextMenuDropdownProps<R, SR>;\n  containerProps?: {\n    className?: string;\n    style?: React.CSSProperties;\n    ref?: React.Ref<HTMLDivElement>;\n  };\n  contentStateOverlay?: TableContentStateOverlay;\n  renderOverlayFeatures?: (ctx: {\n    containerElement: HTMLDivElement;\n    renderInContainer: (children: React.ReactNode) => React.ReactPortal | null;\n  }) => React.ReactNode;\n  CellReadOnlyEditor: (\n    props: CellReadOnlyEditorGlideInstanceProps<R, SR>,\n  ) => ReactNode;\n  onRowsChange?: (\n    rows: R[],\n    data: RowsChangeDataGlideInstance<R, SR, CustomCtxs>,\n  ) => void;\n  onCellClicked?: (\n    cell: readonly [number, number],\n    info: TableInfoWithRow<R, SR, CustomCtxs>,\n  ) => void;\n} & TableGlideInstanceContextMenu<R, SR, CustomCtxs>;",
      "importPath": "@daisforge/ui/components/TableCanvas",
      "importStatement": "import { TableGlideInstanceProps } from '@daisforge/ui/components/TableCanvas';",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/TableGlideInstance/type.ts"
    },
    "GlideInstanceOmitted": {
      "name": "GlideInstanceOmitted",
      "definition": "type GlideInstanceOmitted<\n  RowType extends ObjectForExtending,\n  SummaryRowType,\n> = Pick<\n  Omit<\n    TableGlideInstanceProps<RowType, SummaryRowType>,\n    | keyof TableGlideCustomProps<RowType, SummaryRowType>\n    | 'CellReadOnlyEditor' /* CellReadOnlyEditor - свойство только для GlideInstance */\n  >,\n  | 'className'\n  | 'columnSelect'\n  | 'minColumnWidth'\n  | 'maxColumnWidth'\n  | 'maxColumnAutoWidth'\n  | 'onVisibleRegionChanged'\n  | 'onCellClicked'\n  // | 'CellReadOnlyEditor'\n  // | 'onGroupHeaderClicked'\n  | 'onHeaderClicked'\n  | 'onItemHovered'\n  | 'trapFocus'\n  | 'onColumnResize'\n>;",
      "internal": true,
      "importNotice": "Тип \"GlideInstanceOmitted\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/types/table-config.type.ts"
    },
    "CellTransferCellInfo": {
      "name": "CellTransferCellInfo",
      "definition": "export type CellTransferCellInfo = {\n  /** Объект строки, в которой находится ячейка */\n  row: ObjectForExtending;\n  /** Конфиг колонки (срез важных полей) */\n  column: TransferColumnConfig;\n  /** Индекс колонки в массиве columns */\n  colIndex: number;\n  /** Индекс строки в массиве flattenedRows */\n  rowIndex: number;\n  /** Уровень вложенности subrow: 0 — parent, 1+ — subrow */\n  lvl: number;\n  /** Сырое значение из `row[key]` или `row[subKey]` (без форматирования) */\n  rawValue: unknown;\n  /** Текстовое представление ячейки (то что попадает в TSV) */\n  formattedValue: string;\n};",
      "internal": true,
      "importNotice": "Тип \"CellTransferCellInfo\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableCanvas/feature-cell-transfer/types.ts"
    },
    "CrossAxisSizing": {
      "name": "CrossAxisSizing",
      "definition": "export type CrossAxisSizing = 'auto' | 'deferred-percent-stretch';",
      "internal": true,
      "importNotice": "Тип \"CrossAxisSizing\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/components/TableGlide/lib/canvas/miniflex/types.ts"
    },
    "DatePickerCompProps": {
      "name": "DatePickerCompProps",
      "definition": "export type DatePickerCompProps = ComponentProps<typeof DatePicker>;",
      "importPath": "@daisforge/ui",
      "importStatement": "import { DatePickerCompProps } from '@daisforge/ui';",
      "sourceFile": "packages/ui-kit/src/components/DatePicker/DatePicker.types.ts"
    },
    "DayMonthYear": {
      "name": "DayMonthYear",
      "definition": "type DayMonthYear =\n  `${DayToken}${Delimiter}${MonthToken}${Delimiter}${YearToken}`;",
      "internal": true,
      "importNotice": "Тип \"DayMonthYear\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormDatePickers/types.ts"
    },
    "DayMonth": {
      "name": "DayMonth",
      "definition": "type DayMonth = `${DayToken}${Delimiter}${TextMonthToken}`;",
      "internal": true,
      "importNotice": "Тип \"DayMonth\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormDatePickers/types.ts"
    },
    "MonthYear": {
      "name": "MonthYear",
      "definition": "type MonthYear = `${MonthToken}${Delimiter}${YearToken}`;",
      "internal": true,
      "importNotice": "Тип \"MonthYear\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormDatePickers/types.ts"
    },
    "TDatePickerRangeProps": {
      "name": "TDatePickerRangeProps",
      "definition": "type TDatePickerRangeProps = ComponentProps<typeof DatePickerRange>;",
      "internal": true,
      "importNotice": "Тип \"TDatePickerRangeProps\" не экспортируется из публичной точки входа — импортировать его нельзя. Определение приведено для понимания структуры: опишите нужную форму по месту либо возьмите её из типа, который экспортирован.",
      "sourceFile": "packages/ui-kit/src/formComponents/FormDatePickers/FormDatePickerRange/types.ts"
    }
  },
  "guides": {
    "installation": {
      "title": "Установка и использование",
      "description": "Установка пакета и использование компонентов, иконок и токенов.",
      "docs": "<div className=\"sb-container\">\n  <img src={introImage} />\n</div>\n\n<div className=\"sb-container\">\n  <div className='sb-section-title'>\n    # Установка\n\n    Рекомендуется использовать ```\"typescript\": \">=5.0.0\"```\n\n    Установите зависимости (если не установлены):\n    ```json\n    \"react\": \">=17.0.0\",\n    \"react-dom\": \">=17.0.0\",\n    \"styled-components\": \"5.3.1\"\n    ```\n    <Source\n      language='bash'\n      dark\n      format={'dedent'}\n      code={`\n        npm install react react-dom styled-components@5.3.1\n        npm install -D @types/styled-components\n      `}\n    />\n\n    Установите пакет библиотеки:\n    <Source\n      language='bash'\n      dark\n      format={false}\n      code={`npm install -S @daisforge/ui`}\n    />\n\n  </div>\n</div>\n<div className=\"sb-container\">\n  <div className='sb-section-title'>\n    # Подключение стилей в проекте\n\n    В корне приложения импортируйте готовый компонент `GlobalStyle` или `DarkGlobalStyle` и подключите его:\n\n    ```jsx\n    // index.tsx\n\n    import { GlobalStyle } from '@daisforge/ui/styles';\n    import { App } from './App';\n\n    const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);\n\n    root.render(\n      <React.StrictMode>\n          <GlobalStyle />\n          <App />\n      </React.StrictMode>\n    );\n    ```\n\n  </div>\n</div>\n<div className=\"sb-container\">\n  <div className='sb-section-title'>\n    # Использование компонентов\n\n    Все компоненты доступны из корня или из папки components:\n\n    ```jsx\n    // App.tsx\n\n    import { Button } from '@daisforge/ui';\n    // или import { Button } from '@daisforge/ui/components/Button\n\n    export const App = () => {\n        return (\n            <div>\n              <Button>Hello, SDDS!</Button>\n            </div>\n        );\n    };\n    ```\n\n  </div>\n\n</div>\n<div className=\"sb-container\">\n  <div className='sb-section-title'>\n    # Использование иконок\n    ```jsx\n    // App.tsx\n\n    import { IconClock } from '@daisforge/ui/icons';\n\n    export const App = () => {\n        return (\n            <>\n                <IconClock color=\"red\" />\n            </>\n        );\n    };\n    ```\n\n  </div>\n</div>\n\n<div className=\"sb-container\">\n  <div className='sb-section-title'>\n    # Использование токенов\n    ```jsx\n    // App.tsx\n    import styled from 'styled-components';\n    import { backgroundPrimary, textAccent } from '@daisforge/ui/tokens';\n    import { getTokenValue } from '@daisforge/ui/utils';\n\n    const accentTokenValue = getTokenValue(textAccent) // #0b7ecb\n\n    const StyledDiv = styled.div`\n        background-color: ${backgroundPrimary};\n        color: ${textAccent};\n    `;\n\n    export const App = () => {\n        return (\n            <>\n                <StyledDiv>StyledComponentsExample</StyledDiv>\n                <div style={{ background: backgroundPrimary }}>InlineExample</div>\n            </>\n        );\n    };\n    ```\n\n  </div>\n</div>"
    }
  }
}