@elcrm/components 0.2.14 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +70 -36
  2. package/dist/ActionGroup-DcApj_Mz.js +27 -0
  3. package/dist/ActionGroup.css +1 -1
  4. package/dist/ActionGroup.d.ts +19 -19
  5. package/dist/ActionGroup.js +1 -1
  6. package/dist/Avatar-eGdLrMCv.js +113 -0
  7. package/dist/Avatar.css +1 -1
  8. package/dist/Avatar.d.ts +4 -4
  9. package/dist/Avatar.js +1 -1
  10. package/dist/AvatarGroup-Dq-UrOaC.js +81 -0
  11. package/dist/AvatarGroup.css +1 -1
  12. package/dist/AvatarGroup.d.ts +8 -28
  13. package/dist/AvatarGroup.js +1 -1
  14. package/dist/AvatarName-3B4yCxHn.js +68 -0
  15. package/dist/AvatarName.css +1 -1
  16. package/dist/AvatarName.js +1 -1
  17. package/dist/Badge-BjScAXGy.js +28 -0
  18. package/dist/Badge.css +1 -1
  19. package/dist/Badge.js +1 -1
  20. package/dist/Banner-DAY18FWO.js +34 -0
  21. package/dist/Banner.css +1 -1
  22. package/dist/Banner.js +1 -1
  23. package/dist/Brand-BfCuiyf7.js +34 -0
  24. package/dist/Brand.css +1 -1
  25. package/dist/Brand.d.ts +8 -10
  26. package/dist/Brand.js +1 -1
  27. package/dist/Breadcrumb-DM_hWw5n.js +98 -0
  28. package/dist/Breadcrumb.css +1 -1
  29. package/dist/Breadcrumb.d.ts +8 -5
  30. package/dist/Breadcrumb.js +1 -1
  31. package/dist/Card-a7N8Uh_H.js +12 -0
  32. package/dist/Card.css +1 -1
  33. package/dist/Card.js +1 -1
  34. package/dist/ChatFrame-BdSYRF-B.js +37 -0
  35. package/dist/ChatFrame.css +1 -1
  36. package/dist/ChatList.js +2 -2
  37. package/dist/{ChatMessages-B8rdXiK-.js → ChatMessages-CLxwRGIa.js} +1 -1
  38. package/dist/ChatMessages.js +1 -1
  39. package/dist/ChatSplit-8iw_1Shp.js +21 -0
  40. package/dist/CodeBlock-B3wvMejv.js +34 -0
  41. package/dist/CodeBlock.css +1 -1
  42. package/dist/CodeBlock.js +1 -1
  43. package/dist/Dropdown-CR_XxNak.js +185 -0
  44. package/dist/Dropdown.css +1 -1
  45. package/dist/Dropdown.d.ts +4 -94
  46. package/dist/Dropdown.js +1 -1
  47. package/dist/EmptyState-B_wWPjUu.js +23 -0
  48. package/dist/EmptyState.css +1 -1
  49. package/dist/EmptyState.js +1 -1
  50. package/dist/{Footer-qxUlnPR9.js → Footer-Bgh_JCUe.js} +4 -4
  51. package/dist/Footer.css +1 -1
  52. package/dist/Footer.js +1 -1
  53. package/dist/Header-BMDIi3u2.js +21 -0
  54. package/dist/Header.css +1 -1
  55. package/dist/Header.js +1 -1
  56. package/dist/Healthmap-Z-LLfGW0.js +359 -0
  57. package/dist/Healthmap.css +1 -1
  58. package/dist/Healthmap.d.ts +25 -3
  59. package/dist/Healthmap.js +1 -1
  60. package/dist/{Item-D4okhsfW.js → Item-CGpkMJu0.js} +13 -13
  61. package/dist/Item.css +1 -1
  62. package/dist/Item.d.ts +7 -7
  63. package/dist/Item.js +1 -1
  64. package/dist/ItemColumn-Ch61LqE0.js +41 -0
  65. package/dist/ItemColumn.css +1 -1
  66. package/dist/ItemColumn.js +1 -1
  67. package/dist/Layout-CzEGKl9s.js +31 -0
  68. package/dist/Layout.css +1 -1
  69. package/dist/Layout.d.ts +1 -1
  70. package/dist/Layout.js +1 -1
  71. package/dist/List-D13pqaUY.js +12 -0
  72. package/dist/List.css +1 -1
  73. package/dist/List.js +1 -1
  74. package/dist/Loading-C_CKD-zt.js +16 -0
  75. package/dist/Loading.css +1 -1
  76. package/dist/Loading.js +1 -1
  77. package/dist/Menu-D2kf7fN_.js +72 -0
  78. package/dist/Menu.css +1 -1
  79. package/dist/Menu.d.ts +7 -25
  80. package/dist/Menu.js +1 -1
  81. package/dist/NavSections-CNxxBMPT.js +154 -0
  82. package/dist/NavSections.css +1 -1
  83. package/dist/NavSections.d.ts +16 -28
  84. package/dist/NavSections.js +1 -1
  85. package/dist/PageHead-BfClTLrF.js +31 -0
  86. package/dist/PageHead.css +1 -1
  87. package/dist/PageHead.d.ts +1 -1
  88. package/dist/PageHead.js +1 -1
  89. package/dist/PageShell-BAJges-G.js +30 -0
  90. package/dist/PageShell.css +1 -1
  91. package/dist/PageShell.js +1 -1
  92. package/dist/PanelInfo-Db5GCr-c.js +137 -0
  93. package/dist/PanelInfo.css +1 -1
  94. package/dist/PanelInfo.d.ts +16 -9
  95. package/dist/PanelInfo.js +1 -1
  96. package/dist/Popover-xEZoMY-h.js +143 -0
  97. package/dist/Popover.css +1 -1
  98. package/dist/Popover.d.ts +40 -11
  99. package/dist/Popover.js +1 -1
  100. package/dist/PricingGroup-CWy47MlE.js +138 -0
  101. package/dist/PricingGroup.css +1 -1
  102. package/dist/PricingGroup.d.ts +0 -2
  103. package/dist/PricingGroup.js +1 -1
  104. package/dist/PricingTable-BjpGVAhi.js +157 -0
  105. package/dist/PricingTable.css +1 -1
  106. package/dist/PricingTable.d.ts +4 -7
  107. package/dist/PricingTable.js +1 -1
  108. package/dist/RadioGroup-DI4KKUvZ.js +121 -0
  109. package/dist/RadioGroup.css +1 -1
  110. package/dist/RadioGroup.js +1 -1
  111. package/dist/Section-PprWjOvt.js +47 -0
  112. package/dist/Section.css +1 -1
  113. package/dist/Section.d.ts +29 -9
  114. package/dist/Section.js +1 -1
  115. package/dist/Sidebar-Bouhd5SS.js +205 -0
  116. package/dist/Sidebar.css +1 -1
  117. package/dist/Sidebar.d.ts +18 -26
  118. package/dist/Sidebar.js +1 -1
  119. package/dist/SplitPane-DBa-g9td.js +92 -0
  120. package/dist/SplitPane.css +1 -1
  121. package/dist/SplitPane.d.ts +8 -7
  122. package/dist/SplitPane.js +1 -1
  123. package/dist/Stack-BPTehVYc.js +53 -0
  124. package/dist/Stack.css +1 -1
  125. package/dist/Stack.d.ts +2 -1
  126. package/dist/Stack.js +1 -1
  127. package/dist/Stat-p8j4PjrC.js +28 -0
  128. package/dist/Stat.css +1 -1
  129. package/dist/Stat.js +1 -1
  130. package/dist/TabSections-Dppe9wiz.js +84 -0
  131. package/dist/TabSections.css +1 -1
  132. package/dist/TabSections.d.ts +7 -2
  133. package/dist/TabSections.js +1 -1
  134. package/dist/Table-DqrDUUtb.js +27 -0
  135. package/dist/Table.css +1 -1
  136. package/dist/Table.d.ts +10 -2
  137. package/dist/Table.js +1 -1
  138. package/dist/Text-Bo1u7gVC.js +25 -0
  139. package/dist/Text.css +1 -1
  140. package/dist/Text.js +1 -1
  141. package/dist/TextGroup-236jHxdT.js +23 -0
  142. package/dist/TextGroup.css +1 -1
  143. package/dist/TextGroup.js +1 -1
  144. package/dist/Toolbar-Bl9-5Mis.js +35 -0
  145. package/dist/Toolbar.css +1 -1
  146. package/dist/Toolbar.d.ts +7 -12
  147. package/dist/Toolbar.js +1 -2
  148. package/dist/cx.d.ts +1 -1
  149. package/dist/dark.css +12 -0
  150. package/dist/index.css +40 -40
  151. package/dist/index.d.ts +5 -12
  152. package/dist/index.es.d.ts +5 -12
  153. package/dist/index.es.js +109 -108
  154. package/dist/kit-manifest.json +1646 -0
  155. package/dist/lazyRoute.d.ts +12 -6
  156. package/dist/light.css +12 -0
  157. package/dist/navTree.d.ts +13 -1
  158. package/dist/rovingKeys-Di9N1Nct.js +23 -0
  159. package/dist/rovingKeys.d.ts +7 -1
  160. package/dist/stackGap.d.ts +1 -1
  161. package/dist/tokens.css +13 -0
  162. package/dist/useControllableValue-BaE0VR5d.js +13 -0
  163. package/dist/useControllableValue.d.ts +3 -0
  164. package/package.json +48 -4
  165. package/dist/ActionGroup-ChKFW0mt.js +0 -27
  166. package/dist/Avatar-loGgFt72.js +0 -113
  167. package/dist/AvatarGroup-D1gnT3Od.js +0 -81
  168. package/dist/AvatarName-0BzyfpMq.js +0 -68
  169. package/dist/Badge-jp-9iNNL.js +0 -28
  170. package/dist/Banner-B72lcEMo.js +0 -34
  171. package/dist/Block-Bu7NEA0g.js +0 -8
  172. package/dist/Block.d.ts +0 -30
  173. package/dist/Block.js +0 -4
  174. package/dist/Brand-Zq-Idks4.js +0 -34
  175. package/dist/Breadcrumb-CAM_e9LN.js +0 -98
  176. package/dist/Card-hn37Opo3.js +0 -12
  177. package/dist/ChatFrame-BW2TmCkZ.js +0 -37
  178. package/dist/ChatSplit-DNnu3TNq.js +0 -21
  179. package/dist/CodeBlock-CRzVopIv.js +0 -25
  180. package/dist/Column-BiogBDf8.js +0 -8
  181. package/dist/Column.d.ts +0 -24
  182. package/dist/Column.js +0 -4
  183. package/dist/Dropdown-DosvDR13.js +0 -147
  184. package/dist/EmptyState-mBiWtMIM.js +0 -23
  185. package/dist/Header-DZQopVNy.js +0 -21
  186. package/dist/Healthmap-B6cdiLUl.js +0 -243
  187. package/dist/ItemColumn-M7a9L8CI.js +0 -41
  188. package/dist/Layout-mi6Ghayv.js +0 -31
  189. package/dist/List-BgKkYaGO.js +0 -12
  190. package/dist/Loading-DkkG7RcE.js +0 -16
  191. package/dist/Menu-DuXQv-zT.js +0 -66
  192. package/dist/NavSections-D6rDEtT1.js +0 -142
  193. package/dist/PageHead-DgaJ1mXY.js +0 -31
  194. package/dist/PageShell-D9EZiO8o.js +0 -30
  195. package/dist/PanelInfo-A5y5ysH8.js +0 -81
  196. package/dist/Popover-DWdvZTuA.js +0 -135
  197. package/dist/PricingGroup-Czuhe81Z.js +0 -120
  198. package/dist/PricingTable-BuLC0opK.js +0 -152
  199. package/dist/RadioGroup-fcXzhvMu.js +0 -129
  200. package/dist/Row-DsQOVn18.js +0 -8
  201. package/dist/Row.d.ts +0 -24
  202. package/dist/Row.js +0 -4
  203. package/dist/Section-Crxk2J-E.js +0 -34
  204. package/dist/Sidebar-CYFaPqdC.js +0 -178
  205. package/dist/SplitPane-DR7PCZ8f.js +0 -74
  206. package/dist/Stack-XkmPSswj.js +0 -53
  207. package/dist/Stat-sKXJwz5L.js +0 -27
  208. package/dist/TabSections-DN7yVJoF.js +0 -69
  209. package/dist/Table-BoDr3X2d.js +0 -25
  210. package/dist/Text-zHK2wmsw.js +0 -25
  211. package/dist/TextGroup-DmhuyMR1.js +0 -23
  212. package/dist/Toolbar-C1zAk9ak.js +0 -42
  213. package/dist/rovingKeys-CGlfTtNQ.js +0 -15
  214. package/dist/useControllableValue-CWqH1kpM.js +0 -10
