@elcrm/components 0.2.5 → 0.2.7

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.
@@ -0,0 +1,23 @@
1
+ function a() {
2
+ const e = globalThis;
3
+ return e.elcrm || (e.elcrm = {}), e.elcrm.overlayZ || (e.elcrm.overlayZ = { seq: 0, active: /* @__PURE__ */ new Set() }), e.elcrm.overlayZ;
4
+ }
5
+ function c() {
6
+ const e = a();
7
+ e.seq += 1;
8
+ const t = 1e3 + e.seq * 10;
9
+ return e.active.add(t), t;
10
+ }
11
+ function n(e) {
12
+ const t = a();
13
+ t.active.delete(e), t.active.size === 0 && (t.seq = 0);
14
+ }
15
+ function r() {
16
+ const e = a();
17
+ return e.active.size === 0 ? 1e3 : Math.max(...e.active);
18
+ }
19
+ export {
20
+ c as a,
21
+ r as p,
22
+ n as r
23
+ };
package/dist/tokens.css CHANGED
@@ -25,6 +25,16 @@
25
25
  --shell-disabled-opacity: 0.55;
26
26
  --shell-z: var(--elcrm-z-popover, 1000);
27
27
  --layout-height: 100dvh;
28
+ /* отступ каркаса; 0 — на всю ширину вьюпорта */
29
+ --layout-padding: 0;
30
+ --layout-margin: 0;
31
+ --layout-gap: 0;
32
+ --layout-main-radius: 0;
33
+ --layout-main-background: transparent;
34
+ --layout-main-shadow: none;
35
+ --layout-main-border: none;
36
+ /* none — без ограничения; иначе например 1440px */
37
+ --layout-max-width: none;
28
38
 
29
39
  /* —— header —— */
30
40
  --header-radius: var(--shell-radius);
@@ -34,6 +44,8 @@
34
44
  --header-z: 20;
35
45
  /* shorthand: толщина + стиль + цвет, все стороны. Только снизу — `none` и линия через --header-shadow */
36
46
  --header-border: 1px solid var(--shell-border);
47
+ /* выравнивание nav в оставшейся ширине шапки: flex-start | center | flex-end */
48
+ --header-nav-justify: flex-start;
37
49
 
38
50
  /* —— section / nav-sections —— */
39
51
  --section-padding: 1.5rem 1.75rem 2.5rem;
@@ -69,6 +81,21 @@
69
81
  --stat-value-size: 1.75rem;
70
82
  --action-group-gap: var(--shell-gap-sm);
71
83
 
84
+ /* —— panel-info —— */
85
+ --panel-info-width: min(22rem, 42vw);
86
+ --panel-info-width-min: 16rem;
87
+ --panel-info-overlay-max: 24rem;
88
+ --panel-info-backdrop: color-mix(in srgb, var(--shell-color) 35%, transparent);
89
+
90
+ /* —— healthmap —— */
91
+ --healthmap-cell: 12px;
92
+ --healthmap-gap: 3px;
93
+ --healthmap-l0: var(--shell-background-muted);
94
+ --healthmap-l1: color-mix(in srgb, var(--shell-color-success) 25%, var(--shell-background-muted));
95
+ --healthmap-l2: color-mix(in srgb, var(--shell-color-success) 45%, transparent);
96
+ --healthmap-l3: color-mix(in srgb, var(--shell-color-success) 70%, transparent);
97
+ --healthmap-l4: var(--shell-color-success);
98
+
72
99
  /* —— item-column —— */
73
100
  --item-column-gap: var(--shell-gap);
74
101
  --item-column-icon-size: 40px;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elcrm/components",
3
- "version": "0.2.5",
4
- "description": "Shell UI elCRM: Layout, Header, Sidebar, Popover, PageHead, PageShell, Section, Stack, Stat, ActionGroup, TextGroup, ItemColumn и др.",
3
+ "version": "0.2.7",
4
+ "description": "Shell UI elCRM: Layout, Header, Sidebar, Popover, Healthmap, PanelInfo, PageHead, PageShell, Section, Stack, Stat и др.",
5
5
  "type": "module",
6
6
  "author": "MaSkal <dev@elcrm.online>",
7
7
  "license": "MIT",
