@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.
Files changed (108) hide show
  1. package/README.md +66 -16
  2. package/dist/ActionGroup-ChKFW0mt.js +27 -0
  3. package/dist/ActionGroup.css +1 -0
  4. package/dist/ActionGroup.d.ts +42 -0
  5. package/dist/ActionGroup.js +4 -0
  6. package/dist/Avatar-loGgFt72.js +113 -0
  7. package/dist/Avatar.css +1 -1
  8. package/dist/Avatar.d.ts +9 -1
  9. package/dist/Avatar.js +3 -2
  10. package/dist/{AvatarGroup-DUe7-T3B.js → AvatarGroup-D1gnT3Od.js} +1 -1
  11. package/dist/AvatarGroup.js +1 -1
  12. package/dist/AvatarName-C1sIDPH-.js +66 -0
  13. package/dist/AvatarName.css +1 -1
  14. package/dist/AvatarName.d.ts +4 -1
  15. package/dist/AvatarName.js +1 -1
  16. package/dist/Badge-jp-9iNNL.js +28 -0
  17. package/dist/Badge.css +1 -1
  18. package/dist/Badge.d.ts +32 -17
  19. package/dist/Badge.js +1 -1
  20. package/dist/{Block-BAXh0PPp.js → Block-Bu7NEA0g.js} +1 -1
  21. package/dist/Block.js +1 -1
  22. package/dist/{Breadcrumb-D0wXkE38.js → Breadcrumb-CAM_e9LN.js} +3 -3
  23. package/dist/Breadcrumb.css +1 -1
  24. package/dist/Breadcrumb.js +1 -1
  25. package/dist/Card.css +1 -1
  26. package/dist/Card.d.ts +8 -1
  27. package/dist/{Column-DDaqX-A7.js → Column-BiogBDf8.js} +1 -1
  28. package/dist/Column.js +1 -1
  29. package/dist/Dropdown-CQBMF9aR.js +151 -0
  30. package/dist/Dropdown.css +1 -1
  31. package/dist/Dropdown.d.ts +3 -3
  32. package/dist/Dropdown.js +1 -1
  33. package/dist/Item-D4okhsfW.js +46 -0
  34. package/dist/Item.css +1 -1
  35. package/dist/Item.d.ts +8 -1
  36. package/dist/Item.js +1 -1
  37. package/dist/ItemColumn-M7a9L8CI.js +41 -0
  38. package/dist/ItemColumn.css +1 -0
  39. package/dist/ItemColumn.d.ts +61 -0
  40. package/dist/ItemColumn.js +4 -0
  41. package/dist/Layout-BQwEaeO0.js +22 -0
  42. package/dist/Layout.css +1 -1
  43. package/dist/Layout.d.ts +10 -5
  44. package/dist/Layout.js +1 -1
  45. package/dist/Menu-DpUvOl8Y.js +58 -0
  46. package/dist/Menu.css +1 -1
  47. package/dist/Menu.d.ts +15 -3
  48. package/dist/Menu.js +1 -1
  49. package/dist/PageHead-DgaJ1mXY.js +31 -0
  50. package/dist/PageHead.css +1 -1
  51. package/dist/PageHead.d.ts +28 -6
  52. package/dist/PageHead.js +1 -1
  53. package/dist/{PageShell-CghThHS3.js → PageShell-D9EZiO8o.js} +13 -11
  54. package/dist/PageShell.css +1 -1
  55. package/dist/PageShell.d.ts +11 -6
  56. package/dist/PageShell.js +1 -1
  57. package/dist/Popover-g2xTGubK.js +123 -0
  58. package/dist/Popover.css +1 -0
  59. package/dist/Popover.d.ts +54 -0
  60. package/dist/Popover.js +4 -0
  61. package/dist/PricingGroup-DgcdVSq8.js +126 -0
  62. package/dist/PricingGroup.css +1 -1
  63. package/dist/PricingGroup.js +1 -1
  64. package/dist/{PricingTable-DYTJG4AU.js → PricingTable-DALddSwM.js} +11 -11
  65. package/dist/PricingTable.css +1 -1
  66. package/dist/PricingTable.js +1 -1
  67. package/dist/{RadioGroup-DxoPHPIF.js → RadioGroup-D2UUOTkY.js} +25 -25
  68. package/dist/RadioGroup.css +1 -1
  69. package/dist/RadioGroup.js +1 -1
  70. package/dist/{Row--HIe6vb9.js → Row-DsQOVn18.js} +1 -1
  71. package/dist/Row.js +1 -1
  72. package/dist/Sidebar-DeqxYgxn.js +69 -0
  73. package/dist/Sidebar.css +1 -0
  74. package/dist/Sidebar.d.ts +83 -0
  75. package/dist/Sidebar.js +4 -0
  76. package/dist/Stack-XkmPSswj.js +53 -0
  77. package/dist/Stack.css +1 -1
  78. package/dist/Stack.d.ts +16 -4
  79. package/dist/Stack.js +3 -2
  80. package/dist/Stat-C5iZyEoo.js +27 -0
  81. package/dist/Stat.css +1 -0
  82. package/dist/Stat.d.ts +39 -0
  83. package/dist/Stat.js +4 -0
  84. package/dist/{TabSections-DL7DufKU.js → TabSections-Bf_sZo7b.js} +1 -1
  85. package/dist/TabSections.js +1 -1
  86. package/dist/TextGroup-DmhuyMR1.js +23 -0
  87. package/dist/TextGroup.css +1 -0
  88. package/dist/TextGroup.d.ts +35 -0
  89. package/dist/TextGroup.js +4 -0
  90. package/dist/dark.css +10 -0
  91. package/dist/index.css +27 -15
  92. package/dist/index.d.ts +17 -3
  93. package/dist/index.es.d.ts +73 -0
  94. package/dist/index.es.js +76 -59
  95. package/dist/light.css +10 -0
  96. package/dist/overlayZ.d.ts +9 -0
  97. package/dist/tokens.css +19 -0
  98. package/package.json +2 -2
  99. package/dist/Avatar-Jzan87XD.js +0 -101
  100. package/dist/AvatarName-KBbQrVta.js +0 -56
  101. package/dist/Badge-l6nUkl-H.js +0 -22
  102. package/dist/Dropdown-Cw5LKpcT.js +0 -168
  103. package/dist/Item-CaU4RW2G.js +0 -38
  104. package/dist/Layout-Xb3-xsmA.js +0 -18
  105. package/dist/Menu-DRBHvSdJ.js +0 -40
  106. package/dist/PageHead-Baz9BLuA.js +0 -22
  107. package/dist/PricingGroup-CiqQtzjd.js +0 -126
  108. 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
