@elcrm/components 0.2.13 → 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 (216) hide show
  1. package/README.md +76 -38
  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.d.ts +1 -1
  50. package/dist/EmptyState.js +1 -1
  51. package/dist/{Footer-qxUlnPR9.js → Footer-Bgh_JCUe.js} +4 -4
  52. package/dist/Footer.css +1 -1
  53. package/dist/Footer.js +1 -1
  54. package/dist/Header-BMDIi3u2.js +21 -0
  55. package/dist/Header.css +1 -1
  56. package/dist/Header.js +1 -1
  57. package/dist/Healthmap-Z-LLfGW0.js +359 -0
  58. package/dist/Healthmap.css +1 -1
  59. package/dist/Healthmap.d.ts +25 -3
  60. package/dist/Healthmap.js +1 -1
  61. package/dist/{Item-D4okhsfW.js → Item-CGpkMJu0.js} +13 -13
  62. package/dist/Item.css +1 -1
  63. package/dist/Item.d.ts +7 -7
  64. package/dist/Item.js +1 -1
  65. package/dist/ItemColumn-Ch61LqE0.js +41 -0
  66. package/dist/ItemColumn.css +1 -1
  67. package/dist/ItemColumn.js +1 -1
  68. package/dist/Layout-CzEGKl9s.js +31 -0
  69. package/dist/Layout.css +1 -1
  70. package/dist/Layout.d.ts +1 -1
  71. package/dist/Layout.js +1 -1
  72. package/dist/List-D13pqaUY.js +12 -0
  73. package/dist/List.css +1 -1
  74. package/dist/List.js +1 -1
  75. package/dist/Loading-C_CKD-zt.js +16 -0
  76. package/dist/Loading.css +1 -1
  77. package/dist/Loading.d.ts +1 -1
  78. package/dist/Loading.js +1 -1
  79. package/dist/Menu-D2kf7fN_.js +72 -0
  80. package/dist/Menu.css +1 -1
  81. package/dist/Menu.d.ts +7 -25
  82. package/dist/Menu.js +1 -1
  83. package/dist/NavSections-CNxxBMPT.js +154 -0
  84. package/dist/NavSections.css +1 -1
  85. package/dist/NavSections.d.ts +16 -28
  86. package/dist/NavSections.js +1 -1
  87. package/dist/PageHead-BfClTLrF.js +31 -0
  88. package/dist/PageHead.css +1 -1
  89. package/dist/PageHead.d.ts +1 -1
  90. package/dist/PageHead.js +1 -1
  91. package/dist/PageShell-BAJges-G.js +30 -0
  92. package/dist/PageShell.css +1 -1
  93. package/dist/PageShell.js +1 -1
  94. package/dist/PanelInfo-Db5GCr-c.js +137 -0
  95. package/dist/PanelInfo.css +1 -1
  96. package/dist/PanelInfo.d.ts +16 -9
  97. package/dist/PanelInfo.js +1 -1
  98. package/dist/Popover-xEZoMY-h.js +143 -0
  99. package/dist/Popover.css +1 -1
  100. package/dist/Popover.d.ts +40 -11
  101. package/dist/Popover.js +1 -1
  102. package/dist/PricingGroup-CWy47MlE.js +138 -0
  103. package/dist/PricingGroup.css +1 -1
  104. package/dist/PricingGroup.d.ts +0 -2
  105. package/dist/PricingGroup.js +1 -1
  106. package/dist/PricingTable-BjpGVAhi.js +157 -0
  107. package/dist/PricingTable.css +1 -1
  108. package/dist/PricingTable.d.ts +4 -7
  109. package/dist/PricingTable.js +1 -1
  110. package/dist/RadioGroup-DI4KKUvZ.js +121 -0
  111. package/dist/RadioGroup.css +1 -1
  112. package/dist/RadioGroup.js +1 -1
  113. package/dist/Section-PprWjOvt.js +47 -0
  114. package/dist/Section.css +1 -1
  115. package/dist/Section.d.ts +29 -9
  116. package/dist/Section.js +1 -1
  117. package/dist/Sidebar-Bouhd5SS.js +205 -0
  118. package/dist/Sidebar.css +1 -1
  119. package/dist/Sidebar.d.ts +18 -26
  120. package/dist/Sidebar.js +1 -1
  121. package/dist/SplitPane-DBa-g9td.js +92 -0
  122. package/dist/SplitPane.css +1 -1
  123. package/dist/SplitPane.d.ts +8 -7
  124. package/dist/SplitPane.js +1 -1
  125. package/dist/Stack-BPTehVYc.js +53 -0
  126. package/dist/Stack.css +1 -1
  127. package/dist/Stack.d.ts +2 -1
  128. package/dist/Stack.js +1 -1
  129. package/dist/Stat-p8j4PjrC.js +28 -0
  130. package/dist/Stat.css +1 -1
  131. package/dist/Stat.js +1 -1
  132. package/dist/TabSections-Dppe9wiz.js +84 -0
  133. package/dist/TabSections.css +1 -1
  134. package/dist/TabSections.d.ts +7 -2
  135. package/dist/TabSections.js +1 -1
  136. package/dist/Table-DqrDUUtb.js +27 -0
  137. package/dist/Table.css +1 -1
  138. package/dist/Table.d.ts +10 -2
  139. package/dist/Table.js +1 -1
  140. package/dist/Text-Bo1u7gVC.js +25 -0
  141. package/dist/Text.css +1 -0
  142. package/dist/Text.d.ts +19 -0
  143. package/dist/Text.js +4 -0
  144. package/dist/TextGroup-236jHxdT.js +23 -0
  145. package/dist/TextGroup.css +1 -1
  146. package/dist/TextGroup.js +1 -1
  147. package/dist/Toolbar-Bl9-5Mis.js +35 -0
  148. package/dist/Toolbar.css +1 -1
  149. package/dist/Toolbar.d.ts +7 -12
  150. package/dist/Toolbar.js +1 -2
  151. package/dist/cx.d.ts +1 -1
  152. package/dist/dark.css +12 -0
  153. package/dist/index.css +41 -39
  154. package/dist/index.d.ts +7 -12
  155. package/dist/index.es.d.ts +7 -12
  156. package/dist/index.es.js +110 -107
  157. package/dist/kit-manifest.json +1646 -0
  158. package/dist/lazyRoute.d.ts +12 -6
  159. package/dist/light.css +12 -0
  160. package/dist/navTree.d.ts +13 -1
  161. package/dist/rovingKeys-Di9N1Nct.js +23 -0
  162. package/dist/rovingKeys.d.ts +7 -1
  163. package/dist/stackGap.d.ts +1 -1
  164. package/dist/tokens.css +20 -2
  165. package/dist/useControllableValue-BaE0VR5d.js +13 -0
  166. package/dist/useControllableValue.d.ts +3 -0
  167. package/package.json +48 -4
  168. package/dist/ActionGroup-ChKFW0mt.js +0 -27
  169. package/dist/Avatar-loGgFt72.js +0 -113
  170. package/dist/AvatarGroup-D1gnT3Od.js +0 -81
  171. package/dist/AvatarName-0BzyfpMq.js +0 -68
  172. package/dist/Badge-jp-9iNNL.js +0 -28
  173. package/dist/Banner-B72lcEMo.js +0 -34
  174. package/dist/Block-Bu7NEA0g.js +0 -8
  175. package/dist/Block.d.ts +0 -30
  176. package/dist/Block.js +0 -4
  177. package/dist/Brand-Zq-Idks4.js +0 -34
  178. package/dist/Breadcrumb-CAM_e9LN.js +0 -98
  179. package/dist/Card-hn37Opo3.js +0 -12
  180. package/dist/ChatFrame-BW2TmCkZ.js +0 -37
  181. package/dist/ChatSplit-DNnu3TNq.js +0 -21
  182. package/dist/CodeBlock-CRzVopIv.js +0 -25
  183. package/dist/Column-BiogBDf8.js +0 -8
  184. package/dist/Column.d.ts +0 -24
  185. package/dist/Column.js +0 -4
  186. package/dist/Dropdown-DosvDR13.js +0 -147
  187. package/dist/EmptyState-mBiWtMIM.js +0 -23
  188. package/dist/Header-DZQopVNy.js +0 -21
  189. package/dist/Healthmap-B6cdiLUl.js +0 -243
  190. package/dist/ItemColumn-M7a9L8CI.js +0 -41
  191. package/dist/Layout-mi6Ghayv.js +0 -31
  192. package/dist/List-BgKkYaGO.js +0 -12
  193. package/dist/Loading-DkkG7RcE.js +0 -16
  194. package/dist/Menu-DuXQv-zT.js +0 -66
  195. package/dist/NavSections-D6rDEtT1.js +0 -142
  196. package/dist/PageHead-DgaJ1mXY.js +0 -31
  197. package/dist/PageShell-D9EZiO8o.js +0 -30
  198. package/dist/PanelInfo-A5y5ysH8.js +0 -81
  199. package/dist/Popover-DWdvZTuA.js +0 -135
  200. package/dist/PricingGroup-Czuhe81Z.js +0 -120
  201. package/dist/PricingTable-BuLC0opK.js +0 -152
  202. package/dist/RadioGroup-fcXzhvMu.js +0 -129
  203. package/dist/Row-DsQOVn18.js +0 -8
  204. package/dist/Row.d.ts +0 -24
  205. package/dist/Row.js +0 -4
  206. package/dist/Section-Crxk2J-E.js +0 -34
  207. package/dist/Sidebar-CYFaPqdC.js +0 -178
  208. package/dist/SplitPane-DR7PCZ8f.js +0 -74
  209. package/dist/Stack-XkmPSswj.js +0 -53
  210. package/dist/Stat-sKXJwz5L.js +0 -27
  211. package/dist/TabSections-DN7yVJoF.js +0 -69
  212. package/dist/Table-BoDr3X2d.js +0 -25
  213. package/dist/TextGroup-DmhuyMR1.js +0 -23
  214. package/dist/Toolbar-C1zAk9ak.js +0 -42
  215. package/dist/rovingKeys-CGlfTtNQ.js +0 -15
  216. package/dist/useControllableValue-CWqH1kpM.js +0 -10
