@elcrm/components 0.2.14 → 0.5.2
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.
- package/README.md +70 -36
- package/dist/ActionGroup-DcApj_Mz.js +27 -0
- package/dist/ActionGroup.css +1 -1
- package/dist/ActionGroup.d.ts +19 -19
- package/dist/ActionGroup.js +1 -1
- package/dist/Avatar-eGdLrMCv.js +113 -0
- package/dist/Avatar.css +1 -1
- package/dist/Avatar.d.ts +4 -4
- package/dist/Avatar.js +1 -1
- package/dist/AvatarGroup-Dq-UrOaC.js +81 -0
- package/dist/AvatarGroup.css +1 -1
- package/dist/AvatarGroup.d.ts +8 -28
- package/dist/AvatarGroup.js +1 -1
- package/dist/AvatarName-3B4yCxHn.js +68 -0
- package/dist/AvatarName.css +1 -1
- package/dist/AvatarName.js +1 -1
- package/dist/Badge-BjScAXGy.js +28 -0
- package/dist/Badge.css +1 -1
- package/dist/Badge.js +1 -1
- package/dist/Banner-DAY18FWO.js +34 -0
- package/dist/Banner.css +1 -1
- package/dist/Banner.js +1 -1
- package/dist/Brand-BfCuiyf7.js +34 -0
- package/dist/Brand.css +1 -1
- package/dist/Brand.d.ts +8 -10
- package/dist/Brand.js +1 -1
- package/dist/Breadcrumb-DM_hWw5n.js +98 -0
- package/dist/Breadcrumb.css +1 -1
- package/dist/Breadcrumb.d.ts +8 -5
- package/dist/Breadcrumb.js +1 -1
- package/dist/Card-a7N8Uh_H.js +12 -0
- package/dist/Card.css +1 -1
- package/dist/Card.js +1 -1
- package/dist/ChatFrame-BdSYRF-B.js +37 -0
- package/dist/ChatFrame.css +1 -1
- package/dist/ChatList.js +2 -2
- package/dist/{ChatMessages-B8rdXiK-.js → ChatMessages-CLxwRGIa.js} +1 -1
- package/dist/ChatMessages.js +1 -1
- package/dist/ChatSplit-8iw_1Shp.js +21 -0
- package/dist/CodeBlock-B3wvMejv.js +34 -0
- package/dist/CodeBlock.css +1 -1
- package/dist/CodeBlock.js +1 -1
- package/dist/Dropdown-CR_XxNak.js +185 -0
- package/dist/Dropdown.css +1 -1
- package/dist/Dropdown.d.ts +4 -94
- package/dist/Dropdown.js +1 -1
- package/dist/EmptyState-B_wWPjUu.js +23 -0
- package/dist/EmptyState.css +1 -1
- package/dist/EmptyState.js +1 -1
- package/dist/{Footer-qxUlnPR9.js → Footer-Bgh_JCUe.js} +4 -4
- package/dist/Footer.css +1 -1
- package/dist/Footer.js +1 -1
- package/dist/Header-BMDIi3u2.js +21 -0
- package/dist/Header.css +1 -1
- package/dist/Header.js +1 -1
- package/dist/Healthmap-Z-LLfGW0.js +359 -0
- package/dist/Healthmap.css +1 -1
- package/dist/Healthmap.d.ts +25 -3
- package/dist/Healthmap.js +1 -1
- package/dist/{Item-D4okhsfW.js → Item-CGpkMJu0.js} +13 -13
- package/dist/Item.css +1 -1
- package/dist/Item.d.ts +7 -7
- package/dist/Item.js +1 -1
- package/dist/ItemColumn-Ch61LqE0.js +41 -0
- package/dist/ItemColumn.css +1 -1
- package/dist/ItemColumn.js +1 -1
- package/dist/Layout-CzEGKl9s.js +31 -0
- package/dist/Layout.css +1 -1
- package/dist/Layout.d.ts +1 -1
- package/dist/Layout.js +1 -1
- package/dist/List-D13pqaUY.js +12 -0
- package/dist/List.css +1 -1
- package/dist/List.js +1 -1
- package/dist/Loading-C_CKD-zt.js +16 -0
- package/dist/Loading.css +1 -1
- package/dist/Loading.js +1 -1
- package/dist/Menu-D2kf7fN_.js +72 -0
- package/dist/Menu.css +1 -1
- package/dist/Menu.d.ts +7 -25
- package/dist/Menu.js +1 -1
- package/dist/NavSections-CNxxBMPT.js +154 -0
- package/dist/NavSections.css +1 -1
- package/dist/NavSections.d.ts +16 -28
- package/dist/NavSections.js +1 -1
- package/dist/PageHead-BfClTLrF.js +31 -0
- package/dist/PageHead.css +1 -1
- package/dist/PageHead.d.ts +1 -1
- package/dist/PageHead.js +1 -1
- package/dist/PageShell-BAJges-G.js +30 -0
- package/dist/PageShell.css +1 -1
- package/dist/PageShell.js +1 -1
- package/dist/PanelInfo-Db5GCr-c.js +137 -0
- package/dist/PanelInfo.css +1 -1
- package/dist/PanelInfo.d.ts +16 -9
- package/dist/PanelInfo.js +1 -1
- package/dist/Popover-xEZoMY-h.js +143 -0
- package/dist/Popover.css +1 -1
- package/dist/Popover.d.ts +40 -11
- package/dist/Popover.js +1 -1
- package/dist/PricingGroup-CWy47MlE.js +138 -0
- package/dist/PricingGroup.css +1 -1
- package/dist/PricingGroup.d.ts +0 -2
- package/dist/PricingGroup.js +1 -1
- package/dist/PricingTable-BjpGVAhi.js +157 -0
- package/dist/PricingTable.css +1 -1
- package/dist/PricingTable.d.ts +4 -7
- package/dist/PricingTable.js +1 -1
- package/dist/RadioGroup-DI4KKUvZ.js +121 -0
- package/dist/RadioGroup.css +1 -1
- package/dist/RadioGroup.js +1 -1
- package/dist/Section-PprWjOvt.js +47 -0
- package/dist/Section.css +1 -1
- package/dist/Section.d.ts +29 -9
- package/dist/Section.js +1 -1
- package/dist/Sidebar-Bouhd5SS.js +205 -0
- package/dist/Sidebar.css +1 -1
- package/dist/Sidebar.d.ts +18 -26
- package/dist/Sidebar.js +1 -1
- package/dist/SplitPane-DBa-g9td.js +92 -0
- package/dist/SplitPane.css +1 -1
- package/dist/SplitPane.d.ts +8 -7
- package/dist/SplitPane.js +1 -1
- package/dist/Stack-BPTehVYc.js +53 -0
- package/dist/Stack.css +1 -1
- package/dist/Stack.d.ts +2 -1
- package/dist/Stack.js +1 -1
- package/dist/Stat-p8j4PjrC.js +28 -0
- package/dist/Stat.css +1 -1
- package/dist/Stat.js +1 -1
- package/dist/TabSections-Dppe9wiz.js +84 -0
- package/dist/TabSections.css +1 -1
- package/dist/TabSections.d.ts +7 -2
- package/dist/TabSections.js +1 -1
- package/dist/Table-DqrDUUtb.js +27 -0
- package/dist/Table.css +1 -1
- package/dist/Table.d.ts +10 -2
- package/dist/Table.js +1 -1
- package/dist/Text-Bo1u7gVC.js +25 -0
- package/dist/Text.css +1 -1
- package/dist/Text.js +1 -1
- package/dist/TextGroup-236jHxdT.js +23 -0
- package/dist/TextGroup.css +1 -1
- package/dist/TextGroup.js +1 -1
- package/dist/Toolbar-Bl9-5Mis.js +35 -0
- package/dist/Toolbar.css +1 -1
- package/dist/Toolbar.d.ts +7 -12
- package/dist/Toolbar.js +1 -2
- package/dist/cx.d.ts +1 -1
- package/dist/dark.css +12 -0
- package/dist/index.css +40 -40
- package/dist/index.d.ts +5 -12
- package/dist/index.es.d.ts +5 -12
- package/dist/index.es.js +109 -108
- package/dist/kit-manifest.json +1646 -0
- package/dist/lazyRoute.d.ts +12 -6
- package/dist/light.css +12 -0
- package/dist/navTree.d.ts +13 -1
- package/dist/rovingKeys-Di9N1Nct.js +23 -0
- package/dist/rovingKeys.d.ts +7 -1
- package/dist/stackGap.d.ts +1 -1
- package/dist/tokens.css +13 -0
- package/dist/useControllableValue-BaE0VR5d.js +13 -0
- package/dist/useControllableValue.d.ts +3 -0
- package/package.json +13 -4
- package/dist/ActionGroup-ChKFW0mt.js +0 -27
- package/dist/Avatar-loGgFt72.js +0 -113
- package/dist/AvatarGroup-D1gnT3Od.js +0 -81
- package/dist/AvatarName-0BzyfpMq.js +0 -68
- package/dist/Badge-jp-9iNNL.js +0 -28
- package/dist/Banner-B72lcEMo.js +0 -34
- package/dist/Block-Bu7NEA0g.js +0 -8
- package/dist/Block.d.ts +0 -30
- package/dist/Block.js +0 -4
- package/dist/Brand-Zq-Idks4.js +0 -34
- package/dist/Breadcrumb-CAM_e9LN.js +0 -98
- package/dist/Card-hn37Opo3.js +0 -12
- package/dist/ChatFrame-BW2TmCkZ.js +0 -37
- package/dist/ChatSplit-DNnu3TNq.js +0 -21
- package/dist/CodeBlock-CRzVopIv.js +0 -25
- package/dist/Column-BiogBDf8.js +0 -8
- package/dist/Column.d.ts +0 -24
- package/dist/Column.js +0 -4
- package/dist/Dropdown-DosvDR13.js +0 -147
- package/dist/EmptyState-mBiWtMIM.js +0 -23
- package/dist/Header-DZQopVNy.js +0 -21
- package/dist/Healthmap-B6cdiLUl.js +0 -243
- package/dist/ItemColumn-M7a9L8CI.js +0 -41
- package/dist/Layout-mi6Ghayv.js +0 -31
- package/dist/List-BgKkYaGO.js +0 -12
- package/dist/Loading-DkkG7RcE.js +0 -16
- package/dist/Menu-DuXQv-zT.js +0 -66
- package/dist/NavSections-D6rDEtT1.js +0 -142
- package/dist/PageHead-DgaJ1mXY.js +0 -31
- package/dist/PageShell-D9EZiO8o.js +0 -30
- package/dist/PanelInfo-A5y5ysH8.js +0 -81
- package/dist/Popover-DWdvZTuA.js +0 -135
- package/dist/PricingGroup-Czuhe81Z.js +0 -120
- package/dist/PricingTable-BuLC0opK.js +0 -152
- package/dist/RadioGroup-fcXzhvMu.js +0 -129
- package/dist/Row-DsQOVn18.js +0 -8
- package/dist/Row.d.ts +0 -24
- package/dist/Row.js +0 -4
- package/dist/Section-Crxk2J-E.js +0 -34
- package/dist/Sidebar-CYFaPqdC.js +0 -178
- package/dist/SplitPane-DR7PCZ8f.js +0 -74
- package/dist/Stack-XkmPSswj.js +0 -53
- package/dist/Stat-sKXJwz5L.js +0 -27
- package/dist/TabSections-DN7yVJoF.js +0 -69
- package/dist/Table-BoDr3X2d.js +0 -25
- package/dist/Text-zHK2wmsw.js +0 -25
- package/dist/TextGroup-DmhuyMR1.js +0 -23
- package/dist/Toolbar-C1zAk9ak.js +0 -42
- package/dist/rovingKeys-CGlfTtNQ.js +0 -15
- package/dist/useControllableValue-CWqH1kpM.js +0 -10
|
@@ -0,0 +1,1646 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "elcrm-kit-manifest-v1",
|
|
3
|
+
"package": "@elcrm/components",
|
|
4
|
+
"version": "0.5.2",
|
|
5
|
+
"pkg": "components",
|
|
6
|
+
"generatedAt": "2026-08-30T02:34:28.296Z",
|
|
7
|
+
"components": [
|
|
8
|
+
{
|
|
9
|
+
"slug": "ActionGroup",
|
|
10
|
+
"title": "ActionGroup",
|
|
11
|
+
"description": "Ряд действий в строке списка / карточке (`role=\"toolbar\"`). Роли: тулбар иконок справа в Card. Кнопки — `@elcrm/button` / свои слоты. Слоты — `children` (и опционально `actions` массивом узлов). Не путать с декларативными `items` у Menu / RadioGroup.",
|
|
12
|
+
"importFrom": "@elcrm/components",
|
|
13
|
+
"examples": [
|
|
14
|
+
{
|
|
15
|
+
"title": "Пример",
|
|
16
|
+
"code": "<ActionGroup label=\"Действия: Иван\">\n <Button variant=\"ghost\" onClick={edit}>Изменить</Button>\n <Button variant=\"ghost\" onClick={remove}>Удалить</Button>\n</ActionGroup>\n\n<ActionGroup\n label=\"Ещё\"\n actions={[\n <Button key=\"copy\" variant=\"ghost\">Копировать</Button>,\n ]}\n/>"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"props": [
|
|
20
|
+
{
|
|
21
|
+
"name": "label",
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Подпись тулбара (`aria-label`)"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "actions",
|
|
27
|
+
"type": "React.ReactNode[]",
|
|
28
|
+
"description": "Кнопки массивом узлов (не декларативные `items` групп). Можно вместе с `children` (сначала `actions`)."
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "children",
|
|
32
|
+
"type": "React.ReactNode",
|
|
33
|
+
"description": "Свои кнопки / слоты"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"slug": "Avatar",
|
|
39
|
+
"title": "Avatar",
|
|
40
|
+
"description": "Аватар: фото или инициалы, опционально статус присутствия. Когда использовать: - круглая миниатюра пользователя без текстовой подписи рядом; - в шапке, списках, {@link AvatarGroup}. Связанные компоненты: - {@link AvatarName} — аватар + видимые `title` / `description` (`name` у Avatar остаётся только для инициалов); - {@link AvatarGroup} — стопка аватаров из `items`. CSS-токены: `--avatar-*` (в т.ч. `--avatar-size-s|m|l`, `--avatar-radius`). Скругление: `radius={10}` или `style={{ [\"--avatar-radius\"]: \"10px\" }}`.",
|
|
41
|
+
"importFrom": "@elcrm/components",
|
|
42
|
+
"examples": [
|
|
43
|
+
{
|
|
44
|
+
"title": "Пример",
|
|
45
|
+
"code": "// фото + статус\n<Avatar src=\"/u/42.jpg\" alt=\"Иван Петров\" size=\"m\" status=\"online\" />\n\n// без фото — только инициалы из name\n<Avatar name=\"Иван Петров\" size=\"s\" />\n\n// подпись в UI — через AvatarName (title + description)\n<AvatarName\n name=\"Иван Петров\"\n title=\"Иван Петров\"\n description=\"ivan@elcrm.app\"\n/>"
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"props": []
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"slug": "AvatarGroup",
|
|
52
|
+
"title": "AvatarGroup",
|
|
53
|
+
"description": "Стопка аватаров с оверлапом, счётчиком «+N» и опциональной кнопкой добавления.",
|
|
54
|
+
"importFrom": "@elcrm/components",
|
|
55
|
+
"examples": [
|
|
56
|
+
{
|
|
57
|
+
"title": "Пример",
|
|
58
|
+
"code": "<AvatarGroup\n items={items}\n max={5}\n add\n onAdd={() => openInvite()}\n onValueChange={(value) => openProfile(value)}\n/>"
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"props": [
|
|
62
|
+
{
|
|
63
|
+
"name": "items",
|
|
64
|
+
"type": "AvatarGroupItem[]",
|
|
65
|
+
"description": "Список людей / аватаров."
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "max",
|
|
69
|
+
"type": "number",
|
|
70
|
+
"description": "Сколько аватаров показать до «+N». По умолчанию все."
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "size",
|
|
74
|
+
"type": "UiSize",
|
|
75
|
+
"description": "Размер аватаров: `s` | `m` | `l`."
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"name": "add",
|
|
79
|
+
"type": "boolean",
|
|
80
|
+
"description": "Кнопка «+» справа."
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"name": "addLabel",
|
|
84
|
+
"type": "string",
|
|
85
|
+
"description": "Подпись для кнопки добавления (`aria-label`)."
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"name": "onAdd",
|
|
89
|
+
"type": "() => void",
|
|
90
|
+
"description": "Клик по кнопке добавления."
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"name": "onValueChange",
|
|
94
|
+
"type": "(value: string) => void",
|
|
95
|
+
"description": "Клик по аватару (`item.value`)."
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"slug": "AvatarName",
|
|
101
|
+
"title": "AvatarName",
|
|
102
|
+
"description": "Аватар + видимые `title` и `description` в одну строку. Когда использовать: - строка пользователя в списке / меню / карточке; - нужна подпись рядом с фото (не только инициалы). Связанные компоненты: - {@link Avatar} — только круг (без текста); `name` там лишь для инициалов; - {@link AvatarGroup} — стопка без подписей. Канон: `title` / `description` для UI-текста; `name` — только инициалы. CSS-токены: `--avatar-name-title-color`, `--avatar-name-description-color`, аватар — `--avatar-*`.",
|
|
103
|
+
"importFrom": "@elcrm/components",
|
|
104
|
+
"examples": [
|
|
105
|
+
{
|
|
106
|
+
"title": "Пример",
|
|
107
|
+
"code": "<AvatarName\n src=\"/u/42.jpg\"\n name=\"Иван Петров\"\n title=\"Иван Петров\"\n description=\"ivan@elcrm.app\"\n size=\"m\"\n status=\"online\"\n/>\n\n<AvatarName\n as=\"button\"\n name=\"Мария\"\n title=\"Мария Смирнова\"\n description=\"Менеджер\"\n onClick={() => openProfile()}\n/>"
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
"props": []
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"slug": "Badge",
|
|
114
|
+
"title": "Badge",
|
|
115
|
+
"description": "Компактная метка / статус (роль, состояние). Не заменяет Button. Props (`BadgeProps`): - `tone` — `neutral` | `accent` | `success` | `warning` | `danger` - `size` — `s` | `m` | `l` (по умолчанию `m`) - `dot` — точка слева (как online / offline) - `children` — текст метки - плюс атрибуты `span` (`className`, `style`, …)",
|
|
116
|
+
"importFrom": "@elcrm/components",
|
|
117
|
+
"examples": [
|
|
118
|
+
{
|
|
119
|
+
"title": "Пример",
|
|
120
|
+
"code": "<Badge tone=\"accent\" size=\"s\">ADMIN</Badge>\n<Badge tone=\"success\" size=\"s\" dot>online</Badge>"
|
|
121
|
+
}
|
|
122
|
+
],
|
|
123
|
+
"props": [
|
|
124
|
+
{
|
|
125
|
+
"name": "tone",
|
|
126
|
+
"type": "BadgeTone",
|
|
127
|
+
"description": "Цвет по смыслу. `neutral` | `accent` | `success` | `warning` | `danger`"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "size",
|
|
131
|
+
"type": "BadgeSize",
|
|
132
|
+
"description": "Размер пилюли. `s` — в строке списка; `m` — обычная; `l` — крупнее. По умолчанию `m`."
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"name": "dot",
|
|
136
|
+
"type": "boolean",
|
|
137
|
+
"description": "Точка статуса слева (цвет = `tone`)"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"name": "children",
|
|
141
|
+
"type": "React.ReactNode",
|
|
142
|
+
"description": "Текст метки"
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"slug": "Banner",
|
|
148
|
+
"title": "Banner",
|
|
149
|
+
"description": "Статусная полоса (offline, maintenance). Не toast — не путать с Notice.",
|
|
150
|
+
"importFrom": "@elcrm/components",
|
|
151
|
+
"examples": [
|
|
152
|
+
{
|
|
153
|
+
"title": "Пример",
|
|
154
|
+
"code": "<Banner tone=\"info\" role=\"status\">\n Каталог из снимка <code>kit-catalog.json</code>\n</Banner>"
|
|
155
|
+
}
|
|
156
|
+
],
|
|
157
|
+
"props": [
|
|
158
|
+
{
|
|
159
|
+
"name": "tone",
|
|
160
|
+
"type": "BannerTone",
|
|
161
|
+
"description": "Визуальный акцент"
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"slug": "Brand",
|
|
167
|
+
"title": "Brand",
|
|
168
|
+
"description": "Название / логотип в шапке. По умолчанию статичный `strong`. Кликабельный — `as=\"button\"` или `as=\"a\"`.",
|
|
169
|
+
"importFrom": "@elcrm/components",
|
|
170
|
+
"examples": [
|
|
171
|
+
{
|
|
172
|
+
"title": "Пример",
|
|
173
|
+
"code": "<Header brand={<Brand>elCRM</Brand>} />\n<Header brand={<Brand as=\"a\" href=\"/\">elCRM</Brand>} />"
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
"props": [
|
|
177
|
+
{
|
|
178
|
+
"name": "as",
|
|
179
|
+
"type": "\"strong\"",
|
|
180
|
+
"description": "Тег: статичный заголовок (по умолчанию)"
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"name": "as",
|
|
184
|
+
"type": "\"button\"",
|
|
185
|
+
"description": "Тег: кнопка"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"name": "as",
|
|
189
|
+
"type": "\"a\"",
|
|
190
|
+
"description": "Тег: ссылка на главную"
|
|
191
|
+
}
|
|
192
|
+
]
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"slug": "Breadcrumb",
|
|
196
|
+
"title": "Breadcrumb",
|
|
197
|
+
"description": "Хлебные крошки пути из декларативного массива `items`. Когда использовать: - показать иерархию страницы / вложенных разделов; - нужна свёртка длинного пути (`collapseAfter`). Связанные компоненты: - {@link PageHead} — шапка страницы, куда часто кладут Breadcrumb; - {@link Dropdown} — если крошка с `dropdown` открывает меню выбора. API: декларативные `items`. Идентификатор — `value` (не `key`). Compound-слоты не используются. CSS-токены: `--shell-*`.",
|
|
198
|
+
"importFrom": "@elcrm/components",
|
|
199
|
+
"examples": [
|
|
200
|
+
{
|
|
201
|
+
"title": "Пример",
|
|
202
|
+
"code": "const items = [\n { value: \"home\", label: \"Главная\", href: \"/\" },\n { value: \"settings\", label: \"Настройки\", href: \"/settings\" },\n { value: \"team\", label: \"Команда\", icon: <Avatar name=\"Team\" size=\"s\" /> },\n];\n\n<Breadcrumb\n items={items}\n separator=\"chevron\"\n collapseAfter={2}\n onValueChange={(value) => navigate(items.find((i) => i.value === value)?.href ?? \"/\")}\n/>"
|
|
203
|
+
}
|
|
204
|
+
],
|
|
205
|
+
"props": [
|
|
206
|
+
{
|
|
207
|
+
"name": "items",
|
|
208
|
+
"type": "BreadcrumbItem[]",
|
|
209
|
+
"description": "Цепочка крошек (`value` — идентификатор)."
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"name": "separator",
|
|
213
|
+
"type": "BreadcrumbSeparator",
|
|
214
|
+
"description": "Разделитель: chevron `>`, slash `/` или свой node."
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"name": "collapseAfter",
|
|
218
|
+
"type": "number",
|
|
219
|
+
"description": "Свернуть середину: первые N пунктов, «…», последний. Например `2` → Home, Settings, …, Team."
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"name": "onEllipsisClick",
|
|
223
|
+
"type": "() => void",
|
|
224
|
+
"description": "Клик по «…» (если нужно раскрыть путь)."
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"name": "onValueChange",
|
|
228
|
+
"type": "(value: string) => void",
|
|
229
|
+
"description": "Клик по пункту (`item.value`)."
|
|
230
|
+
}
|
|
231
|
+
]
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"slug": "Card",
|
|
235
|
+
"title": "Card",
|
|
236
|
+
"description": "Карточка-контейнер с опциональным заголовком. Роли: Card = визуальная рамка для группы контента; для секций модуля — Section; для списков — List / Item.",
|
|
237
|
+
"importFrom": "@elcrm/components",
|
|
238
|
+
"examples": [
|
|
239
|
+
{
|
|
240
|
+
"title": "Пример",
|
|
241
|
+
"code": "<Card title=\"Тариф\">\n <p>Базовый план</p>\n</Card>"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
"title": "Пример 2",
|
|
245
|
+
"code": "<Card title=\"Тенанты\" style={{ [\"--card-pointer\" as string]: \"pointer\" }}>\n 12\n</Card>"
|
|
246
|
+
}
|
|
247
|
+
],
|
|
248
|
+
"props": [
|
|
249
|
+
{
|
|
250
|
+
"name": "title",
|
|
251
|
+
"type": "React.ReactNode",
|
|
252
|
+
"description": "Заголовок карточки (если нет — только children)"
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"name": "children",
|
|
256
|
+
"type": "React.ReactNode",
|
|
257
|
+
"description": "Содержимое карточки"
|
|
258
|
+
}
|
|
259
|
+
]
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"slug": "ChatList",
|
|
263
|
+
"title": "ChatList",
|
|
264
|
+
"description": "Колонка списка диалогов (`aside`).",
|
|
265
|
+
"importFrom": "@elcrm/components",
|
|
266
|
+
"examples": [],
|
|
267
|
+
"props": []
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"slug": "ChatMessages",
|
|
271
|
+
"title": "ChatMessages",
|
|
272
|
+
"description": "Колонка переписки (`section`).",
|
|
273
|
+
"importFrom": "@elcrm/components",
|
|
274
|
+
"examples": [],
|
|
275
|
+
"props": []
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
"slug": "CodeBlock",
|
|
279
|
+
"title": "CodeBlock",
|
|
280
|
+
"description": "Блок кода: bar + pre. Подсветку передаёт приложение через `children`.",
|
|
281
|
+
"importFrom": "@elcrm/components",
|
|
282
|
+
"examples": [
|
|
283
|
+
{
|
|
284
|
+
"title": "Пример",
|
|
285
|
+
"code": "<CodeBlock title=\"Пример\" code={snippet} onCopy={() => copy(snippet)} />"
|
|
286
|
+
}
|
|
287
|
+
],
|
|
288
|
+
"props": [
|
|
289
|
+
{
|
|
290
|
+
"name": "title",
|
|
291
|
+
"type": "React.ReactNode",
|
|
292
|
+
"description": "Заголовок в полосе над кодом"
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
"name": "code",
|
|
296
|
+
"type": "string",
|
|
297
|
+
"description": "Текст без подсветки (если нет children)"
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
"name": "children",
|
|
301
|
+
"type": "React.ReactNode",
|
|
302
|
+
"description": "Подсветка / разметка — свой рендер в pre"
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"name": "onCopy",
|
|
306
|
+
"type": "() => void",
|
|
307
|
+
"description": "Кнопка «Копировать»; без onCopy не показывается"
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
"name": "copyLabel",
|
|
311
|
+
"type": "string",
|
|
312
|
+
"description": "Подпись кнопки копирования"
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
"name": "actions",
|
|
316
|
+
"type": "React.ReactNode",
|
|
317
|
+
"description": "Доп. действия справа в bar"
|
|
318
|
+
}
|
|
319
|
+
]
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
"slug": "Dropdown",
|
|
323
|
+
"title": "Dropdown",
|
|
324
|
+
"description": "Выпадающее меню: триггер + панель с `groups` / `items` (portal, {@link Popover}). Когда использовать: - действия строки списка, переключатели колонок, контекстные пункты у кнопки. Отличия: - {@link Menu} — инлайн-навигация в потоке (шапка), без панели; - {@link Popover} — свой контент в portal, без `items`. API: декларативные `items` / `groups`. Идентификатор пункта — `value` (не `key`). Compound-слоты (`Dropdown.Item`) не используются. CSS-токены: `--shell-*`, узкие `--dropdown-min-width` / `--dropdown-max-width` / `--dropdown-max-height`, `--popup-shadow`.",
|
|
325
|
+
"importFrom": "@elcrm/components",
|
|
326
|
+
"examples": [
|
|
327
|
+
{
|
|
328
|
+
"title": "Пример",
|
|
329
|
+
"code": "const groups = [\n {\n title: \"Действия\",\n items: [\n { value: \"edit\", label: \"Изменить\", icon: <Icons.Line name=\"edit\" /> },\n { value: \"delete\", label: \"Удалить\", danger: true },\n ],\n },\n {\n title: \"Колонки\",\n items: [\n { value: \"email\", label: \"Email\", checkbox: true, checked: true },\n { value: \"phone\", label: \"Телефон\", checkbox: true },\n ],\n },\n];\n\n<Dropdown\n label=\"Действия\"\n groups={groups}\n closeOnSelect={false}\n onValueChange={(value) => console.log(value)}\n/>"
|
|
330
|
+
}
|
|
331
|
+
],
|
|
332
|
+
"props": []
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
"slug": "EmptyState",
|
|
336
|
+
"title": "EmptyState",
|
|
337
|
+
"description": "Заглушка «нет данных»: иконка, заголовок, описание, действия. Роли: EmptyState после загрузки при пустом списке; во время загрузки — Loading; для секций с контентом — Section.",
|
|
338
|
+
"importFrom": "@elcrm/components",
|
|
339
|
+
"examples": [
|
|
340
|
+
{
|
|
341
|
+
"title": "Пример",
|
|
342
|
+
"code": "<EmptyState\n title=\"Нет клиентов\"\n description=\"Создайте первого клиента\"\n actions={<Button>Создать</Button>}\n/>"
|
|
343
|
+
}
|
|
344
|
+
],
|
|
345
|
+
"props": [
|
|
346
|
+
{
|
|
347
|
+
"name": "title",
|
|
348
|
+
"type": "React.ReactNode",
|
|
349
|
+
"description": "Заголовок заглушки"
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
"name": "description",
|
|
353
|
+
"type": "React.ReactNode",
|
|
354
|
+
"description": "Поясняющий текст"
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
"name": "icon",
|
|
358
|
+
"type": "React.ReactNode",
|
|
359
|
+
"description": "Иконка над заголовком"
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
"name": "actions",
|
|
363
|
+
"type": "React.ReactNode",
|
|
364
|
+
"description": "Кнопки / CTA под описанием"
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"name": "children",
|
|
368
|
+
"type": "React.ReactNode",
|
|
369
|
+
"description": "Доп. контент между описанием и actions"
|
|
370
|
+
}
|
|
371
|
+
]
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
"slug": "Footer",
|
|
375
|
+
"title": "Footer",
|
|
376
|
+
"description": "Подвал страницы или модуля. Роли: Footer в Layout (глобальный) или в PageShell как `footer` (прибит к низу модуля).",
|
|
377
|
+
"importFrom": "@elcrm/components",
|
|
378
|
+
"examples": [
|
|
379
|
+
{
|
|
380
|
+
"title": "Пример",
|
|
381
|
+
"code": "<Layout footer={<Footer>© elCRM · v1.0</Footer>}>\n …\n</Layout>"
|
|
382
|
+
}
|
|
383
|
+
],
|
|
384
|
+
"props": [
|
|
385
|
+
{
|
|
386
|
+
"name": "children",
|
|
387
|
+
"type": "React.ReactNode",
|
|
388
|
+
"description": "Содержимое подвала (копирайт, ссылки, статус)"
|
|
389
|
+
}
|
|
390
|
+
]
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
"slug": "Header",
|
|
394
|
+
"title": "Header",
|
|
395
|
+
"description": "Шапка приложения со слотами brand / nav / search / actions. Роли: Header = верхняя полоса в Layout; Brand — логотип/название; рядом — Menu, поиск из `@elcrm/form`, кнопки `@elcrm/button`.",
|
|
396
|
+
"importFrom": "@elcrm/components",
|
|
397
|
+
"examples": [
|
|
398
|
+
{
|
|
399
|
+
"title": "Пример",
|
|
400
|
+
"code": "<Header\n brand={<Brand>elCRM</Brand>}\n nav={<Menu items={navItems} />}\n actions={<Button>Выйти</Button>}\n/>"
|
|
401
|
+
}
|
|
402
|
+
],
|
|
403
|
+
"props": [
|
|
404
|
+
{
|
|
405
|
+
"name": "brand",
|
|
406
|
+
"type": "React.ReactNode",
|
|
407
|
+
"description": "Логотип / название (часто `<Brand />`)"
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
"name": "nav",
|
|
411
|
+
"type": "React.ReactNode",
|
|
412
|
+
"description": "Навигация (Menu, ссылки)"
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
"name": "search",
|
|
416
|
+
"type": "React.ReactNode",
|
|
417
|
+
"description": "Поиск или фильтр в шапке"
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
"name": "actions",
|
|
421
|
+
"type": "React.ReactNode",
|
|
422
|
+
"description": "Действия справа (кнопки, аватар, колокольчик)"
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
"name": "children",
|
|
426
|
+
"type": "React.ReactNode",
|
|
427
|
+
"description": "Доп. контент после слотов"
|
|
428
|
+
}
|
|
429
|
+
]
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
"slug": "Healthmap",
|
|
433
|
+
"title": "Healthmap",
|
|
434
|
+
"description": "Теплокарта активности по дням (как GitHub contribution graph). Роли: Healthmap = визуализация `days[]`; данные грузит приложение (`Api.query` / свой RPC), не сам компонент.",
|
|
435
|
+
"importFrom": "@elcrm/components",
|
|
436
|
+
"examples": [
|
|
437
|
+
{
|
|
438
|
+
"title": "Пример",
|
|
439
|
+
"code": "<Healthmap\n data={heatmap}\n loading={pending}\n year={year}\n onYearChange={setYear}\n brandName=\"eKivi\"\n brandSub=\"клиенты\"\n unit={{ one: \"событие\", few: \"события\", many: \"событий\" }}\n/>"
|
|
440
|
+
}
|
|
441
|
+
],
|
|
442
|
+
"props": [
|
|
443
|
+
{
|
|
444
|
+
"name": "data",
|
|
445
|
+
"type": "HealthmapData | null",
|
|
446
|
+
"description": "Данные года; `null` — пустая сетка."
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
"name": "loading",
|
|
450
|
+
"type": "boolean",
|
|
451
|
+
"description": "Показать «Загрузка…» в заголовке."
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
"name": "year",
|
|
455
|
+
"type": "number | null",
|
|
456
|
+
"description": "Выбранный год. - `undefined` — uncontrolled (внутри берётся последний из `data.years`); - `null` — controlled «последний год» (как в ответе сервера); - число — конкретный год."
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
"name": "onYearChange",
|
|
460
|
+
"type": "(year: number | null) => void",
|
|
461
|
+
"description": "Смена года (клик по вкладке)."
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
"name": "hint",
|
|
465
|
+
"type": "string",
|
|
466
|
+
"description": "Подсказка под сеткой."
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
"name": "brandName",
|
|
470
|
+
"type": "string",
|
|
471
|
+
"description": "Бренд в боковой колонке KPI."
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
"name": "brandSub",
|
|
475
|
+
"type": "string",
|
|
476
|
+
"description": "Подпись под брендом."
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
"name": "unit",
|
|
480
|
+
"type": "HealthmapUnit",
|
|
481
|
+
"description": "Единицы для склонения счётчиков."
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
"name": "months",
|
|
485
|
+
"type": "readonly string[]",
|
|
486
|
+
"description": "12 коротких названий месяцев (янв…дек). По умолчанию — русские."
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
"name": "locale",
|
|
490
|
+
"type": "string",
|
|
491
|
+
"description": "Locale для длинной даты в tooltip (`toLocaleDateString`). @default \"ru-RU\""
|
|
492
|
+
},
|
|
493
|
+
{
|
|
494
|
+
"name": "loadingLabel",
|
|
495
|
+
"type": "string",
|
|
496
|
+
"description": "Текст «Загрузка…» в заголовке."
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
"name": "lastYearLabel",
|
|
500
|
+
"type": "string",
|
|
501
|
+
"description": "Фраза «последний год» в заголовке."
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
"name": "weekdays",
|
|
505
|
+
"type": "readonly string[]",
|
|
506
|
+
"description": "7 подписей дней недели (Пн…Вс). Пустая строка — слот без текста (компактная колонка как у GitHub). @default [\"Пн\",\"\",\"Ср\",\"\",\"Пт\",\"\",\"\"]"
|
|
507
|
+
}
|
|
508
|
+
]
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
"slug": "IconButton",
|
|
512
|
+
"title": "IconButton",
|
|
513
|
+
"description": "Иконка-кнопка: `Icons.Line` + {@link ShellIconButton} + {@link Tooltip}.",
|
|
514
|
+
"importFrom": "@elcrm/components",
|
|
515
|
+
"examples": [
|
|
516
|
+
{
|
|
517
|
+
"title": "Пример",
|
|
518
|
+
"code": "<IconButton name=\"power\" label=\"Выход\" onClick={logout} />\n<IconButton name=\"copy_01\" label=\"Копировать\" tooltip=\"Скопировать CSS\" onClick={copy} />"
|
|
519
|
+
}
|
|
520
|
+
],
|
|
521
|
+
"props": [
|
|
522
|
+
{
|
|
523
|
+
"name": "name",
|
|
524
|
+
"type": "string",
|
|
525
|
+
"description": "Имя из `icons update` / `Icons.Line` (в приложении — `IconLineName`)"
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
"name": "label",
|
|
529
|
+
"type": "string",
|
|
530
|
+
"description": "Подпись: `aria-label` и текст tooltip по умолчанию"
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
"name": "tooltip",
|
|
534
|
+
"type": "React.ReactNode | false",
|
|
535
|
+
"description": "Подсказка; `false` — без Tooltip (например, внутри toolbar с aria-label)"
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
"name": "iconSize",
|
|
539
|
+
"type": "number",
|
|
540
|
+
"description": "Размер SVG; по умолчанию от `size` кнопки"
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
"name": "tooltipPlacement",
|
|
544
|
+
"type": "TooltipPlacement",
|
|
545
|
+
"description": "Сторона tooltip"
|
|
546
|
+
}
|
|
547
|
+
]
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
"slug": "Item",
|
|
551
|
+
"title": "Item",
|
|
552
|
+
"description": "Элемент списка / строки меню: кнопка, ссылка или `<li>`. Роли: Item внутри List / Menu; для групповых списков выбора — RadioGroup / Dropdown с `items` (не собирайте Item вручную).",
|
|
553
|
+
"importFrom": "@elcrm/components",
|
|
554
|
+
"examples": [
|
|
555
|
+
{
|
|
556
|
+
"title": "Пример",
|
|
557
|
+
"code": "<List>\n <Item active>Текущий</Item>\n <Item as=\"button\" variant=\"card\" active>Карточка</Item>\n</List>"
|
|
558
|
+
}
|
|
559
|
+
],
|
|
560
|
+
"props": [
|
|
561
|
+
{
|
|
562
|
+
"name": "as",
|
|
563
|
+
"type": "\"li\"",
|
|
564
|
+
"description": "Тег: элемент списка (по умолчанию; внутри `<List>` / `<ul>`)"
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
"name": "as",
|
|
568
|
+
"type": "\"button\"",
|
|
569
|
+
"description": "Тег: кнопка"
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
"name": "as",
|
|
573
|
+
"type": "\"a\"",
|
|
574
|
+
"description": "Тег: ссылка"
|
|
575
|
+
}
|
|
576
|
+
]
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
"slug": "ItemColumn",
|
|
580
|
+
"title": "ItemColumn",
|
|
581
|
+
"description": "Колонка содержимого строки списка: иконка слева, текст столбиком, слоты справа. Роли: внутри {@link Item} / {@link Card} (идеи, тикеты, inbox). Не заменяет Item (клик / active) и не AvatarName (там фото).",
|
|
582
|
+
"importFrom": "@elcrm/components",
|
|
583
|
+
"examples": [
|
|
584
|
+
{
|
|
585
|
+
"title": "Пример",
|
|
586
|
+
"code": "<Item as=\"button\" onClick={open}>\n <ItemColumn\n icon={<Icon />}\n title=\"Тема\"\n extra={<Badge size=\"s\" tone=\"accent\">Новые</Badge>}\n description=\"Превью текста…\"\n meta={[\"★ 2\", \"3 комм.\", \"Иван\"]}\n />\n</Item>"
|
|
587
|
+
}
|
|
588
|
+
],
|
|
589
|
+
"props": [
|
|
590
|
+
{
|
|
591
|
+
"name": "icon",
|
|
592
|
+
"type": "React.ReactNode",
|
|
593
|
+
"description": "Иконка слева"
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
"name": "title",
|
|
597
|
+
"type": "React.ReactNode",
|
|
598
|
+
"description": "Заголовок"
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
"name": "extra",
|
|
602
|
+
"type": "React.ReactNode",
|
|
603
|
+
"description": "Справа сверху у title (Badge, счётчик)"
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
"name": "aside",
|
|
607
|
+
"type": "React.ReactNode",
|
|
608
|
+
"description": "Правая колонка (верхний край)"
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
"name": "description",
|
|
612
|
+
"type": "React.ReactNode",
|
|
613
|
+
"description": "Описание / превью"
|
|
614
|
+
},
|
|
615
|
+
{
|
|
616
|
+
"name": "footer",
|
|
617
|
+
"type": "React.ReactNode",
|
|
618
|
+
"description": "Подвал целиком"
|
|
619
|
+
},
|
|
620
|
+
{
|
|
621
|
+
"name": "meta",
|
|
622
|
+
"type": "React.ReactNode[]",
|
|
623
|
+
"description": "Куски подвала через точку — если нет `footer`"
|
|
624
|
+
},
|
|
625
|
+
{
|
|
626
|
+
"name": "size",
|
|
627
|
+
"type": "UiSize",
|
|
628
|
+
"description": "Размер текста"
|
|
629
|
+
},
|
|
630
|
+
{
|
|
631
|
+
"name": "unread",
|
|
632
|
+
"type": "boolean",
|
|
633
|
+
"description": "Жирный title (непрочитанное)"
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
"name": "children",
|
|
637
|
+
"type": "React.ReactNode",
|
|
638
|
+
"description": "Доп. строки под footer"
|
|
639
|
+
}
|
|
640
|
+
]
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
"slug": "Layout",
|
|
644
|
+
"title": "Layout",
|
|
645
|
+
"description": "Оболочка приложения: шапка, основной контент, подвал. Роли: Layout = каркас страницы; внутри — Header / Section / PageShell / Footer. Используйте как корневой каркас маршрута или приложения. `fixed` — какие слоты не крутятся вместе со страницей. По умолчанию `[\"header\", \"footer\", \"sidebar\"]`: скроллится только `children` в `<main>`. Пустой массив — обычный поток, скролл у предка. Высота каркаса: `--layout-height` (по умолчанию `100dvh`). Вложенный стенд: `--layout-height: 100%` у родителя с явной высотой.",
|
|
646
|
+
"importFrom": "@elcrm/components",
|
|
647
|
+
"examples": [
|
|
648
|
+
{
|
|
649
|
+
"title": "Пример",
|
|
650
|
+
"code": "<Layout\n fixed={[\"header\", \"footer\", \"sidebar\"]}\n sidebar={<Sidebar groups={groups} value={page} onValueChange={setPage} />}\n header={<Header brand=\"App\" />}\n footer={<Footer>© elCRM</Footer>}\n>\n <PageShell>…</PageShell>\n</Layout>"
|
|
651
|
+
}
|
|
652
|
+
],
|
|
653
|
+
"props": [
|
|
654
|
+
{
|
|
655
|
+
"name": "sidebar",
|
|
656
|
+
"type": "React.ReactNode",
|
|
657
|
+
"description": "Левая колонка (обычно `<Sidebar />`) — ряд: сайдбар + контент"
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
"name": "header",
|
|
661
|
+
"type": "React.ReactNode",
|
|
662
|
+
"description": "Слот шапки (обычно `<Header />`)"
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
"name": "footer",
|
|
666
|
+
"type": "React.ReactNode",
|
|
667
|
+
"description": "Слот подвала (обычно `<Footer />`)"
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
"name": "fixed",
|
|
671
|
+
"type": "LayoutFixedSlot[]",
|
|
672
|
+
"description": "Какие слоты зафиксированы (не прокручиваются). По умолчанию все: `header`, `footer`, `sidebar`. `[]` — ничего не фиксировать."
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
"name": "children",
|
|
676
|
+
"type": "React.ReactNode",
|
|
677
|
+
"description": "Основной контент страницы (рендерится в `<main>`)"
|
|
678
|
+
}
|
|
679
|
+
]
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
"slug": "List",
|
|
683
|
+
"title": "List",
|
|
684
|
+
"description": "Список (`<ul>`) — вертикальный или горизонтальный. Роли: List = контейнер; элементы — Item (или свои `<li>`). Для навигации / меню смотрите Menu, NavSections.",
|
|
685
|
+
"importFrom": "@elcrm/components",
|
|
686
|
+
"examples": [
|
|
687
|
+
{
|
|
688
|
+
"title": "Пример",
|
|
689
|
+
"code": "<List>\n <Item as=\"li\">Первый</Item>\n <Item as=\"li\" active>Второй</Item>\n</List>"
|
|
690
|
+
}
|
|
691
|
+
],
|
|
692
|
+
"props": [
|
|
693
|
+
{
|
|
694
|
+
"name": "row",
|
|
695
|
+
"type": "boolean",
|
|
696
|
+
"description": "Горизонтальный список"
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
"name": "children",
|
|
700
|
+
"type": "React.ReactNode",
|
|
701
|
+
"description": "Элементы списка (обычно `<Item as=\"li\" />`)"
|
|
702
|
+
}
|
|
703
|
+
]
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
"slug": "Loading",
|
|
707
|
+
"title": "Loading",
|
|
708
|
+
"description": "Плейсхолдер состояния загрузки (`role=\"status\"`). Роли: Loading = индикация ожидания данных; при пустом результате после загрузки — EmptyState.",
|
|
709
|
+
"importFrom": "@elcrm/components",
|
|
710
|
+
"examples": [
|
|
711
|
+
{
|
|
712
|
+
"title": "Пример",
|
|
713
|
+
"code": "{isLoading ? <Loading>Загружаем клиентов…</Loading> : <List>…</List>}"
|
|
714
|
+
}
|
|
715
|
+
],
|
|
716
|
+
"props": [
|
|
717
|
+
{
|
|
718
|
+
"name": "children",
|
|
719
|
+
"type": "React.ReactNode",
|
|
720
|
+
"description": "Текст или кастомный индикатор (по умолчанию «Загрузка…»)"
|
|
721
|
+
}
|
|
722
|
+
]
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
"slug": "Menu",
|
|
726
|
+
"title": "Menu",
|
|
727
|
+
"description": "Навигационное меню в потоке документа (шапка, сайдбар-ряд) — не popover.",
|
|
728
|
+
"importFrom": "@elcrm/components",
|
|
729
|
+
"examples": [
|
|
730
|
+
{
|
|
731
|
+
"title": "Пример",
|
|
732
|
+
"code": "<Menu\n items={items}\n value={section}\n onValueChange={setSection}\n vertical\n/>"
|
|
733
|
+
}
|
|
734
|
+
],
|
|
735
|
+
"props": [
|
|
736
|
+
{
|
|
737
|
+
"name": "items",
|
|
738
|
+
"type": "MenuItem[]",
|
|
739
|
+
"description": "Декларативный список пунктов. Групповые UI elCRM используют `items`, а не compound-слоты."
|
|
740
|
+
},
|
|
741
|
+
{
|
|
742
|
+
"name": "vertical",
|
|
743
|
+
"type": "boolean",
|
|
744
|
+
"description": "Вертикальный ряд пунктов."
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
"name": "variant",
|
|
748
|
+
"type": "\"plain\" | \"line\"",
|
|
749
|
+
"description": "`plain` — пилюли. `line` — вкладки с нижней чертой (фильтры страницы)."
|
|
750
|
+
},
|
|
751
|
+
{
|
|
752
|
+
"name": "value",
|
|
753
|
+
"type": "string",
|
|
754
|
+
"description": "Активный `value` пункта (если у item не задан `active`). Идентификатор — `value`, не `key`."
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
"name": "defaultValue",
|
|
758
|
+
"type": "string",
|
|
759
|
+
"description": "Начальный `value` (неконтролируемый режим)."
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
"name": "onValueChange",
|
|
763
|
+
"type": "(value: string) => void",
|
|
764
|
+
"description": "Выбор пункта: получает `item.value`."
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
"name": "children",
|
|
768
|
+
"type": "React.ReactNode",
|
|
769
|
+
"description": "Дополнительный контент внутри `<nav>` (редко)."
|
|
770
|
+
}
|
|
771
|
+
]
|
|
772
|
+
},
|
|
773
|
+
{
|
|
774
|
+
"slug": "NavSections",
|
|
775
|
+
"title": "NavSections",
|
|
776
|
+
"description": "Макет «настройки / профиль»: вертикальный сайдбар + lazy-секция справа. Когда использовать: - страницы с несколькими разделами и боковым меню; - контент секции грузится по `value` через `resolveSection`. Связанные компоненты: - {@link TabSections} — то же, но вкладки горизонтально; - {@link createLazyResolver} из `lazyRoute` — кэш lazy-импортов; - {@link Menu} — простая навигация без панелей. API: декларативные `groups` / `items`. Идентификатор раздела — `value` (не `key`). У пункта `items` + `defaultOpen` — раскрываемое подменю (как у Sidebar). Compound-слоты (`NavSections.Item`) не используются. CSS-токены: `--shell-*`, `--nav-sections-padding`, `--nav-sections-nav-width`, `--nav-sections-main-max-width`, `--sidebar-indent`.",
|
|
777
|
+
"importFrom": "@elcrm/components",
|
|
778
|
+
"examples": [
|
|
779
|
+
{
|
|
780
|
+
"title": "Пример",
|
|
781
|
+
"code": "const groups = [\n {\n value: \"docs\",\n label: \"Документация\",\n items: [\n {\n value: \"bridge\",\n label: \"VK Bridge\",\n defaultOpen: true,\n items: [\n { value: \"intro\", label: \"Введение\" },\n { value: \"events\", label: \"События\" },\n ],\n },\n ],\n },\n];\n\n<NavSections\n groups={groups}\n resolveSection={resolveSection}\n value={section}\n onValueChange={setSection}\n/>"
|
|
782
|
+
}
|
|
783
|
+
],
|
|
784
|
+
"props": [
|
|
785
|
+
{
|
|
786
|
+
"name": "groups",
|
|
787
|
+
"type": "NavSectionsGroup[]",
|
|
788
|
+
"description": "Группы бокового меню."
|
|
789
|
+
},
|
|
790
|
+
{
|
|
791
|
+
"name": "resolveSection",
|
|
792
|
+
"type": "(value: string) => LazyRouteChunk | React.ComponentType",
|
|
793
|
+
"description": "Резолвер панели справа по `value`. Обычно: `createLazyResolver((v) => import(\\`./sections/${v}.tsx\\`))`. Не нужен, если передали `children`."
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
"name": "children",
|
|
797
|
+
"type": "React.ReactNode",
|
|
798
|
+
"description": "Готовая панель без lazy (вместо `resolveSection`). Приложение само рендерит контент по `value`."
|
|
799
|
+
},
|
|
800
|
+
{
|
|
801
|
+
"name": "value",
|
|
802
|
+
"type": "string",
|
|
803
|
+
"description": "Контролируемый активный `value`."
|
|
804
|
+
},
|
|
805
|
+
{
|
|
806
|
+
"name": "defaultValue",
|
|
807
|
+
"type": "string",
|
|
808
|
+
"description": "Начальный `value` в неконтролируемом режиме."
|
|
809
|
+
},
|
|
810
|
+
{
|
|
811
|
+
"name": "onValueChange",
|
|
812
|
+
"type": "(value: string) => void",
|
|
813
|
+
"description": "Смена активного раздела (`next` = `item.value`)."
|
|
814
|
+
},
|
|
815
|
+
{
|
|
816
|
+
"name": "open",
|
|
817
|
+
"type": "string[]",
|
|
818
|
+
"description": "Раскрытые родители (их `value`). Контролируемый режим. Вместе с `onOpenChange`."
|
|
819
|
+
},
|
|
820
|
+
{
|
|
821
|
+
"name": "defaultOpen",
|
|
822
|
+
"type": "string[]",
|
|
823
|
+
"description": "Начально раскрытые (плюс `item.defaultOpen` и предки выбранного)."
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
"name": "onOpenChange",
|
|
827
|
+
"type": "(open: string[]) => void",
|
|
828
|
+
"description": "Смена набора раскрытых родителей"
|
|
829
|
+
},
|
|
830
|
+
{
|
|
831
|
+
"name": "loading",
|
|
832
|
+
"type": "React.ReactNode",
|
|
833
|
+
"description": "Fallback для `<Suspense>` при ленивой загрузке секции."
|
|
834
|
+
},
|
|
835
|
+
{
|
|
836
|
+
"name": "footer",
|
|
837
|
+
"type": "React.ReactNode",
|
|
838
|
+
"description": "Низ сайдбара (например кнопка «Назад»)."
|
|
839
|
+
},
|
|
840
|
+
{
|
|
841
|
+
"name": "navLabel",
|
|
842
|
+
"type": "string",
|
|
843
|
+
"description": "`aria-label` для `<nav>`."
|
|
844
|
+
}
|
|
845
|
+
]
|
|
846
|
+
},
|
|
847
|
+
{
|
|
848
|
+
"slug": "PageHead",
|
|
849
|
+
"title": "PageHead",
|
|
850
|
+
"description": "Заголовок страницы: title слева, actions справа в одной линии. Роли: PageHead = шапка контента внутри PageShell / Section; для полноценной секции с description/icon — Section; глобальная шапка приложения — Header.",
|
|
851
|
+
"importFrom": "@elcrm/components",
|
|
852
|
+
"examples": [
|
|
853
|
+
{
|
|
854
|
+
"title": "Пример",
|
|
855
|
+
"code": "<PageShell scroll>\n <PageHead title=\"Идеи\" sup={<Badge size=\"s\" tone=\"accent\">4</Badge>} sticky>\n <Menu items={tabs} value={tab} onValueChange={setTab} />\n </PageHead>\n …\n</PageShell>"
|
|
856
|
+
}
|
|
857
|
+
],
|
|
858
|
+
"props": [
|
|
859
|
+
{
|
|
860
|
+
"name": "title",
|
|
861
|
+
"type": "React.ReactNode",
|
|
862
|
+
"description": "Заголовок страницы"
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
"name": "sup",
|
|
866
|
+
"type": "React.ReactNode",
|
|
867
|
+
"description": "Надстрочный слот сразу после title: текст или {@link Badge}. Пусто / `0` / `false` — не рендерим."
|
|
868
|
+
},
|
|
869
|
+
{
|
|
870
|
+
"name": "subtitle",
|
|
871
|
+
"type": "React.ReactNode",
|
|
872
|
+
"description": "Подзаголовок"
|
|
873
|
+
},
|
|
874
|
+
{
|
|
875
|
+
"name": "actions",
|
|
876
|
+
"type": "React.ReactNode",
|
|
877
|
+
"description": "Кнопки / поиск справа в одной строке с заголовком"
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
"name": "sticky",
|
|
881
|
+
"type": "boolean",
|
|
882
|
+
"description": "Прилипает к верху скролла предка (`PageShell` с `scroll`). По умолчанию `false`."
|
|
883
|
+
},
|
|
884
|
+
{
|
|
885
|
+
"name": "children",
|
|
886
|
+
"type": "React.ReactNode",
|
|
887
|
+
"description": "Контент под строкой заголовка (фильтры, поиск, вкладки). Между title и children — `--shell-gap`."
|
|
888
|
+
}
|
|
889
|
+
]
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
"slug": "PageShell",
|
|
893
|
+
"title": "PageShell",
|
|
894
|
+
"description": "Каркас модуля: опциональный скролл в body, footer прибит к низу. Роли: PageShell = внутренний каркас контента в Layout; сверху часто PageHead / Section, снизу — панель действий.",
|
|
895
|
+
"importFrom": "@elcrm/components",
|
|
896
|
+
"examples": [
|
|
897
|
+
{
|
|
898
|
+
"title": "Пример",
|
|
899
|
+
"code": "<PageShell wide scroll footer={<Footer><Button>Сохранить</Button></Footer>}>\n <PageHead title=\"Редактор\" sticky />\n …\n</PageShell>"
|
|
900
|
+
}
|
|
901
|
+
],
|
|
902
|
+
"props": [
|
|
903
|
+
{
|
|
904
|
+
"name": "children",
|
|
905
|
+
"type": "React.ReactNode",
|
|
906
|
+
"description": "Контент модуля"
|
|
907
|
+
},
|
|
908
|
+
{
|
|
909
|
+
"name": "wide",
|
|
910
|
+
"type": "boolean",
|
|
911
|
+
"description": "Шире контент (редакторы, таблицы)"
|
|
912
|
+
},
|
|
913
|
+
{
|
|
914
|
+
"name": "scroll",
|
|
915
|
+
"type": "boolean",
|
|
916
|
+
"description": "Скролл внутри body. По умолчанию `true`. `false` — шелл растёт с контентом, крутит предок."
|
|
917
|
+
},
|
|
918
|
+
{
|
|
919
|
+
"name": "footer",
|
|
920
|
+
"type": "React.ReactNode",
|
|
921
|
+
"description": "Нижняя панель вне скролла"
|
|
922
|
+
}
|
|
923
|
+
]
|
|
924
|
+
},
|
|
925
|
+
{
|
|
926
|
+
"slug": "PanelInfo",
|
|
927
|
+
"title": "PanelInfo",
|
|
928
|
+
"description": "Выезжающая панель справа: шапка / body / footer. Широкий экран — flex-колонка рядом со списком (`aside`). Узкий (`max-width: 56rem`) — `dialog` + `aria-modal`, затемнение, focus trap и `acquireOverlayZIndex`.",
|
|
929
|
+
"importFrom": "@elcrm/components",
|
|
930
|
+
"examples": [
|
|
931
|
+
{
|
|
932
|
+
"title": "Пример",
|
|
933
|
+
"code": "<PanelInfo\n open={!!row}\n title={row?.name ?? \"\"}\n onClose={() => setId(null)}\n footer={<Button width=\"l\" label=\"Сохранить\" onSend={onSave} />}\n>\n <StringField name=\"name\" form={form} label=\"Название\" />\n</PanelInfo>"
|
|
934
|
+
}
|
|
935
|
+
],
|
|
936
|
+
"props": [
|
|
937
|
+
{
|
|
938
|
+
"name": "open",
|
|
939
|
+
"type": "boolean",
|
|
940
|
+
"description": "Открыта ли панель (controlled)."
|
|
941
|
+
},
|
|
942
|
+
{
|
|
943
|
+
"name": "defaultOpen",
|
|
944
|
+
"type": "boolean",
|
|
945
|
+
"description": "Начальное открытие (uncontrolled)."
|
|
946
|
+
},
|
|
947
|
+
{
|
|
948
|
+
"name": "title",
|
|
949
|
+
"type": "React.ReactNode",
|
|
950
|
+
"description": "Заголовок шапки."
|
|
951
|
+
},
|
|
952
|
+
{
|
|
953
|
+
"name": "onOpenChange",
|
|
954
|
+
"type": "(open: boolean) => void",
|
|
955
|
+
"description": "Смена open (крестик / фон / Escape)."
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
"name": "onClose",
|
|
959
|
+
"type": "() => void",
|
|
960
|
+
"description": "Закрытие. Эквивалент `onOpenChange(false)`. Удобный алиас для controlled-режима."
|
|
961
|
+
},
|
|
962
|
+
{
|
|
963
|
+
"name": "children",
|
|
964
|
+
"type": "React.ReactNode",
|
|
965
|
+
"description": "Тело — форма (`@elcrm/form` поля) или любой контент. Скроллится между шапкой и footer."
|
|
966
|
+
},
|
|
967
|
+
{
|
|
968
|
+
"name": "footer",
|
|
969
|
+
"type": "React.ReactNode",
|
|
970
|
+
"description": "Низ вне скролла — обычно `Stack` + `@elcrm/button` («Отмена» / «Сохранить»)."
|
|
971
|
+
},
|
|
972
|
+
{
|
|
973
|
+
"name": "headerExtra",
|
|
974
|
+
"type": "React.ReactNode",
|
|
975
|
+
"description": "Доп. действия в шапке слева от крестика."
|
|
976
|
+
},
|
|
977
|
+
{
|
|
978
|
+
"name": "close",
|
|
979
|
+
"type": "React.ReactNode",
|
|
980
|
+
"description": "Слот кнопки закрытия. По умолчанию — крестик. Приложение может подставить `@elcrm/button`."
|
|
981
|
+
}
|
|
982
|
+
]
|
|
983
|
+
},
|
|
984
|
+
{
|
|
985
|
+
"slug": "Popover",
|
|
986
|
+
"title": "Popover",
|
|
987
|
+
"description": "Портал у якоря: Escape, клик снаружи, z-index (`globalThis.elcrm.overlayZ`). Роли: Popover = свой попап (слот `children`). Типовое меню пунктов — {@link Dropdown}. Якорь — без `cloneElement`: - `trigger={(api) => <button {...api.anchorProps}>…</button>}` — канон; - `trigger={<span>…</span>}` — клик/ARIA на обёртке.",
|
|
988
|
+
"importFrom": "@elcrm/components",
|
|
989
|
+
"examples": [
|
|
990
|
+
{
|
|
991
|
+
"title": "Пример",
|
|
992
|
+
"code": "<Popover\n trigger={(api) => (\n <Button {...api.anchorProps}>Ещё</Button>\n )}\n label=\"Действия\"\n role=\"dialog\"\n>\n <List><Item as=\"button\">Скачать</Item></List>\n</Popover>"
|
|
993
|
+
}
|
|
994
|
+
],
|
|
995
|
+
"props": [
|
|
996
|
+
{
|
|
997
|
+
"name": "trigger",
|
|
998
|
+
"type": "React.ReactNode | ((api: PopoverTriggerApi) => React.ReactNode)",
|
|
999
|
+
"description": "Якорь: узел **или** render-prop с {@link PopoverTriggerApi}. Render-prop — без clone; пропы на кнопку через `anchorProps`."
|
|
1000
|
+
},
|
|
1001
|
+
{
|
|
1002
|
+
"name": "children",
|
|
1003
|
+
"type": "React.ReactNode",
|
|
1004
|
+
"description": "Содержимое панели"
|
|
1005
|
+
},
|
|
1006
|
+
{
|
|
1007
|
+
"name": "open",
|
|
1008
|
+
"type": "boolean",
|
|
1009
|
+
"description": "Контролируемое открытие"
|
|
1010
|
+
},
|
|
1011
|
+
{
|
|
1012
|
+
"name": "defaultOpen",
|
|
1013
|
+
"type": "boolean",
|
|
1014
|
+
"description": "Начальное открытие"
|
|
1015
|
+
},
|
|
1016
|
+
{
|
|
1017
|
+
"name": "onOpenChange",
|
|
1018
|
+
"type": "(open: boolean) => void",
|
|
1019
|
+
"description": "Смена open"
|
|
1020
|
+
},
|
|
1021
|
+
{
|
|
1022
|
+
"name": "align",
|
|
1023
|
+
"type": "\"start\" | \"end\"",
|
|
1024
|
+
"description": "Выравнивание панели"
|
|
1025
|
+
},
|
|
1026
|
+
{
|
|
1027
|
+
"name": "placement",
|
|
1028
|
+
"type": "PopoverPlacement",
|
|
1029
|
+
"description": "Куда открывать панель. `top` — всегда вверх (футер Sidebar). @default \"auto\""
|
|
1030
|
+
},
|
|
1031
|
+
{
|
|
1032
|
+
"name": "disabled",
|
|
1033
|
+
"type": "boolean",
|
|
1034
|
+
"description": "Не открывать по клику на якорь"
|
|
1035
|
+
},
|
|
1036
|
+
{
|
|
1037
|
+
"name": "label",
|
|
1038
|
+
"type": "string",
|
|
1039
|
+
"description": "aria-label панели"
|
|
1040
|
+
},
|
|
1041
|
+
{
|
|
1042
|
+
"name": "role",
|
|
1043
|
+
"type": "React.AriaRole",
|
|
1044
|
+
"description": "role панели. По умолчанию без роли (произвольный контент). Меню пунктов — `role=\"menu\"` ({@link Dropdown})."
|
|
1045
|
+
},
|
|
1046
|
+
{
|
|
1047
|
+
"name": "panelClassName",
|
|
1048
|
+
"type": "string",
|
|
1049
|
+
"description": "Класс панели (portal)"
|
|
1050
|
+
},
|
|
1051
|
+
{
|
|
1052
|
+
"name": "fitContent",
|
|
1053
|
+
"type": "boolean",
|
|
1054
|
+
"description": "Высота по контенту: без `maxHeight` и без внутреннего скролла. Для меню аккаунта Sidebar (`Dropdown tone=\"account\"`)."
|
|
1055
|
+
}
|
|
1056
|
+
]
|
|
1057
|
+
},
|
|
1058
|
+
{
|
|
1059
|
+
"slug": "PricingGroup",
|
|
1060
|
+
"title": "PricingGroup",
|
|
1061
|
+
"description": "Горизонтальная группа тарифных карточек из декларативного `items`. Когда использовать: - страница тарифов / upgrade без матрицы сравнения; - один и тот же массив {@link PricingPlan} позже уйдёт в {@link PricingTable}. Связанные компоненты: - {@link PricingTable} — сравнительная матрица поверх тех же `items`; - {@link RadioGroup} — выбор опции с индикатором, не обязательно тариф. Общий тип плана — {@link PricingPlan}. Идентификатор — `value` (не `key`). Compound-слоты не используются. CSS-токены: `--shell-*`, узкие `--pricing-card-min-width`.",
|
|
1062
|
+
"importFrom": "@elcrm/components",
|
|
1063
|
+
"examples": [
|
|
1064
|
+
{
|
|
1065
|
+
"title": "Пример",
|
|
1066
|
+
"code": "const items: PricingPlan[] = [\n {\n value: \"starter\",\n title: \"Starter\",\n price: \"$9\",\n meta: \"в месяц\",\n features: [\"1 проект\", \"Email-поддержка\"],\n actions: <Button onSend={…}>Выбрать</Button>,\n },\n {\n value: \"pro\",\n title: \"Pro\",\n price: \"$29\",\n badge: \"Popular\",\n badgePlacement: \"float\",\n highlighted: true,\n features: [\"Безлимит\", \"SSO\"],\n actions: <Button onSend={…}>Выбрать</Button>,\n },\n];\n\n<PricingGroup items={items} selectable value={plan} onValueChange={setPlan} />"
|
|
1067
|
+
}
|
|
1068
|
+
],
|
|
1069
|
+
"props": [
|
|
1070
|
+
{
|
|
1071
|
+
"name": "items",
|
|
1072
|
+
"type": "PricingPlan[]",
|
|
1073
|
+
"description": "Тарифные карточки — тот же shape, что у {@link PricingTable}."
|
|
1074
|
+
},
|
|
1075
|
+
{
|
|
1076
|
+
"name": "value",
|
|
1077
|
+
"type": "string",
|
|
1078
|
+
"description": "Выбранный план (controlled), сравнивается с `item.value`."
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
"name": "defaultValue",
|
|
1082
|
+
"type": "string",
|
|
1083
|
+
"description": "Начальный выбранный план (uncontrolled)."
|
|
1084
|
+
},
|
|
1085
|
+
{
|
|
1086
|
+
"name": "selectable",
|
|
1087
|
+
"type": "boolean",
|
|
1088
|
+
"description": "Клик по карточке выбирает value (actions не трогают выбор)."
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
"name": "disabled",
|
|
1092
|
+
"type": "boolean",
|
|
1093
|
+
"description": "Заблокировать выбор."
|
|
1094
|
+
},
|
|
1095
|
+
{
|
|
1096
|
+
"name": "onValueChange",
|
|
1097
|
+
"type": "(value: string) => void",
|
|
1098
|
+
"description": "Смена выбранного плана."
|
|
1099
|
+
}
|
|
1100
|
+
]
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
"slug": "PricingTable",
|
|
1104
|
+
"title": "PricingTable",
|
|
1105
|
+
"description": "Сравнительная таблица тарифов: колонки из `items` + матрица `sections`. Когда использовать: - страница сравнения фич между планами; - те же {@link PricingPlan} уже используются в {@link PricingGroup}. Связанные компоненты: - {@link PricingGroup} — карточки без матрицы; - общий тип — {@link PricingPlan}. API: декларативные `items` (+ `sections`). Идентификатор плана — `value` (не `key`). Compound-слоты не используются. CSS-токены: `--shell-*`, узкие `--pricing-table-label-width`, `--pricing-card-min-width`.",
|
|
1106
|
+
"importFrom": "@elcrm/components",
|
|
1107
|
+
"examples": [
|
|
1108
|
+
{
|
|
1109
|
+
"title": "Пример",
|
|
1110
|
+
"code": "const items: PricingPlan[] = [\n { value: \"starter\", title: \"Starter\", price: \"$9\", actions: <Button>…</Button> },\n { value: \"pro\", title: \"Pro\", price: \"$29\", highlighted: true, actions: <Button>…</Button> },\n];\n\nconst sections = [\n {\n title: \"Команда\",\n rows: [\n {\n key: \"seats\",\n label: \"Участники\",\n values: { starter: \"3\", pro: \"Безлимит\" },\n },\n {\n key: \"sso\",\n label: \"SSO\",\n hint: \"Единый вход\",\n values: { starter: false, pro: true },\n },\n ],\n },\n];\n\n<PricingTable items={items} sections={sections} selectable />"
|
|
1111
|
+
}
|
|
1112
|
+
],
|
|
1113
|
+
"props": [
|
|
1114
|
+
{
|
|
1115
|
+
"name": "items",
|
|
1116
|
+
"type": "PricingTableItem[]",
|
|
1117
|
+
"description": "Колонки планов — тот же shape, что у {@link PricingGroup}."
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
"name": "sections",
|
|
1121
|
+
"type": "PricingTableSection[]",
|
|
1122
|
+
"description": "Матрица сравнения (секции → строки → values по plan.value)."
|
|
1123
|
+
},
|
|
1124
|
+
{
|
|
1125
|
+
"name": "footerActions",
|
|
1126
|
+
"type": "boolean",
|
|
1127
|
+
"description": "Повторить actions внизу таблицы (как на макетах)."
|
|
1128
|
+
},
|
|
1129
|
+
{
|
|
1130
|
+
"name": "value",
|
|
1131
|
+
"type": "string",
|
|
1132
|
+
"description": "Выбранный план (controlled)."
|
|
1133
|
+
},
|
|
1134
|
+
{
|
|
1135
|
+
"name": "defaultValue",
|
|
1136
|
+
"type": "string",
|
|
1137
|
+
"description": "Начальный план (uncontrolled)."
|
|
1138
|
+
},
|
|
1139
|
+
{
|
|
1140
|
+
"name": "selectable",
|
|
1141
|
+
"type": "boolean",
|
|
1142
|
+
"description": "Клик по шапке колонки выбирает план."
|
|
1143
|
+
},
|
|
1144
|
+
{
|
|
1145
|
+
"name": "disabled",
|
|
1146
|
+
"type": "boolean",
|
|
1147
|
+
"description": "Заблокировать выбор."
|
|
1148
|
+
},
|
|
1149
|
+
{
|
|
1150
|
+
"name": "onValueChange",
|
|
1151
|
+
"type": "(value: string) => void",
|
|
1152
|
+
"description": "Смена выбранного плана (`item.value`)."
|
|
1153
|
+
}
|
|
1154
|
+
]
|
|
1155
|
+
},
|
|
1156
|
+
{
|
|
1157
|
+
"slug": "RadioGroup",
|
|
1158
|
+
"title": "RadioGroup",
|
|
1159
|
+
"description": "Группа выбора одной опции из декларативного массива `items`. Когда использовать: - выбор тарифа, способа оплаты, человека, варианта настроек карточкой; - нужен check/radio-индикатор и опциональные icon / meta / actions. Связанные компоненты: - {@link PricingGroup} — тарифные карточки без radio-индикатора; - {@link AvatarName} — часто как `icon` / контент опции «человек». API: только `items` + value/onValueChange. Compound-слоты (`RadioGroup.Item`) не используются. Идентификатор опции — `value` (не `key`). CSS-токены: `--shell-*`.",
|
|
1160
|
+
"importFrom": "@elcrm/components",
|
|
1161
|
+
"examples": [
|
|
1162
|
+
{
|
|
1163
|
+
"title": "Пример",
|
|
1164
|
+
"code": "const items = [\n {\n value: \"basic\",\n icon: <Icons.Line name=\"zap\" />,\n title: \"Basic\",\n description: \"Для старта\",\n meta: \"$9/мес\",\n },\n {\n value: \"pro\",\n title: \"Pro\",\n description: \"Для команд\",\n price: \"$29\",\n badge: <Badge>Popular</Badge>,\n variant: \"split\",\n },\n];\n\n<RadioGroup\n items={items}\n value={plan}\n onValueChange={setPlan}\n indicator=\"check\"\n indicatorSide=\"end\"\n/>"
|
|
1165
|
+
}
|
|
1166
|
+
],
|
|
1167
|
+
"props": [
|
|
1168
|
+
{
|
|
1169
|
+
"name": "items",
|
|
1170
|
+
"type": "RadioGroupItem[]",
|
|
1171
|
+
"description": "Декларативный список опций."
|
|
1172
|
+
},
|
|
1173
|
+
{
|
|
1174
|
+
"name": "value",
|
|
1175
|
+
"type": "string",
|
|
1176
|
+
"description": "Выбранное значение (controlled)."
|
|
1177
|
+
},
|
|
1178
|
+
{
|
|
1179
|
+
"name": "defaultValue",
|
|
1180
|
+
"type": "string",
|
|
1181
|
+
"description": "Начальное значение (uncontrolled)."
|
|
1182
|
+
},
|
|
1183
|
+
{
|
|
1184
|
+
"name": "name",
|
|
1185
|
+
"type": "string",
|
|
1186
|
+
"description": "`name` для скрытых `input[type=radio]`."
|
|
1187
|
+
},
|
|
1188
|
+
{
|
|
1189
|
+
"name": "disabled",
|
|
1190
|
+
"type": "boolean",
|
|
1191
|
+
"description": "Заблокировать всю группу."
|
|
1192
|
+
},
|
|
1193
|
+
{
|
|
1194
|
+
"name": "indicator",
|
|
1195
|
+
"type": "RadioIndicator",
|
|
1196
|
+
"description": "`check` — квадрат с галочкой; `radio` — круг."
|
|
1197
|
+
},
|
|
1198
|
+
{
|
|
1199
|
+
"name": "indicatorSide",
|
|
1200
|
+
"type": "RadioIndicatorSide",
|
|
1201
|
+
"description": "Сторона индикатора в row-варианте."
|
|
1202
|
+
},
|
|
1203
|
+
{
|
|
1204
|
+
"name": "onValueChange",
|
|
1205
|
+
"type": "(value: string) => void",
|
|
1206
|
+
"description": "Смена выбора (`next` = `item.value`)."
|
|
1207
|
+
}
|
|
1208
|
+
]
|
|
1209
|
+
},
|
|
1210
|
+
{
|
|
1211
|
+
"slug": "Section",
|
|
1212
|
+
"title": "Section",
|
|
1213
|
+
"description": "Единая секция страницы: заголовок, описание, иконка, контент, действия. Роли (не путать): - `Layout` — оболочка приложения (`<main>` внутри); - `PageShell` — каркас модуля (скролл + footer); - `PageHead` — строка title + actions на странице; - `Section` — блок контента / auth / подраздел. Тело (`children`) — тот же ряд/колонка/сетка, что у `Stack` (`direction` / `gap` / `columns`). Ряд кнопок в `actions` — оберни в `<Stack direction=\"row\">`.",
|
|
1214
|
+
"importFrom": "@elcrm/components",
|
|
1215
|
+
"examples": [
|
|
1216
|
+
{
|
|
1217
|
+
"title": "Пример",
|
|
1218
|
+
"code": "<Section title=\"Фильтры\" direction=\"row\" gap={12}>\n <SearchField name=\"q\" />\n <Button>Найти</Button>\n</Section>\n<Section title=\"Карточки\" direction=\"grid\" columns={3} gap={16}>\n <Stat label=\"Всего\" value={10} />\n</Section>"
|
|
1219
|
+
}
|
|
1220
|
+
],
|
|
1221
|
+
"props": [
|
|
1222
|
+
{
|
|
1223
|
+
"name": "title",
|
|
1224
|
+
"type": "React.ReactNode",
|
|
1225
|
+
"description": "Заголовок секции"
|
|
1226
|
+
},
|
|
1227
|
+
{
|
|
1228
|
+
"name": "description",
|
|
1229
|
+
"type": "React.ReactNode",
|
|
1230
|
+
"description": "Подзаголовок / описание"
|
|
1231
|
+
},
|
|
1232
|
+
{
|
|
1233
|
+
"name": "icon",
|
|
1234
|
+
"type": "React.ReactNode",
|
|
1235
|
+
"description": "Иконка / логотип над или рядом с заголовком"
|
|
1236
|
+
},
|
|
1237
|
+
{
|
|
1238
|
+
"name": "children",
|
|
1239
|
+
"type": "React.ReactNode",
|
|
1240
|
+
"description": "Основной контент секции"
|
|
1241
|
+
},
|
|
1242
|
+
{
|
|
1243
|
+
"name": "actions",
|
|
1244
|
+
"type": "React.ReactNode",
|
|
1245
|
+
"description": "Блок действий под контентом (колонка; для ряда — Stack direction=\"row\")"
|
|
1246
|
+
},
|
|
1247
|
+
{
|
|
1248
|
+
"name": "variant",
|
|
1249
|
+
"type": "\"page\" | \"block\" | \"auth\"",
|
|
1250
|
+
"description": "`page` — секция модуля / панель настроек. `block` — блок внутри панели (заголовок + разделитель). `auth` — центрированная карточка входа."
|
|
1251
|
+
},
|
|
1252
|
+
{
|
|
1253
|
+
"name": "align",
|
|
1254
|
+
"type": "\"start\" | \"center\"",
|
|
1255
|
+
"description": "Выравнивание шапки (`start` по умолчанию, для `auth` — `center`)"
|
|
1256
|
+
},
|
|
1257
|
+
{
|
|
1258
|
+
"name": "titleSize",
|
|
1259
|
+
"type": "\"md\" | \"lg\"",
|
|
1260
|
+
"description": "Размер заголовка"
|
|
1261
|
+
},
|
|
1262
|
+
{
|
|
1263
|
+
"name": "direction",
|
|
1264
|
+
"type": "StackDirection",
|
|
1265
|
+
"description": "Раскладка тела: как у Stack (по умолчанию `column`)"
|
|
1266
|
+
},
|
|
1267
|
+
{
|
|
1268
|
+
"name": "gap",
|
|
1269
|
+
"type": "number | string",
|
|
1270
|
+
"description": "Отступ между детьми тела"
|
|
1271
|
+
},
|
|
1272
|
+
{
|
|
1273
|
+
"name": "columns",
|
|
1274
|
+
"type": "StackColumns",
|
|
1275
|
+
"description": "Сетка тела: число колонок или треки (только при `direction=\"grid\"`)"
|
|
1276
|
+
},
|
|
1277
|
+
{
|
|
1278
|
+
"name": "as",
|
|
1279
|
+
"type": "\"section\" | \"main\" | \"div\"",
|
|
1280
|
+
"description": "HTML-тег корня. По умолчанию `section` (Layout уже даёт `<main>`). Явно `main` — только если Section сам корень страницы без Layout."
|
|
1281
|
+
}
|
|
1282
|
+
]
|
|
1283
|
+
},
|
|
1284
|
+
{
|
|
1285
|
+
"slug": "Sidebar",
|
|
1286
|
+
"title": "Sidebar",
|
|
1287
|
+
"description": "Левая колонка приложения: бренд, группы меню, футер. Роли: Sidebar = навигация приложения; не путать с NavSections (сайдбар внутри страницы + lazy-панель). `variant=\"cards\"` — секции-карточки (elWMS Console). `variant=\"plain\"` — плоский список и заголовок группы (backoffice). Иконки, колокольчик, тема, выход — слоты приложения (`brand`, `extra`, `footer`). Роутер не подключаем.",
|
|
1288
|
+
"importFrom": "@elcrm/components",
|
|
1289
|
+
"examples": [
|
|
1290
|
+
{
|
|
1291
|
+
"title": "Пример",
|
|
1292
|
+
"code": "<Sidebar\n variant=\"cards\"\n value={page}\n onValueChange={setPage}\n brand={<Brand as=\"strong\">App</Brand>}\n extra={<Notifications.Bell />}\n groups={[\n {\n value: \"docs\",\n items: [\n { value: \"games\", label: \"VK Games\" },\n {\n value: \"bridge\",\n label: \"VK Bridge\",\n defaultOpen: true,\n items: [\n { value: \"intro\", label: \"Введение\" },\n { value: \"events\", label: \"События\", items: [\n { value: \"evt-init\", label: \"VKWebAppInit\" },\n ] },\n ],\n },\n ],\n },\n ]}\n footer={<AvatarName title=\"Паша\" description=\"mail@…\" />}\n footerItems={[\n { value: \"home\", label: \"Главная\", icon: <Icon /> },\n { value: \"theme\", label: \"Тема\", submenu: true },\n { value: \"logout\", label: \"Выйти\", danger: true },\n ]}\n onFooterValueChange={(value) => console.log(value)}\n version=\"v 0.2.26\"\n/>"
|
|
1293
|
+
}
|
|
1294
|
+
],
|
|
1295
|
+
"props": [
|
|
1296
|
+
{
|
|
1297
|
+
"name": "groups",
|
|
1298
|
+
"type": "SidebarGroup[]",
|
|
1299
|
+
"description": "Группы пунктов (`value` + `items`). Канон — только `groups`."
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
"name": "value",
|
|
1303
|
+
"type": "string",
|
|
1304
|
+
"description": "Текущий пункт (controlled)."
|
|
1305
|
+
},
|
|
1306
|
+
{
|
|
1307
|
+
"name": "defaultValue",
|
|
1308
|
+
"type": "string",
|
|
1309
|
+
"description": "Начальный пункт (uncontrolled)."
|
|
1310
|
+
},
|
|
1311
|
+
{
|
|
1312
|
+
"name": "onValueChange",
|
|
1313
|
+
"type": "(value: string) => void",
|
|
1314
|
+
"description": "Выбор пункта (только листья, без вложенных `items`)."
|
|
1315
|
+
},
|
|
1316
|
+
{
|
|
1317
|
+
"name": "open",
|
|
1318
|
+
"type": "string[]",
|
|
1319
|
+
"description": "Раскрытые родители (их `value`). Контролируемый режим. Вместе с `onOpenChange`."
|
|
1320
|
+
},
|
|
1321
|
+
{
|
|
1322
|
+
"name": "defaultOpen",
|
|
1323
|
+
"type": "string[]",
|
|
1324
|
+
"description": "Начально раскрытые (плюс `item.defaultOpen` и предки выбранного)."
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
"name": "onOpenChange",
|
|
1328
|
+
"type": "(open: string[]) => void",
|
|
1329
|
+
"description": "Смена набора раскрытых родителей"
|
|
1330
|
+
},
|
|
1331
|
+
{
|
|
1332
|
+
"name": "variant",
|
|
1333
|
+
"type": "SidebarVariant",
|
|
1334
|
+
"description": "`cards` — блоки-карточки. `plain` — плоский список. @default \"cards\""
|
|
1335
|
+
},
|
|
1336
|
+
{
|
|
1337
|
+
"name": "brand",
|
|
1338
|
+
"type": "React.ReactNode",
|
|
1339
|
+
"description": "Логотип / название"
|
|
1340
|
+
},
|
|
1341
|
+
{
|
|
1342
|
+
"name": "extra",
|
|
1343
|
+
"type": "React.ReactNode",
|
|
1344
|
+
"description": "Справа от бренда (колокольчик)"
|
|
1345
|
+
},
|
|
1346
|
+
{
|
|
1347
|
+
"name": "footer",
|
|
1348
|
+
"type": "React.ReactNode",
|
|
1349
|
+
"description": "Низ: тема, выход или карточка пользователя"
|
|
1350
|
+
},
|
|
1351
|
+
{
|
|
1352
|
+
"name": "footerItems",
|
|
1353
|
+
"type": "DropdownItem[]",
|
|
1354
|
+
"description": "Меню по клику на `footer` (Dropdown, `placement=\"top\"`). Есть пункты → футер становится триггером, справа ⋮."
|
|
1355
|
+
},
|
|
1356
|
+
{
|
|
1357
|
+
"name": "onFooterValueChange",
|
|
1358
|
+
"type": "(value: string, item: DropdownItem) => void",
|
|
1359
|
+
"description": "Выбор пункта меню аккаунта"
|
|
1360
|
+
},
|
|
1361
|
+
{
|
|
1362
|
+
"name": "footerMenuLabel",
|
|
1363
|
+
"type": "string",
|
|
1364
|
+
"description": "`aria-label` панели меню аккаунта"
|
|
1365
|
+
},
|
|
1366
|
+
{
|
|
1367
|
+
"name": "version",
|
|
1368
|
+
"type": "React.ReactNode",
|
|
1369
|
+
"description": "Версия под футером"
|
|
1370
|
+
}
|
|
1371
|
+
]
|
|
1372
|
+
},
|
|
1373
|
+
{
|
|
1374
|
+
"slug": "SplitPane",
|
|
1375
|
+
"title": "SplitPane",
|
|
1376
|
+
"description": "Две панели с перетаскиваемым разделителем.",
|
|
1377
|
+
"importFrom": "@elcrm/components",
|
|
1378
|
+
"examples": [
|
|
1379
|
+
{
|
|
1380
|
+
"title": "Пример",
|
|
1381
|
+
"code": "<SplitPane\n direction=\"horizontal\"\n ratio={ratio}\n onRatioChange={setRatio}\n first={<Preview />}\n second={<Editor />}\n/>\n<SplitPane direction=\"horizontal\" defaultRatio={0.58} first={…} second={…} />"
|
|
1382
|
+
}
|
|
1383
|
+
],
|
|
1384
|
+
"props": [
|
|
1385
|
+
{
|
|
1386
|
+
"name": "ratio",
|
|
1387
|
+
"type": "number",
|
|
1388
|
+
"description": "Доля первой панели 0…1 (controlled)."
|
|
1389
|
+
},
|
|
1390
|
+
{
|
|
1391
|
+
"name": "defaultRatio",
|
|
1392
|
+
"type": "number",
|
|
1393
|
+
"description": "Начальная доля (uncontrolled). @default 0.5"
|
|
1394
|
+
}
|
|
1395
|
+
]
|
|
1396
|
+
},
|
|
1397
|
+
{
|
|
1398
|
+
"slug": "Stack",
|
|
1399
|
+
"title": "Stack",
|
|
1400
|
+
"description": "Универсальный стек (ряд / колонка) с отступами между детьми. Роли: Stack = базовая раскладка (Block / Row / Column удалены — `elcrm migrate components`). Внутри Section, Card, форм и списков действий.",
|
|
1401
|
+
"importFrom": "@elcrm/components",
|
|
1402
|
+
"examples": [
|
|
1403
|
+
{
|
|
1404
|
+
"title": "Пример",
|
|
1405
|
+
"code": "<Stack direction=\"row\" gap={12}>\n <Button>Отмена</Button>\n <Button>Сохранить</Button>\n</Stack>\n<Stack direction=\"grid\" columns={[\"1fr\", \"100px\", \"100px\"]} gap={12} />"
|
|
1406
|
+
}
|
|
1407
|
+
],
|
|
1408
|
+
"props": [
|
|
1409
|
+
{
|
|
1410
|
+
"name": "direction",
|
|
1411
|
+
"type": "StackDirection",
|
|
1412
|
+
"description": "Направление: по умолчанию `column`. `grid` — сетка"
|
|
1413
|
+
},
|
|
1414
|
+
{
|
|
1415
|
+
"name": "columns",
|
|
1416
|
+
"type": "StackColumns",
|
|
1417
|
+
"description": "Сетка: `4` — четыре равные колонки; `[\"1fr\", \"100px\", \"auto\"]` — свои треки (число в массиве = px)."
|
|
1418
|
+
},
|
|
1419
|
+
{
|
|
1420
|
+
"name": "gap",
|
|
1421
|
+
"type": "number | string",
|
|
1422
|
+
"description": "Отступ между детьми: число (px) или CSS-строка"
|
|
1423
|
+
},
|
|
1424
|
+
{
|
|
1425
|
+
"name": "children",
|
|
1426
|
+
"type": "React.ReactNode",
|
|
1427
|
+
"description": "Дочерние элементы стека"
|
|
1428
|
+
}
|
|
1429
|
+
]
|
|
1430
|
+
},
|
|
1431
|
+
{
|
|
1432
|
+
"slug": "Stat",
|
|
1433
|
+
"title": "Stat",
|
|
1434
|
+
"description": "Карточка-метрика: подпись сверху, крупное число снизу. Роли: сводка на PageHead / над списком. Не заменяет Card с произвольным контентом.",
|
|
1435
|
+
"importFrom": "@elcrm/components",
|
|
1436
|
+
"examples": [
|
|
1437
|
+
{
|
|
1438
|
+
"title": "Пример",
|
|
1439
|
+
"code": "<Stack direction=\"grid\" gap={12}>\n <Stat label=\"Всего\" value={10} labelMuted={false} />\n <Stat label=\"Admin\" value={6} tone=\"accent\" />\n</Stack>"
|
|
1440
|
+
}
|
|
1441
|
+
],
|
|
1442
|
+
"props": [
|
|
1443
|
+
{
|
|
1444
|
+
"name": "label",
|
|
1445
|
+
"type": "React.ReactNode",
|
|
1446
|
+
"description": "Подпись метрики"
|
|
1447
|
+
},
|
|
1448
|
+
{
|
|
1449
|
+
"name": "value",
|
|
1450
|
+
"type": "React.ReactNode",
|
|
1451
|
+
"description": "Значение"
|
|
1452
|
+
},
|
|
1453
|
+
{
|
|
1454
|
+
"name": "tone",
|
|
1455
|
+
"type": "StatTone",
|
|
1456
|
+
"description": "Цвет числа"
|
|
1457
|
+
},
|
|
1458
|
+
{
|
|
1459
|
+
"name": "labelMuted",
|
|
1460
|
+
"type": "boolean",
|
|
1461
|
+
"description": "Приглушить подпись (по умолчанию да)"
|
|
1462
|
+
}
|
|
1463
|
+
]
|
|
1464
|
+
},
|
|
1465
|
+
{
|
|
1466
|
+
"slug": "Table",
|
|
1467
|
+
"title": "Table",
|
|
1468
|
+
"description": "Таблица данных: обёртка со скроллом + стили shell. Подпись таблицы — нативный `<caption>` в `children` (a11y).",
|
|
1469
|
+
"importFrom": "@elcrm/components",
|
|
1470
|
+
"examples": [
|
|
1471
|
+
{
|
|
1472
|
+
"title": "Пример",
|
|
1473
|
+
"code": "<Table stickyHeader>\n <caption className=\"sr-only\">Пользователи</caption>\n <thead>\n <tr>\n <th>Имя</th>\n <th>Тип</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td><code>label</code></td>\n <td>string</td>\n </tr>\n </tbody>\n</Table>"
|
|
1474
|
+
}
|
|
1475
|
+
],
|
|
1476
|
+
"props": [
|
|
1477
|
+
{
|
|
1478
|
+
"name": "layout",
|
|
1479
|
+
"type": "\"auto\" | \"fixed\"",
|
|
1480
|
+
"description": "`fixed` — равномерные колонки, ширины через col/colgroup в children."
|
|
1481
|
+
},
|
|
1482
|
+
{
|
|
1483
|
+
"name": "stickyHeader",
|
|
1484
|
+
"type": "boolean",
|
|
1485
|
+
"description": "Липкий `<thead>` при скролле обёртки. Фон шапки: `--table-head-background` (иначе `--shell-background`)."
|
|
1486
|
+
}
|
|
1487
|
+
]
|
|
1488
|
+
},
|
|
1489
|
+
{
|
|
1490
|
+
"slug": "TabSections",
|
|
1491
|
+
"title": "TabSections",
|
|
1492
|
+
"description": "Как {@link NavSections}, но вкладки горизонтально; без собственного заголовка — обычно оборачивают в `Section` / `PageHead`. Когда использовать: - несколько панелей на одной странице с горизонтальным переключением; - контент грузится lazy по `value`. Связанные компоненты: - {@link NavSections} — сайдбар + секции; - {@link createLazyResolver} — кэш lazy-импортов; - `Section` — обёртка с заголовком страницы. API: декларативные `items`. Идентификатор — `value` (не `key`). Compound-слоты не используются. CSS-токены: `--shell-*`.",
|
|
1493
|
+
"importFrom": "@elcrm/components",
|
|
1494
|
+
"examples": [
|
|
1495
|
+
{
|
|
1496
|
+
"title": "Пример",
|
|
1497
|
+
"code": "const items = [\n { value: \"members\", label: \"Участники\", badge: 12 },\n { value: \"invites\", label: \"Приглашения\" },\n];\n\nconst resolveSection = createLazyResolver(\n (v) => import(`./sections/${v}.tsx`),\n);\n\n<TabSections\n items={items}\n resolveSection={resolveSection}\n value={tab}\n onValueChange={setTab}\n actions={<Button size=\"s\">Фильтр</Button>}\n/>"
|
|
1498
|
+
}
|
|
1499
|
+
],
|
|
1500
|
+
"props": [
|
|
1501
|
+
{
|
|
1502
|
+
"name": "items",
|
|
1503
|
+
"type": "TabSectionsItem[]",
|
|
1504
|
+
"description": "Горизонтальные вкладки. `value` пункта обычно = имя файла секции для `resolveSection`."
|
|
1505
|
+
},
|
|
1506
|
+
{
|
|
1507
|
+
"name": "resolveSection",
|
|
1508
|
+
"type": "(value: string) => LazyRouteChunk | React.ComponentType",
|
|
1509
|
+
"description": "Резолвер панели по `value`. Обычно: `createLazyResolver((v) => import(\\`./sections/${v}.tsx\\`))`. Не нужен, если передали `children`."
|
|
1510
|
+
},
|
|
1511
|
+
{
|
|
1512
|
+
"name": "children",
|
|
1513
|
+
"type": "React.ReactNode",
|
|
1514
|
+
"description": "Готовая панель без lazy (вместо `resolveSection`)."
|
|
1515
|
+
},
|
|
1516
|
+
{
|
|
1517
|
+
"name": "value",
|
|
1518
|
+
"type": "string",
|
|
1519
|
+
"description": "Контролируемый активный `value`."
|
|
1520
|
+
},
|
|
1521
|
+
{
|
|
1522
|
+
"name": "defaultValue",
|
|
1523
|
+
"type": "string",
|
|
1524
|
+
"description": "Начальный `value` (неконтролируемый режим)."
|
|
1525
|
+
},
|
|
1526
|
+
{
|
|
1527
|
+
"name": "onValueChange",
|
|
1528
|
+
"type": "(value: string) => void",
|
|
1529
|
+
"description": "Смена вкладки (`next` = `item.value`)."
|
|
1530
|
+
},
|
|
1531
|
+
{
|
|
1532
|
+
"name": "loading",
|
|
1533
|
+
"type": "React.ReactNode",
|
|
1534
|
+
"description": "Fallback для `<Suspense>`."
|
|
1535
|
+
},
|
|
1536
|
+
{
|
|
1537
|
+
"name": "actions",
|
|
1538
|
+
"type": "React.ReactNode",
|
|
1539
|
+
"description": "Справа в ряду вкладок (фильтр, сортировка…)."
|
|
1540
|
+
},
|
|
1541
|
+
{
|
|
1542
|
+
"name": "navLabel",
|
|
1543
|
+
"type": "string",
|
|
1544
|
+
"description": "`aria-label` для `<nav>` вкладок."
|
|
1545
|
+
}
|
|
1546
|
+
]
|
|
1547
|
+
},
|
|
1548
|
+
{
|
|
1549
|
+
"slug": "Text",
|
|
1550
|
+
"title": "Text",
|
|
1551
|
+
"description": "Короткий текст с тоном. Для пары title+description — {@link TextGroup}.",
|
|
1552
|
+
"importFrom": "@elcrm/components",
|
|
1553
|
+
"examples": [
|
|
1554
|
+
{
|
|
1555
|
+
"title": "Пример",
|
|
1556
|
+
"code": "<Text tone=\"muted\">Ничего не найдено</Text>"
|
|
1557
|
+
}
|
|
1558
|
+
],
|
|
1559
|
+
"props": [
|
|
1560
|
+
{
|
|
1561
|
+
"name": "tone",
|
|
1562
|
+
"type": "TextTone",
|
|
1563
|
+
"description": "Семантика цвета: default = `--shell-color`, muted = `--shell-color-muted`"
|
|
1564
|
+
},
|
|
1565
|
+
{
|
|
1566
|
+
"name": "as",
|
|
1567
|
+
"type": "\"p\" | \"span\" | \"div\" | \"label\" | \"strong\" | \"em\"",
|
|
1568
|
+
"description": "HTML-тег"
|
|
1569
|
+
}
|
|
1570
|
+
]
|
|
1571
|
+
},
|
|
1572
|
+
{
|
|
1573
|
+
"slug": "TextGroup",
|
|
1574
|
+
"title": "TextGroup",
|
|
1575
|
+
"description": "Две строки текста: заголовок + приглушённая подпись. Роли: мета в строке списка (тенант + slug), без аватара. С аватаром — {@link AvatarName}.",
|
|
1576
|
+
"importFrom": "@elcrm/components",
|
|
1577
|
+
"examples": [
|
|
1578
|
+
{
|
|
1579
|
+
"title": "Пример",
|
|
1580
|
+
"code": "<TextGroup title=\"SHMEL\" description=\"wms-k8voao47\" />"
|
|
1581
|
+
}
|
|
1582
|
+
],
|
|
1583
|
+
"props": [
|
|
1584
|
+
{
|
|
1585
|
+
"name": "title",
|
|
1586
|
+
"type": "React.ReactNode",
|
|
1587
|
+
"description": "Основная строка"
|
|
1588
|
+
},
|
|
1589
|
+
{
|
|
1590
|
+
"name": "description",
|
|
1591
|
+
"type": "React.ReactNode",
|
|
1592
|
+
"description": "Подпись (email, slug…)"
|
|
1593
|
+
},
|
|
1594
|
+
{
|
|
1595
|
+
"name": "size",
|
|
1596
|
+
"type": "UiSize",
|
|
1597
|
+
"description": "Размер типографики"
|
|
1598
|
+
},
|
|
1599
|
+
{
|
|
1600
|
+
"name": "children",
|
|
1601
|
+
"type": "React.ReactNode",
|
|
1602
|
+
"description": "Доп. строки под подписью"
|
|
1603
|
+
}
|
|
1604
|
+
]
|
|
1605
|
+
},
|
|
1606
|
+
{
|
|
1607
|
+
"slug": "Toolbar",
|
|
1608
|
+
"title": "Toolbar",
|
|
1609
|
+
"description": "Ряд контролов одной высоты: поиск, поля, кнопки, меню. Роли: Toolbar = фильтры / действия над списком (`PageHead.children`). Иконки в карточке — `ActionGroup`. Размер: - CSS: `data-size` → `--control-height` / `--field-height` / `--button-height`; - JS: {@link useToolbar} (как {@link Dropdown}).",
|
|
1610
|
+
"importFrom": "@elcrm/components",
|
|
1611
|
+
"examples": [
|
|
1612
|
+
{
|
|
1613
|
+
"title": "Пример",
|
|
1614
|
+
"code": "<Toolbar size=\"s\" align=\"end\" label=\"Фильтры\">\n <Search value={q} onValue={setQ} />\n <Button label=\"Создать\" />\n</Toolbar>"
|
|
1615
|
+
}
|
|
1616
|
+
],
|
|
1617
|
+
"props": [
|
|
1618
|
+
{
|
|
1619
|
+
"name": "size",
|
|
1620
|
+
"type": "UiSize",
|
|
1621
|
+
"description": "Общий размер: токены `data-size` + {@link useToolbar}. Явный `size` у ребёнка важнее контекста. @default \"s\""
|
|
1622
|
+
},
|
|
1623
|
+
{
|
|
1624
|
+
"name": "label",
|
|
1625
|
+
"type": "string",
|
|
1626
|
+
"description": "Подпись для `aria-label`."
|
|
1627
|
+
},
|
|
1628
|
+
{
|
|
1629
|
+
"name": "align",
|
|
1630
|
+
"type": "ToolbarAlign",
|
|
1631
|
+
"description": "Направление ряда (`justify-content`). @default \"start\""
|
|
1632
|
+
},
|
|
1633
|
+
{
|
|
1634
|
+
"name": "width",
|
|
1635
|
+
"type": "ToolbarWidth",
|
|
1636
|
+
"description": "Ширина корня: `l` — `100%` (фильтры над списком), `s` — по контенту (компактный ряд, не растягивать). @default \"l\""
|
|
1637
|
+
},
|
|
1638
|
+
{
|
|
1639
|
+
"name": "children",
|
|
1640
|
+
"type": "React.ReactNode",
|
|
1641
|
+
"description": "Узлы тулбара (`*Field`, `Search`, `Button`, `Dropdown`, …). Размер — через контекст / CSS, не через cloneElement."
|
|
1642
|
+
}
|
|
1643
|
+
]
|
|
1644
|
+
}
|
|
1645
|
+
]
|
|
1646
|
+
}
|