package/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  Shell UI для elCRM: `Layout`, `Header`, `Section`, `Stack`, `NavSections`, `TabSections` и др.
4
4
 
5
- Стили — CSS Modules с короткими уникальными классами; значения токенов задаёт приложение (`theme-dark.css` / `theme-light.css`). Fallback в пакете нет.
5
+ Стили — CSS Modules. В DOM className всегда **3 буквы** `{семья}{компонент}{первая буква локального}` (короткий код вроде c8s, только a–z): List `.root` → `llr`, Layout `.root` → `slr`, Sidebar `.root` → `nsr`. В исходнике — слова (`.root`, `.icon`). Семьи: `l` lists, `n` nav, `s` shell, `k` kit, `t` type, `a` avatar, `o` overlay, `g` pricing, `h` healthmap, `d` data. Значения токенов задаёт приложение (`theme-dark.css` / `theme-light.css`). Fallback в пакете нет.
6
+
7
+ **Локаль:** дефолтные подписи UI — на русском (`navLabel`, `label`, `copyLabel`, `aria-label` и т.п. можно переопределить). Пакет не тянет i18n-runtime.
6
8
 
7
9
  ## Визуальный стенд
8
10
 
@@ -64,13 +66,18 @@ import {
64
66
  ChatSplit,
65
67
  Sidebar,
66
68
  Popover,
69
+ Healthmap,
70
+ PanelInfo,
67
71
  createLazyResolver,
72
+ acquireOverlayZIndex,
68
73
  } from "@elcrm/components";
