@elcrm/components 0.0.3 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +450 -202
  2. package/dist/Avatar-CyNXYvsa.js +101 -0
  3. package/dist/Avatar.css +1 -1
  4. package/dist/Avatar.d.ts +56 -5
  5. package/dist/Avatar.js +1 -1
  6. package/dist/AvatarGroup-BAWas4pU.js +81 -0
  7. package/dist/AvatarGroup.css +1 -0
  8. package/dist/AvatarGroup.d.ts +77 -0
  9. package/dist/AvatarGroup.js +4 -0
  10. package/dist/AvatarName-DhD3TytF.js +56 -0
  11. package/dist/AvatarName.css +1 -0
  12. package/dist/AvatarName.d.ts +76 -0
  13. package/dist/AvatarName.js +4 -0
  14. package/dist/Badge.css +1 -1
  15. package/dist/Badge.d.ts +16 -1
  16. package/dist/Block-BAXh0PPp.js +8 -0
  17. package/dist/Block.d.ts +27 -6
  18. package/dist/Block.js +1 -1
  19. package/dist/Brand.css +1 -1
  20. package/dist/Brand.d.ts +20 -1
  21. package/dist/Breadcrumb-CAM_e9LN.js +98 -0
  22. package/dist/Breadcrumb.css +1 -0
  23. package/dist/Breadcrumb.d.ts +80 -0
  24. package/dist/Breadcrumb.js +4 -0
  25. package/dist/Card.css +1 -1
  26. package/dist/Card.d.ts +22 -1
  27. package/dist/Column-DDaqX-A7.js +8 -0
  28. package/dist/Column.d.ts +23 -7
  29. package/dist/Column.js +1 -1
  30. package/dist/Dropdown-DQlDiWCR.js +168 -0
  31. package/dist/Dropdown.css +1 -0
  32. package/dist/Dropdown.d.ts +124 -0
  33. package/dist/Dropdown.js +4 -0
  34. package/dist/EmptyState.css +1 -1
  35. package/dist/EmptyState.d.ts +24 -1
  36. package/dist/Footer.css +1 -1
  37. package/dist/Footer.d.ts +20 -1
  38. package/dist/Header.css +1 -1
  39. package/dist/Header.d.ts +25 -2
  40. package/dist/Item.css +1 -1
  41. package/dist/Item.d.ts +24 -1
  42. package/dist/Layout.css +1 -1
  43. package/dist/Layout.d.ts +23 -3
  44. package/dist/List.css +1 -1
  45. package/dist/List.d.ts +22 -1
  46. package/dist/Loading.css +1 -1
  47. package/dist/Loading.d.ts +19 -1
  48. package/dist/Menu-DRBHvSdJ.js +40 -0
  49. package/dist/Menu.css +1 -1
  50. package/dist/Menu.d.ts +64 -8
  51. package/dist/Menu.js +1 -1
  52. package/dist/{NavSections-CM-VPai2.js → NavSections-NDcIDD6H.js} +26 -26
  53. package/dist/NavSections.css +1 -1
  54. package/dist/NavSections.d.ts +79 -15
  55. package/dist/NavSections.js +1 -1
  56. package/dist/PageHead-Baz9BLuA.js +22 -0
  57. package/dist/PageHead.css +1 -0
  58. package/dist/PageHead.d.ts +36 -0
  59. package/dist/PageHead.js +4 -0
  60. package/dist/PageShell-CghThHS3.js +28 -0
  61. package/dist/PageShell.css +1 -0
  62. package/dist/PageShell.d.ts +33 -0
  63. package/dist/PageShell.js +4 -0
  64. package/dist/PricingGroup-DgcdVSq8.js +126 -0
  65. package/dist/PricingGroup.css +1 -0
  66. package/dist/PricingGroup.d.ts +130 -0
  67. package/dist/PricingGroup.js +4 -0
  68. package/dist/PricingTable-DALddSwM.js +158 -0
  69. package/dist/PricingTable.css +1 -0
  70. package/dist/PricingTable.d.ts +108 -0
  71. package/dist/PricingTable.js +4 -0
  72. package/dist/RadioGroup-D2UUOTkY.js +138 -0
  73. package/dist/RadioGroup.css +1 -0
  74. package/dist/RadioGroup.d.ts +111 -0
  75. package/dist/RadioGroup.js +4 -0
  76. package/dist/Row--HIe6vb9.js +8 -0
  77. package/dist/Row.d.ts +23 -7
  78. package/dist/Row.js +1 -1
  79. package/dist/Section.css +1 -1
  80. package/dist/Section.d.ts +23 -3
  81. package/dist/Stack-b0-XWwQ1.js +31 -0
  82. package/dist/Stack.css +1 -0
  83. package/dist/Stack.d.ts +34 -0
  84. package/dist/Stack.js +4 -0
  85. package/dist/TabSections-DL7DufKU.js +50 -0
  86. package/dist/TabSections.css +1 -1
  87. package/dist/TabSections.d.ts +69 -13
  88. package/dist/TabSections.js +1 -1
  89. package/dist/cx.d.ts +8 -1
  90. package/dist/dark.css +24 -0
  91. package/dist/index.css +32 -18
  92. package/dist/index.d.ts +21 -1
  93. package/dist/index.es.js +58 -38
  94. package/dist/lazyRoute.d.ts +19 -3
  95. package/dist/light.css +25 -0
  96. package/dist/stackGap.d.ts +13 -1
  97. package/dist/tokens.css +57 -0
  98. package/package.json +20 -4
  99. package/dist/Avatar-DHNPaIjZ.js +0 -64
  100. package/dist/Block-CVKukh1e.js +0 -28
  101. package/dist/Block.css +0 -1
  102. package/dist/Column-DlNrvFq1.js +0 -26
  103. package/dist/Column.css +0 -1
  104. package/dist/Menu-DS7zKQbY.js +0 -40
  105. package/dist/Row-CnD7Q7pD.js +0 -20
  106. package/dist/Row.css +0 -1
  107. package/dist/TabSections-oeEBx0nM.js +0 -50
  108. package/dist/stackGap-CDsjER0g.js +0 -7