@@ -0,0 +1,12 @@
1
+ import a from "react";
2
+ import { c } from "./cx-CcykAxZN.js";
3
+ import './List.css';const s = "llr", e = "llh", o = {
4
+ root: s,
5
+ horizontal: e
6
+ };
7
+ function h({ row: t, children: r, className: l, ...n }) {
8
+ return /* @__PURE__ */ a.createElement("ul", { className: c(o.root, t && o.horizontal, l), ...n }, r);
9
+ }
10
+ export {
11
+ h as L
12
+ };
package/dist/List.css CHANGED
@@ -1 +1 @@
1
- @layer elcrm-components{.csr{display:flex;flex-direction:column;gap:var(--shell-gap-sm);padding:0;margin:0;list-style:none}.csh{flex-direction:row;flex-wrap:wrap}}
1
+ @layer elcrm-components{.llr{display:flex;flex-direction:column;gap:var(--shell-gap-sm);padding:0;margin:0;list-style:none}.llh{flex-direction:row;flex-wrap:wrap}}
package/dist/List.js CHANGED
@@ -1,4 +1,4 @@
1
- import { L as s } from "./List-BgKkYaGO.js";
1
+ import { L as s } from "./List-D13pqaUY.js";
2
2
  export {
3
3
  s as List
4
4
  };