69
- import type { PricingPlan } from "@elcrm/components";
74
+ import type { PricingPlan, HealthmapData, NavTreeItem } from "@elcrm/components";
70
75
  // CSS подтягивается с чанками; при необходимости единый файл:
71
76
  // import "@elcrm/components/style.css";
72
77
  ```
73
78
 
79
+ Слоты `Header` заполняет приложение: поиск — `@elcrm/form` (`Search`), кнопки — `@elcrm/button`.
80
+
74
81
  Точечный импорт:
75
82
 
76
83
  ```ts
@@ -89,45 +96,65 @@ import { RadioGroup } from "@elcrm/components/RadioGroup";
89
96
  | **Brand** | Название / логотип | `as`, `children`, `onClick` |
90
97
  | **Avatar** | Фото или инициалы | `src`, `name`, `size`, `radius`, `status`, `as` |
91
98
  | **AvatarName** | Аватар + title + description | `title`, `description`, `radius`, `--avatar-name-*-color` |
92
- | **AvatarGroup** | Стопка аватаров + «+N» | `items` (`value`/`title`/`name`), `max`, `add` |
99
+ | **AvatarGroup** | Стопка аватаров + «+N» | `items` (`value` обязателен), `max`, `add`, `onValueChange` |
93
100
  | **Badge** | Метка / статус | `tone`, `size`, `dot`, `children` |
94
- | **RadioGroup** | Выбор одной опции-карточки | `items`, `value`, `indicator`, `indicatorSide` |
95
- | **PricingGroup** | Тарифные карточки в ряд | `items` (`PricingPlan`), `selectable`, `value` |
101
+ | **RadioGroup** | Выбор одной опции-карточки | `items`, `value`, `onValueChange`, `indicator`, `indicatorSide` |
102
+ | **PricingGroup** | Тарифные карточки в ряд | `items` (`PricingPlan`), `selectable`, `value`, `onValueChange` |
96
103
  | **PricingTable** | Сравнение тарифов (таблица) | те же `items` + `sections` |
97
- | **Table** | Таблица данных со скроллом | `layout` (`auto`/`fixed`), стандартные props `<table>` |
104
+ | **Table** | Таблица данных со скроллом | `layout`, `stickyHeader`, `<caption>` |
98
105
  | **CodeBlock** | Блок кода с bar и копированием | `title`, `code` / `children`, `onCopy`, `actions` |
99
- | **SplitPane** | Две панели с разделителем | `direction`, `ratio`, `onRatioChange`, `first`, `second`, `minFirst` / `minSecond` |
106
+ | **SplitPane** | Две панели с разделителем | `direction`, `ratio` / `defaultRatio`, `onRatioChange`, `first`, `second` |
100
107
  | **Banner** | Статусная полоса | `tone` (`info`/`warning`/`danger`/`success`), не toast |
101
108
  | **IconButton** | Иконка + tooltip | `name`, обязательный `label`, `tooltip` (`false` — без подсказки) |
102
- | **Menu** | Навигация в шапке (не popover) | `items` (`value`, `badge`: `0` скрыт), `value`, `onSelect`, `variant` (`plain`/`line`) |
103
- | **Dropdown** | Выпадающее меню (items, portal) | `label`/`trigger`, `items`/`groups`, `onSelect` |
104
- | **Popover** | Свой попап в portal | `trigger`, `children`, `align`, `open` |
105
- | **Breadcrumb** | Хлебные крошки | `items`, `separator`, `collapseAfter` |
106
- | **Sidebar** | Левое меню приложения | `groups`, `value`, `item.items` + `defaultOpen`, `open` / `onOpenChange`, `footerItems` |
109
+ | **Menu** | Навигация в шапке (не popover) | `items`, `value` / `defaultValue`, `onValueChange`, `variant` (`plain`/`line`) |
110
+ | **Dropdown** | Выпадающее меню (items, portal) | `label`/`trigger`, `items`/`groups`, `onValueChange` |
111
+ | **Popover** | Свой попап в portal | `trigger` (render-prop `anchorProps` или узел), `children`, `align`, `open` |
112
+ | **Breadcrumb** | Хлебные крошки | `items`, `separator`, `collapseAfter`, `onValueChange` |
113
+ | **Sidebar** | Левое меню приложения | `groups`, `value` / `defaultValue`, `onValueChange`, `footerItems` + `onFooterValueChange` |
107
114
  | **PageShell** | Каркас модуля (скролл + footer) | `wide`, `scroll`, `footer`, `children` |
108
115
  | **ChatList** | Колонка диалогов | `header`, `footer`, `children` (`List`/`Item`), `bodyRef` |
109
116
  | **ChatMessages** | Колонка переписки | `header`, `footer`, `children`, `bodyRef`, `onBodyScroll` |
110
117
  | **ChatSplit** | Список + лента | `list`, `messages` |
111
118
  | **PageHead** | Заголовок страницы + actions | `title`, `sup` (текст/Badge), `subtitle`, `actions`, `sticky`, `children` |