- * - `@elcrm/overlay`портальный popover/меню поверх страницы;
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: "Команда", disabled: true },
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
@@ -1,4 +1,4 @@
1
- import { M as r } from "./Menu-DRBHvSdJ.js";
1
+ import { M as r } from "./Menu-DpUvOl8Y.js";
2
2
  export {
3
3
  r as Menu
4
4
  };
@@ -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-lg)}.ccw{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:var(--shell-gap)}.cct{min-width:0;max-width:36rem}.cch{margin:0;font-size:var(--section-title-size);font-weight:var(--shell-font-weight);color:var(--shell-color);line-height:1.25}.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)}}
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}}
@@ -8,8 +8,10 @@ import { default as React } from 'react';
8
8
  *
9
9
  * @example
10
10
  * ```tsx
11
- * <PageShell>
12
- * <PageHead title="Клиенты" subtitle="Все компании" actions={<Button>Создать</Button>} />
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
- /** Контент под строкой заголовка (фильтры, Breadcrumb) */
40
+ /**
41
+ * Контент под строкой заголовка (фильтры, поиск, вкладки).
42
+ * Между title и children — `--shell-gap`.
43
+ */
29
44
  children?: React.ReactNode;
30
45
  };
31
46
  /**
32
- * Заголовок: title слева, actions справа (одна линия).
47
+ * Заголовок: title слева (+ `sup` сверху), actions справа.
33
48
  *
34
- * @see PageShell, Section, Header
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,4 +1,4 @@
1
- import { P as o } from "./PageHead-Baz9BLuA.js";
1
+ import { P as o } from "./PageHead-DgaJ1mXY.js";
2
2
  export {
3
3
  o as PageHead
4
4
  };
@@ -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", o = "ckw", f = "ckb", i = "ckf", c = {
3
+ import './PageShell.css';const m = "ckr", f = "ckw", i = "ckb", k = "ckf", u = "cko", c = {
4
4
  r: m,
5
- w: o,
6
- b: f,
7
- f: i
5
+ w: f,
6
+ b: i,
7
+ f: k,
8
+ o: u
8
9
  };
9
- function u({
10
+ function d({
10
11
  children: s,
11
- className: a,
12
- wide: n,
12
+ className: n,
13
+ wide: o,
14
+ scroll: r = !0,
13
15
  footer: t,
14
- ...r
16
+ ...a
15
17
  }) {
16
18
  return /* @__PURE__ */ e.createElement(
17
19
  "div",
18
20
  {
19
- ...r,
20
- className: l(c.r, n && c.w, a)
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
- u as P
29
+ d as P
28
30
  };
@@ -1 +1 @@
1
- @layer elcrm-components{.ckr{flex:1 1 auto;min-height:0;height:100%;width:100%;display:flex;flex-direction:column;box-sizing:border-box;padding:var(--shell-padding);overflow:hidden}.ckw{max-width:none}.ckb{flex:1 1 auto;min-height:0;overflow:auto;display:flex;flex-direction:column;gap:var(--shell-gap)}.ckf{flex:0 0 auto;padding-top:var(--shell-gap-sm)}}
1
+ @layer elcrm-components{.ckr{flex:1 1 auto;min-height:0;height:100%;width:100%;display:flex;flex-direction:column;box-sizing:border-box;padding:var(--shell-padding);overflow:hidden}.ckw{max-width:none}.ckb{flex:1 1 auto;min-height:0;overflow:auto;display:flex;flex-direction:column;gap:var(--shell-gap)}.ckf{flex:0 0 auto;padding-top:var(--shell-gap-sm)}.cko{overflow:visible;height:auto}.cko .ckb{overflow:visible;flex:0 1 auto;min-height:auto}}
@@ -1,14 +1,14 @@
1
1
  import { default as React } from 'react';
2
2
  /**
3
- * Каркас модуля: скролл в body, опциональный footer прибит к низу.
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
@@ -1,4 +1,4 @@
1
- import { P as l } from "./PageShell-CghThHS3.js";
1
+ import { P as l } from "./PageShell-D9EZiO8o.js";
2
2
  export {
3
3
  l as PageShell
4
4
  };
@@ -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
+ };
@@ -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;
@@ -0,0 +1,4 @@
1
+ import { P as e } from "./Popover-g2xTGubK.js";
2
+ export {
3
+ e as Popover
4
+ };
@@ -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
+ };
@@ -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}.cugt{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%}.cukv{width:60%;height:60%;display:block}}
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}}
@@ -1,4 +1,4 @@
1
- import { P as i } from "./PricingGroup-CiqQtzjd.js";
1
+ import { P as i } from "./PricingGroup-DgcdVSq8.js";
2
2
  export {
3
3
  i as PricingGroup
4
4
  };