@@ -0,0 +1,16 @@
1
+ import o from "react";
2
+ import { c as s } from "./cx-CcykAxZN.js";
3
+ import './Loading.css';const c = "sor", i = "soi", t = {
4
+ root: c,
5
+ indicator: i
6
+ };
7
+ function d({
8
+ children: r = "Загрузка…",
9
+ className: a,
10
+ ...e
11
+ }) {
12
+ return /* @__PURE__ */ o.createElement("div", { className: s(t.root, a), role: "status", ...e }, /* @__PURE__ */ o.createElement("span", { className: t.indicator, "aria-hidden": !0 }), r);
13
+ }
14
+ export {
15
+ d as L
16
+ };
package/dist/Loading.css CHANGED
@@ -1 +1 @@
1
- @layer elcrm-components{.cgr{display:flex;align-items:center;justify-content:center;gap:var(--shell-gap-sm);padding:var(--shell-gap-lg);color:var(--shell-color-muted)}.cgi{box-sizing:border-box;width:var(--shell-icon-size);height:var(--shell-icon-size);border:2px solid var(--shell-border);border-top-color:var(--shell-color-accent);border-radius:var(--avatar-radius);animation:cgk .7s linear infinite}}@keyframes cgk{to{transform:rotate(360deg)}}
1
+ @layer elcrm-components{.sor{display:flex;align-items:center;justify-content:center;gap:var(--shell-gap-sm);padding:var(--shell-gap-lg);min-height:var(--loading-min-height);color:var(--shell-color-muted)}.soi{box-sizing:border-box;width:var(--shell-icon-size);height:var(--shell-icon-size);border:2px solid var(--shell-border);border-top-color:var(--shell-color-accent);border-radius:var(--avatar-radius);animation:sos .7s linear infinite}}@keyframes sos{to{transform:rotate(360deg)}}
package/dist/Loading.d.ts CHANGED
@@ -10,7 +10,7 @@ import { default as React } from 'react';
10
10
  * {isLoading ? <Loading>Загружаем клиентов…</Loading> : <List>…</List>}