112
- | **Section** | Блок контента / auth / подраздел | `title`, `description`, `icon`, `actions`, `variant` |
113
- | **NavSections** | Сайдбар + lazy-панель | `groups`, `item.items` + `defaultOpen`, `open` / `onOpenChange`, `resolveSection` |
114
- | **TabSections** | Горизонтальные вкладки + lazy | `items` (`value` + `badge`), `resolveSection` |
119
+ | **Section** | Блок контента / auth / подраздел | `title`, `description`, `icon`, `actions`, `variant`, `direction`/`gap`/`columns` (тело = Stack) |
120
+ | **NavSections** | Сайдбар + lazy-панель | `groups` (`value`), `resolveSection?`, `children` (готовая панель) |
121
+ | **TabSections** | Горизонтальные вкладки + lazy | `items`, `resolveSection?`, `children` |
115
122
  | **Card** | Карточка | `title`, `--card-pointer` |
116
- | **ActionGroup** | Ряд иконок в карточке | `label`, `items` и/или `children` |
117
- | **Toolbar** | Фильтры одной высоты | `size`, `width` (`l` = 100%, `s` = по контенту), `align`, `label`, `children` |
123
+ | **ActionGroup** | Ряд иконок в карточке | `label`, `actions` и/или `children` (не декларативные `items`) |
124
+ | **Toolbar** | Фильтры одной высоты | `size` `useToolbar` + `data-size`, `width`, `align`, `label`, `children` |
118
125
  | **TextGroup** | Title + description | `title`, `description`, `size` |
119
126
  | **Text** | Короткий текст | `tone` (`default`/`muted`), `as` |
120
127
  | **ItemColumn** | Иконка + столбик в Item | `icon`, `title`, `extra`, `aside`, `description`, `footer` / `meta`, `unread` |
121
128
  | **Stat** | Карточка-метрика | `label`, `value`, `tone`, `labelMuted` |
122
- | **List** / **Item** | Список и строка | List: `row`; Item: `as`, `active`, `variant` (`plain`/`card`) |
129
+ | **List** / **Item** | Список и строка | List: `row`; Item: по умолчанию `li`, кликабельный `as="button"` |
123
130
  | **Stack** | Ряд / колонка / сетка | `direction`, `columns` (N или `["1fr", "100px"]`), `gap` |
124
131
  | **Loading** | Плейсхолдер загрузки | `children`; `--loading-min-height` |
125
132
  | **EmptyState** | Пустой / ошибка | `title`, `description`, `icon`, `actions`; `--empty-*` |
126
- | **createLazyResolver** | Кэш `import()` секций | `(key) => import(…)` |
127
-
128
- Слоты `Header` заполняет приложение: поиск — `@elcrm/search`, кнопки — `@elcrm/button`, и т.д.
129
-
130
- `Block` / `Row` / `Column` — deprecated-обёртки над `Stack`. В проектах: `elcrm migrate components`.
133
+ | **PanelInfo** | Выезд справа | `open` / `defaultOpen`, `onOpenChange` |
134
+ | **createLazyResolver** | Кэш `import()` секций | `(key) => import(…)`; `.clear(segment?)` при ошибке / retry |
135
+
136
+ Раскладка — только `Stack` (или `Section` с `direction`/`gap`/`columns`). `Block` / `Row` / `Column` **удалены** из пакета; в проектах: `elcrm migrate components`.
137
+
138
+ ### Кто когда (роли)
139
+
140
+ Не сливаем компоненты — выбирай по слою:
141
+
142
+ | Слой | Компоненты | Не путать с |
143
+ | --- | --- | --- |
144
+ | Оболочка app | `Layout` (+ Header / Footer / Sidebar) | PageShell |
145
+ | Каркас модуля | `PageShell` | Section |
146
+ | Шапка страницы | `PageHead` | Section title |
147
+ | Блок контента | `Section` (`direction` / `gap` / `columns` как у Stack) | PageHead |
148
+ | Нав app | `Sidebar` | NavSections (страница + lazy-панель) |
149
+ | Вкладки | `Menu variant="line"` = только табы; `TabSections` = табы + lazy-панель | |
150
+ | Две колонки | `SplitPane` = resize; `ChatSplit` = чат list+messages без resize | |
151
+ | Чат | `ChatList` / `ChatMessages` / `ChatSplit`; `ChatFrame` — deep `@elcrm/components/ChatFrame` | |
152
+ | Таблица | `Table` (`stickyHeader`) | PricingTable |
153
+ | Выбор планов | `PricingGroup` / `PricingTable`; `RadioGroup variant="split"` — общий radio-UI | |
154
+ | Toolbar | `Toolbar` = фильтры одной высоты; `ActionGroup` = иконки в карточке | |
155
+ | Текст | `Text` / `TextGroup` / `AvatarName` (+аватар) | |
156
+ | Статус | `Badge` метка; `Banner` полоса; `EmptyState` пустой экран | |
157
+ | Раскладка | `Stack` | Block / Row / Column |
131
158
 
132
159
  ### Sidebar
133
160
 
@@ -137,8 +164,8 @@ import { RadioGroup } from "@elcrm/components/RadioGroup";
137
164
  <Sidebar
138
165
  variant="cards"
139
166
  value={page}
140
- onSelect={setPage}
141
- brand={<Brand as="strong">App</Brand>}
167
+ onValueChange={setPage}
168
+ brand={<Brand>App</Brand>}
142
169
  extra={<Notifications.Bell />}
