@elcrm/components 0.2.8 → 0.2.11
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 +23 -4
- package/dist/NavSections-D6rDEtT1.js +142 -0
- package/dist/NavSections.css +1 -1
- package/dist/NavSections.d.ts +38 -10
- package/dist/NavSections.js +1 -1
- package/dist/Sidebar-CYFaPqdC.js +178 -0
- package/dist/Sidebar.css +1 -1
- package/dist/Sidebar.d.ts +41 -4
- package/dist/Sidebar.js +1 -1
- package/dist/Toolbar.css +1 -1
- package/dist/index.css +3 -3
- package/dist/index.es.js +2 -2
- package/dist/kit-manifest.json +36 -6
- package/dist/navTree-BRyaILN9.js +57 -0
- package/dist/navTree.d.ts +33 -0
- package/dist/tokens.css +1 -0
- package/package.json +1 -1
- package/dist/NavSections-BpyZPimZ.js +0 -79
- package/dist/Sidebar-BgZiGEDH.js +0 -108
package/README.md
CHANGED
|
@@ -92,14 +92,14 @@ import { RadioGroup } from "@elcrm/components/RadioGroup";
|
|
|
92
92
|
| **Dropdown** | Выпадающее меню (items, portal) | `label`/`trigger`, `items`/`groups`, `onSelect` |
|
|
93
93
|
| **Popover** | Свой попап в portal | `trigger`, `children`, `align`, `open` |
|
|
94
94
|
| **Breadcrumb** | Хлебные крошки | `items`, `separator`, `collapseAfter` |
|
|
95
|
-
| **Sidebar** | Левое меню приложения | `groups`, `value`, `
|
|
95
|
+
| **Sidebar** | Левое меню приложения | `groups`, `value`, `item.items` + `defaultOpen`, `open` / `onOpenChange`, `footerItems` |
|
|
96
96
|
| **PageShell** | Каркас модуля (скролл + footer) | `wide`, `scroll`, `footer`, `children` |
|
|
97
97
|
| **ChatList** | Колонка диалогов | `header`, `footer`, `children` (`List`/`Item`), `bodyRef` |
|
|
98
98
|
| **ChatMessages** | Колонка переписки | `header`, `footer`, `children`, `bodyRef`, `onBodyScroll` |
|
|
99
99
|
| **ChatSplit** | Список + лента | `list`, `messages` |
|
|
100
100
|
| **PageHead** | Заголовок страницы + actions | `title`, `sup` (текст/Badge), `subtitle`, `actions`, `sticky`, `children` |
|
|
101
101
|
| **Section** | Блок контента / auth / подраздел | `title`, `description`, `icon`, `actions`, `variant` |
|
|
102
|
-
| **NavSections** | Сайдбар + lazy-панель | `groups`
|
|
102
|
+
| **NavSections** | Сайдбар + lazy-панель | `groups`, `item.items` + `defaultOpen`, `open` / `onOpenChange`, `resolveSection` |
|
|
103
103
|
| **TabSections** | Горизонтальные вкладки + lazy | `items` (`value` + `badge`), `resolveSection` |
|
|
104
104
|
| **Card** | Карточка | `title`, `--card-pointer` |
|
|
105
105
|
| **ActionGroup** | Ряд иконок в карточке | `label`, `items` и/или `children` |
|
|
@@ -136,7 +136,17 @@ import { RadioGroup } from "@elcrm/components/RadioGroup";
|
|
|
136
136
|
{
|
|
137
137
|
value: "admin",
|
|
138
138
|
title: "Админ",
|
|
139
|
-
items: [
|
|
139
|
+
items: [
|
|
140
|
+
{
|
|
141
|
+
value: "bridge",
|
|
142
|
+
label: "VK Bridge",
|
|
143
|
+
defaultOpen: true,
|
|
144
|
+
items: [
|
|
145
|
+
{ value: "intro", label: "Введение" },
|
|
146
|
+
{ value: "events", label: "События" },
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
],
|
|
140
150
|
},
|
|
141
151
|
]}
|
|
142
152
|
footer={<AvatarName title="Паша" description="mail@…" />}
|
|
@@ -150,7 +160,7 @@ import { RadioGroup } from "@elcrm/components/RadioGroup";
|
|
|
150
160
|
/>
|
|
151
161
|
```
|
|
152
162
|
|
|
153
|
-
Токены: `--sidebar-width`, `--sidebar-item-font-size`, `--sidebar-item-padding`, `--sidebar-icon-size`, `--sidebar-group-font-size`, `--sidebar-item-active`. Для orange active в `plain` переопределите `--sidebar-item-active` в теме приложения.
|
|
163
|
+
Токены: `--sidebar-width`, `--sidebar-item-font-size`, `--sidebar-item-padding`, `--sidebar-icon-size`, `--sidebar-group-font-size`, `--sidebar-indent`, `--sidebar-item-active`. Для orange active в `plain` переопределите `--sidebar-item-active` в теме приложения.
|
|
154
164
|
|
|
155
165
|
### Stack
|
|
156
166
|
|
|
@@ -656,6 +666,15 @@ const resolve = createLazyResolver(
|
|
|
656
666
|
label: "Личное",
|
|
657
667
|
items: [
|
|
658
668
|
{ value: "Profile", label: "Профиль" },
|
|
669
|
+
{
|
|
670
|
+
value: "bridge",
|
|
671
|
+
label: "VK Bridge",
|
|
672
|
+
defaultOpen: true,
|
|
673
|
+
items: [
|
|
674
|
+
{ value: "Intro", label: "Введение" },
|
|
675
|
+
{ value: "Events", label: "События" },
|
|
676
|
+
],
|
|
677
|
+
},
|
|
659
678
|
{ value: "Appearance", label: "Оформление" },
|
|
660
679
|
],
|
|
661
680
|
},
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import e, { useMemo as B, Suspense as D } from "react";
|
|
2
|
+
import { c as K } from "./cx-CcykAxZN.js";
|
|
3
|
+
import { I as F } from "./Item-D4okhsfW.js";
|
|
4
|
+
import { f as I, c as M, a as O, b as P, i as V } from "./navTree-BRyaILN9.js";
|
|
5
|
+
import { h as j } from "./rovingKeys-CGlfTtNQ.js";
|
|
6
|
+
import { u as y } from "./useControllableValue-CWqH1kpM.js";
|
|
7
|
+
import './NavSections.css';const A = "cvr", W = "cvn", $ = "cvg", q = "cvl", z = "cvi", G = "cva", H = "cvc", J = "cvt", Q = "cve", T = "cvs", U = "cvf", X = "cvm", c = {
|
|
8
|
+
r: A,
|
|
9
|
+
n: W,
|
|
10
|
+
g: $,
|
|
11
|
+
l: q,
|
|
12
|
+
i: z,
|
|
13
|
+
a: G,
|
|
14
|
+
c: H,
|
|
15
|
+
t: J,
|
|
16
|
+
e: Q,
|
|
17
|
+
s: T,
|
|
18
|
+
f: U,
|
|
19
|
+
m: X
|
|
20
|
+
};
|
|
21
|
+
function Y({ className: a }) {
|
|
22
|
+
return /* @__PURE__ */ e.createElement("svg", { className: a, 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 C({
|
|
35
|
+
items: a,
|
|
36
|
+
value: d,
|
|
37
|
+
open: f,
|
|
38
|
+
onSelect: m,
|
|
39
|
+
onToggle: E
|
|
40
|
+
}) {
|
|
41
|
+
return /* @__PURE__ */ e.createElement(e.Fragment, null, a.map((t) => {
|
|
42
|
+
const v = t.items, s = v != null && v.length > 0, u = s && f.includes(t.value), r = !s && t.value === d;
|
|
43
|
+
return /* @__PURE__ */ e.createElement(e.Fragment, { key: t.value }, /* @__PURE__ */ e.createElement(
|
|
44
|
+
F,
|
|
45
|
+
{
|
|
46
|
+
as: "button",
|
|
47
|
+
active: r,
|
|
48
|
+
className: K(c.i, r && c.a),
|
|
49
|
+
"data-active": r ? "true" : void 0,
|
|
50
|
+
"data-open": u ? "true" : void 0,
|
|
51
|
+
"aria-current": r ? "page" : void 0,
|
|
52
|
+
"aria-expanded": s ? u : void 0,
|
|
53
|
+
disabled: t.disabled,
|
|
54
|
+
onClick: () => {
|
|
55
|
+
s ? E(t.value) : m(t.value);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
t.icon != null ? /* @__PURE__ */ e.createElement("span", { className: c.c, "aria-hidden": !0 }, t.icon) : null,
|
|
59
|
+
/* @__PURE__ */ e.createElement("span", { className: c.t }, t.label),
|
|
60
|
+
s ? /* @__PURE__ */ e.createElement(Y, { className: c.e }) : null
|
|
61
|
+
), s && u ? /* @__PURE__ */ e.createElement("div", { className: c.s }, /* @__PURE__ */ e.createElement(
|
|
62
|
+
C,
|
|
63
|
+
{
|
|
64
|
+
items: v,
|
|
65
|
+
value: d,
|
|
66
|
+
open: f,
|
|
67
|
+
onSelect: m,
|
|
68
|
+
onToggle: E
|
|
69
|
+
}
|
|
70
|
+
)) : null);
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
function le({
|
|
74
|
+
groups: a,
|
|
75
|
+
resolveSection: d,
|
|
76
|
+
value: f,
|
|
77
|
+
defaultValue: m,
|
|
78
|
+
onValueChange: E,
|
|
79
|
+
open: t,
|
|
80
|
+
defaultOpen: v,
|
|
81
|
+
onOpenChange: s,
|
|
82
|
+
loading: u = null,
|
|
83
|
+
footer: r,
|
|
84
|
+
className: R,
|
|
85
|
+
navLabel: S = "Разделы"
|
|
86
|
+
}) {
|
|
87
|
+
const g = B(
|
|
88
|
+
() => m || I(a),
|
|
89
|
+
[m, a]
|
|
90
|
+
), [l, b] = y(
|
|
91
|
+
f,
|
|
92
|
+
g,
|
|
93
|
+
E
|
|
94
|
+
), [o = [], N] = y(
|
|
95
|
+
t,
|
|
96
|
+
M(a, v, l),
|
|
97
|
+
s
|
|
98
|
+
), x = O(a).map((n) => n.value), p = e.useRef(l);
|
|
99
|
+
e.useEffect(() => {
|
|
100
|
+
if (l == null || l === p.current) {
|
|
101
|
+
p.current = l;
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
p.current = l;
|
|
105
|
+
const i = P(a, l).filter((w) => !o.includes(w));
|
|
106
|
+
i.length && N([...o, ...i]);
|
|
107
|
+
}, [l, a, o, N]);
|
|
108
|
+
const h = (n) => {
|
|
109
|
+
N(
|
|
110
|
+
o.includes(n) ? o.filter((i) => i !== n) : [...o, n]
|
|
111
|
+
);
|
|
112
|
+
}, L = (n) => {
|
|
113
|
+
V(a, n) ? h(n) : b(n);
|
|
114
|
+
}, k = l ? d(l) : null;
|
|
115
|
+
return /* @__PURE__ */ e.createElement("div", { className: K(c.r, R) }, /* @__PURE__ */ e.createElement(
|
|
116
|
+
"nav",
|
|
117
|
+
{
|
|
118
|
+
className: c.n,
|
|
119
|
+
"aria-label": S,
|
|
120
|
+
onKeyDown: (n) => j(n, {
|
|
121
|
+
values: x,
|
|
122
|
+
value: l,
|
|
123
|
+
onSelect: L,
|
|
124
|
+
vertical: !0
|
|
125
|
+
})
|
|
126
|
+
},
|
|
127
|
+
a.map((n, i) => /* @__PURE__ */ e.createElement("div", { key: i, className: c.g }, n.label != null ? /* @__PURE__ */ e.createElement("div", { className: c.l }, n.label) : null, /* @__PURE__ */ e.createElement(
|
|
128
|
+
C,
|
|
129
|
+
{
|
|
130
|
+
items: n.items,
|
|
131
|
+
value: l,
|
|
132
|
+
open: o,
|
|
133
|
+
onSelect: b,
|
|
134
|
+
onToggle: h
|
|
135
|
+
}
|
|
136
|
+
))),
|
|
137
|
+
r != null ? /* @__PURE__ */ e.createElement("div", { className: c.f }, r) : null
|
|
138
|
+
), /* @__PURE__ */ e.createElement("div", { className: c.m }, k ? /* @__PURE__ */ e.createElement(D, { fallback: u }, e.createElement(k)) : null));
|
|
139
|
+
}
|
|
140
|
+
export {
|
|
141
|
+
le as N
|
|
142
|
+
};
|
package/dist/NavSections.css
CHANGED
|
@@ -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;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{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.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{.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}}}
|
package/dist/NavSections.d.ts
CHANGED
|
@@ -15,6 +15,17 @@ export type NavSectionsItem = {
|
|
|
15
15
|
icon?: React.ReactNode;
|
|
16
16
|
/** Недоступный пункт. */
|
|
17
17
|
disabled?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Вложенные пункты — есть → шеврон и раскрытие.
|
|
20
|
+
* Клик по родителю только открывает/закрывает, панель не меняем.
|
|
21
|
+
*/
|
|
22
|
+
items?: NavSectionsItem[];
|
|
23
|
+
/**
|
|
24
|
+
* Подменю открыто при первом рендере.
|
|
25
|
+
* Если выбран потомок — ветка откроется сама.
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
defaultOpen?: boolean;
|
|
18
29
|
};
|
|
19
30
|
/**
|
|
20
31
|
* Группа пунктов сайдбара (опциональный заголовок + `items`).
|
|
@@ -46,6 +57,17 @@ export type NavSectionsProps = {
|
|
|
46
57
|
defaultValue?: string;
|
|
47
58
|
/** Смена активного раздела (`next` = `item.value`). */
|
|
48
59
|
onValueChange?: (value: string) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Раскрытые родители (их `value`). Контролируемый режим.
|
|
62
|
+
* Вместе с `onOpenChange`.
|
|
63
|
+
*/
|
|
64
|
+
open?: string[];
|
|
65
|
+
/**
|
|
66
|
+
* Начально раскрытые (плюс `item.defaultOpen` и предки выбранного).
|
|
67
|
+
*/
|
|
68
|
+
defaultOpen?: string[];
|
|
69
|
+
/** Смена набора раскрытых родителей */
|
|
70
|
+
onOpenChange?: (open: string[]) => void;
|
|
49
71
|
/** Fallback для `<Suspense>` при ленивой загрузке секции. */
|
|
50
72
|
loading?: React.ReactNode;
|
|
51
73
|
/** Низ сайдбара (например кнопка «Назад»). */
|
|
@@ -68,34 +90,40 @@ export type NavSectionsProps = {
|
|
|
68
90
|
* - {@link Menu} — простая навигация без панелей.
|
|
69
91
|
*
|
|
70
92
|
* API: декларативные `groups` / `items`. Идентификатор раздела — `value` (не `key`).
|
|
93
|
+
* У пункта `items` + `defaultOpen` — раскрываемое подменю (как у Sidebar).
|
|
71
94
|
* Compound-слоты (`NavSections.Item`) не используются.
|
|
72
95
|
*
|
|
73
96
|
* CSS-токены: `--shell-*`, `--nav-sections-padding`, `--nav-sections-nav-width`,
|
|
74
|
-
* `--nav-sections-main-max-width`.
|
|
97
|
+
* `--nav-sections-main-max-width`, `--sidebar-indent`.
|
|
75
98
|
*
|
|
76
99
|
* @example
|
|
77
100
|
* ```tsx
|
|
78
101
|
* const groups = [
|
|
79
102
|
* {
|
|
80
|
-
* label: "
|
|
103
|
+
* label: "Документация",
|
|
81
104
|
* items: [
|
|
82
|
-
* {
|
|
83
|
-
*
|
|
105
|
+
* {
|
|
106
|
+
* value: "bridge",
|
|
107
|
+
* label: "VK Bridge",
|
|
108
|
+
* defaultOpen: true,
|
|
109
|
+
* items: [
|
|
110
|
+
* { value: "intro", label: "Введение" },
|
|
111
|
+
* { value: "events", label: "События", items: [
|
|
112
|
+
* { value: "evt-init", label: "VKWebAppInit" },
|
|
113
|
+
* ] },
|
|
114
|
+
* ],
|
|
115
|
+
* },
|
|
116
|
+
* { value: "auth", label: "Авторизация VK" },
|
|
84
117
|
* ],
|
|
85
118
|
* },
|
|
86
119
|
* ];
|
|
87
120
|
*
|
|
88
|
-
* const resolveSection = createLazyResolver(
|
|
89
|
-
* (v) => import(`./sections/${v}.tsx`),
|
|
90
|
-
* );
|
|
91
|
-
*
|
|
92
121
|
* <NavSections
|
|
93
122
|
* groups={groups}
|
|
94
123
|
* resolveSection={resolveSection}
|
|
95
124
|
* value={section}
|
|
96
125
|
* onValueChange={setSection}
|
|
97
|
-
* footer={<Button onSend={() => navigate(-1)}>Назад</Button>}
|
|
98
126
|
* />
|
|
99
127
|
* ```
|
|
100
128
|
*/
|
|
101
|
-
export declare function NavSections({ groups, resolveSection, value: valueProp, defaultValue, onValueChange, loading, footer, className, navLabel, }: NavSectionsProps): React.JSX.Element;
|
|
129
|
+
export declare function NavSections({ groups, resolveSection, value: valueProp, defaultValue, onValueChange, open: openProp, defaultOpen, onOpenChange, loading, footer, className, navLabel, }: NavSectionsProps): React.JSX.Element;
|
package/dist/NavSections.js
CHANGED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import e from "react";
|
|
2
|
+
import { B as K } from "./Badge-jp-9iNNL.js";
|
|
3
|
+
import { D as R } from "./Dropdown-DosvDR13.js";
|
|
4
|
+
import { I as F } from "./Item-D4okhsfW.js";
|
|
5
|
+
import { b as I } from "./badgeText-CRzlIzi3.js";
|
|
6
|
+
import { c as f } from "./cx-CcykAxZN.js";
|
|
7
|
+
import { c as L, b as M } from "./navTree-BRyaILN9.js";
|
|
8
|
+
import { u as O } from "./useControllableValue-CWqH1kpM.js";
|
|
9
|
+
import './Sidebar.css';const T = "c2r", V = "c2b", j = "c2x", z = "c2g", A = "c2s", W = "c2p", $ = "c2h", G = "c2n", H = "c2i", J = "c2a", P = "c2o", Q = "c2l", U = "c2d", X = "c2c", Y = "c2m", Z = "c2f", _ = "c2q", S = "c2w", ee = "c2u", ne = "c2k", ce = "c2v", n = {
|
|
10
|
+
r: T,
|
|
11
|
+
b: V,
|
|
12
|
+
x: j,
|
|
13
|
+
g: z,
|
|
14
|
+
s: A,
|
|
15
|
+
p: W,
|
|
16
|
+
h: $,
|
|
17
|
+
n: G,
|
|
18
|
+
i: H,
|
|
19
|
+
a: J,
|
|
20
|
+
o: P,
|
|
21
|
+
l: Q,
|
|
22
|
+
d: U,
|
|
23
|
+
c: X,
|
|
24
|
+
m: Y,
|
|
25
|
+
f: Z,
|
|
26
|
+
q: _,
|
|
27
|
+
w: S,
|
|
28
|
+
u: ee,
|
|
29
|
+
k: ne,
|
|
30
|
+
v: ce
|
|
31
|
+
};
|
|
32
|
+
function te({ className: l }) {
|
|
33
|
+
return /* @__PURE__ */ e.createElement("svg", { className: l, viewBox: "0 0 16 16", "aria-hidden": !0 }, /* @__PURE__ */ e.createElement("circle", { cx: "8", cy: "3", r: "1.3", fill: "currentColor" }), /* @__PURE__ */ e.createElement("circle", { cx: "8", cy: "8", r: "1.3", fill: "currentColor" }), /* @__PURE__ */ e.createElement("circle", { cx: "8", cy: "13", r: "1.3", fill: "currentColor" }));
|
|
34
|
+
}
|
|
35
|
+
function le({
|
|
36
|
+
footer: l,
|
|
37
|
+
className: u,
|
|
38
|
+
...c
|
|
39
|
+
}) {
|
|
40
|
+
const o = /* @__PURE__ */ e.createElement(te, { className: n.k });
|
|
41
|
+
if (e.isValidElement(l) && typeof l.type != "string") {
|
|
42
|
+
const s = l.props;
|
|
43
|
+
return e.cloneElement(l, {
|
|
44
|
+
as: "button",
|
|
45
|
+
extra: s.extra ?? o,
|
|
46
|
+
className: f(s.className, u),
|
|
47
|
+
...c,
|
|
48
|
+
onClick: (t) => {
|
|
49
|
+
var i, a;
|
|
50
|
+
(i = s.onClick) == null || i.call(s, t), (a = c.onClick) == null || a.call(c, t);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return /* @__PURE__ */ e.createElement("button", { type: "button", className: f(n.u, u), ...c }, /* @__PURE__ */ e.createElement("span", { className: n.w }, l), o);
|
|
55
|
+
}
|
|
56
|
+
function ae({ className: l }) {
|
|
57
|
+
return /* @__PURE__ */ e.createElement("svg", { className: l, viewBox: "0 0 12 12", "aria-hidden": !0 }, /* @__PURE__ */ e.createElement(
|
|
58
|
+
"path",
|
|
59
|
+
{
|
|
60
|
+
d: "M2.5 4.5 6 8l3.5-3.5",
|
|
61
|
+
fill: "none",
|
|
62
|
+
stroke: "currentColor",
|
|
63
|
+
strokeWidth: "1.5",
|
|
64
|
+
strokeLinecap: "round",
|
|
65
|
+
strokeLinejoin: "round"
|
|
66
|
+
}
|
|
67
|
+
));
|
|
68
|
+
}
|
|
69
|
+
function x({
|
|
70
|
+
items: l,
|
|
71
|
+
value: u,
|
|
72
|
+
open: c,
|
|
73
|
+
onSelect: o,
|
|
74
|
+
onToggle: s
|
|
75
|
+
}) {
|
|
76
|
+
return /* @__PURE__ */ e.createElement(e.Fragment, null, l.map((t) => {
|
|
77
|
+
const i = t.items, a = i != null && i.length > 0, E = a && c.includes(t.value), p = I(t.badge), m = !a && u === t.value;
|
|
78
|
+
return /* @__PURE__ */ e.createElement("li", { key: t.value }, /* @__PURE__ */ e.createElement(
|
|
79
|
+
F,
|
|
80
|
+
{
|
|
81
|
+
as: "button",
|
|
82
|
+
active: m,
|
|
83
|
+
className: f(n.i, m && n.a),
|
|
84
|
+
"aria-current": m ? "page" : void 0,
|
|
85
|
+
"aria-expanded": a ? E : void 0,
|
|
86
|
+
"data-open": E ? "true" : void 0,
|
|
87
|
+
onClick: () => {
|
|
88
|
+
a ? s(t.value) : o == null || o(t.value);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
t.icon != null ? /* @__PURE__ */ e.createElement("span", { className: n.o, "aria-hidden": !0 }, t.icon) : null,
|
|
92
|
+
/* @__PURE__ */ e.createElement("span", { className: n.l }, t.label),
|
|
93
|
+
p != null ? /* @__PURE__ */ e.createElement(K, { className: n.d, tone: "accent", size: "s" }, p) : null,
|
|
94
|
+
a ? /* @__PURE__ */ e.createElement(ae, { className: n.c }) : null
|
|
95
|
+
), a && E ? /* @__PURE__ */ e.createElement("ul", { className: n.m }, /* @__PURE__ */ e.createElement(
|
|
96
|
+
x,
|
|
97
|
+
{
|
|
98
|
+
items: i,
|
|
99
|
+
value: u,
|
|
100
|
+
open: c,
|
|
101
|
+
onSelect: o,
|
|
102
|
+
onToggle: s
|
|
103
|
+
}
|
|
104
|
+
)) : null);
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
function pe({
|
|
108
|
+
groups: l,
|
|
109
|
+
items: u,
|
|
110
|
+
value: c,
|
|
111
|
+
onSelect: o,
|
|
112
|
+
open: s,
|
|
113
|
+
defaultOpen: t,
|
|
114
|
+
onOpenChange: i,
|
|
115
|
+
variant: a = "cards",
|
|
116
|
+
brand: E,
|
|
117
|
+
extra: p,
|
|
118
|
+
footer: m,
|
|
119
|
+
footerItems: g,
|
|
120
|
+
onFooterSelect: y,
|
|
121
|
+
footerMenuLabel: C = "Меню аккаунта",
|
|
122
|
+
version: v,
|
|
123
|
+
className: w,
|
|
124
|
+
"aria-label": q = "Основное меню"
|
|
125
|
+
}) {
|
|
126
|
+
const N = l ?? u ?? [], [d = [], k] = O(
|
|
127
|
+
s,
|
|
128
|
+
L(N, t, c),
|
|
129
|
+
i
|
|
130
|
+
), h = e.useRef(c);
|
|
131
|
+
e.useEffect(() => {
|
|
132
|
+
if (c == null || c === h.current) {
|
|
133
|
+
h.current = c;
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
h.current = c;
|
|
137
|
+
const b = M(N, c).filter((D) => !d.includes(D));
|
|
138
|
+
b.length && k([...d, ...b]);
|
|
139
|
+
}, [c, N, d, k]);
|
|
140
|
+
const B = (r) => {
|
|
141
|
+
k(
|
|
142
|
+
d.includes(r) ? d.filter((b) => b !== r) : [...d, r]
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
return /* @__PURE__ */ e.createElement(
|
|
146
|
+
"aside",
|
|
147
|
+
{
|
|
148
|
+
className: f(n.r, a === "plain" && n.p, w),
|
|
149
|
+
"aria-label": q
|
|
150
|
+
},
|
|
151
|
+
E != null || p != null ? /* @__PURE__ */ e.createElement("div", { className: n.b }, E, p != null ? /* @__PURE__ */ e.createElement("div", { className: n.x }, p) : null) : null,
|
|
152
|
+
/* @__PURE__ */ e.createElement("div", { className: n.g }, N.map((r) => /* @__PURE__ */ e.createElement("nav", { key: r.value, className: n.s, "aria-label": r.title ?? "Навигация" }, r.title ? /* @__PURE__ */ e.createElement("div", { className: n.h }, r.title) : null, /* @__PURE__ */ e.createElement("ul", { className: n.n }, /* @__PURE__ */ e.createElement(
|
|
153
|
+
x,
|
|
154
|
+
{
|
|
155
|
+
items: r.items ?? [],
|
|
156
|
+
value: c,
|
|
157
|
+
open: d,
|
|
158
|
+
onSelect: o,
|
|
159
|
+
onToggle: B
|
|
160
|
+
}
|
|
161
|
+
))))),
|
|
162
|
+
m != null || v != null ? /* @__PURE__ */ e.createElement("div", { className: f(n.s, n.f) }, m != null && g != null && g.length > 0 ? /* @__PURE__ */ e.createElement(
|
|
163
|
+
R,
|
|
164
|
+
{
|
|
165
|
+
className: n.q,
|
|
166
|
+
align: "start",
|
|
167
|
+
placement: "top",
|
|
168
|
+
label: C,
|
|
169
|
+
trigger: /* @__PURE__ */ e.createElement(le, { footer: m, className: n.w }),
|
|
170
|
+
items: g,
|
|
171
|
+
onSelect: y
|
|
172
|
+
}
|
|
173
|
+
) : m, v != null ? /* @__PURE__ */ e.createElement("div", { className: n.v }, v) : null) : null
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
export {
|
|
177
|
+
pe as S
|
|
178
|
+
};
|
package/dist/Sidebar.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer elcrm-components{.c2r{box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;width:var(--sidebar-width, 248px);min-width:0;min-height:0;height:100%;max-height:100%;padding:var(--sidebar-pad-y, 16px) var(--sidebar-pad-x, 12px);gap:var(--shell-gap-sm, 8px);color:var(--shell-color);align-self:stretch}.c2b{display:flex;flex-direction:row;align-items:center;gap:var(--shell-gap);padding:4px 8px;min-width:0}.c2x{flex-shrink:0;margin-left:auto}.c2g{flex:1;min-height:0;display:flex;flex-direction:column;gap:var(--shell-gap-sm);overflow-y:auto;overflow-x:hidden;scrollbar-width:thin}.c2s{box-sizing:border-box;flex-shrink:0;padding:8px}.c2p{--sidebar-plain: 1}.c2r:not(.c2p) .c2s{background:var(--sidebar-block-bg);border:1px solid var(--sidebar-block-border);border-radius:var(--sidebar-block-radius);box-shadow:var(--sidebar-block-shadow)}.c2h{margin:2px 10px 6px;font-size:var(--sidebar-group-font-size);font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--shell-color-muted)}.c2n{margin:0;padding:0;list-style:none}.c2n>li{list-style:none}.c2n .c2i:is(button){position:relative;display:flex;width:100%;box-sizing:border-box;flex-direction:row;align-items:center;gap:8px;margin:0 0 1px;padding:var(--sidebar-item-padding);border:0;border-radius:8px;background:transparent;color:var(--shell-color-muted);font-family:inherit;font-size:var(--sidebar-item-font-size);font-weight:500;line-height:1.25;letter-spacing:0;text-align:left;cursor:pointer}.c2n .c2i:is(button):hover{color:var(--shell-color);background:var(--shell-background-hover)}.c2n .c2i:is(button).c2a,.c2n .c2i:is(button)[aria-current=page],.c2n .c2i:is(button)[data-active=true],.c2n .c2i:is(button).c2a:hover{color:var(--sidebar-item-active);background:var(--sidebar-item-active-bg)}.c2o{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size);color:inherit}.c2o :is(svg){display:block;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size)}.c2a .c2o{color:var(--sidebar-icon-active)}.c2l{flex:1;min-width:0}.c2d{flex-shrink:0;min-width:16px;height:16px;padding:0 4px;font-size:10px}.c2f{margin-top:auto}.c2q{display:flex;width:100%;min-width:0;flex:0 0 auto;height:auto;align-items:center}.c2q>*{display:flex;width:100%;min-width:0;height:auto;align-items:center}.c2w{display:flex;width:100%;min-width:0;align-items:center}.c2u{display:flex;align-items:center;width:100%;min-width:0;gap:var(--shell-gap-sm);margin:0;padding:0;border:none;background:transparent;font:inherit;color:inherit;cursor:pointer;text-align:left}.c2k{flex-shrink:0;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size);color:var(--shell-color-muted)}.c2v{margin-top:var(--shell-gap-sm);font-size:11px;color:var(--shell-color-muted);text-align:center}@media (max-width: 900px){.c2r{width:72px;padding:12px 8px}.c2l,.c2h,.c2v{display:none}.c2b{flex-direction:column;justify-content:center;align-items:center;gap:8px;padding:4px 0}.c2x{margin-left:0}.c2s{padding:6px}.c2n .c2i{justify-content:center;align-items:center;gap:0;width:100%;min-height:40px;padding:10px 0}.c2n .c2d{position:absolute;top:4px;right:4px;min-width:14px;height:14px;padding:0 4px;font-size:.625rem;line-height:14px;pointer-events:none}}}
|
|
1
|
+
@layer elcrm-components{.c2r{box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;width:var(--sidebar-width, 248px);min-width:0;min-height:0;height:100%;max-height:100%;padding:var(--sidebar-pad-y, 16px) var(--sidebar-pad-x, 12px);gap:var(--shell-gap-sm, 8px);color:var(--shell-color);align-self:stretch}.c2b{display:flex;flex-direction:row;align-items:center;gap:var(--shell-gap);padding:4px 8px;min-width:0}.c2x{flex-shrink:0;margin-left:auto}.c2g{flex:1;min-height:0;display:flex;flex-direction:column;gap:var(--shell-gap-sm);overflow-y:auto;overflow-x:hidden;scrollbar-width:thin}.c2s{box-sizing:border-box;flex-shrink:0;padding:8px}.c2p{--sidebar-plain: 1}.c2r:not(.c2p) .c2s{background:var(--sidebar-block-bg);border:1px solid var(--sidebar-block-border);border-radius:var(--sidebar-block-radius);box-shadow:var(--sidebar-block-shadow)}.c2h{margin:2px 10px 6px;font-size:var(--sidebar-group-font-size);font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--shell-color-muted)}.c2n{margin:0;padding:0;list-style:none}.c2n>li{list-style:none}.c2n .c2i:is(button){position:relative;display:flex;width:100%;box-sizing:border-box;flex-direction:row;align-items:center;gap:8px;margin:0 0 1px;padding:var(--sidebar-item-padding);border:0;border-radius:8px;background:transparent;color:var(--shell-color-muted);font-family:inherit;font-size:var(--sidebar-item-font-size);font-weight:500;line-height:1.25;letter-spacing:0;text-align:left;cursor:pointer}.c2n .c2i:is(button):hover{color:var(--shell-color);background:var(--shell-background-hover)}.c2n .c2i:is(button).c2a,.c2n .c2i:is(button)[aria-current=page],.c2n .c2i:is(button)[data-active=true],.c2n .c2i:is(button).c2a:hover{color:var(--sidebar-item-active);background:var(--sidebar-item-active-bg)}.c2o{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size);color:inherit}.c2o :is(svg){display:block;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size)}.c2a .c2o{color:var(--sidebar-icon-active)}.c2l{flex:1;min-width:0}.c2d{flex-shrink:0;min-width:16px;height:16px;padding:0 4px;font-size:10px}.c2c{flex-shrink:0;width:12px;height:12px;margin-left:auto;color:var(--shell-color-muted);transition:transform .15s ease}.c2n .c2i:is(button)[data-open=true] .c2c{transform:rotate(180deg);color:inherit}.c2m{margin:0;padding:0 0 0 var(--sidebar-indent);list-style:none}.c2m>li{list-style:none}.c2f{margin-top:auto}.c2q{display:flex;width:100%;min-width:0;flex:0 0 auto;height:auto;align-items:center}.c2q>*{display:flex;width:100%;min-width:0;height:auto;align-items:center}.c2w{display:flex;width:100%;min-width:0;align-items:center}.c2u{display:flex;align-items:center;width:100%;min-width:0;gap:var(--shell-gap-sm);margin:0;padding:0;border:none;background:transparent;font:inherit;color:inherit;cursor:pointer;text-align:left}.c2k{flex-shrink:0;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size);color:var(--shell-color-muted)}.c2v{margin-top:var(--shell-gap-sm);font-size:11px;color:var(--shell-color-muted);text-align:center}@media (max-width: 900px){.c2r{width:72px;padding:12px 8px}.c2l,.c2h,.c2v,.c2c,.c2m{display:none}.c2b{flex-direction:column;justify-content:center;align-items:center;gap:8px;padding:4px 0}.c2x{margin-left:0}.c2s{padding:6px}.c2n .c2i{justify-content:center;align-items:center;gap:0;width:100%;min-height:40px;padding:10px 0}.c2n .c2d{position:absolute;top:4px;right:4px;min-width:14px;height:14px;padding:0 4px;font-size:.625rem;line-height:14px;pointer-events:none}}}
|
package/dist/Sidebar.d.ts
CHANGED
|
@@ -11,6 +11,17 @@ export type SidebarItem = {
|
|
|
11
11
|
icon?: React.ReactNode;
|
|
12
12
|
/** Счётчик справа */
|
|
13
13
|
badge?: number | string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Вложенные пункты — есть → шеврон и раскрытие.
|
|
16
|
+
* Клик по родителю только открывает/закрывает, `onSelect` не зовём.
|
|
17
|
+
*/
|
|
18
|
+
items?: SidebarItem[];
|
|
19
|
+
/**
|
|
20
|
+
* Подменю открыто при первом рендере.
|
|
21
|
+
* Если выбран потомок — ветка откроется сама.
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
defaultOpen?: boolean;
|
|
14
25
|
};
|
|
15
26
|
/** Группа пунктов. `title` — «Аккаунт» / «Админ». */
|
|
16
27
|
export type SidebarGroup = {
|
|
@@ -39,8 +50,23 @@ export type SidebarGroup = {
|
|
|
39
50
|
* brand={<Brand as="strong">App</Brand>}
|
|
40
51
|
* extra={<Notifications.Bell />}
|
|
41
52
|
* groups={[
|
|
42
|
-
* {
|
|
43
|
-
*
|
|
53
|
+
* {
|
|
54
|
+
* value: "docs",
|
|
55
|
+
* items: [
|
|
56
|
+
* { value: "games", label: "VK Games" },
|
|
57
|
+
* {
|
|
58
|
+
* value: "bridge",
|
|
59
|
+
* label: "VK Bridge",
|
|
60
|
+
* defaultOpen: true,
|
|
61
|
+
* items: [
|
|
62
|
+
* { value: "intro", label: "Введение" },
|
|
63
|
+
* { value: "events", label: "События", items: [
|
|
64
|
+
* { value: "evt-init", label: "VKWebAppInit" },
|
|
65
|
+
* ] },
|
|
66
|
+
* ],
|
|
67
|
+
* },
|
|
68
|
+
* ],
|
|
69
|
+
* },
|
|
44
70
|
* ]}
|
|
45
71
|
* footer={<AvatarName title="Паша" description="mail@…" />}
|
|
46
72
|
* footerItems={[
|
|
@@ -62,8 +88,19 @@ export type SidebarProps = {
|
|
|
62
88
|
items?: SidebarGroup[];
|
|
63
89
|
/** Текущий пункт */
|
|
64
90
|
value?: string;
|
|
65
|
-
/** Выбор пункта */
|
|
91
|
+
/** Выбор пункта (только листья, без `items`) */
|
|
66
92
|
onSelect?: (value: string) => void;
|
|
93
|
+
/**
|
|
94
|
+
* Раскрытые родители (их `value`). Контролируемый режим.
|
|
95
|
+
* Вместе с `onOpenChange`.
|
|
96
|
+
*/
|
|
97
|
+
open?: string[];
|
|
98
|
+
/**
|
|
99
|
+
* Начально раскрытые (плюс `item.defaultOpen` и предки выбранного).
|
|
100
|
+
*/
|
|
101
|
+
defaultOpen?: string[];
|
|
102
|
+
/** Смена набора раскрытых родителей */
|
|
103
|
+
onOpenChange?: (open: string[]) => void;
|
|
67
104
|
/**
|
|
68
105
|
* `cards` — блоки-карточки.
|
|
69
106
|
* `plain` — плоский список.
|
|
@@ -96,4 +133,4 @@ export type SidebarProps = {
|
|
|
96
133
|
*
|
|
97
134
|
* @see Layout, Brand, Item, Badge, NavSections
|
|
98
135
|
*/
|
|
99
|
-
export declare function Sidebar({ groups, items, value, onSelect, variant, brand, extra, footer, footerItems, onFooterSelect, footerMenuLabel, version, className, "aria-label": ariaLabel, }: SidebarProps): React.JSX.Element;
|
|
136
|
+
export declare function Sidebar({ groups, items, value, onSelect, open: openProp, defaultOpen, onOpenChange, variant, brand, extra, footer, footerItems, onFooterSelect, footerMenuLabel, version, className, "aria-label": ariaLabel, }: SidebarProps): React.JSX.Element;
|
package/dist/Sidebar.js
CHANGED
package/dist/Toolbar.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer elcrm-components{.cCr{display:flex;flex-wrap:wrap;align-items:center;gap:var(--toolbar-gap);width:100%;min-width:0;box-sizing:border-box}.cCr[data-width=s]{display:inline-flex;width:auto;max-width:100%}.cCr[data-align=center]{justify-content:center}.cCr[data-align=end]{justify-content:flex-end}.cCr[data-align=between]{justify-content:space-between}.cCr[data-size=s]{--control-height: var(--control-height-s);--field-height: var(--control-height-s);--control-font-size: 13px;--button-height: var(--button-height-s);--button-height-m: var(--button-height-s);--button-padding: var(--button-padding-s);--button-size-m: var(--button-size-s)}.cCr[data-size=l]{--control-height: var(--control-height-l);--field-height: var(--control-height-l);--button-height: var(--button-height-l);--button-height-m: var(--button-height-l);--button-size-m: var(--button-size-l)}}
|
|
1
|
+
@layer elcrm-components{.cCr{display:flex;flex-wrap:wrap;align-items:center;gap:var(--toolbar-gap);width:100%;min-width:0;box-sizing:border-box;--field-width: auto}.cCr>[data-field]{flex:0 1 auto;width:auto;min-width:0;max-width:100%}.cCr>[data-field=search]{flex:1 1 var(--field-search-min-width, 10rem);width:auto!important;max-width:none}.cCr[data-width=s]{display:inline-flex;width:auto;max-width:100%}.cCr[data-align=center]{justify-content:center}.cCr[data-align=end]{justify-content:flex-end}.cCr[data-align=between]{justify-content:space-between}.cCr[data-size=s]{--control-height: var(--control-height-s);--field-height: var(--control-height-s);--control-font-size: 13px;--button-height: var(--button-height-s);--button-height-m: var(--button-height-s);--button-padding: var(--button-padding-s);--button-size-m: var(--button-size-s)}.cCr[data-size=l]{--control-height: var(--control-height-l);--field-height: var(--control-height-l);--button-height: var(--button-height-l);--button-height-m: var(--button-height-l);--button-size-m: var(--button-size-l)}}
|
package/dist/index.css
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
@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)}}
|
|
40
40
|
|
|
41
|
-
@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;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{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.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}}}
|
|
41
|
+
@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}}}
|
|
42
42
|
|
|
43
43
|
@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}}
|
|
44
44
|
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
|
|
57
57
|
@layer elcrm-components{.cep{display:flex;flex-direction:column;gap:var(--shell-gap);padding:var(--section-padding);flex:1;min-width:0}.ceu{box-sizing:border-box;min-height:100svh;display:flex;align-items:center;justify-content:center;padding:var(--section-padding)}.cek{box-sizing:border-box;width:100%;max-width:var(--section-auth-card-max-width);padding:var(--shell-gap-lg);background:var(--shell-background);border:1px solid var(--shell-border);border-radius:var(--shell-radius);box-shadow:var(--shell-shadow);display:flex;flex-direction:column;gap:var(--shell-gap)}.ceh{display:flex;flex-direction:column;gap:var(--shell-gap-sm)}.cec{text-align:center;align-items:center}.cei{display:flex;margin-bottom:var(--shell-gap-sm)}.cec .cei{justify-content:center}.cet{margin:0;font-size:var(--section-title-size);font-weight:var(--shell-font-weight);letter-spacing:-.02em;color:var(--shell-color);line-height:1.25}.ced{font-size:var(--section-title-size-md)}.cee{margin:0;font-size:var(--shell-font-size);color:var(--shell-color-muted);line-height:1.45}.ceb{display:flex;flex-direction:column;gap:var(--shell-gap);width:100%;text-align:left}.ces{display:flex;flex-direction:column;gap:var(--shell-gap-sm);width:100%}.cel{display:flex;flex-direction:column;gap:var(--shell-gap);margin-bottom:var(--shell-gap-lg);padding-bottom:var(--shell-gap-lg);border-bottom:1px solid var(--shell-border)}.cel:last-of-type{margin-bottom:0;padding-bottom:0;border-bottom:none}.cel .cet{font-size:var(--shell-font-size);font-weight:var(--shell-font-weight)}}
|
|
58
58
|
|
|
59
|
-
@layer elcrm-components{.c2r{box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;width:var(--sidebar-width, 248px);min-width:0;min-height:0;height:100%;max-height:100%;padding:var(--sidebar-pad-y, 16px) var(--sidebar-pad-x, 12px);gap:var(--shell-gap-sm, 8px);color:var(--shell-color);align-self:stretch}.c2b{display:flex;flex-direction:row;align-items:center;gap:var(--shell-gap);padding:4px 8px;min-width:0}.c2x{flex-shrink:0;margin-left:auto}.c2g{flex:1;min-height:0;display:flex;flex-direction:column;gap:var(--shell-gap-sm);overflow-y:auto;overflow-x:hidden;scrollbar-width:thin}.c2s{box-sizing:border-box;flex-shrink:0;padding:8px}.c2p{--sidebar-plain: 1}.c2r:not(.c2p) .c2s{background:var(--sidebar-block-bg);border:1px solid var(--sidebar-block-border);border-radius:var(--sidebar-block-radius);box-shadow:var(--sidebar-block-shadow)}.c2h{margin:2px 10px 6px;font-size:var(--sidebar-group-font-size);font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--shell-color-muted)}.c2n{margin:0;padding:0;list-style:none}.c2n>li{list-style:none}.c2n .c2i:is(button){position:relative;display:flex;width:100%;box-sizing:border-box;flex-direction:row;align-items:center;gap:8px;margin:0 0 1px;padding:var(--sidebar-item-padding);border:0;border-radius:8px;background:transparent;color:var(--shell-color-muted);font-family:inherit;font-size:var(--sidebar-item-font-size);font-weight:500;line-height:1.25;letter-spacing:0;text-align:left;cursor:pointer}.c2n .c2i:is(button):hover{color:var(--shell-color);background:var(--shell-background-hover)}.c2n .c2i:is(button).c2a,.c2n .c2i:is(button)[aria-current=page],.c2n .c2i:is(button)[data-active=true],.c2n .c2i:is(button).c2a:hover{color:var(--sidebar-item-active);background:var(--sidebar-item-active-bg)}.c2o{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size);color:inherit}.c2o :is(svg){display:block;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size)}.c2a .c2o{color:var(--sidebar-icon-active)}.c2l{flex:1;min-width:0}.c2d{flex-shrink:0;min-width:16px;height:16px;padding:0 4px;font-size:10px}.c2f{margin-top:auto}.c2q{display:flex;width:100%;min-width:0;flex:0 0 auto;height:auto;align-items:center}.c2q>*{display:flex;width:100%;min-width:0;height:auto;align-items:center}.c2w{display:flex;width:100%;min-width:0;align-items:center}.c2u{display:flex;align-items:center;width:100%;min-width:0;gap:var(--shell-gap-sm);margin:0;padding:0;border:none;background:transparent;font:inherit;color:inherit;cursor:pointer;text-align:left}.c2k{flex-shrink:0;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size);color:var(--shell-color-muted)}.c2v{margin-top:var(--shell-gap-sm);font-size:11px;color:var(--shell-color-muted);text-align:center}@media (max-width: 900px){.c2r{width:72px;padding:12px 8px}.c2l,.c2h,.c2v{display:none}.c2b{flex-direction:column;justify-content:center;align-items:center;gap:8px;padding:4px 0}.c2x{margin-left:0}.c2s{padding:6px}.c2n .c2i{justify-content:center;align-items:center;gap:0;width:100%;min-height:40px;padding:10px 0}.c2n .c2d{position:absolute;top:4px;right:4px;min-width:14px;height:14px;padding:0 4px;font-size:.625rem;line-height:14px;pointer-events:none}}}
|
|
59
|
+
@layer elcrm-components{.c2r{box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;width:var(--sidebar-width, 248px);min-width:0;min-height:0;height:100%;max-height:100%;padding:var(--sidebar-pad-y, 16px) var(--sidebar-pad-x, 12px);gap:var(--shell-gap-sm, 8px);color:var(--shell-color);align-self:stretch}.c2b{display:flex;flex-direction:row;align-items:center;gap:var(--shell-gap);padding:4px 8px;min-width:0}.c2x{flex-shrink:0;margin-left:auto}.c2g{flex:1;min-height:0;display:flex;flex-direction:column;gap:var(--shell-gap-sm);overflow-y:auto;overflow-x:hidden;scrollbar-width:thin}.c2s{box-sizing:border-box;flex-shrink:0;padding:8px}.c2p{--sidebar-plain: 1}.c2r:not(.c2p) .c2s{background:var(--sidebar-block-bg);border:1px solid var(--sidebar-block-border);border-radius:var(--sidebar-block-radius);box-shadow:var(--sidebar-block-shadow)}.c2h{margin:2px 10px 6px;font-size:var(--sidebar-group-font-size);font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--shell-color-muted)}.c2n{margin:0;padding:0;list-style:none}.c2n>li{list-style:none}.c2n .c2i:is(button){position:relative;display:flex;width:100%;box-sizing:border-box;flex-direction:row;align-items:center;gap:8px;margin:0 0 1px;padding:var(--sidebar-item-padding);border:0;border-radius:8px;background:transparent;color:var(--shell-color-muted);font-family:inherit;font-size:var(--sidebar-item-font-size);font-weight:500;line-height:1.25;letter-spacing:0;text-align:left;cursor:pointer}.c2n .c2i:is(button):hover{color:var(--shell-color);background:var(--shell-background-hover)}.c2n .c2i:is(button).c2a,.c2n .c2i:is(button)[aria-current=page],.c2n .c2i:is(button)[data-active=true],.c2n .c2i:is(button).c2a:hover{color:var(--sidebar-item-active);background:var(--sidebar-item-active-bg)}.c2o{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size);color:inherit}.c2o :is(svg){display:block;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size)}.c2a .c2o{color:var(--sidebar-icon-active)}.c2l{flex:1;min-width:0}.c2d{flex-shrink:0;min-width:16px;height:16px;padding:0 4px;font-size:10px}.c2c{flex-shrink:0;width:12px;height:12px;margin-left:auto;color:var(--shell-color-muted);transition:transform .15s ease}.c2n .c2i:is(button)[data-open=true] .c2c{transform:rotate(180deg);color:inherit}.c2m{margin:0;padding:0 0 0 var(--sidebar-indent);list-style:none}.c2m>li{list-style:none}.c2f{margin-top:auto}.c2q{display:flex;width:100%;min-width:0;flex:0 0 auto;height:auto;align-items:center}.c2q>*{display:flex;width:100%;min-width:0;height:auto;align-items:center}.c2w{display:flex;width:100%;min-width:0;align-items:center}.c2u{display:flex;align-items:center;width:100%;min-width:0;gap:var(--shell-gap-sm);margin:0;padding:0;border:none;background:transparent;font:inherit;color:inherit;cursor:pointer;text-align:left}.c2k{flex-shrink:0;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size);color:var(--shell-color-muted)}.c2v{margin-top:var(--shell-gap-sm);font-size:11px;color:var(--shell-color-muted);text-align:center}@media (max-width: 900px){.c2r{width:72px;padding:12px 8px}.c2l,.c2h,.c2v,.c2c,.c2m{display:none}.c2b{flex-direction:column;justify-content:center;align-items:center;gap:8px;padding:4px 0}.c2x{margin-left:0}.c2s{padding:6px}.c2n .c2i{justify-content:center;align-items:center;gap:0;width:100%;min-height:40px;padding:10px 0}.c2n .c2d{position:absolute;top:4px;right:4px;min-width:14px;height:14px;padding:0 4px;font-size:.625rem;line-height:14px;pointer-events:none}}}
|
|
60
60
|
|
|
61
61
|
@layer elcrm-components{.c1r{box-sizing:border-box;min-width:0;gap:var(--shell-gap)}.c1c,.c1g{width:100%}.c1c{display:flex;flex-direction:column}.c1h{display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;width:auto;max-width:100%}.c1g{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,var(--stack-grid-min)),1fr))}.c1n{display:grid;width:100%;align-items:stretch;grid-template-columns:var(--stack-columns-template)}}
|
|
62
62
|
|
|
@@ -66,4 +66,4 @@
|
|
|
66
66
|
|
|
67
67
|
@layer elcrm-components{.c6r{display:flex;flex-direction:column;gap:2px;min-width:0;text-align:left}.c6t{margin:0;font-size:var(--shell-font-size);font-weight:var(--shell-font-weight);color:var(--shell-color);line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c6d{margin:0;font-size:var(--shell-font-size-sm);font-weight:400;color:var(--shell-color-muted);line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c6s .c6t{font-size:var(--shell-font-size-sm)}.c6l .c6t{font-size:var(--shell-font-size-lg)}.c6l .c6d{font-size:var(--shell-font-size)}}
|
|
68
68
|
|
|
69
|
-
@layer elcrm-components{.cCr{display:flex;flex-wrap:wrap;align-items:center;gap:var(--toolbar-gap);width:100%;min-width:0;box-sizing:border-box}.cCr[data-width=s]{display:inline-flex;width:auto;max-width:100%}.cCr[data-align=center]{justify-content:center}.cCr[data-align=end]{justify-content:flex-end}.cCr[data-align=between]{justify-content:space-between}.cCr[data-size=s]{--control-height: var(--control-height-s);--field-height: var(--control-height-s);--control-font-size: 13px;--button-height: var(--button-height-s);--button-height-m: var(--button-height-s);--button-padding: var(--button-padding-s);--button-size-m: var(--button-size-s)}.cCr[data-size=l]{--control-height: var(--control-height-l);--field-height: var(--control-height-l);--button-height: var(--button-height-l);--button-height-m: var(--button-height-l);--button-size-m: var(--button-size-l)}}
|
|
69
|
+
@layer elcrm-components{.cCr{display:flex;flex-wrap:wrap;align-items:center;gap:var(--toolbar-gap);width:100%;min-width:0;box-sizing:border-box;--field-width: auto}.cCr>[data-field]{flex:0 1 auto;width:auto;min-width:0;max-width:100%}.cCr>[data-field=search]{flex:1 1 var(--field-search-min-width, 10rem);width:auto!important;max-width:none}.cCr[data-width=s]{display:inline-flex;width:auto;max-width:100%}.cCr[data-align=center]{justify-content:center}.cCr[data-align=end]{justify-content:flex-end}.cCr[data-align=between]{justify-content:space-between}.cCr[data-size=s]{--control-height: var(--control-height-s);--field-height: var(--control-height-s);--control-font-size: 13px;--button-height: var(--button-height-s);--button-height-m: var(--button-height-s);--button-padding: var(--button-padding-s);--button-size-m: var(--button-size-s)}.cCr[data-size=l]{--control-height: var(--control-height-l);--field-height: var(--control-height-l);--button-height: var(--button-height-l);--button-height-m: var(--button-height-l);--button-size-m: var(--button-size-l)}}
|
package/dist/index.es.js
CHANGED
|
@@ -18,7 +18,7 @@ import { D as j } from "./Dropdown-DosvDR13.js";
|
|
|
18
18
|
import { B as K } from "./Breadcrumb-CAM_e9LN.js";
|
|
19
19
|
import { L as U } from "./Loading-DkkG7RcE.js";
|
|
20
20
|
import { S as W } from "./Section-Crxk2J-E.js";
|
|
21
|
-
import { N as Y } from "./NavSections-
|
|
21
|
+
import { N as Y } from "./NavSections-D6rDEtT1.js";
|
|
22
22
|
import { T as $ } from "./TabSections-DN7yVJoF.js";
|
|
23
23
|
import { A as or, a as ar, i as er } from "./Avatar-loGgFt72.js";
|
|
24
24
|
import { A as sr } from "./AvatarGroup-D1gnT3Od.js";
|
|
@@ -34,7 +34,7 @@ import { P as Br } from "./PageShell-D9EZiO8o.js";
|
|
|
34
34
|
import { C as Lr, a as br } from "./ChatSplit-DNnu3TNq.js";
|
|
35
35
|
import { C as Rr } from "./ChatFrame-BW2TmCkZ.js";
|
|
36
36
|
import { C as Hr } from "./ChatMessages-B8rdXiK-.js";
|
|
37
|
-
import { S as kr } from "./Sidebar-
|
|
37
|
+
import { S as kr } from "./Sidebar-CYFaPqdC.js";
|
|
38
38
|
import { P as Nr } from "./Popover-DWdvZTuA.js";
|
|
39
39
|
import { H as Mr } from "./Healthmap-B6cdiLUl.js";
|
|
40
40
|
import { P as Zr } from "./PanelInfo-A5y5ysH8.js";
|
package/dist/kit-manifest.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": "elcrm-kit-manifest-v1",
|
|
3
3
|
"package": "@elcrm/components",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.11",
|
|
5
5
|
"pkg": "components",
|
|
6
|
-
"generatedAt": "2026-08-
|
|
6
|
+
"generatedAt": "2026-08-23T09:13:24.421Z",
|
|
7
7
|
"components": [
|
|
8
8
|
{
|
|
9
9
|
"slug": "ActionGroup",
|
|
@@ -749,12 +749,12 @@
|
|
|
749
749
|
{
|
|
750
750
|
"slug": "NavSections",
|
|
751
751
|
"title": "NavSections",
|
|
752
|
-
"description": "Макет «настройки / профиль»: вертикальный сайдбар + lazy-секция справа. Когда использовать: - страницы с несколькими разделами и боковым меню; - контент секции грузится по `value` через `resolveSection`. Связанные компоненты: - {@link TabSections} — то же, но вкладки горизонтально; - {@link createLazyResolver} из `lazyRoute` — кэш lazy-импортов; - {@link Menu} — простая навигация без панелей. API: декларативные `groups` / `items`. Идентификатор раздела — `value` (не `key`). Compound-слоты (`NavSections.Item`) не используются. CSS-токены: `--shell-*`, `--nav-sections-padding`, `--nav-sections-nav-width`, `--nav-sections-main-max-width`.",
|
|
752
|
+
"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`.",
|
|
753
753
|
"importFrom": "@elcrm/components",
|
|
754
754
|
"examples": [
|
|
755
755
|
{
|
|
756
756
|
"title": "Пример",
|
|
757
|
-
"code": "const groups = [\n {\n label: \"
|
|
757
|
+
"code": "const groups = [\n {\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: \"События\", items: [\n { value: \"evt-init\", label: \"VKWebAppInit\" },\n ] },\n ],\n },\n { value: \"auth\", label: \"Авторизация VK\" },\n ],\n },\n];\n\n<NavSections\n groups={groups}\n resolveSection={resolveSection}\n value={section}\n onValueChange={setSection}\n/>"
|
|
758
758
|
}
|
|
759
759
|
],
|
|
760
760
|
"props": [
|
|
@@ -783,6 +783,21 @@
|
|
|
783
783
|
"type": "(value: string) => void",
|
|
784
784
|
"description": "Смена активного раздела (`next` = `item.value`)."
|
|
785
785
|
},
|
|
786
|
+
{
|
|
787
|
+
"name": "open",
|
|
788
|
+
"type": "string[]",
|
|
789
|
+
"description": "Раскрытые родители (их `value`). Контролируемый режим. Вместе с `onOpenChange`."
|
|
790
|
+
},
|
|
791
|
+
{
|
|
792
|
+
"name": "defaultOpen",
|
|
793
|
+
"type": "string[]",
|
|
794
|
+
"description": "Начально раскрытые (плюс `item.defaultOpen` и предки выбранного)."
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
"name": "onOpenChange",
|
|
798
|
+
"type": "(open: string[]) => void",
|
|
799
|
+
"description": "Смена набора раскрытых родителей"
|
|
800
|
+
},
|
|
786
801
|
{
|
|
787
802
|
"name": "loading",
|
|
788
803
|
"type": "React.ReactNode",
|
|
@@ -1228,7 +1243,7 @@
|
|
|
1228
1243
|
"examples": [
|
|
1229
1244
|
{
|
|
1230
1245
|
"title": "Пример",
|
|
1231
|
-
"code": "<Sidebar\n variant=\"cards\"\n value={page}\n onSelect={setPage}\n brand={<Brand as=\"strong\">App</Brand>}\n extra={<Notifications.Bell />}\n groups={[\n {
|
|
1246
|
+
"code": "<Sidebar\n variant=\"cards\"\n value={page}\n onSelect={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 onFooterSelect={(value) => console.log(value)}\n version=\"v 0.2.26\"\n/>"
|
|
1232
1247
|
}
|
|
1233
1248
|
],
|
|
1234
1249
|
"props": [
|
|
@@ -1250,7 +1265,22 @@
|
|
|
1250
1265
|
{
|
|
1251
1266
|
"name": "onSelect",
|
|
1252
1267
|
"type": "(value: string) => void",
|
|
1253
|
-
"description": "Выбор пункта"
|
|
1268
|
+
"description": "Выбор пункта (только листья, без `items`)"
|
|
1269
|
+
},
|
|
1270
|
+
{
|
|
1271
|
+
"name": "open",
|
|
1272
|
+
"type": "string[]",
|
|
1273
|
+
"description": "Раскрытые родители (их `value`). Контролируемый режим. Вместе с `onOpenChange`."
|
|
1274
|
+
},
|
|
1275
|
+
{
|
|
1276
|
+
"name": "defaultOpen",
|
|
1277
|
+
"type": "string[]",
|
|
1278
|
+
"description": "Начально раскрытые (плюс `item.defaultOpen` и предки выбранного)."
|
|
1279
|
+
},
|
|
1280
|
+
{
|
|
1281
|
+
"name": "onOpenChange",
|
|
1282
|
+
"type": "(open: string[]) => void",
|
|
1283
|
+
"description": "Смена набора раскрытых родителей"
|
|
1254
1284
|
},
|
|
1255
1285
|
{
|
|
1256
1286
|
"name": "variant",
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
function o(e, n, t = []) {
|
|
2
|
+
var u;
|
|
3
|
+
for (const a of e ?? [])
|
|
4
|
+
n(a, t), (u = a.items) != null && u.length && o(a.items, n, [...t, a.value]);
|
|
5
|
+
}
|
|
6
|
+
function f(e, n) {
|
|
7
|
+
for (const t of e)
|
|
8
|
+
o(t.items, n);
|
|
9
|
+
}
|
|
10
|
+
function r(e, n) {
|
|
11
|
+
if (n == null) return [];
|
|
12
|
+
let t = null;
|
|
13
|
+
return f(e, (u, a) => {
|
|
14
|
+
u.value === n && (t = a);
|
|
15
|
+
}), t ?? [];
|
|
16
|
+
}
|
|
17
|
+
function i(e, n, t) {
|
|
18
|
+
const u = new Set(n ?? []);
|
|
19
|
+
f(e, (a) => {
|
|
20
|
+
var l;
|
|
21
|
+
a.defaultOpen && ((l = a.items) != null && l.length) && u.add(a.value);
|
|
22
|
+
});
|
|
23
|
+
for (const a of r(e, t)) u.add(a);
|
|
24
|
+
return [...u];
|
|
25
|
+
}
|
|
26
|
+
function c(e, n) {
|
|
27
|
+
if (n == null) return !1;
|
|
28
|
+
let t = !1;
|
|
29
|
+
return f(e, (u) => {
|
|
30
|
+
var a;
|
|
31
|
+
u.value === n && ((a = u.items) != null && a.length) && (t = !0);
|
|
32
|
+
}), t;
|
|
33
|
+
}
|
|
34
|
+
function s(e) {
|
|
35
|
+
const n = [];
|
|
36
|
+
return f(e, (t) => {
|
|
37
|
+
var u;
|
|
38
|
+
!((u = t.items) != null && u.length) && !t.disabled && n.push(t);
|
|
39
|
+
}), n;
|
|
40
|
+
}
|
|
41
|
+
function d(e) {
|
|
42
|
+
var n;
|
|
43
|
+
return ((n = s(e)[0]) == null ? void 0 : n.value) ?? "";
|
|
44
|
+
}
|
|
45
|
+
function v(e) {
|
|
46
|
+
const n = [];
|
|
47
|
+
return f(e, (t) => {
|
|
48
|
+
t.disabled || n.push(t);
|
|
49
|
+
}), n;
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
v as a,
|
|
53
|
+
r as b,
|
|
54
|
+
i as c,
|
|
55
|
+
d as f,
|
|
56
|
+
c as i
|
|
57
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Узел дерева меню (Sidebar / NavSections). */
|
|
2
|
+
export type NavTreeNode = {
|
|
3
|
+
value: string;
|
|
4
|
+
items?: NavTreeNode[];
|
|
5
|
+
defaultOpen?: boolean;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare function walkNavTree<T extends NavTreeNode>(items: T[] | undefined, fn: (item: T, ancestors: string[]) => void, ancestors?: string[]): void;
|
|
9
|
+
export declare function walkNavGroups<T extends NavTreeNode>(groups: {
|
|
10
|
+
items?: T[];
|
|
11
|
+
}[], fn: (item: T, ancestors: string[]) => void): void;
|
|
12
|
+
/** Предки выбранного листа — ветку нужно раскрыть. */
|
|
13
|
+
export declare function findNavAncestors<T extends NavTreeNode>(groups: {
|
|
14
|
+
items?: T[];
|
|
15
|
+
}[], selected: string | undefined): string[];
|
|
16
|
+
/** Стартовый набор раскрытых: defaultOpen + extra + предки selected. */
|
|
17
|
+
export declare function collectNavDefaultOpen<T extends NavTreeNode>(groups: {
|
|
18
|
+
items?: T[];
|
|
19
|
+
}[], extra: string[] | undefined, selected: string | undefined): string[];
|
|
20
|
+
export declare function isNavParent<T extends NavTreeNode>(groups: {
|
|
21
|
+
items?: T[];
|
|
22
|
+
}[], value: string | undefined): boolean;
|
|
23
|
+
/** Листья без `items` (для панели / firstValue). */
|
|
24
|
+
export declare function flattenNavLeaves<T extends NavTreeNode>(groups: {
|
|
25
|
+
items?: T[];
|
|
26
|
+
}[]): T[];
|
|
27
|
+
export declare function firstNavLeafValue<T extends NavTreeNode>(groups: {
|
|
28
|
+
items?: T[];
|
|
29
|
+
}[]): string;
|
|
30
|
+
/** Все доступные пункты (родители + листья) — для клавиатуры. */
|
|
31
|
+
export declare function flattenNavEnabled<T extends NavTreeNode>(groups: {
|
|
32
|
+
items?: T[];
|
|
33
|
+
}[]): T[];
|
package/dist/tokens.css
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elcrm/components",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.11",
|
|
4
4
|
"description": "Shell UI elCRM: Layout, Header, Sidebar, Popover, Healthmap, PanelInfo, PageHead, PageShell, Section, Stack, Stat и др.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "MaSkal <dev@elcrm.online>",
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import a, { useMemo as h, Suspense as S } from "react";
|
|
2
|
-
import { c as d } from "./cx-CcykAxZN.js";
|
|
3
|
-
import { I as g } from "./Item-D4okhsfW.js";
|
|
4
|
-
import { h as x } from "./rovingKeys-CGlfTtNQ.js";
|
|
5
|
-
import { u as C } from "./useControllableValue-CWqH1kpM.js";
|
|
6
|
-
import './NavSections.css';const I = "cvr", K = "cvn", M = "cvg", R = "cvl", V = "cvi", w = "cva", D = "cvc", P = "cvt", j = "cvf", q = "cvm", l = {
|
|
7
|
-
r: I,
|
|
8
|
-
n: K,
|
|
9
|
-
g: M,
|
|
10
|
-
l: R,
|
|
11
|
-
i: V,
|
|
12
|
-
a: w,
|
|
13
|
-
c: D,
|
|
14
|
-
t: P,
|
|
15
|
-
f: j,
|
|
16
|
-
m: q
|
|
17
|
-
};
|
|
18
|
-
function z(n) {
|
|
19
|
-
for (const m of n) {
|
|
20
|
-
const c = m.items.find((s) => !s.disabled);
|
|
21
|
-
if (c) return c.value;
|
|
22
|
-
}
|
|
23
|
-
return "";
|
|
24
|
-
}
|
|
25
|
-
function J({
|
|
26
|
-
groups: n,
|
|
27
|
-
resolveSection: m,
|
|
28
|
-
value: c,
|
|
29
|
-
defaultValue: s,
|
|
30
|
-
onValueChange: f,
|
|
31
|
-
loading: b = null,
|
|
32
|
-
footer: i,
|
|
33
|
-
className: E,
|
|
34
|
-
navLabel: N = "Разделы"
|
|
35
|
-
}) {
|
|
36
|
-
const p = h(
|
|
37
|
-
() => s || z(n),
|
|
38
|
-
[s, n]
|
|
39
|
-
), [r, v] = C(
|
|
40
|
-
c,
|
|
41
|
-
p,
|
|
42
|
-
f
|
|
43
|
-
), k = n.flatMap((e) => e.items).filter((e) => !e.disabled).map((e) => e.value), u = r ? m(r) : null;
|
|
44
|
-
return /* @__PURE__ */ a.createElement("div", { className: d(l.r, E) }, /* @__PURE__ */ a.createElement(
|
|
45
|
-
"nav",
|
|
46
|
-
{
|
|
47
|
-
className: l.n,
|
|
48
|
-
"aria-label": N,
|
|
49
|
-
onKeyDown: (e) => x(e, {
|
|
50
|
-
values: k,
|
|
51
|
-
value: r,
|
|
52
|
-
onSelect: v,
|
|
53
|
-
vertical: !0
|
|
54
|
-
})
|
|
55
|
-
},
|
|
56
|
-
n.map((e, y) => /* @__PURE__ */ a.createElement("div", { key: y, className: l.g }, e.label != null ? /* @__PURE__ */ a.createElement("div", { className: l.l }, e.label) : null, e.items.map((t) => {
|
|
57
|
-
const o = t.value === r;
|
|
58
|
-
return /* @__PURE__ */ a.createElement(
|
|
59
|
-
g,
|
|
60
|
-
{
|
|
61
|
-
key: t.value,
|
|
62
|
-
as: "button",
|
|
63
|
-
active: o,
|
|
64
|
-
className: d(l.i, o && l.a),
|
|
65
|
-
"data-active": o ? "true" : void 0,
|
|
66
|
-
"aria-current": o ? "page" : void 0,
|
|
67
|
-
disabled: t.disabled,
|
|
68
|
-
onClick: () => v(t.value)
|
|
69
|
-
},
|
|
70
|
-
t.icon != null ? /* @__PURE__ */ a.createElement("span", { className: l.c, "aria-hidden": !0 }, t.icon) : null,
|
|
71
|
-
/* @__PURE__ */ a.createElement("span", { className: l.t }, t.label)
|
|
72
|
-
);
|
|
73
|
-
}))),
|
|
74
|
-
i != null ? /* @__PURE__ */ a.createElement("div", { className: l.f }, i) : null
|
|
75
|
-
), /* @__PURE__ */ a.createElement("div", { className: l.m }, u ? /* @__PURE__ */ a.createElement(S, { fallback: b }, a.createElement(u)) : null));
|
|
76
|
-
}
|
|
77
|
-
export {
|
|
78
|
-
J as N
|
|
79
|
-
};
|
package/dist/Sidebar-BgZiGEDH.js
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import e from "react";
|
|
2
|
-
import { B as h } from "./Badge-jp-9iNNL.js";
|
|
3
|
-
import { D as w } from "./Dropdown-DosvDR13.js";
|
|
4
|
-
import { I as y } from "./Item-D4okhsfW.js";
|
|
5
|
-
import { b as C } from "./badgeText-CRzlIzi3.js";
|
|
6
|
-
import { c as u } from "./cx-CcykAxZN.js";
|
|
7
|
-
import './Sidebar.css';const q = "c2r", B = "c2b", D = "c2x", T = "c2g", z = "c2s", F = "c2p", I = "c2h", M = "c2n", R = "c2i", V = "c2a", $ = "c2o", j = "c2l", A = "c2d", G = "c2f", H = "c2q", J = "c2w", K = "c2u", L = "c2k", O = "c2v", l = {
|
|
8
|
-
r: q,
|
|
9
|
-
b: B,
|
|
10
|
-
x: D,
|
|
11
|
-
g: T,
|
|
12
|
-
s: z,
|
|
13
|
-
p: F,
|
|
14
|
-
h: I,
|
|
15
|
-
n: M,
|
|
16
|
-
i: R,
|
|
17
|
-
a: V,
|
|
18
|
-
o: $,
|
|
19
|
-
l: j,
|
|
20
|
-
d: A,
|
|
21
|
-
f: G,
|
|
22
|
-
q: H,
|
|
23
|
-
w: J,
|
|
24
|
-
u: K,
|
|
25
|
-
k: L,
|
|
26
|
-
v: O
|
|
27
|
-
};
|
|
28
|
-
function P({ className: c }) {
|
|
29
|
-
return /* @__PURE__ */ e.createElement("svg", { className: c, viewBox: "0 0 16 16", "aria-hidden": !0 }, /* @__PURE__ */ e.createElement("circle", { cx: "8", cy: "3", r: "1.3", fill: "currentColor" }), /* @__PURE__ */ e.createElement("circle", { cx: "8", cy: "8", r: "1.3", fill: "currentColor" }), /* @__PURE__ */ e.createElement("circle", { cx: "8", cy: "13", r: "1.3", fill: "currentColor" }));
|
|
30
|
-
}
|
|
31
|
-
function Q({
|
|
32
|
-
footer: c,
|
|
33
|
-
className: E,
|
|
34
|
-
...a
|
|
35
|
-
}) {
|
|
36
|
-
const r = /* @__PURE__ */ e.createElement(P, { className: l.k });
|
|
37
|
-
if (e.isValidElement(c) && typeof c.type != "string") {
|
|
38
|
-
const n = c.props;
|
|
39
|
-
return e.cloneElement(c, {
|
|
40
|
-
as: "button",
|
|
41
|
-
extra: n.extra ?? r,
|
|
42
|
-
className: u(n.className, E),
|
|
43
|
-
...a,
|
|
44
|
-
onClick: (i) => {
|
|
45
|
-
var m, t;
|
|
46
|
-
(m = n.onClick) == null || m.call(n, i), (t = a.onClick) == null || t.call(a, i);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
return /* @__PURE__ */ e.createElement("button", { type: "button", className: u(l.u, E), ...a }, /* @__PURE__ */ e.createElement("span", { className: l.w }, c), r);
|
|
51
|
-
}
|
|
52
|
-
function S({
|
|
53
|
-
groups: c,
|
|
54
|
-
items: E,
|
|
55
|
-
value: a,
|
|
56
|
-
onSelect: r,
|
|
57
|
-
variant: n = "cards",
|
|
58
|
-
brand: i,
|
|
59
|
-
extra: m,
|
|
60
|
-
footer: t,
|
|
61
|
-
footerItems: d,
|
|
62
|
-
onFooterSelect: v,
|
|
63
|
-
footerMenuLabel: g = "Меню аккаунта",
|
|
64
|
-
version: p,
|
|
65
|
-
className: k,
|
|
66
|
-
"aria-label": x = "Основное меню"
|
|
67
|
-
}) {
|
|
68
|
-
const f = c ?? E ?? [];
|
|
69
|
-
return /* @__PURE__ */ e.createElement(
|
|
70
|
-
"aside",
|
|
71
|
-
{
|
|
72
|
-
className: u(l.r, n === "plain" && l.p, k),
|
|
73
|
-
"aria-label": x
|
|
74
|
-
},
|
|
75
|
-
i != null || m != null ? /* @__PURE__ */ e.createElement("div", { className: l.b }, i, m != null ? /* @__PURE__ */ e.createElement("div", { className: l.x }, m) : null) : null,
|
|
76
|
-
/* @__PURE__ */ e.createElement("div", { className: l.g }, f.map((o) => /* @__PURE__ */ e.createElement("nav", { key: o.value, className: l.s, "aria-label": o.title ?? "Навигация" }, o.title ? /* @__PURE__ */ e.createElement("div", { className: l.h }, o.title) : null, /* @__PURE__ */ e.createElement("ul", { className: l.n }, (o.items ?? []).map((s) => {
|
|
77
|
-
const b = C(s.badge), N = a === s.value;
|
|
78
|
-
return /* @__PURE__ */ e.createElement("li", { key: s.value }, /* @__PURE__ */ e.createElement(
|
|
79
|
-
y,
|
|
80
|
-
{
|
|
81
|
-
as: "button",
|
|
82
|
-
active: N,
|
|
83
|
-
className: u(l.i, N && l.a),
|
|
84
|
-
"aria-current": N ? "page" : void 0,
|
|
85
|
-
onClick: () => r == null ? void 0 : r(s.value)
|
|
86
|
-
},
|
|
87
|
-
s.icon != null ? /* @__PURE__ */ e.createElement("span", { className: l.o, "aria-hidden": !0 }, s.icon) : null,
|
|
88
|
-
/* @__PURE__ */ e.createElement("span", { className: l.l }, s.label),
|
|
89
|
-
b != null ? /* @__PURE__ */ e.createElement(h, { className: l.d, tone: "accent", size: "s" }, b) : null
|
|
90
|
-
));
|
|
91
|
-
}))))),
|
|
92
|
-
t != null || p != null ? /* @__PURE__ */ e.createElement("div", { className: u(l.s, l.f) }, t != null && d != null && d.length > 0 ? /* @__PURE__ */ e.createElement(
|
|
93
|
-
w,
|
|
94
|
-
{
|
|
95
|
-
className: l.q,
|
|
96
|
-
align: "start",
|
|
97
|
-
placement: "top",
|
|
98
|
-
label: g,
|
|
99
|
-
trigger: /* @__PURE__ */ e.createElement(Q, { footer: t, className: l.w }),
|
|
100
|
-
items: d,
|
|
101
|
-
onSelect: v
|
|
102
|
-
}
|
|
103
|
-
) : t, p != null ? /* @__PURE__ */ e.createElement("div", { className: l.v }, p) : null) : null
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
export {
|
|
107
|
-
S
|
|
108
|
-
};
|