@@ -84,18 +84,6 @@
84
84
  },
85
85
  "./package.json": "./package.json"
86
86
  },
87
- "scripts": {
88
- "dev": "vite --config test/vite.config.ts",
89
- "build": "vite build",
90
- "postbuild": "node scripts/postbuild.mjs",
91
- "check:css": "node scripts/check-css-scoped.mjs",
92
- "check:tokens": "node scripts/check-tokens.mjs",
93
- "test": "vitest run",
94
- "test:build": "vite build --config test/vite.config.ts",
95
- "test:preview": "vite preview --config test/vite.config.ts",
96
- "prepublishOnly": "npm run check:css && npm run check:tokens && npm run test && npm run build",
97
- "pack:check": "npm pack --dry-run"
98
- },
99
87
  "peerDependencies": {
100
88
  "@types/react": ">=18.0.0",
101
89
  "react": ">=18.0.0",
@@ -105,22 +93,5 @@
105
93
  "@types/react": {
106
94
  "optional": true
107
95
  }
108
- },
109
- "devDependencies": {
110
- "@elcrm/storybook": "file:../elCRM.storybook",
111
- "@testing-library/react": "^16.2.0",
112
- "@types/node": "^22.13.10",
113
- "@types/react": "^18.2.66",
114
- "@types/react-dom": "^18.2.22",
115
- "@vitejs/plugin-react": "^4.3.1",
116
- "elcrm": "file:../elCRM.cli",
117
- "jsdom": "^26.0.0",
118
- "react": "^18.2.0",
119
- "react-dom": "^18.2.0",
120
- "typescript": "^5.8.2",
121
- "vite": "^5.4.2",
122
- "vite-plugin-dts": "^4.0.3",
123
- "vite-plugin-lib-inject-css": "^2.1.1",
124
- "vitest": "^3.0.8"
125
96
  }
126
97
  }