@@ -0,0 +1,101 @@
1
+ import a from "react";
2
+ import { c as f } from "./cx-CcykAxZN.js";
3
+ import './Avatar.css';const N = "car", g = "cav", h = "cas", y = "cam", A = "cal", C = "caa", x = "cai", z = "cab", B = "cao", F = "caf", e = {
4
+ r: N,
5
+ v: g,
6
+ s: h,
7
+ m: y,
8
+ l: A,
9
+ a: C,
10
+ i: x,
11
+ b: z,
12
+ o: B,
13
+ f: F
14
+ };
15
+ function U(t) {
16
+ const s = t.trim();
17
+ if (!s) return "?";
18
+ const n = s.split(/\s+/).filter(Boolean);
19
+ return n.length >= 2 ? (n[0][0] + n[1][0]).toUpperCase() : s.slice(0, 2).toUpperCase();
20
+ }
21
+ function D({ status: t }) {
22
+ return /* @__PURE__ */ a.createElement(
23
+ "span",
24
+ {
25
+ className: f(e.b, t === "online" ? e.o : e.f),
26
+ "data-status": t,
27
+ "aria-hidden": !0
28
+ }
29
+ );
30
+ }
31
+ function R({
32
+ src: t,
33
+ label: s,
34
+ children: n,
35
+ name: l,
36
+ status: o
37
+ }) {
38
+ const c = t != null && t !== "" ? /* @__PURE__ */ a.createElement("img", { className: e.i, src: t, alt: s ?? "", draggable: !1 }) : n ?? (l != null ? U(l) : "?");
39
+ return /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement("span", { className: e.v }, c), o != null ? /* @__PURE__ */ a.createElement(D, { status: o }) : null);
40
+ }
41
+ function j(t) {
42
+ const {
43
+ src: s,
44
+ alt: n,
45
+ name: l,
46
+ size: o = "m",
47
+ status: c,
48
+ active: i,
49
+ children: p,
50
+ className: b,
51
+ as: v = "span",
52
+ ...m
53
+ } = t, E = o === "s" ? e.s : o === "l" ? e.l : e.m, u = f(e.r, E, i && e.a, b), r = n ?? l, d = /* @__PURE__ */ a.createElement(
54
+ R,
55
+ {
56
+ src: s,
57
+ label: r,
58
+ name: l,
59
+ status: c,
60
+ children: p
61
+ }
62
+ );
63
+ return v === "button" ? /* @__PURE__ */ a.createElement(
64
+ "button",
65
+ {
66
+ type: "button",
67
+ className: u,
68
+ "aria-label": r,
69
+ "data-active": i ? "true" : void 0,
70
+ "data-status": c,
71
+ ...m
72
+ },
73
+ d
74
+ ) : v === "div" ? /* @__PURE__ */ a.createElement(
75
+ "div",
76
+ {
77
+ className: u,
78
+ role: r ? "img" : void 0,
79
+ "aria-label": r,
80
+ "data-active": i ? "true" : void 0,
81
+ "data-status": c,
82
+ ...m
83
+ },
84
+ d
85
+ ) : /* @__PURE__ */ a.createElement(
86
+ "span",
87
+ {
88
+ className: u,
89
+ role: r ? "img" : void 0,
90
+ "aria-label": r,
91
+ "data-active": i ? "true" : void 0,
92
+ "data-status": c,
93
+ ...m
94
+ },
95
+ d
96
+ );
97
+ }
98
+ export {
99
+ j as A,
100
+ U as i
101
+ };
package/dist/Avatar.css CHANGED
@@ -1 +1 @@
1
- @layer elcrm-components{.car{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;overflow:hidden;border-radius:var(--avatar-radius);border:var(--avatar-border);background:var(--avatar-background);color:var(--avatar-color);font-weight:var(--avatar-font-weight);line-height:1;-webkit-user-select:none;user-select:none;vertical-align:middle}.car:is(button){-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;padding:0;font:inherit;font-weight:var(--avatar-font-weight);cursor:pointer}.cas{width:var(--avatar-size-s);height:var(--avatar-size-s);font-size:var(--avatar-font-size-s)}.cam{width:var(--avatar-size-m);height:var(--avatar-size-m);font-size:var(--avatar-font-size-m)}.cal{width:var(--avatar-size-l);height:var(--avatar-size-l);font-size:var(--avatar-font-size-l)}.caa,.car[data-active=true]{outline:var(--avatar-outline-active);outline-offset:var(--avatar-outline-offset)}.cai{width:100%;height:100%;object-fit:cover;display:block}}
1
+ @layer elcrm-components{.car{position:relative;box-sizing:border-box;display:inline-flex;flex-shrink:0;width:fit-content;height:fit-content;border-radius:var(--avatar-radius);-webkit-user-select:none;user-select:none;vertical-align:middle}.car:is(button){-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;padding:0;font:inherit;cursor:pointer;background:transparent;border:none}.cav{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;overflow:hidden;width:100%;height:100%;border-radius:inherit;border:var(--avatar-border);background:var(--avatar-background);color:var(--avatar-color);font-weight:var(--avatar-font-weight);line-height:1}.cas{width:var(--avatar-size-s);height:var(--avatar-size-s);font-size:var(--avatar-font-size-s)}.cas .cav{font-size:inherit}.cam{width:var(--avatar-size-m);height:var(--avatar-size-m);font-size:var(--avatar-font-size-m)}.cam .cav{font-size:inherit}.cal{width:var(--avatar-size-l);height:var(--avatar-size-l);font-size:var(--avatar-font-size-l)}.cal .cav{font-size:inherit}.caa .cav,.car[data-active=true] .cav{outline:var(--avatar-outline-active);outline-offset:var(--avatar-outline-offset)}.cai{width:100%;height:100%;object-fit:cover;display:block}.cab{position:absolute;right:0;bottom:0;box-sizing:border-box;width:var(--shell-status-size);height:var(--shell-status-size);border-radius:50%;border:2px solid var(--shell-background);pointer-events:none}.cas .cab{width:8px;height:8px}.cam .cab{width:var(--shell-status-size);height:var(--shell-status-size)}.cal .cab{width:12px;height:12px}.cao{background:var(--shell-color-success)}.caf{background:var(--shell-color-muted)}}
package/dist/Avatar.d.ts CHANGED
@@ -1,20 +1,45 @@
1
1
  import { default as React } from 'react';
