elcrm 1.1.26 → 1.1.28
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/dist/index.js
CHANGED
|
@@ -1149,6 +1149,11 @@ function isColorToken(name, value) {
|
|
|
1149
1149
|
return true;
|
|
1150
1150
|
return false;
|
|
1151
1151
|
}
|
|
1152
|
+
function isButtonShadowNoise(name, value) {
|
|
1153
|
+
if (!/^--button-.+-shadow(-(hover|active))?$/.test(name))
|
|
1154
|
+
return false;
|
|
1155
|
+
return /^none$/i.test(value.trim());
|
|
1156
|
+
}
|
|
1152
1157
|
function listCssFiles(dir, acc = []) {
|
|
1153
1158
|
if (!existsSync5(dir))
|
|
1154
1159
|
return acc;
|
|
@@ -1425,6 +1430,7 @@ function syncElcrmCss(options) {
|
|
|
1425
1430
|
skippedPkgs.push(name);
|
|
1426
1431
|
allDefs.push(...defs);
|
|
1427
1432
|
}
|
|
1433
|
+
const pkgsWithTokens = new Set(cssExports.filter((e) => e.tokens).map((e) => e.name));
|
|
1428
1434
|
const added = {
|
|
1429
1435
|
"theme.css": [],
|
|
1430
1436
|
"theme-light.css": [],
|
|
@@ -1440,7 +1446,7 @@ function syncElcrmCss(options) {
|
|
|
1440
1446
|
continue;
|
|
1441
1447
|
let css = readFileSync7(file, "utf8");
|
|
1442
1448
|
const have = existingTokenNames(css);
|
|
1443
|
-
const missing = allDefs.filter((d) => d.bucket === bucket && !have.has(d.name) && !d.name.startsWith("--search-") && !TOKEN_DEPRECATED.has(d.name));
|
|
1449
|
+
const missing = allDefs.filter((d) => d.bucket === bucket && !have.has(d.name) && !d.name.startsWith("--search-") && !TOKEN_DEPRECATED.has(d.name) && !isButtonShadowNoise(d.name, d.value) && !(bucket === "geometry" && pkgsWithTokens.has(d.pkg)));
|
|
1444
1450
|
const uniq = [];
|
|
1445
1451
|
const seen = new Set;
|
|
1446
1452
|
for (const d of missing) {
|
|
@@ -1488,6 +1494,32 @@ function syncElcrmCss(options) {
|
|
|
1488
1494
|
}
|
|
1489
1495
|
return { styleDir, added, imports, removedImports, skippedPkgs };
|
|
1490
1496
|
}
|
|
1497
|
+
function stripButtonShadowNoiseFromTheme(styleDir, dry = false) {
|
|
1498
|
+
const file = join5(styleDir, "theme.css");
|
|
1499
|
+
if (!existsSync5(file))
|
|
1500
|
+
return [];
|
|
1501
|
+
const css = readFileSync7(file, "utf8");
|
|
1502
|
+
const lines = css.split(/\r?\n/);
|
|
1503
|
+
const removed = [];
|
|
1504
|
+
const kept = lines.filter((line) => {
|
|
1505
|
+
const m = line.match(/^\s*(--button-[a-z0-9-]+shadow[a-z0-9-]*)\s*:\s*(.+);/i);
|
|
1506
|
+
if (!m)
|
|
1507
|
+
return true;
|
|
1508
|
+
if (!isButtonShadowNoise(m[1], m[2]))
|
|
1509
|
+
return true;
|
|
1510
|
+
removed.push(m[1]);
|
|
1511
|
+
return false;
|
|
1512
|
+
});
|
|
1513
|
+
if (!removed.length)
|
|
1514
|
+
return [];
|
|
1515
|
+
const next = kept.join(`
|
|
1516
|
+
`).replace(/\n{3,}/g, `
|
|
1517
|
+
|
|
1518
|
+
`);
|
|
1519
|
+
if (!dry)
|
|
1520
|
+
writeFileSync3(file, next, "utf8");
|
|
1521
|
+
return removed;
|
|
1522
|
+
}
|
|
1491
1523
|
|
|
1492
1524
|
// src/lib/migrate/socket-server.ts
|
|
1493
1525
|
import {
|
|
@@ -4589,6 +4621,12 @@ async function cmdCss(parsed) {
|
|
|
4589
4621
|
try {
|
|
4590
4622
|
const result = syncElcrmCss({ cwd, pkgNames: names, dry });
|
|
4591
4623
|
console.log(`\u041A\u0430\u0442\u0430\u043B\u043E\u0433 \u0441\u0442\u0438\u043B\u0435\u0439: ${result.styleDir}`);
|
|
4624
|
+
const stripped = stripButtonShadowNoiseFromTheme(result.styleDir, dry);
|
|
4625
|
+
if (stripped.length) {
|
|
4626
|
+
console.log(` ${dry ? "[dry] " : ""}${c.yellow("\u2212")} theme.css: \u0443\u0431\u0440\u0430\u043D\u043E ${stripped.length} button-shadow (none)`);
|
|
4627
|
+
for (const t of stripped)
|
|
4628
|
+
console.log(` ${c.dim(t)}`);
|
|
4629
|
+
}
|
|
4592
4630
|
let total = 0;
|
|
4593
4631
|
for (const [file, tokens] of Object.entries(result.added)) {
|
|
4594
4632
|
if (!tokens.length) {
|
package/package.json
CHANGED
|
@@ -18,7 +18,7 @@ elcrm cursor
|
|
|
18
18
|
| # | Команда | Что делает |
|
|
19
19
|
| --- | --- | --- |
|
|
20
20
|
| 1 | `elcrm update --fix --test` | Обновляет глобальный `elcrm` + все `@elcrm/*` в `package.json` → install → **migrate front** (API/токены/css-sanitize) → внутри `--fix` ещё раз **sync CSS** → `elcrm test` |
|
|
21
|
-
| 2 | `elcrm css` | Недостающие
|
|
21
|
+
| 2 | `elcrm css` | Недостающие **цвета** → `theme-light` / `theme-dark`. Геометрию из пакетов с `tokens.css` **не** дублирует в `theme.css` (дефолты через `@import …/tokens.css`). **Не дописывает** `--button-*-shadow: none` и снимает такие строки. В `elcrm.css`: **добавляет** рабочие `@import`, **удаляет битые**. Затем css-sanitize |
|
|
22
22
|
| 3 | `elcrm docs` | Перезаписывает `docs/*.elCRM.md` (шпаргалки пакетов) |
|
|
23
23
|
| 4 | `elcrm cursor` | `.cursor/rules` + `.cursor/docs` + `AGENTS.md` для агента |
|
|
24
24
|
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
Card, Stat, ActionGroup, Toolbar, TextGroup, ItemColumn, List, Item, PageHead, PageShell, ChatList, ChatMessages, ChatSplit, Sidebar, Popover,
|
|
18
18
|
Healthmap, PanelInfo,
|
|
19
19
|
Loading, EmptyState, RadioGroup, PricingGroup, PricingTable,
|
|
20
|
-
Table, CodeBlock, SplitPane, Banner, IconButton,
|
|
20
|
+
Table, CodeBlock, SplitPane, Banner, IconButton, Text,
|
|
21
21
|
createLazyResolver,
|
|
22
22
|
} from "@elcrm/components";
|
|
23
23
|
import type { PricingPlan, HealthmapData } from "@elcrm/components";
|
|
@@ -42,6 +42,9 @@ import type { PricingPlan, HealthmapData } from "@elcrm/components";
|
|
|
42
42
|
- **ActionGroup** — ряд иконок в карточке / строке: `label` + `items` и/или `children`. Кнопки — `@elcrm/button`.
|
|
43
43
|
- **Toolbar** — фильтры над списком. `size` (`s`/`m`/`l`, по умолчанию `s`) наследуют вложенные `*Field`, `Search`, `Button`, `Dropdown` (свой `size` важнее). `align`: `start` / `center` / `end` / `between`. `width`: `l` (100%, по умолчанию) или `s` (по контенту, не растягивать). Токены `--toolbar-gap`. Не `ActionGroup`.
|
|
44
44
|
- **TextGroup** — две строки: `title` + `description` (без аватара; с аватаром — AvatarName).
|
|
45
|
+
- **Text** — короткий текст. `tone="muted"` → `--shell-color-muted`. `as` — тег (`p`/`span`/…). Не `className="muted"` в приложении.
|
|
46
|
+
- **Loading** — индикатор ожидания. Мин. высота: `--loading-min-height` (`min(50vh, 24rem)`).
|
|
47
|
+
- **EmptyState** — заглушка / ошибка страницы. `--empty-max-width`, `--empty-padding`.
|
|
45
48
|
- **Item** — строка списка. `as` button/a/li, `active`. `variant="card"` — рамка и muted-фон (идеи / тикеты / inbox). Не дублировать `.desk-row` в приложении.
|
|
46
49
|
- **ItemColumn** — внутри Item: `icon` слева, столбик `title` / `description` / `footer` или `meta`, `extra` — бейджи справа сверху, `aside` — колонка справа. `unread` — жирный title. Title: `--item-column-title-size` / `--item-column-title-line` (в console = `--button-size-s` / `--button-line-height`).
|
|
47
50
|
- **Table** — `<table>` в обёртке со скроллом. `layout="fixed"` для фиксированной сетки. Токены `--table-*`.
|
|
@@ -20,24 +20,6 @@
|
|
|
20
20
|
--button-size-s: 14px;
|
|
21
21
|
--button-size-m: 16px;
|
|
22
22
|
--button-size-l: 18px;
|
|
23
|
-
--button-shadow: none;
|
|
24
|
-
--button-shadow-hover: none;
|
|
25
|
-
--button-shadow-active: none;
|
|
26
|
-
--button-primary-shadow: none;
|
|
27
|
-
--button-primary-hover-shadow: none;
|
|
28
|
-
--button-primary-active-shadow: none;
|
|
29
|
-
--button-secondary-shadow: none;
|
|
30
|
-
--button-secondary-hover-shadow: none;
|
|
31
|
-
--button-secondary-active-shadow: none;
|
|
32
|
-
--button-positive-shadow: none;
|
|
33
|
-
--button-positive-hover-shadow: none;
|
|
34
|
-
--button-positive-active-shadow: none;
|
|
35
|
-
--button-negative-shadow: none;
|
|
36
|
-
--button-negative-hover-shadow: none;
|
|
37
|
-
--button-negative-active-shadow: none;
|
|
38
|
-
--button-ghost-shadow: none;
|
|
39
|
-
--button-ghost-hover-shadow: none;
|
|
40
|
-
--button-ghost-active-shadow: none;
|
|
41
23
|
|
|
42
24
|
/* —— form / control —— */
|
|
43
25
|
--control-height: 44px;
|
|
@@ -166,6 +148,26 @@
|
|
|
166
148
|
--healthmap-l2: color-mix(in srgb, var(--shell-color-success) 45%, transparent);
|
|
167
149
|
--healthmap-l3: color-mix(in srgb, var(--shell-color-success) 70%, transparent);
|
|
168
150
|
--healthmap-l4: var(--shell-color-success);
|
|
151
|
+
--table-font-size: 0.9rem;
|
|
152
|
+
--table-cell-padding: 0.55rem 0.7rem;
|
|
153
|
+
--table-head-font-size: 0.75rem;
|
|
154
|
+
--table-code-font-size: 0.8rem;
|
|
155
|
+
--code-block-bg: var(--shell-background);
|
|
156
|
+
--code-block-bar-padding: 0.4rem 0.75rem;
|
|
157
|
+
--code-block-padding: 0.85rem 1rem;
|
|
158
|
+
--code-block-font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
159
|
+
--code-block-font-size: 0.8rem;
|
|
160
|
+
--code-block-line-height: 1.55;
|
|
161
|
+
--split-handle-size: 6px;
|
|
162
|
+
--split-handle-bg: var(--shell-border);
|
|
163
|
+
--split-handle-bg-hover: color-mix(
|
|
164
|
+
in srgb,
|
|
165
|
+
var(--shell-color-accent) 25%,
|
|
166
|
+
var(--shell-border)
|
|
167
|
+
);
|
|
168
|
+
--banner-padding: 0.55rem 0.85rem;
|
|
169
|
+
--banner-bg: color-mix(in srgb, var(--shell-color-accent) 8%, var(--shell-bg));
|
|
170
|
+
--banner-border: color-mix(in srgb, var(--shell-color-accent) 35%, var(--shell-border));
|
|
169
171
|
}
|
|
170
172
|
|
|
171
173
|
/* —— база приложения (без захардкоженных цветов) —— */
|
|
@@ -20,24 +20,6 @@
|
|
|
20
20
|
--button-size-s: 14px;
|
|
21
21
|
--button-size-m: 16px;
|
|
22
22
|
--button-size-l: 18px;
|
|
23
|
-
--button-shadow: none;
|
|
24
|
-
--button-shadow-hover: none;
|
|
25
|
-
--button-shadow-active: none;
|
|
26
|
-
--button-primary-shadow: none;
|
|
27
|
-
--button-primary-hover-shadow: none;
|
|
28
|
-
--button-primary-active-shadow: none;
|
|
29
|
-
--button-secondary-shadow: none;
|
|
30
|
-
--button-secondary-hover-shadow: none;
|
|
31
|
-
--button-secondary-active-shadow: none;
|
|
32
|
-
--button-positive-shadow: none;
|
|
33
|
-
--button-positive-hover-shadow: none;
|
|
34
|
-
--button-positive-active-shadow: none;
|
|
35
|
-
--button-negative-shadow: none;
|
|
36
|
-
--button-negative-hover-shadow: none;
|
|
37
|
-
--button-negative-active-shadow: none;
|
|
38
|
-
--button-ghost-shadow: none;
|
|
39
|
-
--button-ghost-hover-shadow: none;
|
|
40
|
-
--button-ghost-active-shadow: none;
|
|
41
23
|
|
|
42
24
|
/* —— form / control —— */
|
|
43
25
|
--control-height: 44px;
|
|
@@ -177,6 +159,26 @@
|
|
|
177
159
|
--healthmap-l2: color-mix(in srgb, var(--shell-color-success) 45%, transparent);
|
|
178
160
|
--healthmap-l3: color-mix(in srgb, var(--shell-color-success) 70%, transparent);
|
|
179
161
|
--healthmap-l4: var(--shell-color-success);
|
|
162
|
+
--table-font-size: 0.9rem;
|
|
163
|
+
--table-cell-padding: 0.55rem 0.7rem;
|
|
164
|
+
--table-head-font-size: 0.75rem;
|
|
165
|
+
--table-code-font-size: 0.8rem;
|
|
166
|
+
--code-block-bg: var(--shell-background);
|
|
167
|
+
--code-block-bar-padding: 0.4rem 0.75rem;
|
|
168
|
+
--code-block-padding: 0.85rem 1rem;
|
|
169
|
+
--code-block-font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
170
|
+
--code-block-font-size: 0.8rem;
|
|
171
|
+
--code-block-line-height: 1.55;
|
|
172
|
+
--split-handle-size: 6px;
|
|
173
|
+
--split-handle-bg: var(--shell-border);
|
|
174
|
+
--split-handle-bg-hover: color-mix(
|
|
175
|
+
in srgb,
|
|
176
|
+
var(--shell-color-accent) 25%,
|
|
177
|
+
var(--shell-border)
|
|
178
|
+
);
|
|
179
|
+
--banner-padding: 0.55rem 0.85rem;
|
|
180
|
+
--banner-bg: color-mix(in srgb, var(--shell-color-accent) 8%, var(--shell-bg));
|
|
181
|
+
--banner-border: color-mix(in srgb, var(--shell-color-accent) 35%, var(--shell-border));
|
|
180
182
|
}
|
|
181
183
|
|
|
182
184
|
/* —— база приложения (без захардкоженных цветов) —— */
|