@elcrm/components 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -16
- package/dist/ActionGroup-ChKFW0mt.js +27 -0
- package/dist/ActionGroup.css +1 -0
- package/dist/ActionGroup.d.ts +42 -0
- package/dist/ActionGroup.js +4 -0
- package/dist/Avatar-loGgFt72.js +113 -0
- package/dist/Avatar.css +1 -1
- package/dist/Avatar.d.ts +9 -1
- package/dist/Avatar.js +3 -2
- package/dist/{AvatarGroup-DUe7-T3B.js → AvatarGroup-D1gnT3Od.js} +1 -1
- package/dist/AvatarGroup.js +1 -1
- package/dist/AvatarName-C1sIDPH-.js +66 -0
- package/dist/AvatarName.css +1 -1
- package/dist/AvatarName.d.ts +4 -1
- package/dist/AvatarName.js +1 -1
- package/dist/Badge-jp-9iNNL.js +28 -0
- package/dist/Badge.css +1 -1
- package/dist/Badge.d.ts +32 -17
- package/dist/Badge.js +1 -1
- package/dist/{Block-BAXh0PPp.js → Block-Bu7NEA0g.js} +1 -1
- package/dist/Block.js +1 -1
- package/dist/{Breadcrumb-D0wXkE38.js → Breadcrumb-CAM_e9LN.js} +3 -3
- package/dist/Breadcrumb.css +1 -1
- package/dist/Breadcrumb.js +1 -1
- package/dist/Card.css +1 -1
- package/dist/Card.d.ts +8 -1
- package/dist/{Column-DDaqX-A7.js → Column-BiogBDf8.js} +1 -1
- package/dist/Column.js +1 -1
- package/dist/Dropdown-CQBMF9aR.js +151 -0
- package/dist/Dropdown.css +1 -1
- package/dist/Dropdown.d.ts +3 -3
- package/dist/Dropdown.js +1 -1
- package/dist/Item-D4okhsfW.js +46 -0
- package/dist/Item.css +1 -1
- package/dist/Item.d.ts +8 -1
- package/dist/Item.js +1 -1
- package/dist/ItemColumn-M7a9L8CI.js +41 -0
- package/dist/ItemColumn.css +1 -0
- package/dist/ItemColumn.d.ts +61 -0
- package/dist/ItemColumn.js +4 -0
- package/dist/Layout-BQwEaeO0.js +22 -0
- package/dist/Layout.css +1 -1
- package/dist/Layout.d.ts +10 -5
- package/dist/Layout.js +1 -1
- package/dist/Menu-DpUvOl8Y.js +58 -0
- package/dist/Menu.css +1 -1
- package/dist/Menu.d.ts +15 -3
- package/dist/Menu.js +1 -1
- package/dist/PageHead-DgaJ1mXY.js +31 -0
- package/dist/PageHead.css +1 -1
- package/dist/PageHead.d.ts +28 -6
- package/dist/PageHead.js +1 -1
- package/dist/{PageShell-CghThHS3.js → PageShell-D9EZiO8o.js} +13 -11
- package/dist/PageShell.css +1 -1
- package/dist/PageShell.d.ts +11 -6
- package/dist/PageShell.js +1 -1
- package/dist/Popover-g2xTGubK.js +123 -0
- package/dist/Popover.css +1 -0
- package/dist/Popover.d.ts +54 -0
- package/dist/Popover.js +4 -0
- package/dist/PricingGroup-DgcdVSq8.js +126 -0
- package/dist/PricingGroup.css +1 -1
- package/dist/PricingGroup.js +1 -1
- package/dist/{PricingTable-DYTJG4AU.js → PricingTable-DALddSwM.js} +11 -11
- package/dist/PricingTable.css +1 -1
- package/dist/PricingTable.js +1 -1
- package/dist/{RadioGroup-DxoPHPIF.js → RadioGroup-D2UUOTkY.js} +25 -25
- package/dist/RadioGroup.css +1 -1
- package/dist/RadioGroup.js +1 -1
- package/dist/{Row--HIe6vb9.js → Row-DsQOVn18.js} +1 -1
- package/dist/Row.js +1 -1
- package/dist/Sidebar-DeqxYgxn.js +69 -0
- package/dist/Sidebar.css +1 -0
- package/dist/Sidebar.d.ts +83 -0
- package/dist/Sidebar.js +4 -0
- package/dist/Stack-XkmPSswj.js +53 -0
- package/dist/Stack.css +1 -1
- package/dist/Stack.d.ts +16 -4
- package/dist/Stack.js +3 -2
- package/dist/Stat-C5iZyEoo.js +27 -0
- package/dist/Stat.css +1 -0
- package/dist/Stat.d.ts +39 -0
- package/dist/Stat.js +4 -0
- package/dist/{TabSections-DL7DufKU.js → TabSections-Bf_sZo7b.js} +1 -1
- package/dist/TabSections.js +1 -1
- package/dist/TextGroup-DmhuyMR1.js +23 -0
- package/dist/TextGroup.css +1 -0
- package/dist/TextGroup.d.ts +35 -0
- package/dist/TextGroup.js +4 -0
- package/dist/dark.css +10 -0
- package/dist/index.css +27 -15
- package/dist/index.d.ts +17 -3
- package/dist/index.es.d.ts +73 -0
- package/dist/index.es.js +76 -59
- package/dist/light.css +10 -0
- package/dist/overlayZ.d.ts +9 -0
- package/dist/tokens.css +19 -0
- package/package.json +2 -2
- package/dist/Avatar-Jzan87XD.js +0 -101
- package/dist/AvatarName-KBbQrVta.js +0 -56
- package/dist/Badge-l6nUkl-H.js +0 -22
- package/dist/Dropdown-Cw5LKpcT.js +0 -168
- package/dist/Item-CaU4RW2G.js +0 -38
- package/dist/Layout-Xb3-xsmA.js +0 -18
- package/dist/Menu-DRBHvSdJ.js +0 -40
- package/dist/PageHead-Baz9BLuA.js +0 -22
- package/dist/PricingGroup-CiqQtzjd.js +0 -126
- package/dist/Stack-b0-XWwQ1.js +0 -31
package/dist/Menu.d.ts
CHANGED
|
@@ -19,6 +19,11 @@ export type MenuItem = {
|
|
|
19
19
|
onClick?: () => void;
|
|
20
20
|
/** Недоступный пункт. */
|
|
21
21
|
disabled?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Счётчик справа (`Badge`).
|
|
24
|
+
* `0`, `null`, `""` — не рендерим.
|
|
25
|
+
*/
|
|
26
|
+
badge?: number | string | null;
|
|
22
27
|
};
|
|
23
28
|
/**
|
|
24
29
|
* Props компонента {@link Menu}.
|
|
@@ -34,6 +39,11 @@ export type MenuProps = Omit<React.HTMLAttributes<HTMLElement>, "onSelect"> & {
|
|
|
34
39
|
items?: MenuItem[];
|
|
35
40
|
/** Вертикальный ряд пунктов. */
|
|
36
41
|
vertical?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* `plain` — пилюли.
|
|
44
|
+
* `line` — вкладки с нижней чертой (фильтры страницы).
|
|
45
|
+
*/
|
|
46
|
+
variant?: "plain" | "line";
|
|
37
47
|
/**
|
|
38
48
|
* Активный `value` пункта (если у item не задан `active`).
|
|
39
49
|
* Идентификатор — `value`, не `key`.
|
|
@@ -53,18 +63,20 @@ export type MenuProps = Omit<React.HTMLAttributes<HTMLElement>, "onSelect"> & {
|
|
|
53
63
|
*
|
|
54
64
|
* Связанные компоненты:
|
|
55
65
|
* - {@link Dropdown} — выпадающая панель рядом с триггером;
|
|
56
|
-
* -
|
|
66
|
+
* - {@link Popover} / {@link Dropdown} — панель в portal;
|
|
57
67
|
* - {@link NavSections} / {@link TabSections} — разделы с lazy-контентом.
|
|
58
68
|
*
|
|
59
69
|
* API: декларативные `items` (идентификатор — `value`). Compound-слоты не используются.
|
|
60
70
|
*
|
|
71
|
+
* @param variant `plain` (пилюли) или `line` (черта снизу)
|
|
72
|
+
*
|
|
61
73
|
* CSS-токены: `--shell-*` (цвета/отступы shell-навигации).
|
|
62
74
|
*
|
|
63
75
|
* @example
|
|
64
76
|
* ```tsx
|
|
65
77
|
* const items = [
|
|
66
78
|
* { value: "home", label: "Главная" },
|
|
67
|
-
* { value: "team", label: "Команда",
|
|
79
|
+
* { value: "team", label: "Команда", badge: 3 },
|
|
68
80
|
* ];
|
|
69
81
|
*
|
|
70
82
|
* <Menu
|
|
@@ -75,4 +87,4 @@ export type MenuProps = Omit<React.HTMLAttributes<HTMLElement>, "onSelect"> & {
|
|
|
75
87
|
* />
|
|
76
88
|
* ```
|
|
77
89
|
*/
|
|
78
|
-
export declare function Menu({ items, vertical, value, onSelect, children, className, ...rest }: MenuProps): React.JSX.Element;
|
|
90
|
+
export declare function Menu({ items, vertical, variant, value, onSelect, children, className, ...rest }: MenuProps): React.JSX.Element;
|
package/dist/Menu.js
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import c from "react";
|
|
2
|
+
import { c as o } from "./cx-CcykAxZN.js";
|
|
3
|
+
import './PageHead.css';const u = "ccr", f = "cck", i = "ccw", E = "cct", N = "cch", d = "ccn", h = "ccu", v = "ccs", w = "cca", k = "ccc", e = {
|
|
4
|
+
r: u,
|
|
5
|
+
k: f,
|
|
6
|
+
w: i,
|
|
7
|
+
t: E,
|
|
8
|
+
h: N,
|
|
9
|
+
n: d,
|
|
10
|
+
u: h,
|
|
11
|
+
s: v,
|
|
12
|
+
a: w,
|
|
13
|
+
c: k
|
|
14
|
+
};
|
|
15
|
+
function p(t) {
|
|
16
|
+
return !(t == null || t === !1 || t === "" || typeof t == "number" && t === 0 || t === "0");
|
|
17
|
+
}
|
|
18
|
+
function g({
|
|
19
|
+
title: t,
|
|
20
|
+
sup: n,
|
|
21
|
+
subtitle: a,
|
|
22
|
+
actions: l,
|
|
23
|
+
sticky: r,
|
|
24
|
+
className: m,
|
|
25
|
+
children: s
|
|
26
|
+
}) {
|
|
27
|
+
return /* @__PURE__ */ c.createElement("div", { className: o(e.r, r && e.k, m) }, /* @__PURE__ */ c.createElement("div", { className: e.w }, /* @__PURE__ */ c.createElement("div", { className: e.t }, /* @__PURE__ */ c.createElement("h1", { className: e.h }, /* @__PURE__ */ c.createElement("span", { className: e.n }, t), p(n) ? /* @__PURE__ */ c.createElement("span", { className: e.u }, n) : null), a != null ? /* @__PURE__ */ c.createElement("p", { className: e.s }, a) : null), l != null ? /* @__PURE__ */ c.createElement("div", { className: e.a }, l) : null), s != null ? /* @__PURE__ */ c.createElement("div", { className: e.c }, s) : null);
|
|
28
|
+
}
|
|
29
|
+
export {
|
|
30
|
+
g as P
|
|
31
|
+
};
|
package/dist/PageHead.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer elcrm-components{.ccr{margin:0 0 var(--shell-gap-
|
|
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, var(--shell-background-muted))}.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}}
|
package/dist/PageHead.d.ts
CHANGED
|
@@ -8,8 +8,10 @@ import { default as React } from 'react';
|
|
|
8
8
|
*
|
|
9
9
|
* @example
|
|
10
10
|
* ```tsx
|
|
11
|
-
* <PageShell>
|
|
12
|
-
* <PageHead title="
|
|
11
|
+
* <PageShell scroll>
|
|
12
|
+
* <PageHead title="Идеи" sup={<Badge size="s" tone="accent">4</Badge>} sticky>
|
|
13
|
+
* <Menu items={tabs} value={tab} onSelect={setTab} />
|
|
14
|
+
* </PageHead>
|
|
13
15
|
* …
|
|
14
16
|
* </PageShell>
|
|
15
17
|
* ```
|
|
@@ -19,18 +21,38 @@ import { default as React } from 'react';
|
|
|
19
21
|
export type PageHeadProps = {
|
|
20
22
|
/** Заголовок страницы */
|
|
21
23
|
title: React.ReactNode;
|
|
24
|
+
/**
|
|
25
|
+
* Надстрочный слот сразу после title: текст или {@link Badge}.
|
|
26
|
+
* Пусто / `0` / `false` — не рендерим.
|
|
27
|
+
*/
|
|
28
|
+
sup?: React.ReactNode;
|
|
22
29
|
/** Подзаголовок */
|
|
23
30
|
subtitle?: React.ReactNode;
|
|
24
31
|
/** Кнопки / поиск справа в одной строке с заголовком */
|
|
25
32
|
actions?: React.ReactNode;
|
|
33
|
+
/**
|
|
34
|
+
* Прилипает к верху скролла предка (`PageShell` с `scroll`).
|
|
35
|
+
* По умолчанию `false`.
|
|
36
|
+
*/
|
|
37
|
+
sticky?: boolean;
|
|
26
38
|
/** Доп. CSS-класс */
|
|
27
39
|
className?: string;
|
|
28
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Контент под строкой заголовка (фильтры, поиск, вкладки).
|
|
42
|
+
* Между title и children — `--shell-gap`.
|
|
43
|
+
*/
|
|
29
44
|
children?: React.ReactNode;
|
|
30
45
|
};
|
|
31
46
|
/**
|
|
32
|
-
* Заголовок: title
|
|
47
|
+
* Заголовок: title слева (+ `sup` сверху), actions справа.
|
|
33
48
|
*
|
|
34
|
-
* @
|
|
49
|
+
* @param props.title — заголовок
|
|
50
|
+
* @param props.sup — текст или Badge после title (надстрочно)
|
|
51
|
+
* @param props.subtitle — строка под заголовком
|
|
52
|
+
* @param props.actions — кнопки справа
|
|
53
|
+
* @param props.sticky — прилипает к скроллу
|
|
54
|
+
* @param props.children — фильтры / вкладки под шапкой
|
|
55
|
+
*
|
|
56
|
+
* @see PageShell, Section, Header, Badge
|
|
35
57
|
*/
|
|
36
|
-
export declare function PageHead({ title, subtitle, actions, className, children, }: PageHeadProps): React.JSX.Element;
|
|
58
|
+
export declare function PageHead({ title, sup, subtitle, actions, sticky, className, children, }: PageHeadProps): React.JSX.Element;
|
package/dist/PageHead.js
CHANGED
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
import e from "react";
|
|
2
2
|
import { c as l } from "./cx-CcykAxZN.js";
|
|
3
|
-
import './PageShell.css';const m = "ckr",
|
|
3
|
+
import './PageShell.css';const m = "ckr", f = "ckw", i = "ckb", k = "ckf", u = "cko", c = {
|
|
4
4
|
r: m,
|
|
5
|
-
w:
|
|
6
|
-
b:
|
|
7
|
-
f:
|
|
5
|
+
w: f,
|
|
6
|
+
b: i,
|
|
7
|
+
f: k,
|
|
8
|
+
o: u
|
|
8
9
|
};
|
|
9
|
-
function
|
|
10
|
+
function d({
|
|
10
11
|
children: s,
|
|
11
|
-
className:
|
|
12
|
-
wide:
|
|
12
|
+
className: n,
|
|
13
|
+
wide: o,
|
|
14
|
+
scroll: r = !0,
|
|
13
15
|
footer: t,
|
|
14
|
-
...
|
|
16
|
+
...a
|
|
15
17
|
}) {
|
|
16
18
|
return /* @__PURE__ */ e.createElement(
|
|
17
19
|
"div",
|
|
18
20
|
{
|
|
19
|
-
...
|
|
20
|
-
className: l(c.r,
|
|
21
|
+
...a,
|
|
22
|
+
className: l(c.r, o && c.w, !r && c.o, n)
|
|
21
23
|
},
|
|
22
24
|
/* @__PURE__ */ e.createElement("div", { className: c.b }, s),
|
|
23
25
|
t != null ? /* @__PURE__ */ e.createElement("div", { className: c.f }, t) : null
|
|
24
26
|
);
|
|
25
27
|
}
|
|
26
28
|
export {
|
|
27
|
-
|
|
29
|
+
d as P
|
|
28
30
|
};
|
package/dist/PageShell.css
CHANGED
|
@@ -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)}}
|
|
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}}
|
package/dist/PageShell.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
2
|
/**
|
|
3
|
-
* Каркас модуля: скролл в body,
|
|
3
|
+
* Каркас модуля: опциональный скролл в body, footer прибит к низу.
|
|
4
4
|
*
|
|
5
5
|
* Роли: PageShell = внутренний каркас контента в Layout;
|
|
6
6
|
* сверху часто PageHead / Section, снизу — панель действий.
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* ```tsx
|
|
10
|
-
* <PageShell wide footer={<Footer><Button>Сохранить</Button></Footer>}>
|
|
11
|
-
* <PageHead title="Редактор" />
|
|
10
|
+
* <PageShell wide scroll footer={<Footer><Button>Сохранить</Button></Footer>}>
|
|
11
|
+
* <PageHead title="Редактор" sticky />
|
|
12
12
|
* …
|
|
13
13
|
* </PageShell>
|
|
14
14
|
* ```
|
|
@@ -16,18 +16,23 @@ import { default as React } from 'react';
|
|
|
16
16
|
* Токены: `--shell-*`.
|
|
17
17
|
*/
|
|
18
18
|
export type PageShellProps = {
|
|
19
|
-
/** Контент модуля
|
|
19
|
+
/** Контент модуля */
|
|
20
20
|
children: React.ReactNode;
|
|
21
21
|
/** Доп. CSS-класс */
|
|
22
22
|
className?: string;
|
|
23
23
|
/** Шире контент (редакторы, таблицы) */
|
|
24
24
|
wide?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Скролл внутри body. По умолчанию `true`.
|
|
27
|
+
* `false` — шелл растёт с контентом, крутит предок.
|
|
28
|
+
*/
|
|
29
|
+
scroll?: boolean;
|
|
25
30
|
/** Нижняя панель вне скролла */
|
|
26
31
|
footer?: React.ReactNode;
|
|
27
32
|
} & Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "className">;
|
|
28
33
|
/**
|
|
29
|
-
* Каркас модуля: скролл в body, footer прибит к низу.
|
|
34
|
+
* Каркас модуля: скролл в body (если `scroll`), footer прибит к низу.
|
|
30
35
|
*
|
|
31
36
|
* @see PageHead, Layout, Section, Footer
|
|
32
37
|
*/
|
|
33
|
-
export declare function PageShell({ children, className, wide, footer, ...rootProps }: PageShellProps): React.JSX.Element;
|
|
38
|
+
export declare function PageShell({ children, className, wide, scroll, footer, ...rootProps }: PageShellProps): React.JSX.Element;
|
package/dist/PageShell.js
CHANGED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import w, { useRef as h, useId as Q, useState as x, useLayoutEffect as S, useEffect as W } from "react";
|
|
2
|
+
import { createPortal as V } from "react-dom";
|
|
3
|
+
import { c as H } from "./cx-CcykAxZN.js";
|
|
4
|
+
import './Popover.css';const N = 1e3, X = 10;
|
|
5
|
+
function E() {
|
|
6
|
+
const e = globalThis;
|
|
7
|
+
return e.elcrm || (e.elcrm = {}), e.elcrm.overlayZ || (e.elcrm.overlayZ = { seq: 0, active: /* @__PURE__ */ new Set() }), e.elcrm.overlayZ;
|
|
8
|
+
}
|
|
9
|
+
function Y() {
|
|
10
|
+
const e = E();
|
|
11
|
+
e.seq += 1;
|
|
12
|
+
const r = N + e.seq * X;
|
|
13
|
+
return e.active.add(r), r;
|
|
14
|
+
}
|
|
15
|
+
function B(e) {
|
|
16
|
+
const r = E();
|
|
17
|
+
r.active.delete(e), r.active.size === 0 && (r.seq = 0);
|
|
18
|
+
}
|
|
19
|
+
function oe() {
|
|
20
|
+
const e = E();
|
|
21
|
+
return e.active.size === 0 ? N : Math.max(...e.active);
|
|
22
|
+
}
|
|
23
|
+
const _ = "c3r", $ = "c3t", C = "c3p", y = {
|
|
24
|
+
r: _,
|
|
25
|
+
t: $,
|
|
26
|
+
p: C
|
|
27
|
+
};
|
|
28
|
+
function re({
|
|
29
|
+
trigger: e,
|
|
30
|
+
children: r,
|
|
31
|
+
open: L,
|
|
32
|
+
defaultOpen: D = !1,
|
|
33
|
+
onOpenChange: m,
|
|
34
|
+
align: M = "end",
|
|
35
|
+
disabled: g = !1,
|
|
36
|
+
label: O,
|
|
37
|
+
role: T = "menu",
|
|
38
|
+
className: A,
|
|
39
|
+
panelClassName: F
|
|
40
|
+
}) {
|
|
41
|
+
const f = h(null), z = h(null), R = Q(), [K, U] = x(D), Z = L !== void 0, n = Z ? L : K, [c, I] = x(null), [i, P] = x(null), p = h(null);
|
|
42
|
+
p.current = i;
|
|
43
|
+
const v = (t) => {
|
|
44
|
+
g && t || (Z || U(t), m == null || m(t));
|
|
45
|
+
};
|
|
46
|
+
S(() => {
|
|
47
|
+
if (n) {
|
|
48
|
+
i == null && P(Y());
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
i != null && (B(i), P(null));
|
|
52
|
+
}, [n, i]), W(() => () => {
|
|
53
|
+
p.current != null && B(p.current);
|
|
54
|
+
}, []);
|
|
55
|
+
const b = () => {
|
|
56
|
+
const t = f.current;
|
|
57
|
+
if (!t) return;
|
|
58
|
+
const o = t.getBoundingClientRect(), s = 8, a = window.innerHeight - o.bottom - s - 8, l = o.top - s - 8, u = a >= 160 || a >= l, q = Math.min(420, Math.max(120, u ? a : l)), d = Math.max(200, o.width), G = u ? o.bottom + s : Math.max(8, o.top - s - q), J = M === "end" ? Math.max(8, Math.min(o.right - d, window.innerWidth - d - 8)) : Math.max(8, Math.min(o.left, window.innerWidth - d - 8));
|
|
59
|
+
I({ top: G, left: J, minWidth: d, maxHeight: q });
|
|
60
|
+
};
|
|
61
|
+
S(() => {
|
|
62
|
+
if (!n) {
|
|
63
|
+
I(null);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
b();
|
|
67
|
+
const t = () => b();
|
|
68
|
+
return window.addEventListener("resize", t), window.addEventListener("scroll", t, !0), () => {
|
|
69
|
+
window.removeEventListener("resize", t), window.removeEventListener("scroll", t, !0);
|
|
70
|
+
};
|
|
71
|
+
}, [n, M]), W(() => {
|
|
72
|
+
if (!n) return;
|
|
73
|
+
const t = (s) => {
|
|
74
|
+
var l, u;
|
|
75
|
+
const a = s.target;
|
|
76
|
+
(l = f.current) != null && l.contains(a) || (u = z.current) != null && u.contains(a) || v(!1);
|
|
77
|
+
}, o = (s) => {
|
|
78
|
+
s.key === "Escape" && v(!1);
|
|
79
|
+
};
|
|
80
|
+
return document.addEventListener("mousedown", t), document.addEventListener("keydown", o), () => {
|
|
81
|
+
document.removeEventListener("mousedown", t), document.removeEventListener("keydown", o);
|
|
82
|
+
};
|
|
83
|
+
}, [n]);
|
|
84
|
+
const j = c ? {
|
|
85
|
+
position: "fixed",
|
|
86
|
+
top: c.top,
|
|
87
|
+
left: c.left,
|
|
88
|
+
minWidth: c.minWidth,
|
|
89
|
+
maxHeight: c.maxHeight,
|
|
90
|
+
zIndex: i ?? 1e3
|
|
91
|
+
} : void 0, k = n && c ? /* @__PURE__ */ w.createElement(
|
|
92
|
+
"div",
|
|
93
|
+
{
|
|
94
|
+
ref: z,
|
|
95
|
+
id: R,
|
|
96
|
+
role: T,
|
|
97
|
+
"aria-label": O,
|
|
98
|
+
className: H(y.p, F),
|
|
99
|
+
style: j,
|
|
100
|
+
onMouseDown: (t) => t.stopPropagation()
|
|
101
|
+
},
|
|
102
|
+
r
|
|
103
|
+
) : null;
|
|
104
|
+
return /* @__PURE__ */ w.createElement("div", { ref: f, className: H(y.r, A) }, /* @__PURE__ */ w.createElement(
|
|
105
|
+
"div",
|
|
106
|
+
{
|
|
107
|
+
className: y.t,
|
|
108
|
+
"aria-haspopup": "menu",
|
|
109
|
+
"aria-expanded": n,
|
|
110
|
+
"aria-controls": n ? R : void 0,
|
|
111
|
+
onClick: () => {
|
|
112
|
+
g || v(!n);
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
e
|
|
116
|
+
), k && typeof document < "u" ? V(k, document.body) : null);
|
|
117
|
+
}
|
|
118
|
+
export {
|
|
119
|
+
re as P,
|
|
120
|
+
Y as a,
|
|
121
|
+
oe as p,
|
|
122
|
+
B as r
|
|
123
|
+
};
|
package/dist/Popover.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer elcrm-components{.c3r{position:relative;display:inline-flex;vertical-align:middle}.c3t{display:inline-flex;align-items:center;min-width:0}.c3p{box-sizing:border-box;overflow:auto;padding:var(--shell-gap-sm);background:var(--shell-background);border:1px solid var(--shell-border);border-radius:var(--shell-radius);box-shadow:var(--popup-shadow);color:var(--shell-color);min-width:var(--dropdown-min-width, 200px);max-width:var(--dropdown-max-width, min(360px, calc(100vw - 16px) ));max-height:var(--dropdown-max-height, 420px)}}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Портал у якоря: Escape, клик снаружи, z-index (`globalThis.elcrm.overlayZ`).
|
|
4
|
+
*
|
|
5
|
+
* Роли: Popover = свой попап (слот `children`).
|
|
6
|
+
* Типовое меню пунктов — {@link Dropdown}.
|
|
7
|
+
* Инлайн-навигация — {@link Menu} (не путать).
|
|
8
|
+
*
|
|
9
|
+
* Бывший `@elcrm/overlay` `Menu` — этот компонент (`Popover`).
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <Popover
|
|
14
|
+
* trigger={<Button>Ещё</Button>}
|
|
15
|
+
* label="Действия"
|
|
16
|
+
* align="end"
|
|
17
|
+
* >
|
|
18
|
+
* <List>
|
|
19
|
+
* <Item as="button">Скачать</Item>
|
|
20
|
+
* </List>
|
|
21
|
+
* </Popover>
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* Токены: `--shell-*`, `--popup-shadow`, `--dropdown-min-width`.
|
|
25
|
+
*/
|
|
26
|
+
export type PopoverProps = {
|
|
27
|
+
/** Якорь (кнопка / иконка) */
|
|
28
|
+
trigger: React.ReactNode;
|
|
29
|
+
/** Содержимое панели */
|
|
30
|
+
children?: React.ReactNode;
|
|
31
|
+
/** Контролируемое открытие */
|
|
32
|
+
open?: boolean;
|
|
33
|
+
/** Начальное открытие */
|
|
34
|
+
defaultOpen?: boolean;
|
|
35
|
+
/** Смена open */
|
|
36
|
+
onOpenChange?: (open: boolean) => void;
|
|
37
|
+
/** Выравнивание панели */
|
|
38
|
+
align?: "start" | "end";
|
|
39
|
+
/** Не открывать по клику на якорь */
|
|
40
|
+
disabled?: boolean;
|
|
41
|
+
/** aria-label панели */
|
|
42
|
+
label?: string;
|
|
43
|
+
/** role панели */
|
|
44
|
+
role?: React.AriaRole;
|
|
45
|
+
className?: string;
|
|
46
|
+
/** Класс панели (portal) */
|
|
47
|
+
panelClassName?: string;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Панель в portal рядом с триггером.
|
|
51
|
+
*
|
|
52
|
+
* @see Dropdown, Menu
|
|
53
|
+
*/
|
|
54
|
+
export declare function Popover({ trigger, children, open: openProp, defaultOpen, onOpenChange, align, disabled, label, role, className, panelClassName, }: PopoverProps): React.JSX.Element;
|
package/dist/Popover.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import e from "react";
|
|
2
|
+
import { c as i } from "./cx-CcykAxZN.js";
|
|
3
|
+
import './PricingGroup.css';const z = "cur", O = "cui", j = "cus", M = "cub", R = "cug", A = "cua", G = "cum", I = "cuh", K = "cut", T = "cup", U = "cuz", W = "cuo", $ = "cue", q = "cud", C = "cux", H = "cuf", J = "cuy", Q = "cul", X = "cuu", Y = "cun", Z = "cuc", _ = "cuk", V = "cuw", c = {
|
|
4
|
+
r: z,
|
|
5
|
+
i: O,
|
|
6
|
+
s: j,
|
|
7
|
+
b: M,
|
|
8
|
+
g: R,
|
|
9
|
+
a: A,
|
|
10
|
+
m: G,
|
|
11
|
+
h: I,
|
|
12
|
+
t: K,
|
|
13
|
+
p: T,
|
|
14
|
+
z: U,
|
|
15
|
+
o: W,
|
|
16
|
+
e: $,
|
|
17
|
+
d: q,
|
|
18
|
+
x: C,
|
|
19
|
+
f: H,
|
|
20
|
+
y: J,
|
|
21
|
+
l: Q,
|
|
22
|
+
u: X,
|
|
23
|
+
n: Y,
|
|
24
|
+
c: Z,
|
|
25
|
+
k: _,
|
|
26
|
+
w: V
|
|
27
|
+
};
|
|
28
|
+
function N() {
|
|
29
|
+
return /* @__PURE__ */ e.createElement("span", { className: c.k, "aria-hidden": !0 }, /* @__PURE__ */ e.createElement("svg", { className: c.w, viewBox: "0 0 12 12" }, /* @__PURE__ */ e.createElement(
|
|
30
|
+
"path",
|
|
31
|
+
{
|
|
32
|
+
d: "M2.5 6.2 4.8 8.5 9.5 3.5",
|
|
33
|
+
fill: "none",
|
|
34
|
+
stroke: "currentColor",
|
|
35
|
+
strokeWidth: "1.8",
|
|
36
|
+
strokeLinecap: "round",
|
|
37
|
+
strokeLinejoin: "round"
|
|
38
|
+
}
|
|
39
|
+
)));
|
|
40
|
+
}
|
|
41
|
+
function ee({ feature: l }) {
|
|
42
|
+
if (l != null && typeof l == "object" && !e.isValidElement(l) && "label" in l) {
|
|
43
|
+
const t = l;
|
|
44
|
+
return /* @__PURE__ */ e.createElement("li", { className: c.c }, t.icon != null ? t.icon : /* @__PURE__ */ e.createElement(N, null), /* @__PURE__ */ e.createElement("span", null, t.label));
|
|
45
|
+
}
|
|
46
|
+
return /* @__PURE__ */ e.createElement("li", { className: c.c }, /* @__PURE__ */ e.createElement(N, null), /* @__PURE__ */ e.createElement("span", null, l));
|
|
47
|
+
}
|
|
48
|
+
function h({ item: l }) {
|
|
49
|
+
const t = l.badge != null && (l.badgePlacement ?? "pill") === "pill";
|
|
50
|
+
return l.title == null && !t ? null : /* @__PURE__ */ e.createElement("div", { className: c.h }, l.title != null ? /* @__PURE__ */ e.createElement("h3", { className: c.t }, l.title) : null, t ? /* @__PURE__ */ e.createElement("span", { className: c.g }, l.badge) : null);
|
|
51
|
+
}
|
|
52
|
+
function k({ item: l }) {
|
|
53
|
+
return l.price == null && l.priceOld == null && l.meta == null ? null : /* @__PURE__ */ e.createElement("div", { className: c.p }, l.priceOld != null ? /* @__PURE__ */ e.createElement("span", { className: c.o }, l.priceOld) : null, l.price != null ? /* @__PURE__ */ e.createElement("span", { className: c.z }, l.price) : null, l.meta != null ? /* @__PURE__ */ e.createElement("span", { className: c.e }, l.meta) : null);
|
|
54
|
+
}
|
|
55
|
+
function d({ item: l }) {
|
|
56
|
+
return l.description == null ? null : /* @__PURE__ */ e.createElement("p", { className: c.d }, l.description);
|
|
57
|
+
}
|
|
58
|
+
function le({
|
|
59
|
+
actions: l,
|
|
60
|
+
placement: t
|
|
61
|
+
}) {
|
|
62
|
+
return /* @__PURE__ */ e.createElement(
|
|
63
|
+
"div",
|
|
64
|
+
{
|
|
65
|
+
className: t === "footer" ? c.f : c.x,
|
|
66
|
+
onClick: (a) => a.stopPropagation(),
|
|
67
|
+
onMouseDown: (a) => a.preventDefault()
|
|
68
|
+
},
|
|
69
|
+
l
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
function ne({ item: l }) {
|
|
73
|
+
return l.features == null && l.featuresLabel == null && l.featuresSummary == null ? null : /* @__PURE__ */ e.createElement("div", { className: c.y }, l.featuresLabel != null ? /* @__PURE__ */ e.createElement("p", { className: c.l }, l.featuresLabel) : null, l.featuresSummary != null ? /* @__PURE__ */ e.createElement("p", { className: c.u }, l.featuresSummary) : null, l.features != null && l.features.length > 0 ? /* @__PURE__ */ e.createElement("ul", { className: c.n }, l.features.map((t, a) => /* @__PURE__ */ e.createElement(ee, { key: a, feature: t }))) : null);
|
|
74
|
+
}
|
|
75
|
+
function ae({
|
|
76
|
+
items: l,
|
|
77
|
+
value: t,
|
|
78
|
+
defaultValue: a,
|
|
79
|
+
selectable: y = !1,
|
|
80
|
+
disabled: P = !1,
|
|
81
|
+
onValueChange: u,
|
|
82
|
+
className: w,
|
|
83
|
+
...x
|
|
84
|
+
}) {
|
|
85
|
+
const [B, D] = e.useState(a), m = t !== void 0, F = m ? t : B, f = (n) => {
|
|
86
|
+
m || D(n), u == null || u(n);
|
|
87
|
+
};
|
|
88
|
+
return /* @__PURE__ */ e.createElement("div", { className: i(c.r, w), role: "list", ...x }, l.map((n) => {
|
|
89
|
+
const p = F === n.value, E = P || !!n.disabled, L = !!n.highlighted || p, b = n.badgePlacement ?? "pill", r = n.actionsPlacement ?? "after", g = n.descriptionPlacement ?? "after-price", s = y && !E, v = n.actions != null ? /* @__PURE__ */ e.createElement(
|
|
90
|
+
le,
|
|
91
|
+
{
|
|
92
|
+
actions: n.actions,
|
|
93
|
+
placement: r
|
|
94
|
+
}
|
|
95
|
+
) : null, S = /* @__PURE__ */ e.createElement(e.Fragment, null, n.priceFirst ? /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(k, { item: n }), /* @__PURE__ */ e.createElement(h, { item: n }), /* @__PURE__ */ e.createElement(d, { item: n })) : /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement(h, { item: n }), g === "before-price" ? /* @__PURE__ */ e.createElement(d, { item: n }) : null, /* @__PURE__ */ e.createElement(k, { item: n }), g === "after-price" ? /* @__PURE__ */ e.createElement(d, { item: n }) : null));
|
|
96
|
+
return /* @__PURE__ */ e.createElement(
|
|
97
|
+
"div",
|
|
98
|
+
{
|
|
99
|
+
key: n.value,
|
|
100
|
+
role: "listitem",
|
|
101
|
+
className: i(c.i, L && c.s),
|
|
102
|
+
"data-selected": p ? "true" : void 0,
|
|
103
|
+
"data-highlighted": n.highlighted ? "true" : void 0,
|
|
104
|
+
"data-selectable": s ? "true" : void 0,
|
|
105
|
+
"aria-disabled": E || void 0,
|
|
106
|
+
tabIndex: s ? 0 : void 0,
|
|
107
|
+
onClick: () => {
|
|
108
|
+
s && f(n.value);
|
|
109
|
+
},
|
|
110
|
+
onKeyDown: (o) => {
|
|
111
|
+
s && (o.key === "Enter" || o.key === " ") && (o.preventDefault(), f(n.value));
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
n.badge != null && b === "banner" ? /* @__PURE__ */ e.createElement("div", { className: c.b }, n.badge) : null,
|
|
115
|
+
n.badge != null && b === "float" ? /* @__PURE__ */ e.createElement("div", { className: i(c.g, c.a) }, n.badge) : null,
|
|
116
|
+
n.icon != null ? /* @__PURE__ */ e.createElement("div", { className: c.m }, n.icon) : null,
|
|
117
|
+
S,
|
|
118
|
+
r === "before" ? v : null,
|
|
119
|
+
/* @__PURE__ */ e.createElement(ne, { item: n }),
|
|
120
|
+
r === "after" || r === "footer" ? v : null
|
|
121
|
+
);
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
export {
|
|
125
|
+
ae as P
|
|
126
|
+
};
|
package/dist/PricingGroup.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer elcrm-components{.cur{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--pricing-card-min-width),1fr));gap:var(--shell-gap-lg);align-items:stretch}.cui{position:relative;display:flex;flex-direction:column;gap:var(--shell-gap);padding:var(--shell-padding);box-sizing:border-box;text-align:left;font:inherit;color:var(--shell-color);background:var(--shell-background);border:1px solid var(--shell-border);border-radius:var(--shell-radius);box-shadow:var(--shell-shadow)}.cui[data-selectable=true]{cursor:pointer}.cui:disabled,.cui[aria-disabled=true]{opacity:var(--shell-disabled-opacity);cursor:not-allowed}.cus,.cui[data-selected=true],.cui[data-highlighted=true]{border-color:var(--shell-color-accent);background:var(--shell-background-selected);box-shadow:var(--shell-shadow)}.cub{display:flex;align-items:center;justify-content:center;margin:calc(-1 * var(--shell-padding-block)) calc(-1 * var(--shell-padding-inline)) 0;padding:var(--shell-gap-sm) var(--shell-padding-inline);border-radius:var(--shell-radius) var(--shell-radius) 0 0;background:var(--shell-color-accent);color:#fff;font-size:var(--shell-font-size-sm);font-weight:var(--shell-font-weight);text-align:center}.cug{display:inline-flex;align-items:center;width:fit-content;padding:.15rem .5rem;border-radius:999px;background:var(--shell-background-hover);color:var(--shell-color-accent);font-size:var(--shell-font-size-sm);font-weight:var(--shell-font-weight);line-height:1.2}.
|
|
1
|
+
@layer elcrm-components{.cur{display:grid;grid-template-columns:repeat(auto-fit,minmax(var(--pricing-card-min-width),1fr));gap:var(--shell-gap-lg);align-items:stretch}.cui{position:relative;display:flex;flex-direction:column;gap:var(--shell-gap);padding:var(--shell-padding);box-sizing:border-box;text-align:left;font:inherit;color:var(--shell-color);background:var(--shell-background);border:1px solid var(--shell-border);border-radius:var(--shell-radius);box-shadow:var(--shell-shadow)}.cui[data-selectable=true]{cursor:pointer}.cui:disabled,.cui[aria-disabled=true]{opacity:var(--shell-disabled-opacity);cursor:not-allowed}.cus,.cui[data-selected=true],.cui[data-highlighted=true]{border-color:var(--shell-color-accent);background:var(--shell-background-selected);box-shadow:var(--shell-shadow)}.cub{display:flex;align-items:center;justify-content:center;margin:calc(-1 * var(--shell-padding-block)) calc(-1 * var(--shell-padding-inline)) 0;padding:var(--shell-gap-sm) var(--shell-padding-inline);border-radius:var(--shell-radius) var(--shell-radius) 0 0;background:var(--shell-color-accent);color:#fff;font-size:var(--shell-font-size-sm);font-weight:var(--shell-font-weight);text-align:center}.cug{display:inline-flex;align-items:center;width:fit-content;padding:.15rem .5rem;border-radius:999px;background:var(--shell-background-hover);color:var(--shell-color-accent);font-size:var(--shell-font-size-sm);font-weight:var(--shell-font-weight);line-height:1.2}.cua{position:absolute;top:0;left:50%;transform:translate(-50%,-50%)}.cum{display:flex;flex-shrink:0;align-items:center;justify-content:center;width:calc(var(--shell-icon-size) * 1.6);height:calc(var(--shell-icon-size) * 1.6);color:var(--shell-color-accent);background:var(--shell-background-hover);border-radius:50%;overflow:hidden}.cuh{display:flex;flex-wrap:wrap;align-items:center;gap:var(--shell-gap-sm)}.cut{margin:0;font-size:var(--shell-font-size);font-weight:var(--shell-font-weight);color:var(--shell-color);line-height:1.3}.cup{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--shell-gap-sm)}.cuz{font-size:calc(var(--shell-font-size-lg) * 1.35);font-weight:700;color:var(--shell-color);line-height:1.15}.cui[data-highlighted=true] .cuz,.cui[data-selected=true] .cuz{color:var(--shell-color-accent)}.cuo{font-size:var(--shell-font-size-sm);color:var(--shell-color-muted);text-decoration:line-through}.cue{font-size:var(--shell-font-size-sm);color:var(--shell-color-muted)}.cud{margin:0;font-size:var(--shell-font-size-sm);color:var(--shell-color-muted);line-height:1.45}.cux{display:flex;flex-direction:column;gap:var(--shell-gap-sm)}.cuf{display:flex;flex-direction:column;gap:var(--shell-gap-sm);margin:auto calc(-1 * var(--shell-padding-inline)) calc(-1 * var(--shell-padding-block));padding:var(--shell-padding);background:var(--shell-background-muted);border-top:1px solid var(--shell-border);border-radius:0 0 var(--shell-radius) var(--shell-radius)}.cuy{display:flex;flex-direction:column;gap:var(--shell-gap-sm);margin-top:auto}.cul{margin:0;font-size:var(--shell-font-size-sm);font-weight:var(--shell-font-weight);letter-spacing:.04em;text-transform:uppercase;color:var(--shell-color-muted)}.cuu{margin:0;font-size:var(--shell-font-size-sm);color:var(--shell-color-muted);line-height:1.4}.cun{display:flex;flex-direction:column;gap:var(--shell-gap-sm);margin:0;padding:0;list-style:none}.cuc{display:flex;align-items:flex-start;gap:var(--shell-gap-sm);font-size:var(--shell-font-size-sm);color:var(--shell-color);line-height:1.4}.cuk{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:var(--shell-check-size);height:var(--shell-check-size);margin-top:.1em;color:#fff;background:var(--shell-color-success);border-radius:50%}.cuw{width:60%;height:60%;display:block}}
|
package/dist/PricingGroup.js
CHANGED