2
2
  /**
3
3
  * Инициалы из имени: «Иван Петров» → «ИП», «admin» → «AD».
4
+ *
5
+ * Используется {@link Avatar}, когда нет `src`.
4
6
  */
5
7
  export declare function initialsFromName(name: string): string;
8
+ /** Статус присутствия у аватара. */
9
+ export type AvatarStatus = "online" | "offline";
10
+ /**
11
+ * Общие поля аватара (фото / инициалы / статус).
12
+ *
13
+ * Важно: `name` — **только** для расчёта инициалов (если нет `src`).
14
+ * Подпись в списках (ФИО, email) — через {@link AvatarName} (`title` + `description`).
15
+ */
6
16
  type Common = {
7
- /** URL картинки; если нет — инициалы из `name` / `children` */
17
+ /** URL картинки; если нет — инициалы из `name` / `children`. */
8
18
  src?: string;
19
+ /** Доступное имя для `alt` / `aria-label`. */
9
20
  alt?: string;
10
- /** Имя для инициалов и aria-label по умолчанию */
21
+ /**
22
+ * Только для инициалов (если нет `src`).
23
+ * Не используйте как видимую подпись в UI — для этого {@link AvatarName}
24
+ * с полями `title` / `description`.
25
+ */
11
26
  name?: string;
27
+ /** Размер: `s` | `m` | `l`. */
12
28
  size?: "s" | "m" | "l";
13
- /** Подсветка (например активный пункт шапки) */
29
+ /** Точка статуса (online / offline). */
30
+ status?: AvatarStatus;
31
+ /** Подсветка (например активный пункт шапки). */
14
32
  active?: boolean;
33
+ /** Кастомное содержимое вместо инициалов (если нет `src`). */
15
34
  children?: React.ReactNode;
35
+ /** CSS-класс корня. */
16
36
  className?: string;
17
37
  };