143
170
  groups={[
144
171
  {
@@ -167,7 +194,7 @@ import { RadioGroup } from "@elcrm/components/RadioGroup";
167
194
  { value: "theme", label: "Тема", submenu: true },
168
195
  { value: "logout", label: "Выйти", danger: true },
169
196
  ]}
170
- onFooterSelect={(value) => console.log(value)}
197
+ onFooterValueChange={(value) => console.log(value)}
171
198
  version="v 0.2.26"
172
199
  />
173
200
  ```
@@ -359,18 +386,24 @@ const sections = [
359
386
  | ------------- | -------------------------------------------------------------------------------------------------------- |
360
387
  | **PageShell** | Каркас модуля: скролл в body (`scroll`, по умолчанию да), опциональный footer снизу |
361
388
  | **PageHead** | Строка title (+ `sup` надстрочно, subtitle) слева и actions справа; `sticky` — прилипает к верху скролла |
362
- | **Section** | Блок контента / auth-карточка / подраздел с title+description |
389
+ | **Section** | Блок контента / auth / подраздел. Корень по умолчанию `<section>` (не `<main>` — его даёт Layout). Тело: `direction` / `gap` / `columns` как у Stack |
363
390
 
364
391
  ```tsx
365
- <PageShell scroll footer={<button type="button">Сохранить</button>}>
392
+ <PageShell scroll footer={<Button>Сохранить</Button>}>
366
393
  <PageHead
367
394
  sticky
368
395
  title="Товары"
369
396
  sup={12}
370
397
  subtitle="Каталог"
371
- actions={<button>Добавить</button>}
398
+ actions={<Button>Добавить</Button>}
372
399
  />
373
- <Section title="Фильтры">{/* */}</Section>
400
+ <Section title="Фильтры" direction="row" gap={12}>
401
+ <SearchField name="q" />
402
+ <Button>Найти</Button>
403
+ </Section>
404
+ <Section title="Метрики" direction="grid" columns={3} gap={16}>
405
+ <Stat label="Всего" value={10} />
406
+ </Section>
374
407
  </PageShell>
375
408
  ```
376
409
 
@@ -433,11 +466,11 @@ const people = [
433
466
  max={5}
434
467
  add
435
468
  onAdd={() => {}}
436
- onItemClick={(item) => console.log(item)}
469
+ onValueChange={(value) => console.log(value)}
437
470
  />
438
471
  ```
439
472
 
440
- `max` — сколько показать; остаток → «+N». `add` — кнопка «+» справа.
473
+ `max` — сколько показать; остаток → «+N». `add` — кнопка «+» справа. У каждого пункта обязателен `value`.
441
474
 
442
475
  ### Avatar / AvatarName
443
476
 
@@ -493,7 +526,7 @@ const people = [
493
526
  items: [{ value: "details", label: "View details", submenu: true }],
494
527
  },
495
528
  ]}
496
- onSelect={(value) => console.log(value)}
529
+ onValueChange={(value) => console.log(value)}
497
530
  />;
498
531
 
499
532
  {
@@ -568,13 +601,13 @@ const people = [
568
601
  },
569
602
  { value: "brand", label: "Бренд", checkbox: true, checked: false },
570
603
  ]}
571
- onSelect={(value) => toggleColumn(value)}
604
+ onValueChange={(value) => toggleColumn(value)}
572
605
  />;
573
606
  ```
574
607
 
575
608
  `Menu` — навигация в шапке (inline, не popover).
576
609
 
577
- **Dropdown vs Popover:** `Dropdown` — пункты `items`/`groups`. `Popover` — свой `children` в portal (тот же z-стек, что у `@elcrm/form`). `@elcrm/overlay` `Menu` — устаревший алиас `Popover`. Select — `@elcrm/form`, не overlay.
610
+ **Dropdown vs Popover:** `Dropdown` — пункты `items`/`groups`. `Popover` — свой `children` в portal; канон `trigger={(api) => <button {...api.anchorProps}>…</button>}` (без cloneElement). `@elcrm/overlay` `Menu` — устаревший алиас `Popover`. Select — `@elcrm/form`, не overlay.
578
611
 
579
612
  ### Breadcrumb
580
613
 
@@ -621,7 +654,7 @@ const people = [
621
654
  ```tsx
622
655
  <Layout
623
656
  fixed={["header", "footer", "sidebar"]}