11
11
  * ```
12
12
  *
13
- * Токены: `--shell-*`.
13
+ * Токены: `--shell-*`, `--loading-min-height`.
14
14
  */
15
15
  export type LoadingProps = React.HTMLAttributes<HTMLDivElement> & {
16
16
  /** Текст или кастомный индикатор (по умолчанию «Загрузка…») */
package/dist/Loading.js CHANGED
@@ -1,4 +1,4 @@
1
- import { L as r } from "./Loading-DkkG7RcE.js";
1
+ import { L as r } from "./Loading-C_CKD-zt.js";
2
2
  export {
3
3
  r as Loading
4
4
  };
@@ -0,0 +1,72 @@
1
+ import l from "react";
2
+ import { B as E } from "./Badge-BjScAXGy.js";
3
+ import { b as N } from "./badgeText-CRzlIzi3.js";
4
+ import { c as p } from "./cx-CcykAxZN.js";
5
+ import { h } from "./rovingKeys-Di9N1Nct.js";
6
+ import { u as w } from "./useControllableValue-BaE0VR5d.js";
7
+ import './Menu.css';const B = "lnr", C = "lnv", K = "lni", M = "lnd", z = "lna", D = "lnu", n = {
8
+ root: B,
9
+ vertical: C,
10
+ item: K,
11
+ dot: M,
12
+ active: z,
13
+ underline: D
14
+ };
15
+ function F({
16
+ items: o,
17
+ vertical: c,
18
+ variant: m = "plain",
19
+ value: r,
20
+ defaultValue: s,
21
+ onValueChange: u,
22
+ children: g,
23
+ className: R,
24
+ ...x
25
+ }) {
26
+ const [t, v] = w(
27
+ r,
28
+ s,
29
+ u
30
+ ), y = (o ?? []).filter((e) => !e.disabled).map((e) => e.value), k = m === "line", d = l.useRef(null), i = u || r !== void 0 || s !== void 0;
31
+ return /* @__PURE__ */ l.createElement(
32
+ "nav",
33
+ {
34
+ ref: d,
35
+ className: p(n.root, c && n.vertical, k && n.underline, R),
36
+ onKeyDown: i ? (e) => h(e, {
37
+ values: y,
38
+ value: t,
39
+ onSelect: v,
40
+ vertical: c,
41
+ focusRoot: d.current
42
+ }) : void 0,
43
+ ...x
44
+ },
45
+ o == null ? void 0 : o.map((e) => {
46
+ const a = e.active ?? (t != null && e.value === t), b = N(e.badge);
47
+ return /* @__PURE__ */ l.createElement(
48
+ "button",
49
+ {
50
+ key: e.value,
51
+ type: "button",
52
+ className: p(n.item, a && n.active),
53
+ "data-value": e.value,
54
+ "data-active": a ? "true" : void 0,
55
+ "aria-current": a ? "page" : void 0,
56
+ tabIndex: i ? a ? 0 : -1 : void 0,
57
+ disabled: e.disabled,
58
+ onClick: () => {
59
+ var f;
60
+ (f = e.onClick) == null || f.call(e), v(e.value);
61
+ }
62
+ },
63
+ e.label,
64
+ b != null ? /* @__PURE__ */ l.createElement(E, { className: n.dot, tone: "accent", size: "s" }, b) : null
65
+ );
66
+ }),
67
+ g
68
+ );
69
+ }
70
+ export {
71
+ F as M
72
+ };
package/dist/Menu.css CHANGED
@@ -1 +1 @@
1
- @layer elcrm-components{.cmr{display:flex;align-items:center;gap:var(--shell-gap-sm);margin:0;padding:0;list-style:none}.cmv{flex-direction:column;align-items:stretch}.cmi{-webkit-appearance:none;-moz-appearance:none;appearance:none;display:inline-flex;align-items:center;justify-content:center;border:0;background:transparent;color:var(--button-color-muted);padding:var(--button-padding);border-radius:var(--button-radius);font:inherit;line-height:1;cursor:pointer;text-align:left;gap:var(--shell-gap-sm)}.cmd{flex-shrink:0;min-width:16px;height:16px;padding:0 4px;font-size:10px}.cmi>svg{display:block;flex-shrink:0}.cmi:hover{background:var(--button-background-hover);color:var(--button-color)}.cma,.cmi[aria-current=page],.cmi[data-active=true]{background:var(--button-background-selected);color:var(--button-color)}.cmu{width:100%;align-items:stretch;gap:1.25rem;padding:0;border-bottom:1px solid var(--shell-border)}.cmu .cmi{border-radius:0;background:transparent;padding:.45rem .1rem .55rem;border-bottom:2px solid transparent;margin-bottom:-1px}.cmu .cmi:hover{background:transparent;color:var(--shell-color)}.cmu .cma,.cmu .cmi[aria-current=page],.cmu .cmi[data-active=true]{background:transparent;color:var(--shell-color);border-bottom-color:var(--shell-color-accent)}}
1
+ @layer elcrm-components{.lnr{display:flex;align-items:center;gap:var(--shell-gap-sm);margin:0;padding:0;list-style:none}.lnv{flex-direction:column;align-items:stretch}.lni{-webkit-appearance:none;-moz-appearance:none;appearance:none;display:inline-flex;align-items:center;justify-content:center;border:0;background:transparent;color:var(--button-color-muted);padding:var(--button-padding);border-radius:var(--button-radius);font:inherit;line-height:1;cursor:pointer;text-align:left;gap:var(--shell-gap-sm)}.lnd{flex-shrink:0;min-width:1rem;height:1rem;padding:0 calc(var(--shell-gap-sm) / 2);font-size:var(--shell-status-size)}.lni>svg{display:block;flex-shrink:0}.lni:hover{background:var(--button-background-hover);color:var(--button-color)}.lna,.lni[aria-current=page],.lni[data-active=true]{background:var(--button-background-selected);color:var(--button-color)}.lnu{width:100%;align-items:stretch;gap:1.25rem;padding:0;border-bottom:1px solid var(--shell-border)}.lnu .lni{border-radius:0;background:transparent;padding:.45rem .1rem .55rem;border-bottom:2px solid transparent;margin-bottom:-1px}.lnu .lni:hover{background:transparent;color:var(--shell-color)}.lnu .lna,.lnu .lni[aria-current=page],.lnu .lni[data-active=true]{background:transparent;color:var(--shell-color);border-bottom-color:var(--shell-color-accent)}}
package/dist/Menu.d.ts CHANGED
@@ -15,7 +15,7 @@ export type MenuItem = {
15
15
  * Если не задан — активность берётся из `MenuProps.value`.
16
16
  */
17
17
  active?: boolean;
18
- /** Обработчик клика по пункту (дополнительно к `onSelect` меню). */
18
+ /** Обработчик клика по пункту (дополнительно к `onValueChange` меню). */
19
19
  onClick?: () => void;
20
20
  /** Недоступный пункт. */
21
21
  disabled?: boolean;
@@ -28,7 +28,7 @@ export type MenuItem = {
28
28
  /**
29
29
  * Props компонента {@link Menu}.
30
30
  *
31
- * Предпочтительный API — `items` + `value` / `onSelect`.
31
+ * API — `items` + `value` / `defaultValue` / `onValueChange`.
32
32
  * `children` — запасной слот для редких кастомных вставок.
33
33
  */
34
34
  export type MenuProps = Omit<React.HTMLAttributes<HTMLElement>, "onSelect"> & {
@@ -49,42 +49,24 @@ export type MenuProps = Omit<React.HTMLAttributes<HTMLElement>, "onSelect"> & {
49
49
  * Идентификатор — `value`, не `key`.
50
50
  */
51
51
  value?: string;
52
+ /** Начальный `value` (неконтролируемый режим). */
53
+ defaultValue?: string;
52
54
  /** Выбор пункта: получает `item.value`. */
53
- onSelect?: (value: string) => void;
55
+ onValueChange?: (value: string) => void;
54
56
  /** Дополнительный контент внутри `<nav>` (редко). */
55
57
  children?: React.ReactNode;
56
58
  };
57
59
  /**
58
60
  * Навигационное меню в потоке документа (шапка, сайдбар-ряд) — не popover.
59
61
  *
60
- * Когда использовать:
61
- * - горизонтальная/вертикальная навигация в layout;
62
- * - нужно подсветить текущий раздел по `value`.
63
- *
64
- * Связанные компоненты:
65
- * - {@link Dropdown} — выпадающая панель рядом с триггером;
66
- * - {@link Popover} / {@link Dropdown} — панель в portal;
67
- * - {@link NavSections} / {@link TabSections} — разделы с lazy-контентом.
68
- *
69
- * API: декларативные `items` (идентификатор — `value`). Compound-слоты не используются.
70
- *
71
- * @param variant `plain` (пилюли) или `line` (черта снизу)
72
- *
73
- * CSS-токены: `--shell-*` (цвета/отступы shell-навигации).
74
- *
75
62
  * @example
76
63
  * ```tsx
77
- * const items = [
78
- * { value: "home", label: "Главная" },
79
- * { value: "team", label: "Команда", badge: 3 },
80
- * ];
81
- *
82
64
  * <Menu
83
65
  * items={items}
84
66
  * value={section}
85
- * onSelect={setSection}
67
+ * onValueChange={setSection}
86
68
  * vertical
87
69
  * />