38
+ /**
39
+ * Props {@link Avatar}: корень как `button` | `span` | `div`.
40
+ *
41
+ * По умолчанию `as="span"`. Для кликабельного аватара — `as="button"`.
42
+ */
18
43
  export type AvatarProps = (Common & React.ButtonHTMLAttributes<HTMLButtonElement> & {
19
44
  as?: "button";
20
45
  }) | (Common & React.HTMLAttributes<HTMLSpanElement> & {
@@ -23,8 +48,34 @@ export type AvatarProps = (Common & React.ButtonHTMLAttributes<HTMLButtonElement
23
48
  as: "div";
24
49
  });
25
50
  /**
26
- * Аватар: фото или инициалы.
27
- * Токены: --avatar-*
51
+ * Аватар: фото или инициалы, опционально статус присутствия.
52
+ *
53
+ * Когда использовать:
54
+ * - круглая миниатюра пользователя без текстовой подписи рядом;
55
+ * - в шапке, списках, {@link AvatarGroup}.
56
+ *
57
+ * Связанные компоненты:
58
+ * - {@link AvatarName} — аватар + видимые `title` / `description`
59
+ * (`name` у Avatar остаётся только для инициалов);
60
+ * - {@link AvatarGroup} — стопка аватаров из `items`.
61
+ *
62
+ * CSS-токены: `--avatar-*` (в т.ч. `--avatar-size-s|m|l`).
63
+ *
64
+ * @example
65
+ * ```tsx
66
+ * // фото + статус
67
+ * <Avatar src="/u/42.jpg" alt="Иван Петров" size="m" status="online" />
68
+ *
69
+ * // без фото — только инициалы из name
70
+ * <Avatar name="Иван Петров" size="s" />
71
+ *
72
+ * // подпись в UI — через AvatarName (title + description)
73
+ * <AvatarName
74
+ * name="Иван Петров"
75
+ * title="Иван Петров"
76
+ * description="ivan@elcrm.app"
77
+ * />
78
+ * ```
28
79
  */
29
80
  export declare function Avatar(props: AvatarProps): React.JSX.Element;
30
81
  export {};
package/dist/Avatar.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as r, i as m } from "./Avatar-DHNPaIjZ.js";
1
+ import { A as r, i as m } from "./Avatar-CyNXYvsa.js";
2
2
  export {
3
3
  r as Avatar,
4
4
  m as initialsFromName
@@ -0,0 +1,81 @@
1
+ import n from "react";
2
+ import { A as f } from "./Avatar-CyNXYvsa.js";
3
+ import { c as u } from "./cx-CcykAxZN.js";
4
+ import './AvatarGroup.css';const G = "cyr", I = "cyi", M = "cyo", R = "cyd", S = "cys", j = "cym", q = "cyl", l = {
5
+ r: G,
6
+ i: I,
7
+ o: M,
8
+ d: R,
9
+ s: S,
10
+ m: j,
11
+ l: q
12
+ };
13
+ function w(a) {
14
+ if (a.name != null && a.name !== "") return a.name;
15
+ if (a.title != null && a.title !== "") return a.title;
16
+ }
17
+ function F({
18
+ items: a,
19
+ max: c,
20
+ size: s = "m",
21
+ add: g = !1,
22
+ addLabel: v = "Добавить",
23
+ onAdd: r,
24
+ onItemClick: i,
25
+ className: E,
26
+ "aria-label": h = "Аватары",
27
+ ...N
28
+ }) {
29
+ const p = s === "s" ? l.s : s === "l" ? l.l : l.m, k = c != null && c >= 0 ? Math.min(c, a.length) : a.length, y = a.slice(0, k), e = a.length - y.length;
30
+ return /* @__PURE__ */ n.createElement(
31
+ "div",
32
+ {
33
+ className: u(l.r, E),
34
+ role: "group",
35
+ "aria-label": h,
36
+ ...N
37
+ },
38
+ y.map((t, o) => {
39
+ const C = t.value ?? t.title ?? t.name ?? t.src ?? String(o), b = w(t), m = t.alt ?? t.title ?? t.name, P = i != null;
40
+ return /* @__PURE__ */ n.createElement("span", { key: C, className: l.i, style: { zIndex: o + 1 } }, P ? /* @__PURE__ */ n.createElement(
41
+ f,
42
+ {
43
+ as: "button",
44
+ src: t.src,
45
+ name: b,
46
+ alt: m,
47
+ size: s,
48
+ status: t.status,
49
+ onClick: ($) => {
50
+ $.stopPropagation(), i(t, o);
51
+ }
52
+ }
53
+ ) : /* @__PURE__ */ n.createElement(
54
+ f,
55
+ {
56
+ src: t.src,
57
+ name: b,
58
+ alt: m,
59
+ size: s,
60
+ status: t.status
61
+ }
62
+ ));
63
+ }),
64
+ e > 0 ? /* @__PURE__ */ n.createElement("span", { className: u(l.o, p), "aria-label": `Ещё ${e}` }, "+", e) : null,
65
+ g ? /* @__PURE__ */ n.createElement(
66
+ "button",
67
+ {
68
+ type: "button",
69
+ className: u(l.d, p),
70
+ "aria-label": v,
71
+ onClick: (t) => {
72
+ t.stopPropagation(), r == null || r();
73
+ }
74
+ },
75
+ "+"
76
+ ) : null
77
+ );
78
+ }
79
+ export {
80
+ F as A
81
+ };
@@ -0,0 +1 @@
1
+ @layer elcrm-components{.cyr{display:inline-flex;align-items:center;vertical-align:middle}.cyi{position:relative;margin-left:var(--avatar-group-overlap);box-shadow:0 0 0 var(--avatar-group-ring) var(--shell-background);border-radius:var(--avatar-radius)}.cyi:first-child{margin-left:0}.cyo,.cyd{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;margin-left:var(--avatar-group-overlap);border-radius:var(--avatar-radius);font-weight:var(--avatar-font-weight);line-height:1;-webkit-user-select:none;user-select:none}.cyo{z-index:20;color:var(--shell-color-muted);background:var(--shell-background-muted);border:1px solid var(--shell-border);box-shadow:0 0 0 var(--avatar-group-ring) var(--shell-background)}.cyd{z-index:21;margin-left:var(--shell-gap-sm);color:var(--shell-color-muted);background:var(--shell-background);border:1px dashed var(--shell-border);cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:0;font:inherit;font-weight:var(--avatar-font-weight)}.cyd:hover{background:var(--shell-background-hover)}.cys{width:var(--avatar-size-s);height:var(--avatar-size-s);font-size:var(--avatar-font-size-s)}.cym{width:var(--avatar-size-m);height:var(--avatar-size-m);font-size:var(--avatar-font-size-m)}.cyl{width:var(--avatar-size-l);height:var(--avatar-size-l);font-size:var(--avatar-font-size-l)}}
@@ -0,0 +1,77 @@
1
+ import { default as React } from 'react';
2
+ /**
3
+ * Элемент стопки {@link AvatarGroup}.
4
+ *
5
+ * Предпочтительный идентификатор — `value` (как у остальных group-UI).
6
+ * `name` — только для инициалов; видимую подпись в списках даёт {@link AvatarName}.
7
+ */
8
+ export type AvatarGroupItem = {
9
+ /** Уникальный id (предпочтительно; не React `key`). */
10
+ value?: string;
11
+ /** URL фото. */
12
+ src?: string;
13
+ /** Только для инициалов (если нет `src`). */
14
+ name?: string;
15
+ /** Подпись / aria; также fallback для инициалов, если нет `name`. */
16
+ title?: string;
17
+ /** `alt` у картинки. */
18
+ alt?: string;
19
+ /** Точка статуса. */
20
+ status?: "online" | "offline";
21
+ };
22
+ /**
23
+ * Props {@link AvatarGroup}.
24
+ *
25
+ * Групповой UI: декларативный `items` (+ `max` / `add`), без compound-слотов.
26
+ */
27
+ export type AvatarGroupProps = React.HTMLAttributes<HTMLDivElement> & {
28
+ /** Список людей / аватаров. */
29
+ items: AvatarGroupItem[];
30
+ /** Сколько аватаров показать до «+N». По умолчанию все. */
31
+ max?: number;
32
+ /** Размер аватаров: `s` | `m` | `l`. */
33
+ size?: "s" | "m" | "l";
34
+ /** Кнопка «+» справа. */
35
+ add?: boolean;
36
+ /** Подпись для кнопки добавления (`aria-label`). */
37
+ addLabel?: string;
38
+ /** Клик по кнопке добавления. */
39
+ onAdd?: () => void;
40
+ /** Клик по аватару. */
41
+ onItemClick?: (item: AvatarGroupItem, index: number) => void;
42
+ };
43
+ /**
44
+ * Стопка аватаров с оверлапом, счётчиком «+N» и опциональной кнопкой добавления.
45
+ *
46
+ * Когда использовать:
47
+ * - участники задачи / канала / сделки в одну строку;
48
+ * - нужно ограничить видимое число (`max`) и добавить «+».
49
+ *
50
+ * Связанные компоненты:
51
+ * - {@link Avatar} — одиночный аватар;
52
+ * - {@link AvatarName} — аватар с текстовой подписью (`title` / `description`).
53
+ *
54
+ * API: декларативные `items`. Идентификатор предпочтительно `value` (не `key`).
55
+ * Compound-слоты не используются.
56
+ *
57
+ * CSS-токены: `--avatar-group-*`, размеры из `--avatar-size-*`.
58
+ *
59
+ * @example
60
+ * ```tsx
61
+ * const items = [
62
+ * { value: "u1", name: "Иван Петров", src: "/u/1.jpg", status: "online" },
63
+ * { value: "u2", name: "Мария Смирнова" },
64
+ * { value: "u3", name: "Алексей" },
65
+ * ];
66
+ *
67
+ * <AvatarGroup
68
+ * items={items}
69
+ * max={5}
70
+ * size="m"
71
+ * add
72
+ * onAdd={() => openInvite()}
73
+ * onItemClick={(item) => openProfile(item.value)}
74
+ * />
75
+ * ```
76
+ */
77
+ export declare function AvatarGroup({ items, max, size, add, addLabel, onAdd, onItemClick, className, "aria-label": ariaLabel, ...rest }: AvatarGroupProps): React.JSX.Element;
@@ -0,0 +1,4 @@
1
+ import { A as o } from "./AvatarGroup-BAWas4pU.js";
2
+ export {
3
+ o as AvatarGroup
4
+ };
@@ -0,0 +1,56 @@
1
+ import t from "react";
2
+ import { A as v } from "./Avatar-CyNXYvsa.js";
3
+ import { c as b } from "./cx-CcykAxZN.js";
4
+ import './AvatarName.css';const g = "czr", y = "czc", A = "czt", h = "czd", x = "czs", C = "czm", F = "czl", e = {
5
+ r: g,
6
+ c: y,
7
+ t: A,
8
+ d: h,
9
+ s: x,
10
+ m: C,
11
+ l: F
12
+ };
13
+ function I(s, n) {
14
+ if (s != null && s !== "") return s;
15
+ if (typeof n == "string") return n;
16
+ }
17
+ function j(s) {
18
+ const {
19
+ src: n,
20
+ name: c,
21
+ title: m,
22
+ description: i,
23
+ size: a = "m",
24
+ status: f,
25
+ className: p,
26
+ children: z,
27
+ as: u = "div",
28
+ ...r
29
+ } = s, E = a === "s" ? e.s : a === "l" ? e.l : e.m, l = b(e.r, E, p), d = m ?? (typeof c == "string" ? c : void 0), N = I(c, m), o = /* @__PURE__ */ t.createElement(t.Fragment, null, /* @__PURE__ */ t.createElement(v, { src: n, name: N, size: a, status: f }), /* @__PURE__ */ t.createElement("span", { className: e.c }, d != null ? /* @__PURE__ */ t.createElement("span", { className: e.t }, d) : null, i != null ? /* @__PURE__ */ t.createElement("span", { className: e.d }, i) : null, z));
30
+ return u === "button" ? /* @__PURE__ */ t.createElement(
31
+ "button",
32
+ {
33
+ type: "button",
34
+ className: l,
35
+ ...r
36
+ },
37
+ o
38
+ ) : u === "a" ? /* @__PURE__ */ t.createElement(
39
+ "a",
40
+ {
41
+ className: l,
42
+ ...r
43
+ },
44
+ o
45
+ ) : /* @__PURE__ */ t.createElement(
46
+ "div",
47
+ {
48
+ className: l,
49
+ ...r
50
+ },
51
+ o
52
+ );
53
+ }
54
+ export {
55
+ j as A
56
+ };
@@ -0,0 +1 @@
1
+ @layer elcrm-components{.czr{display:inline-flex;align-items:center;gap:var(--shell-gap);max-width:100%;text-align:left;vertical-align:middle}.czr:is(button,a){-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;padding:0;border:none;background:transparent;font:inherit;color:inherit;cursor:pointer;text-decoration:none}.czc{display:flex;flex-direction:column;gap:2px;min-width:0}.czt{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}.czd{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}.czs{gap:var(--shell-gap-sm)}.czs .czt{font-size:var(--shell-font-size-sm)}.czm{gap:var(--shell-gap)}.czl{gap:var(--shell-gap-lg)}.czl .czt{font-size:var(--shell-font-size-lg)}.czl .czd{font-size:var(--shell-font-size)}}
@@ -0,0 +1,76 @@
1
+ import { default as React } from 'react';
2
+ import { AvatarStatus } from './Avatar';
3
+ /**
4
+ * Общие поля блока «аватар + текст».
5
+ *
6
+ * Канон подписей: видимые `title` и `description`.
7
+ * `name` уходит в {@link Avatar} **только** для инициалов (если нет `src`).
8
+ */
9
+ type Common = {
10
+ /** URL фото. */
11
+ src?: string;
12
+ /**
13
+ * Только для инициалов (если нет `src`).
14
+ * Не заменяет видимый заголовок — для него `title`.
15
+ */
16
+ name?: string;
17
+ /** Заголовок (имя пользователя и т.п.) — видимый текст. */
18
+ title?: React.ReactNode;
19
+ /** Подпись: email, роль… */
20
+ description?: React.ReactNode;
21
+ /** Размер: `s` | `m` | `l`. */
22
+ size?: "s" | "m" | "l";
23
+ /** Статус у аватара. */
24
+ status?: AvatarStatus;
25
+ /** CSS-класс корня. */
26
+ className?: string;
27
+ /** Доп. контент в текстовой колонке. */
28
+ children?: React.ReactNode;
29
+ };
30
+ /**
31
+ * Props {@link AvatarName}: корень как `button` | `a` | `div`.
32
+ */
33
+ export type AvatarNameProps = (Common & React.ButtonHTMLAttributes<HTMLButtonElement> & {
34
+ as?: "button";
35
+ }) | (Common & React.AnchorHTMLAttributes<HTMLAnchorElement> & {
36
+ as: "a";
37
+ }) | (Common & React.HTMLAttributes<HTMLDivElement> & {
38
+ as: "div";
39
+ });
40
+ /**
41
+ * Аватар + видимые `title` и `description` в одну строку.
42
+ *
43
+ * Когда использовать:
44
+ * - строка пользователя в списке / меню / карточке;
45
+ * - нужна подпись рядом с фото (не только инициалы).
46
+ *
47
+ * Связанные компоненты:
48
+ * - {@link Avatar} — только круг (без текста); `name` там лишь для инициалов;
49
+ * - {@link AvatarGroup} — стопка без подписей.
50
+ *
51
+ * Канон: `title` / `description` для UI-текста; `name` — только инициалы.
52
+ *
53
+ * CSS-токены: `--shell-*` (типографика строки), аватар — `--avatar-*`.
54
+ *
55
+ * @example
56
+ * ```tsx
57
+ * <AvatarName
58
+ * src="/u/42.jpg"
59
+ * name="Иван Петров"
60
+ * title="Иван Петров"
61
+ * description="ivan@elcrm.app"
62
+ * size="m"
63
+ * status="online"
64
+ * />
65
+ *
66
+ * <AvatarName
67
+ * as="button"
68
+ * name="Мария"
69
+ * title="Мария Смирнова"
70
+ * description="Менеджер"
71
+ * onClick={() => openProfile()}
72
+ * />
73
+ * ```
74
+ */
75
+ export declare function AvatarName(props: AvatarNameProps): React.JSX.Element;
76
+ export {};
@@ -0,0 +1,4 @@
1
+ import { A as e } from "./AvatarName-DhD3TytF.js";
2
+ export {
3
+ e as AvatarName
4
+ };
package/dist/Badge.css CHANGED
@@ -1 +1 @@
1
- @layer elcrm-components{.cjr{display:inline-flex;align-items:center;justify-content:center;gap:.25rem;padding:var(--badge-padding);border-radius:var(--badge-radius);border:var(--badge-border);font-size:var(--badge-font-size);font-weight:var(--badge-font-weight);line-height:1;white-space:nowrap}.cjn{background:var(--badge-neutral-background);color:var(--badge-neutral-color)}.cja{background:var(--badge-accent-background);color:var(--badge-accent-color)}.cju{background:var(--badge-success-background);color:var(--badge-success-color)}.cjw{background:var(--badge-warning-background);color:var(--badge-warning-color)}.cjd{background:var(--badge-danger-background);color:var(--badge-danger-color)}}
1
+ @layer elcrm-components{.cjr{display:inline-flex;align-items:center;justify-content:center;gap:.25rem;padding:.2rem .5rem;border-radius:999px;border:0;font-size:var(--shell-font-size-sm);font-weight:var(--shell-font-weight);line-height:1;white-space:nowrap}.cjn{background:var(--shell-background-hover);color:var(--shell-color)}.cja{background:color-mix(in srgb,var(--shell-color-accent) 16%,transparent);color:var(--shell-color-accent)}.cju{background:color-mix(in srgb,var(--shell-color-success) 16%,transparent);color:var(--shell-color-success)}.cjw{background:color-mix(in srgb,var(--shell-color-warning) 16%,transparent);color:var(--shell-color-warning)}.cjd{background:color-mix(in srgb,var(--shell-color-danger) 16%,transparent);color:var(--shell-color-danger)}}
package/dist/Badge.d.ts CHANGED
@@ -1,11 +1,26 @@
1
1
  import { default as React } from 'react';
2
+ /**
3
+ * Компактная метка / статус (тон по смыслу).
4
+ *
5
+ * Роли: Badge рядом с Item, в Card, в PageHead; не заменяет Button.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * <Badge tone="success">Активен</Badge>
10
+ * <Badge tone="danger">Просрочен</Badge>
11
+ * ```
12
+ *
13
+ * Токены: `--shell-*` (tone через color-mix от `--shell-color-*`).
14
+ */
2
15
  export type BadgeProps = React.HTMLAttributes<HTMLSpanElement> & {
3
16
  /** Визуальный тон */
4
17
  tone?: "neutral" | "accent" | "success" | "warning" | "danger";
18
+ /** Текст или содержимое метки */
5
19
  children?: React.ReactNode;
6
20
  };
7
21
  /**
8
22
  * Компактная метка / статус.
9
- * Токены: --badge-*
23
+ *
24
+ * @see Item, Card, Avatar
10
25
  */
11
26
  export declare function Badge({ tone, children, className, ...rest }: BadgeProps): React.JSX.Element;
@@ -0,0 +1,8 @@
1
+ import t from "react";
2
+ import { S as e } from "./Stack-b0-XWwQ1.js";
3
+ function n({ row: o, ...r }) {
4
+ return /* @__PURE__ */ t.createElement(e, { direction: o ? "row" : "column", ...r });
5
+ }
6
+ export {
7
+ n as B
8
+ };
package/dist/Block.d.ts CHANGED
@@ -1,9 +1,30 @@
1
1
  import { default as React } from 'react';
2
- export type BlockProps = React.HTMLAttributes<HTMLDivElement> & {
2
+ import { StackProps } from './Stack';
3
+ /**
4
+ * @deprecated Используйте `Stack` (`direction="column"|"row"`).
5
+ * Миграция: `elcrm migrate components`.
6
+ *
7
+ * Обёртка над Stack для обратной совместимости.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * // Было:
12
+ * <Block row gap={8}>…</Block>
13
+ * // Стало:
14
+ * <Stack direction="row" gap={8}>…</Stack>
15
+ * ```
16
+ */
17
+ export type BlockProps = Omit<StackProps, "direction"> & {
18
+ /**
19
+ * @deprecated Используйте `<Stack direction="row">`.
20
+ * Если `true` — горизонтальный стек.
21
+ */
3
22
  row?: boolean;
4
- /** Отступ между детьми: число (px) или CSS-строка */
5
- gap?: number | string;
6
- children?: React.ReactNode;
7
23
  };
8
- /** Блок-стек (колонка или ряд). Токены: --block-* */
9
- export declare function Block({ row, gap, children, className, style, ...rest }: BlockProps): React.JSX.Element;
24
+ /**
25
+ * @deprecated Используйте `Stack` (`direction="column"|"row"`).
26
+ * Миграция: `elcrm migrate components`.
27
+ *
28
+ * @see Stack, Row, Column
29
+ */
30
+ export declare function Block({ row, ...rest }: BlockProps): React.JSX.Element;
package/dist/Block.js CHANGED
@@ -1,4 +1,4 @@
1
- import { B } from "./Block-CVKukh1e.js";
1
+ import { B } from "./Block-BAXh0PPp.js";
2
2
  export {
3
3
  B as Block
4
4
  };
package/dist/Brand.css CHANGED
@@ -1 +1 @@
1
- @layer elcrm-components{.cnr{-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;padding:0;border:0;background:transparent;font:inherit;font-weight:var(--brand-font-weight);letter-spacing:var(--brand-letter-spacing);color:var(--brand-color);white-space:nowrap;cursor:pointer;text-decoration:none}.cnr:hover{color:var(--brand-color-hover)}}
1
+ @layer elcrm-components{.cnr{-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;padding:0;border:0;background:transparent;font:inherit;font-weight:700;letter-spacing:.02em;color:var(--shell-color);white-space:nowrap;cursor:pointer;text-decoration:none}.cnr:hover{color:var(--shell-color-accent)}}
package/dist/Brand.d.ts CHANGED
@@ -1,18 +1,37 @@
1
1
  import { default as React } from 'react';
2
2
  type Common = {
3
+ /** Текст или логотип бренда */
3
4
  children?: React.ReactNode;
5
+ /** Доп. CSS-класс */
4
6
  className?: string;
5
7
  };
8
+ /**
9
+ * Название / логотип в шапке.
10
+ *
11
+ * Роли: Brand = кликабельный или статичный бренд в Header;
12
+ * рендерится как `button` (по умолчанию), `a` или `strong`.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * <Header brand={<Brand as="a" href="/">elCRM</Brand>} />
17
+ * ```
18
+ *
19
+ * Токены: `--shell-color`, `--shell-color-accent`.
20
+ */
6
21
  export type BrandProps = (Common & React.ButtonHTMLAttributes<HTMLButtonElement> & {
22
+ /** Тег: кнопка (по умолчанию) */
7
23
  as?: "button";
8
24
  }) | (Common & React.HTMLAttributes<HTMLElement> & {
25
+ /** Тег: статичный заголовок без клика */
9
26
  as: "strong";
10
27
  }) | (Common & React.AnchorHTMLAttributes<HTMLAnchorElement> & {
28
+ /** Тег: ссылка на главную */
11
29
  as: "a";
12
30
  });
13
31
  /**
14
32
  * Название / логотип в шапке.
15
- * Токены: --brand-*
33
+ *
34
+ * @see Header, Layout
16
35
  */
17
36
  export declare function Brand(props: BrandProps): React.JSX.Element;
18
37
  export {};