624
- sidebar={<Sidebar groups={groups} value={page} onSelect={setPage} />}
657
+ sidebar={<Sidebar groups={groups} value={page} onValueChange={setPage} />}
625
658
  header={
626
659
  <Header
627
660
  brand={<Brand onClick={() => {}}>App</Brand>}
@@ -675,6 +708,7 @@ const resolve = createLazyResolver(
675
708
  resolveSection={resolve}
676
709
  groups={[
677
710
  {
711
+ value: "personal",
678
712
  label: "Личное",
679
713
  items: [
680
714
  { value: "Profile", label: "Профиль" },
@@ -0,0 +1,27 @@
1
+ import c from "react";
2
+ import { c as l } from "./cx-CcykAxZN.js";
3
+ import './ActionGroup.css';const n = "lgr", s = {
4
+ root: n
5
+ };
6
+ function p({
7
+ label: o,
8
+ actions: r,
9
+ children: t,
10
+ className: a,
11
+ ...e
12
+ }) {
13
+ return /* @__PURE__ */ c.createElement(
14
+ "div",
15
+ {
16
+ className: l(s.root, a),
17
+ role: "toolbar",
18
+ "aria-label": o,
19
+ ...e
20
+ },
21
+ r,
22
+ t
23
+ );
24
+ }
25
+ export {
26
+ p as A
27
+ };
@@ -1 +1 @@
1
- @layer elcrm-components{.c5r{display:flex;flex-wrap:nowrap;align-items:center;gap:var(--action-group-gap);flex:0 0 auto}}
1
+ @layer elcrm-components{.lgr{display:flex;flex-wrap:nowrap;align-items:center;gap:var(--action-group-gap);flex:0 0 auto}}
@@ -2,26 +2,23 @@ import { default as React } from 'react';
2
2
  /**
3
3
  * Ряд действий в строке списка / карточке (`role="toolbar"`).
4
4
  *
5
- * Роли: тулбар иконок справа в Card. Кнопки — `@elcrm/button` / свои слоты,
6
- * не нативный `<button>` в приложении.
7
- *
8
- * @param label подпись для `aria-label`
9
- * @param items массив узлов (если нет — только `children`)
10
- * @param children слот кнопок; можно вместе с `items` (сначала items)
5
+ * Роли: тулбар иконок справа в Card. Кнопки — `@elcrm/button` / свои слоты.
6
+ * Слоты `children` опционально `actions` массивом узлов).
7
+ * Не путать с декларативными `items` у Menu / RadioGroup.
11
8
  *
12
9
  * @example
13
10
  * ```tsx
11
+ * <ActionGroup label="Действия: Иван">
12
+ * <Button variant="ghost" onClick={edit}>Изменить</Button>
13
+ * <Button variant="ghost" onClick={remove}>Удалить</Button>
14
+ * </ActionGroup>
15
+ *
14
16
  * <ActionGroup
15
- * label="Действия: Иван"
16
- * items={[
17
- * <Button key="edit" variant="ghost" onClick={edit}>Изменить</Button>,
18
- * <Button key="del" variant="ghost" onClick={remove}>Удалить</Button>,
17
+ * label="Ещё"
18
+ * actions={[
19
+ * <Button key="copy" variant="ghost">Копировать</Button>,
19
20
  * ]}
20
21
  * />
21
- *
22
- * <ActionGroup label="Ещё">
23
- * <Button variant="ghost">Копировать</Button>
24
- * </ActionGroup>
25
22
  * ```
26
23
  *
27
24
  * Токены: `--action-group-gap` (иначе `--shell-gap-sm`).
@@ -29,14 +26,17 @@ import { default as React } from 'react';
29
26
  export type ActionGroupProps = React.HTMLAttributes<HTMLDivElement> & {
30
27
  /** Подпись тулбара (`aria-label`) */
31
28
  label: string;
32
- /** Кнопки массивом узлов */
33
- items?: React.ReactNode[];
29
+ /**
30
+ * Кнопки массивом узлов (не декларативные `items` групп).
31
+ * Можно вместе с `children` (сначала `actions`).
32
+ */
33
+ actions?: React.ReactNode[];
34
34
  /** Свои кнопки / слоты */
35
35
  children?: React.ReactNode;
36
36
  };
37
37
  /**
38
- * Группа действий: `items` и/или `children`.
38
+ * Группа действий: `actions` и/или `children`.
39
39
  *
40
- * @see Card, Stack, Item
40
+ * @see Card, Stack, Item, Toolbar
41
41
  */
42
- export declare function ActionGroup({ label, items, children, className, ...rest }: ActionGroupProps): React.JSX.Element;
42
+ export declare function ActionGroup({ label, actions, children, className, ...rest }: ActionGroupProps): React.JSX.Element;
@@ -1,4 +1,4 @@
1
- import { A as p } from "./ActionGroup-ChKFW0mt.js";
1
+ import { A as p } from "./ActionGroup-DcApj_Mz.js";
2
2
  export {
3
3
  p as ActionGroup
4
4
  };
@@ -0,0 +1,113 @@
1
+ import a from "react";
2
+ import { c as p } from "./cx-CcykAxZN.js";
3
+ import './Avatar.css';const x = "aar", h = "aav", A = "aas", C = "aam", S = "aal", z = "aaa", B = "aai", F = "aab", R = "aao", U = "aaf", e = {
4
+ root: x,
5
+ vtext: h,
6
+ small: A,
7
+ middle: C,
8
+ large: S,
9
+ active: z,
10
+ img: B,
11
+ bead: F,
12
+ online: R,
13
+ foff: U
14
+ };
15
+ function D(t) {
16
+ const n = t.trim();
17
+ if (!n) return "?";
18
+ const l = n.split(/\s+/).filter(Boolean);
19
+ return l.length >= 2 ? (l[0][0] + l[1][0]).toUpperCase() : n.slice(0, 2).toUpperCase();
20
+ }
21
+ function $(t) {
22
+ if (!(t == null || t === ""))
23
+ return {
24
+ "--avatar-radius": typeof t == "number" ? `${t}px` : t
25
+ };
26
+ }
27
+ function j({ status: t }) {
28
+ return /* @__PURE__ */ a.createElement(
29
+ "span",
30
+ {
31
+ className: p(e.bead, t === "online" ? e.online : e.foff),
32
+ "data-status": t,
33
+ "aria-hidden": !0
34
+ }
35
+ );
36
+ }
37
+ function k({
38
+ src: t,
39
+ label: n,
40
+ children: l,
41
+ name: r,
42
+ status: i
43
+ }) {
44
+ const s = t != null && t !== "" ? /* @__PURE__ */ a.createElement("img", { className: e.img, src: t, alt: n ?? "", draggable: !1 }) : l ?? (r != null ? D(r) : "?");
45
+ return /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement("span", { className: e.vtext }, s), i != null ? /* @__PURE__ */ a.createElement(j, { status: i }) : null);
46
+ }
47
+ function G(t) {
48
+ const {
49
+ src: n,
50
+ alt: l,
51
+ name: r,
52
+ size: i = "m",
53
+ status: s,
54
+ active: c,
55
+ children: b,
56
+ className: g,
57
+ radius: y,
58
+ as: v = "span",
59
+ style: E,
60
+ ...m
61
+ } = t, N = i === "s" ? e.small : i === "l" ? e.large : e.middle, u = p(e.root, N, c && e.active, g), o = l ?? r, d = { ...$(y), ...E }, f = /* @__PURE__ */ a.createElement(
62
+ k,
63
+ {
64
+ src: n,
65
+ label: o,
66
+ name: r,
67
+ status: s,
68
+ children: b
69
+ }
70
+ );
71
+ return v === "button" ? /* @__PURE__ */ a.createElement(
72
+ "button",
73
+ {
74
+ type: "button",
75
+ className: u,
76
+ "aria-label": o,
77
+ "data-active": c ? "true" : void 0,
78
+ "data-status": s,
79
+ style: d,
80
+ ...m
81
+ },
82
+ f
83
+ ) : v === "div" ? /* @__PURE__ */ a.createElement(
84
+ "div",
85
+ {
86
+ className: u,
87
+ role: o ? "img" : void 0,
88
+ "aria-label": o,
89
+ "data-active": c ? "true" : void 0,
90
+ "data-status": s,
91
+ style: d,
92
+ ...m
93
+ },
94
+ f
95
+ ) : /* @__PURE__ */ a.createElement(
96
+ "span",
97
+ {
98
+ className: u,
99
+ role: o ? "img" : void 0,
100
+ "aria-label": o,
101
+ "data-active": c ? "true" : void 0,
102
+ "data-status": s,
103
+ style: d,
104
+ ...m
105
+ },
106
+ f
107
+ );
108
+ }
109
+ export {
110
+ G as A,
111
+ $ as a,
112
+ D as i
113
+ };
package/dist/Avatar.css CHANGED
@@ -1 +1 @@
1
- @layer elcrm-components{.car{position:relative;box-sizing:border-box;display:inline-flex;flex-shrink:0;width:fit-content;height:fit-content;border-radius:var(--avatar-radius);-webkit-user-select:none;user-select:none;vertical-align:middle}.car:is(button){-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;padding:0;font:inherit;cursor:pointer;background:transparent;border:none}.cav{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;overflow:hidden;width:100%;height:100%;border-radius:inherit;border:var(--avatar-border);background:var(--avatar-background);color:var(--avatar-color);font-weight:var(--avatar-font-weight);line-height:1}.cas{width:var(--avatar-size-s);height:var(--avatar-size-s);font-size:var(--avatar-font-size-s)}.cas .cav{font-size:inherit}.cam{width:var(--avatar-size-m);height:var(--avatar-size-m);font-size:var(--avatar-font-size-m)}.cam .cav{font-size:inherit}.cal{width:var(--avatar-size-l);height:var(--avatar-size-l);font-size:var(--avatar-font-size-l)}.cal .cav{font-size:inherit}.caa .cav,.car[data-active=true] .cav{outline:var(--avatar-outline-active);outline-offset:var(--avatar-outline-offset)}.cai{width:100%;height:100%;object-fit:cover;display:block}.cab{position:absolute;right:0;bottom:0;box-sizing:border-box;width:var(--shell-status-size);height:var(--shell-status-size);border-radius:50%;border:2px solid var(--shell-background);pointer-events:none}.cas .cab{width:8px;height:8px}.cam .cab{width:var(--shell-status-size);height:var(--shell-status-size)}.cal .cab{width:12px;height:12px}.cao{background:var(--shell-color-success)}.caf{background:var(--shell-color-muted)}}
1
+ @layer elcrm-components{.aar{position:relative;box-sizing:border-box;display:inline-flex;flex-shrink:0;width:fit-content;height:fit-content;border-radius:var(--avatar-radius);-webkit-user-select:none;user-select:none;vertical-align:middle}.aar:is(button){-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;padding:0;font:inherit;cursor:pointer;background:transparent;border:none}.aav{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;overflow:hidden;width:100%;height:100%;border-radius:inherit;border:var(--avatar-border);background:var(--avatar-background);color:var(--avatar-color);font-weight:var(--avatar-font-weight);line-height:1}.aas{width:var(--avatar-size-s);height:var(--avatar-size-s);font-size:var(--avatar-font-size-s)}.aas .aav{font-size:inherit}.aam{width:var(--avatar-size-m);height:var(--avatar-size-m);font-size:var(--avatar-font-size-m)}.aam .aav{font-size:inherit}.aal{width:var(--avatar-size-l);height:var(--avatar-size-l);font-size:var(--avatar-font-size-l)}.aal .aav{font-size:inherit}.aaa .aav,.aar[data-active=true] .aav{outline:var(--avatar-outline-active);outline-offset:var(--avatar-outline-offset)}.aai{width:100%;height:100%;object-fit:cover;display:block}.aab{position:absolute;right:0;bottom:0;box-sizing:border-box;width:var(--shell-status-size);height:var(--shell-status-size);border-radius:50%;border:2px solid var(--shell-background);pointer-events:none}.aas .aab{width:8px;height:8px}.aam .aab{width:var(--shell-status-size);height:var(--shell-status-size)}.aal .aab{width:12px;height:12px}.aao{background:var(--shell-color-success)}.aaf{background:var(--shell-color-muted)}}
package/dist/Avatar.d.ts CHANGED
@@ -48,10 +48,10 @@ export declare function avatarRadiusStyle(radius?: number | string): React.CSSPr
48
48
  *
49
49
  * По умолчанию `as="span"`. Для кликабельного аватара — `as="button"`.
50
50
  */
51
- export type AvatarProps = (Common & React.ButtonHTMLAttributes<HTMLButtonElement> & {
52
- as?: "button";
53
- }) | (Common & React.HTMLAttributes<HTMLSpanElement> & {
54
- as: "span";
51
+ export type AvatarProps = (Common & React.HTMLAttributes<HTMLSpanElement> & {
52
+ as?: "span";
53
+ }) | (Common & React.ButtonHTMLAttributes<HTMLButtonElement> & {
54
+ as: "button";
55
55
  }) | (Common & React.HTMLAttributes<HTMLDivElement> & {
56
56
  as: "div";
57
57
  });
package/dist/Avatar.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as r, a as s, i as t } from "./Avatar-loGgFt72.js";
1
+ import { A as r, a as s, i as t } from "./Avatar-eGdLrMCv.js";
2
2
  export {
3
3
  r as Avatar,
4
4
  s as avatarRadiusStyle,
@@ -0,0 +1,81 @@
1
+ import e from "react";
2
+ import { A as f } from "./Avatar-eGdLrMCv.js";
3
+ import { c } from "./cx-CcykAxZN.js";
4
+ import './AvatarGroup.css';const C = "lar", I = "lai", P = "lao", x = "lad", G = "las", M = "lam", R = "lal", t = {
5
+ root: C,
6
+ item: I,
7
+ overflow: P,
8
+ dadd: x,
9
+ small: G,
10
+ middle: M,
11
+ large: R
12
+ };
13
+ function $(a) {
14
+ if (a.name != null && a.name !== "") return a.name;
15
+ if (a.title != null && a.title !== "") return a.title;
16
+ }
17
+ function B({
18
+ items: a,
19
+ max: s,
20
+ size: n = "m",
21
+ add: v = !1,
22
+ addLabel: b = "Добавить",
23
+ onAdd: r,
24
+ onValueChange: u,
25
+ className: g,
26
+ "aria-label": E = "Аватары",
27
+ ...h
28
+ }) {
29
+ const i = n === "s" ? t.small : n === "l" ? t.large : t.middle, k = s != null && s >= 0 ? Math.min(s, a.length) : a.length, m = a.slice(0, k), o = a.length - m.length;
30
+ return /* @__PURE__ */ e.createElement(
31
+ "div",
32
+ {
33
+ className: c(t.root, g),
34
+ role: "group",
35
+ "aria-label": E,
36
+ ...h
37
+ },
38
+ m.map((l, N) => {
39
+ const p = $(l), d = l.alt ?? l.title ?? l.name, w = u != null;
40
+ return /* @__PURE__ */ e.createElement("span", { key: l.value, className: t.item, style: { zIndex: N + 1 } }, w ? /* @__PURE__ */ e.createElement(
41
+ f,
42
+ {
43
+ as: "button",
44
+ src: l.src,
45
+ name: p,
46
+ alt: d,
47
+ size: n,
48
+ status: l.status,
49
+ onClick: (y) => {
50
+ y.stopPropagation(), u(l.value);
51
+ }
52
+ }
53
+ ) : /* @__PURE__ */ e.createElement(
54
+ f,
55
+ {
56
+ src: l.src,
57
+ name: p,
58
+ alt: d,
59
+ size: n,
60
+ status: l.status
61
+ }
62
+ ));
63
+ }),
64
+ o > 0 ? /* @__PURE__ */ e.createElement("span", { className: c(t.overflow, i), "aria-label": `Ещё ${o}` }, "+", o) : null,
65
+ v ? /* @__PURE__ */ e.createElement(
66
+ "button",
67
+ {
68
+ type: "button",
69
+ className: c(t.dadd, i),
70
+ "aria-label": b,
71
+ onClick: (l) => {
72
+ l.stopPropagation(), r == null || r();
73
+ }
74
+ },
75
+ "+"
76
+ ) : null
77
+ );
78
+ }
79
+ export {
80
+ B as A
81
+ };
@@ -1 +1 @@
1
- @layer elcrm-components{.cyr{display:inline-flex;align-items:center;vertical-align:middle}.cyi{position:relative;margin-left:var(--avatar-group-overlap);box-shadow:0 0 0 var(--avatar-group-ring) var(--shell-background);border-radius:var(--avatar-radius)}.cyi:first-child{margin-left:0}.cyo,.cyd{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;margin-left:var(--avatar-group-overlap);border-radius:var(--avatar-radius);font-weight:var(--avatar-font-weight);line-height:1;-webkit-user-select:none;user-select:none}.cyo{z-index:20;color:var(--shell-color-muted);background:var(--shell-background-muted);border:1px solid var(--shell-border);box-shadow:0 0 0 var(--avatar-group-ring) var(--shell-background)}.cyd{z-index:21;margin-left:var(--shell-gap-sm);color:var(--shell-color-muted);background:var(--shell-background);border:1px dashed var(--shell-border);cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;font:inherit;font-weight:var(--avatar-font-weight)}.cyd:hover{background:var(--shell-background-hover)}.cys{width:var(--avatar-size-s);height:var(--avatar-size-s);font-size:var(--avatar-font-size-s)}.cym{width:var(--avatar-size-m);height:var(--avatar-size-m);font-size:var(--avatar-font-size-m)}.cyl{width:var(--avatar-size-l);height:var(--avatar-size-l);font-size:var(--avatar-font-size-l)}}
1
+ @layer elcrm-components{.lar{display:inline-flex;align-items:center;vertical-align:middle}.lai{position:relative;margin-left:var(--avatar-group-overlap);box-shadow:0 0 0 var(--avatar-group-ring) var(--shell-background);border-radius:var(--avatar-radius)}.lai:first-child{margin-left:0}.lao,.lad{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;margin-left:var(--avatar-group-overlap);border-radius:var(--avatar-radius);font-weight:var(--avatar-font-weight);line-height:1;-webkit-user-select:none;user-select:none}.lao{z-index:20;color:var(--shell-color-muted);background:var(--shell-background-muted);border:1px solid var(--shell-border);box-shadow:0 0 0 var(--avatar-group-ring) var(--shell-background)}.lad{z-index:21;margin-left:var(--shell-gap-sm);color:var(--shell-color-muted);background:var(--shell-background);border:1px dashed var(--shell-border);cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;font:inherit;font-weight:var(--avatar-font-weight)}.lad:hover{background:var(--shell-background-hover)}.las{width:var(--avatar-size-s);height:var(--avatar-size-s);font-size:var(--avatar-font-size-s)}.lam{width:var(--avatar-size-m);height:var(--avatar-size-m);font-size:var(--avatar-font-size-m)}.lal{width:var(--avatar-size-l);height:var(--avatar-size-l);font-size:var(--avatar-font-size-l)}}
@@ -3,12 +3,12 @@ import { UiSize } from './types';
3
3
  /**
4
4
  * Элемент стопки {@link AvatarGroup}.
5
5
  *
6
- * Предпочтительный идентификатор — `value` (как у остальных group-UI).
7
- * `name` — только для инициалов; видимую подпись в списках даёт {@link AvatarName}.
6
+ * Идентификатор — `value` (как у остальных group-UI).
7
+ * `name` — только для инициалов; видимую подпись {@link AvatarName}.
8
8
  */
9
9
  export type AvatarGroupItem = {
10
- /** Уникальный id (предпочтительно; не React `key`). */
11
- value?: string;
10
+ /** Уникальный id (не React `key`). */
11
+ value: string;
12
12
  /** URL фото. */
13
13
  src?: string;
14
14
  /** Только для инициалов (если нет `src`). */
@@ -38,41 +38,21 @@ export type AvatarGroupProps = React.HTMLAttributes<HTMLDivElement> & {
38
38
  addLabel?: string;
39
39
  /** Клик по кнопке добавления. */
40
40
  onAdd?: () => void;
41
- /** Клик по аватару. */
42
- onItemClick?: (item: AvatarGroupItem, index: number) => void;
41
+ /** Клик по аватару (`item.value`). */
42
+ onValueChange?: (value: string) => void;
43
43
  };
44
44
  /**
45
45
  * Стопка аватаров с оверлапом, счётчиком «+N» и опциональной кнопкой добавления.
46
46
  *
47
- * Когда использовать:
48
- * - участники задачи / канала / сделки в одну строку;
49
- * - нужно ограничить видимое число (`max`) и добавить «+».
50
- *
51
- * Связанные компоненты:
52
- * - {@link Avatar} — одиночный аватар;
53
- * - {@link AvatarName} — аватар с текстовой подписью (`title` / `description`).
54
- *
55
- * API: декларативные `items`. Идентификатор предпочтительно `value` (не `key`).
56
- * Compound-слоты не используются.
57
- *
58
- * CSS-токены: `--avatar-group-*`, размеры из `--avatar-size-*`.
59
- *
60
47
  * @example
61
48
  * ```tsx
62
- * const items = [
63
- * { value: "u1", name: "Иван Петров", src: "/u/1.jpg", status: "online" },
64
- * { value: "u2", name: "Мария Смирнова" },
65
- * { value: "u3", name: "Алексей" },
66
- * ];
67
- *
68
49
  * <AvatarGroup
69
50
  * items={items}
70
51
  * max={5}
71
- * size="m"
72
52
  * add
73
53
  * onAdd={() => openInvite()}
74
- * onItemClick={(item) => openProfile(item.value)}
54
+ * onValueChange={(value) => openProfile(value)}
75
55
  * />
76
56
  * ```
77
57
  */
78
- export declare function AvatarGroup({ items, max, size, add, addLabel, onAdd, onItemClick, className, "aria-label": ariaLabel, ...rest }: AvatarGroupProps): React.JSX.Element;
58
+ export declare function AvatarGroup({ items, max, size, add, addLabel, onAdd, onValueChange, className, "aria-label": ariaLabel, ...rest }: AvatarGroupProps): React.JSX.Element;
@@ -1,4 +1,4 @@
1
- import { A as o } from "./AvatarGroup-D1gnT3Od.js";
1
+ import { A as o } from "./AvatarGroup-Dq-UrOaC.js";
2
2
  export {
3
3
  o as AvatarGroup
4
4
  };