@@ -1,156 +0,0 @@
1
- import u, { useRef as E, useId as $, useState as T, useLayoutEffect as A, useEffect as B } from "react";
2
- import { createPortal as ee } from "react-dom";
3
- import { c as F } from "./cx-CcykAxZN.js";
4
- import { u as te } from "./useControllableValue-CWqH1kpM.js";
5
- import './Popover.css';const V = 1e3, ne = 10;
6
- function b() {
7
- const e = globalThis;
8
- return e.elcrm || (e.elcrm = {}), e.elcrm.overlayZ || (e.elcrm.overlayZ = { seq: 0, active: /* @__PURE__ */ new Set() }), e.elcrm.overlayZ;
9
- }
10
- function oe() {
11
- const e = b();
12
- e.seq += 1;
13
- const t = V + e.seq * ne;
14
- return e.active.add(t), t;
15
- }
16
- function N(e) {
17
- const t = b();
18
- t.active.delete(e), t.active.size === 0 && (t.seq = 0);
19
- }
20
- function ve() {
21
- const e = b();
22
- return e.active.size === 0 ? V : Math.max(...e.active);
23
- }
24
- const se = "c3r", ie = "c3t", re = "c3p", H = {
25
- r: se,
26
- t: ie,
27
- p: re
28
- };
29
- function ce(e, t) {
30
- const c = (t == null ? void 0 : t.querySelector("button, a, [role='button']")) ?? (t == null ? void 0 : t.firstElementChild);
31
- return (c instanceof HTMLElement ? c : t ?? e).getBoundingClientRect();
32
- }
33
- function ae(e, t) {
34
- return e != null && e.top === t.top && e.left === t.left && e.minWidth === t.minWidth && e.maxHeight === t.maxHeight;
35
- }
36
- function le(e, t, c, p) {
37
- if (!u.isValidElement(e)) return e;
38
- const d = e.props.onClick;
39
- return u.cloneElement(e, {
40
- "aria-haspopup": "menu",
41
- "aria-expanded": t,
42
- "aria-controls": t ? c : void 0,
43
- onClick: (v) => {
44
- d == null || d(v), p();
45
- }
46
- });
47
- }
48
- function he({
49
- trigger: e,
50
- children: t,
51
- open: c,
52
- defaultOpen: p = !1,
53
- onOpenChange: d,
54
- align: v = "end",
55
- placement: x = "auto",
56
- disabled: z = !1,
57
- label: D,
58
- role: K = "menu",
59
- className: j,
60
- panelClassName: G
61
- }) {
62
- const w = E(null), P = E(null), y = E(null), g = $(), [s = !1, J] = te(
63
- c,
64
- p,
65
- d
66
- ), [m, W] = T(null), [a, q] = T(null), L = E(null);
67
- L.current = a;
68
- const M = (o) => {
69
- z && o || J(o);
70
- };
71
- A(() => {
72
- if (s) {
73
- a == null && q(oe());
74
- return;
75
- }
76
- a != null && (N(a), q(null));
77
- }, [s, a]), B(() => () => {
78
- L.current != null && N(L.current);
79
- }, []);
80
- const R = () => {
81
- var S;
82
- const o = w.current;
83
- if (!o) return;
84
- const n = ce(o, P.current), i = 8, l = 8, r = ((S = y.current) == null ? void 0 : S.offsetHeight) ?? 0, f = window.innerHeight - n.bottom - i - l, U = n.top - i - l, X = r > 0 ? r : 160, I = x === "bottom" || x !== "top" && f >= X, Y = Math.min(
85
- 420,
86
- Math.max(120, I ? f : U)
87
- ), h = Math.max(200, n.width), _ = v === "end" ? Math.max(8, Math.min(n.right - h, window.innerWidth - h - 8)) : Math.max(8, Math.min(n.left, window.innerWidth - h - 8)), O = { top: I ? n.bottom + i : Math.max(l, n.top - i - (r > 0 ? r : 0)), left: _, minWidth: h, maxHeight: Y };
88
- W((C) => ae(C, O) ? C : O);
89
- };
90
- A(() => {
91
- if (!s) {
92
- W(null);
93
- return;
94
- }
95
- R();
96
- const o = window.requestAnimationFrame(() => R()), n = () => R();
97
- return window.addEventListener("resize", n), window.addEventListener("scroll", n, !0), () => {
98
- window.cancelAnimationFrame(o), window.removeEventListener("resize", n), window.removeEventListener("scroll", n, !0);
99
- };
100
- }, [s, v, x, t]), B(() => {
101
- if (!s) return;
102
- const o = (i) => {
103
- var r, f;
104
- const l = i.target;
105
- (r = w.current) != null && r.contains(l) || (f = y.current) != null && f.contains(l) || M(!1);
106
- }, n = (i) => {
107
- i.key === "Escape" && M(!1);
108
- };
109
- return document.addEventListener("mousedown", o), document.addEventListener("keydown", n), () => {
110
- document.removeEventListener("mousedown", o), document.removeEventListener("keydown", n);
111
- };
112
- }, [s]);
113
- const Q = {
114
- position: "fixed",
115
- zIndex: a ?? 1e3,
116
- ...m ? {
117
- top: m.top,
118
- bottom: "auto",
119
- left: m.left,
120
- minWidth: m.minWidth,
121
- maxHeight: m.maxHeight
122
- } : { visibility: "hidden", pointerEvents: "none" }
123
- }, Z = s ? /* @__PURE__ */ u.createElement(
124
- "div",
125
- {
126
- ref: y,
127
- id: g,
128
- role: K,
129
- "aria-label": D,
130
- className: F(H.p, G),
131
- style: Q,
132
- onMouseDown: (o) => o.stopPropagation()
133
- },
134
- t
135
- ) : null, k = () => {
136
- z || M(!s);
137
- };
138
- return /* @__PURE__ */ u.createElement("div", { ref: w, className: F(H.r, j) }, /* @__PURE__ */ u.createElement(
139
- "div",
140
- {
141
- ref: P,
142
- className: H.t,
143
- "aria-haspopup": "menu",
144
- "aria-expanded": s,
145
- "aria-controls": s ? g : void 0,
146
- onClick: u.isValidElement(e) ? void 0 : k
147
- },
148
- le(e, s, g, k)
149
- ), Z && typeof document < "u" ? ee(Z, document.body) : null);
150
- }
151
- export {
152
- he as P,
153
- oe as a,
154
- ve as p,
155
- N as r
156
- };