88
70
  * ```
89
71
  */
90
- export declare function Menu({ items, vertical, variant, value, onSelect, children, className, ...rest }: MenuProps): React.JSX.Element;
72
+ export declare function Menu({ items, vertical, variant, value: valueProp, defaultValue, onValueChange, children, className, ...rest }: MenuProps): React.JSX.Element;
package/dist/Menu.js CHANGED
@@ -1,4 +1,4 @@
1
- import { M as r } from "./Menu-DuXQv-zT.js";
1
+ import { M as r } from "./Menu-D2kf7fN_.js";
2
2
  export {
3
3
  r as Menu
4
4
  };
@@ -0,0 +1,154 @@
1
+ import e, { useMemo as B, Suspense as D } from "react";
2
+ import { c as F } from "./cx-CcykAxZN.js";
3
+ import { f as M, c as O, a as P, b as j, i as A } from "./navTree-BRyaILN9.js";
4
+ import { h as W } from "./rovingKeys-Di9N1Nct.js";
5
+ import { u as C } from "./useControllableValue-BaE0VR5d.js";
6
+ import { I as q } from "./Item-CGpkMJu0.js";
7
+ import './NavSections.css';const z = "nnr", G = "nnn", H = "nng", J = "nnl", Q = "nni", T = "nna", U = "nnc", X = "nnt", Y = "nne", Z = "nns", _ = "nnf", $ = "nnm", s = {
8
+ root: z,
9
+ nav: G,
10
+ group: H,
11
+ label: J,
12
+ item: Q,
13
+ active: T,
14
+ cicon: U,
15
+ text: X,
16
+ expand: Y,
17
+ subtree: Z,
18
+ footer: _,
19
+ main: $
20
+ };
21
+ function ee({ className: l }) {
22
+ return /* @__PURE__ */ e.createElement("svg", { className: l, viewBox: "0 0 12 12", "aria-hidden": !0 }, /* @__PURE__ */ e.createElement(
23
+ "path",
24
+ {
25
+ d: "M2.5 4.5 6 8l3.5-3.5",
26
+ fill: "none",
27
+ stroke: "currentColor",
28
+ strokeWidth: "1.5",
29
+ strokeLinecap: "round",
30
+ strokeLinejoin: "round"
31
+ }
32
+ ));
33
+ }
34
+ function I({
35
+ items: l,
36
+ value: i,
37
+ focusValue: m,
38
+ open: E,
39
+ onSelect: v,
40
+ onToggle: b
41
+ }) {
42
+ return /* @__PURE__ */ e.createElement(e.Fragment, null, l.map((a) => {
43
+ const d = a.items, c = d != null && d.length > 0, f = c && E.includes(a.value), r = !c && a.value === i, p = a.value === (m ?? i);
44
+ return /* @__PURE__ */ e.createElement(e.Fragment, { key: a.value }, /* @__PURE__ */ e.createElement(
45
+ q,
46
+ {
47
+ as: "button",
48
+ active: r,
49
+ className: F(s.item, r && s.active),
50
+ "data-value": a.value,
51
+ "data-active": r ? "true" : void 0,
52
+ "data-open": f ? "true" : void 0,
53
+ "aria-current": r ? "page" : void 0,
54
+ "aria-expanded": c ? f : void 0,
55
+ tabIndex: p ? 0 : -1,
56
+ disabled: a.disabled,
57
+ onClick: () => {
58
+ c ? b(a.value) : v(a.value);
59
+ }
60
+ },
61
+ a.icon != null ? /* @__PURE__ */ e.createElement("span", { className: s.cicon, "aria-hidden": !0 }, a.icon) : null,
62
+ /* @__PURE__ */ e.createElement("span", { className: s.text }, a.label),
63
+ c ? /* @__PURE__ */ e.createElement(ee, { className: s.expand }) : null
64
+ ), c && f ? /* @__PURE__ */ e.createElement("div", { className: s.subtree }, /* @__PURE__ */ e.createElement(
65
+ I,
66
+ {
67
+ items: d,
68
+ value: i,
69
+ focusValue: m,
70
+ open: E,
71
+ onSelect: v,
72
+ onToggle: b
73
+ }
74
+ )) : null);
75
+ }));
76
+ }
77
+ function oe({
78
+ groups: l,
79
+ resolveSection: i,
80
+ children: m,
81
+ value: E,
82
+ defaultValue: v,
83
+ onValueChange: b,
84
+ open: a,
85
+ defaultOpen: d,
86
+ onOpenChange: c,
87
+ loading: f = null,
88
+ footer: r,
89
+ className: p,
90
+ navLabel: L = "Разделы"
91
+ }) {
92
+ const S = B(
93
+ () => v || M(l),
94
+ [v, l]
95
+ ), [n, x] = C(
96
+ E,
97
+ S,
98
+ b
99
+ ), [u = [], N] = C(
100
+ a,
101
+ O(l, d, n),
102
+ c
103
+ ), V = P(l).map((t) => t.value), h = e.useRef(null), [R, y] = e.useState(n);
104
+ e.useEffect(() => {
105
+ n && y(n);
106
+ }, [n]);
107
+ const k = e.useRef(n);
108
+ e.useEffect(() => {
109
+ if (n == null || n === k.current) {
110
+ k.current = n;
111
+ return;
112
+ }
113
+ k.current = n;
114
+ const o = j(l, n).filter((w) => !u.includes(w));
115
+ o.length && N([...u, ...o]);
116
+ }, [n, l, u, N]);
117
+ const g = (t) => {
118
+ N(
119
+ u.includes(t) ? u.filter((o) => o !== t) : [...u, t]
120
+ );
121
+ }, K = m == null && n && i ? i(n) : null;
122
+ return /* @__PURE__ */ e.createElement("div", { className: F(s.root, p) }, /* @__PURE__ */ e.createElement(
123
+ "nav",
124
+ {
125
+ ref: h,
126
+ className: s.nav,
127
+ "aria-label": L,
128
+ onKeyDown: (t) => W(t, {
129
+ values: V,
130
+ value: R,
131
+ vertical: !0,
132
+ focusRoot: h.current,
133
+ onSelect: (o) => {
134
+ y(o), A(l, o) || x(o);
135
+ }
136
+ })
137
+ },
138
+ l.map((t) => /* @__PURE__ */ e.createElement("div", { key: t.value, className: s.group }, t.label != null ? /* @__PURE__ */ e.createElement("div", { className: s.label }, t.label) : null, /* @__PURE__ */ e.createElement(
139
+ I,
140
+ {
141
+ items: t.items,
142
+ value: n,
143
+ focusValue: R,
144
+ open: u,
145
+ onSelect: x,
146
+ onToggle: g
147
+ }
148
+ ))),
149
+ r != null ? /* @__PURE__ */ e.createElement("div", { className: s.footer }, r) : null
150
+ ), /* @__PURE__ */ e.createElement("div", { className: s.main }, m ?? (K ? /* @__PURE__ */ e.createElement(D, { fallback: f }, e.createElement(K)) : null)));
151
+ }
152
+ export {
153
+ oe as N
154
+ };
@@ -1 +1 @@
1
- @layer elcrm-components{.cvr{display:flex;align-items:stretch;gap:var(--shell-gap-lg);width:100%;flex:1 1 auto;min-height:0;box-sizing:border-box;padding:var(--nav-sections-padding)}.cvn{display:flex;flex-direction:column;gap:var(--shell-gap);flex:0 0 var(--nav-sections-nav-width);width:var(--nav-sections-nav-width);min-width:var(--nav-sections-nav-width);box-sizing:border-box}.cvg{display:flex;flex-direction:column;gap:2px;padding-bottom:var(--shell-gap);border-bottom:1px solid var(--shell-border)}.cvg:last-of-type{border-bottom:none;padding-bottom:0}.cvl{font-size:var(--sidebar-group-font-size);font-weight:var(--shell-font-weight);letter-spacing:.04em;text-transform:uppercase;color:var(--shell-color-muted);padding:0 var(--shell-padding-inline) var(--shell-gap-sm)}.cvi:is(button){position:relative;display:flex;width:100%;align-items:center;font-size:var(--shell-font-size-sm)}.cva:before{content:"";position:absolute;left:0;top:6px;bottom:6px;width:3px;border-radius:0 2px 2px 0;background:var(--shell-color-accent)}.cvi:disabled{opacity:var(--shell-disabled-opacity);cursor:not-allowed}.cvc{display:inline-flex;flex:0 0 auto;color:var(--shell-color-muted);line-height:0}.cva .cvc{color:var(--shell-color)}.cvt{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.cve{flex-shrink:0;width:12px;height:12px;margin-left:auto;color:var(--shell-color-muted);transition:transform .15s ease}.cvi:is(button)[data-open=true] .cve{transform:rotate(180deg);color:inherit}.cvs{display:flex;flex-direction:column;gap:2px;padding-inline-start:var(--sidebar-indent)}.cvf{margin-top:auto;padding-top:var(--shell-gap);border-top:1px solid var(--shell-border)}.cvm{flex:1 1 auto;min-width:0;max-width:var(--nav-sections-main-max-width);width:100%;min-height:0;overflow:auto}@media (max-width: 720px){.cvr{flex-direction:column}.cvn{flex:none;width:100%;min-width:0;max-width:none}}}
1
+ @layer elcrm-components{.nnr{display:flex;align-items:stretch;gap:var(--shell-gap-lg);width:100%;flex:1 1 auto;min-height:0;box-sizing:border-box;padding:var(--nav-sections-padding)}.nnn{display:flex;flex-direction:column;gap:var(--shell-gap);flex:0 0 var(--nav-sections-nav-width);width:var(--nav-sections-nav-width);min-width:var(--nav-sections-nav-width);box-sizing:border-box}.nng{display:flex;flex-direction:column;gap:2px;padding-bottom:var(--shell-gap);border-bottom:1px solid var(--shell-border)}.nng:last-of-type{border-bottom:none;padding-bottom:0}.nnl{font-size:var(--sidebar-group-font-size);font-weight:var(--shell-font-weight);letter-spacing:.04em;text-transform:uppercase;color:var(--shell-color-muted);padding:0 var(--shell-padding-inline) var(--shell-gap-sm)}.nni:is(button){position:relative;display:flex;width:100%;align-items:center;font-size:var(--shell-font-size-sm)}.nna:before{content:"";position:absolute;left:0;top:6px;bottom:6px;width:3px;border-radius:0 2px 2px 0;background:var(--shell-color-accent)}.nni:disabled{opacity:var(--shell-disabled-opacity);cursor:not-allowed}.nnc{display:inline-flex;flex:0 0 auto;color:var(--shell-color-muted);line-height:0}.nna .nnc{color:var(--shell-color)}.nnt{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nne{flex-shrink:0;width:var(--shell-status-size);height:var(--shell-status-size);margin-left:auto;color:var(--shell-color-muted);transition:transform .15s ease}.nni:is(button)[data-open=true] .nne{transform:rotate(180deg);color:inherit}.nns{display:flex;flex-direction:column;gap:2px;padding-inline-start:var(--sidebar-indent)}.nnf{margin-top:auto;padding-top:var(--shell-gap);border-top:1px solid var(--shell-border)}.nnm{flex:1 1 auto;min-width:0;max-width:var(--nav-sections-main-max-width);width:100%;min-height:0;overflow:auto}@media (max-width: 720px){.nnr{flex-direction:column}.nnn{flex:none;width:100%;min-width:0;max-width:none}}}
@@ -1,31 +1,12 @@
1
1
  import { default as React } from 'react';
2
2
  import { LazyRouteChunk } from './lazyRoute';
3
+ import { NavTreeItem } from './navTree';
3
4
  /**
4
5
  * Пункт боковой навигации {@link NavSections}.
5
- *
6
- * Идентификатор — `value` (обычно совпадает с именем файла секции).
7
- * Не используйте `key` как бизнес-идентификатор.
6
+ * База — {@link NavTreeItem} (`value` / `label` / `icon` / `items` / `defaultOpen`).
8
7
  */
9
- export type NavSectionsItem = {
10
- /** Уникальный идентификатор раздела (не `key`). */
11
- value: string;
12
- /** Подпись в сайдбаре. */
13
- label: React.ReactNode;
14
- /** Иконка слева; нет поля — не рисуем. */
15
- icon?: React.ReactNode;
16
- /** Недоступный пункт. */
17
- disabled?: boolean;
18
- /**
19
- * Вложенные пункты — есть → шеврон и раскрытие.
20
- * Клик по родителю только открывает/закрывает, панель не меняем.
21
- */
8
+ export type NavSectionsItem = NavTreeItem & {
22
9
  items?: NavSectionsItem[];
23
- /**
24
- * Подменю открыто при первом рендере.
25
- * Если выбран потомок — ветка откроется сама.
26
- * @default false
27
- */
28
- defaultOpen?: boolean;
29
10
  };
30
11
  /**
31
12
  * Группа пунктов сайдбара (опциональный заголовок + `items`).
@@ -33,6 +14,8 @@ export type NavSectionsItem = {
33
14
  * Декларативный API: группа собирается из данных, без compound-слотов.
34
15
  */
35
16
  export type NavSectionsGroup = {
17
+ /** Идентификатор группы (ключ React; канон как у SidebarGroup). */
18
+ value: string;
36
19
  /** Подпись группы (например «Личное»). Нет — заголовок не рисуется. */
37
20
  label?: React.ReactNode;
38
21
  /** Пункты группы (`value` — идентификатор). */
@@ -42,6 +25,7 @@ export type NavSectionsGroup = {
42
25
  * Props компонента {@link NavSections}.
43
26
  *
44
27
  * Групповой UI: `groups` → внутри каждой группы декларативные `items`.
28
+ * Панель: `resolveSection` (lazy) **или** `children` (готовая панель).
45
29
  */
46
30
  export type NavSectionsProps = {
47
31
  /** Группы бокового меню. */
@@ -49,8 +33,14 @@ export type NavSectionsProps = {
49
33
  /**
50
34
  * Резолвер панели справа по `value`.
51
35
  * Обычно: `createLazyResolver((v) => import(\`./sections/${v}.tsx\`))`.
36
+ * Не нужен, если передали `children`.
37
+ */
38
+ resolveSection?: (value: string) => LazyRouteChunk | React.ComponentType;
39
+ /**
40
+ * Готовая панель без lazy (вместо `resolveSection`).
41
+ * Приложение само рендерит контент по `value`.
52
42
  */
53
- resolveSection: (value: string) => LazyRouteChunk | React.ComponentType;
43
+ children?: React.ReactNode;
54
44
  /** Контролируемый активный `value`. */
55
45
  value?: string;
56
46
  /** Начальный `value` в неконтролируемом режиме. */
@@ -100,6 +90,7 @@ export type NavSectionsProps = {
100
90
  * ```tsx
101
91
  * const groups = [
102
92
  * {
93
+ * value: "docs",
103
94
  * label: "Документация",
104
95
  * items: [
105
96
  * {
@@ -108,12 +99,9 @@ export type NavSectionsProps = {
108
99
  * defaultOpen: true,
109
100
  * items: [
110
101
  * { value: "intro", label: "Введение" },
111
- * { value: "events", label: "События", items: [
112
- * { value: "evt-init", label: "VKWebAppInit" },
113
- * ] },
102
+ * { value: "events", label: "События" },
114
103
  * ],
115
104
  * },
116
- * { value: "auth", label: "Авторизация VK" },
117
105
  * ],
118
106
  * },
119
107
  * ];
@@ -126,4 +114,4 @@ export type NavSectionsProps = {
126
114
  * />
127
115
  * ```
128
116
  */
129
- export declare function NavSections({ groups, resolveSection, value: valueProp, defaultValue, onValueChange, open: openProp, defaultOpen, onOpenChange, loading, footer, className, navLabel, }: NavSectionsProps): React.JSX.Element;
117
+ export declare function NavSections({ groups, resolveSection, children, value: valueProp, defaultValue, onValueChange, open: openProp, defaultOpen, onOpenChange, loading, footer, className, navLabel, }: NavSectionsProps): React.JSX.Element;
@@ -1,4 +1,4 @@
1
- import { N as e } from "./NavSections-D6rDEtT1.js";
1
+ import { N as e } from "./NavSections-CNxxBMPT.js";
2
2
  export {
3
3
  e as NavSections
4
4
  };
@@ -0,0 +1,31 @@
1
+ import t from "react";
2
+ import { c as m } from "./cx-CcykAxZN.js";
3
+ import './PageHead.css';const d = "sdr", i = "sdk", u = "sdw", f = "sdt", p = "sdh", E = "sdn", N = "sdu", h = "sds", v = "sda", w = "sdc", e = {
4
+ root: d,
5
+ kept: i,
6
+ wrap: u,
7
+ textcol: f,
8
+ heading: p,
9
+ name: E,
10
+ usup: N,
11
+ subtitle: h,
12
+ actions: v,
13
+ children: w
14
+ };
15
+ function x(n) {
16
+ return !(n == null || n === !1 || n === "" || typeof n == "number" && n === 0 || n === "0");
17
+ }
18
+ function b({
19
+ title: n,
20
+ sup: s,
21
+ subtitle: a,
22
+ actions: l,
23
+ sticky: r,
24
+ className: o,
25
+ children: c
26
+ }) {
27
+ return /* @__PURE__ */ t.createElement("div", { className: m(e.root, r && e.kept, o) }, /* @__PURE__ */ t.createElement("div", { className: e.wrap }, /* @__PURE__ */ t.createElement("div", { className: e.textcol }, /* @__PURE__ */ t.createElement("h1", { className: e.heading }, /* @__PURE__ */ t.createElement("span", { className: e.name }, n), x(s) ? /* @__PURE__ */ t.createElement("span", { className: e.usup }, s) : null), a != null ? /* @__PURE__ */ t.createElement("p", { className: e.subtitle }, a) : null), l != null ? /* @__PURE__ */ t.createElement("div", { className: e.actions }, l) : null), c != null ? /* @__PURE__ */ t.createElement("div", { className: e.children }, c) : null);
28
+ }
29
+ export {
30
+ b as P
31
+ };
package/dist/PageHead.css CHANGED
@@ -1 +1 @@
1
- @layer elcrm-components{.ccr{display:flex;flex-direction:column;gap:var(--shell-gap);margin:0 0 var(--shell-gap)}.cck{position:sticky;top:0;z-index:var(--shell-z);background:var(--shell-bg)}.ccw{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--shell-gap-sm)}.cct{min-width:0;max-width:36rem}.cch{margin:0;display:flex;align-items:flex-start;gap:.4em;font-size:var(--section-title-size);font-weight:var(--shell-font-weight);color:var(--shell-color);line-height:1.15}.ccn{min-width:0}.ccu{display:inline-flex;align-items:center;margin-top:.12em;font-size:.7rem;font-weight:600;line-height:1;color:var(--shell-color-muted)}.ccs{margin:var(--shell-gap-sm) 0 0;font-size:var(--shell-font-size);color:var(--shell-color-muted);line-height:1.45}.cca{display:flex;flex-wrap:wrap;align-items:center;gap:var(--shell-gap-sm)}.ccc{display:flex;flex-direction:column;gap:var(--shell-gap);min-width:0}}
1
+ @layer elcrm-components{.sdr{display:flex;flex-direction:column;gap:var(--shell-gap);margin:0 0 var(--shell-gap)}.sdk{position:sticky;top:0;z-index:var(--shell-z);background:var(--shell-bg)}.sdw{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--shell-gap-sm)}.sdt{min-width:0;max-width:36rem}.sdh{margin:0;display:flex;align-items:flex-start;gap:.4em;font-size:var(--section-title-size);font-weight:var(--shell-font-weight);color:var(--shell-color);line-height:1.15}.sdn{min-width:0}.sdu{display:inline-flex;align-items:center;margin-top:.12em;font-size:.7rem;font-weight:600;line-height:1;color:var(--shell-color-muted)}.sds{margin:var(--shell-gap-sm) 0 0;font-size:var(--shell-font-size);color:var(--shell-color-muted);line-height:1.45}.sda{display:flex;flex-wrap:wrap;align-items:center;gap:var(--shell-gap-sm)}.sdc{display:flex;flex-direction:column;gap:var(--shell-gap);min-width:0}}
@@ -10,7 +10,7 @@ import { default as React } from 'react';
10
10
  * ```tsx
11
11
  * <PageShell scroll>
12
12
  * <PageHead title="Идеи" sup={<Badge size="s" tone="accent">4</Badge>} sticky>
13
- * <Menu items={tabs} value={tab} onSelect={setTab} />
13
+ * <Menu items={tabs} value={tab} onValueChange={setTab} />
14
14
  * </PageHead>
15
15
  * …
16
16
  * </PageShell>
package/dist/PageHead.js CHANGED
@@ -1,4 +1,4 @@
1
- import { P as o } from "./PageHead-DgaJ1mXY.js";
1
+ import { P as o } from "./PageHead-BfClTLrF.js";
2
2
  export {
3
3
  o as PageHead
4
4
  };
@@ -0,0 +1,30 @@
1
+ import e from "react";
2
+ import { c as f } from "./cx-CcykAxZN.js";
3
+ import './PageShell.css';const l = "spr", m = "spw", d = "spb", i = "spf", p = "spo", o = {
4
+ root: l,
5
+ wide: m,
6
+ body: d,
7
+ footer: i,
8
+ off: p
9
+ };
10
+ function w({
11
+ children: s,
12
+ className: r,
13
+ wide: c,
14
+ scroll: n = !0,
15
+ footer: t,
16
+ ...a
17
+ }) {
18
+ return /* @__PURE__ */ e.createElement(
19
+ "div",
20
+ {
21
+ ...a,
22
+ className: f(o.root, c && o.wide, !n && o.off, r)
23
+ },
24
+ /* @__PURE__ */ e.createElement("div", { className: o.body }, s),
25
+ t != null ? /* @__PURE__ */ e.createElement("div", { className: o.footer }, t) : null
26
+ );
27
+ }
28
+ export {
29
+ w as P
30
+ };
@@ -1 +1 @@
1
- @layer elcrm-components{.ckr{flex:1 1 auto;min-height:0;height:100%;width:100%;display:flex;flex-direction:column;box-sizing:border-box;padding:var(--shell-padding);overflow:hidden}.ckw{max-width:none}.ckb{flex:1 1 auto;min-height:0;overflow:auto;display:flex;flex-direction:column;gap:var(--shell-gap)}.ckf{flex:0 0 auto;padding-top:var(--shell-gap-sm)}.cko{overflow:visible;height:auto}.cko .ckb{overflow:visible;flex:0 1 auto;min-height:auto}}
1
+ @layer elcrm-components{.spr{flex:1 1 auto;min-height:0;height:100%;width:100%;display:flex;flex-direction:column;box-sizing:border-box;padding:var(--shell-padding);overflow:hidden}.spw{max-width:none}.spb{flex:1 1 auto;min-height:0;overflow:auto;display:flex;flex-direction:column;gap:var(--shell-gap)}.spf{flex:0 0 auto;padding-top:var(--shell-gap-sm)}.spo{overflow:visible;height:auto}.spo .spb{overflow:visible;flex:0 1 auto;min-height:auto}}
package/dist/PageShell.js CHANGED
@@ -1,4 +1,4 @@
1
- import { P as l } from "./PageShell-D9EZiO8o.js";
1
+ import { P as l } from "./PageShell-BAJges-G.js";
2
2
  export {
3
3
  l as PageShell
4
4
  };