@elcrm/components 0.2.11 → 0.2.13

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 CHANGED
@@ -49,6 +49,11 @@ import {
49
49
  RadioGroup,
50
50
  PricingGroup,
51
51
  PricingTable,
52
+ Table,
53
+ CodeBlock,
54
+ SplitPane,
55
+ Banner,
56
+ IconButton,
52
57
  Dropdown,
53
58
  Breadcrumb,
54
59
  PageHead,
@@ -88,6 +93,11 @@ import { RadioGroup } from "@elcrm/components/RadioGroup";
88
93
  | **RadioGroup** | Выбор одной опции-карточки | `items`, `value`, `indicator`, `indicatorSide` |
89
94
  | **PricingGroup** | Тарифные карточки в ряд | `items` (`PricingPlan`), `selectable`, `value` |
90
95
  | **PricingTable** | Сравнение тарифов (таблица) | те же `items` + `sections` |
96
+ | **Table** | Таблица данных со скроллом | `layout` (`auto`/`fixed`), стандартные props `<table>` |
97
+ | **CodeBlock** | Блок кода с bar и копированием | `title`, `code` / `children`, `onCopy`, `actions` |
98
+ | **SplitPane** | Две панели с разделителем | `direction`, `ratio`, `onRatioChange`, `first`, `second`, `minFirst` / `minSecond` |
99
+ | **Banner** | Статусная полоса | `tone` (`info`/`warning`/`danger`/`success`), не toast |
100
+ | **IconButton** | Иконка + tooltip | `name`, обязательный `label`, `tooltip` (`false` — без подсказки) |
91
101
  | **Menu** | Навигация в шапке (не popover) | `items` (`value`, `badge`: `0` скрыт), `value`, `onSelect`, `variant` (`plain`/`line`) |
92
102
  | **Dropdown** | Выпадающее меню (items, portal) | `label`/`trigger`, `items`/`groups`, `onSelect` |
93
103
  | **Popover** | Свой попап в portal | `trigger`, `children`, `align`, `open` |
@@ -760,6 +770,10 @@ const resolve = createLazyResolver(
760
770
  --stack-grid-min
761
771
  --toolbar-gap
762
772
  --healthmap-cell / --healthmap-gap / --healthmap-l0…l4
773
+ --table-font-size / --table-cell-padding / --table-head-font-size / --table-code-font-size
774
+ --code-block-bg / --code-block-padding / --code-block-font-size
775
+ --split-handle-size / --split-handle-bg / --split-handle-bg-hover
776
+ --banner-padding / --banner-bg / --banner-border
763
777
  --panel-info-width / --panel-info-width-min / --panel-info-overlay-max / --panel-info-backdrop
764
778
  --row-gap / --column-gap
765
779
  --popup-shadow
@@ -0,0 +1,34 @@
1
+ import e from "react";
2
+ import { c as a } from "./cx-CcykAxZN.js";
3
+ import './Banner.css';const i = "cLr", d = "cLi", m = "cLw", f = "cLd", w = "cLs", s = {
4
+ r: i,
5
+ i: d,
6
+ w: m,
7
+ d: f,
8
+ s: w
9
+ }, L = {
10
+ info: s.i,
11
+ warning: s.w,
12
+ danger: s.d,
13
+ success: s.s
14
+ };
15
+ function p({
16
+ tone: c = "info",
17
+ className: n,
18
+ role: t = "status",
19
+ children: o,
20
+ ...r
21
+ }) {
22
+ return /* @__PURE__ */ e.createElement(
23
+ "div",
24
+ {
25
+ className: a(s.r, L[c], n),
26
+ role: t,
27
+ ...r
28
+ },
29
+ o
30
+ );
31
+ }
32
+ export {
33
+ p as B
34
+ };
@@ -0,0 +1 @@
1
+ @layer elcrm-components{.cLr{margin:0;padding:var(--banner-padding);border:1px solid var(--banner-border);border-radius:var(--shell-radius);background:var(--banner-bg);font-size:var(--shell-font-size-sm);color:var(--shell-color);line-height:1.45}.cLi{--banner-bg: color-mix(in srgb, var(--shell-color-accent) 8%, var(--shell-bg));--banner-border: color-mix(in srgb, var(--shell-color-accent) 35%, var(--shell-border))}.cLw{--banner-bg: color-mix(in srgb, var(--shell-color-warning) 10%, var(--shell-bg));--banner-border: color-mix(in srgb, var(--shell-color-warning) 40%, var(--shell-border))}.cLd{--banner-bg: color-mix(in srgb, var(--shell-color-danger) 10%, var(--shell-bg));--banner-border: color-mix(in srgb, var(--shell-color-danger) 40%, var(--shell-border))}.cLs{--banner-bg: color-mix(in srgb, var(--shell-color-success) 10%, var(--shell-bg));--banner-border: color-mix(in srgb, var(--shell-color-success) 40%, var(--shell-border))}.cLr code{font-size:.92em}}
@@ -0,0 +1,19 @@
1
+ import { default as React } from 'react';
2
+ export type BannerTone = "info" | "warning" | "danger" | "success";
3
+ export type BannerProps = React.HTMLAttributes<HTMLDivElement> & {
4
+ /** Визуальный акцент */
5
+ tone?: BannerTone;
6
+ };
7
+ /**
8
+ * Статусная полоса (offline, maintenance). Не toast — не путать с Notice.
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * <Banner tone="info" role="status">
13
+ * Каталог из снимка <code>kit-catalog.json</code>
14
+ * </Banner>
15
+ * ```
16
+ *
17
+ * Токены: `--banner-*`, `--shell-bg`.
18
+ */
19
+ export declare function Banner({ tone, className, role, children, ...rest }: BannerProps): React.JSX.Element;
package/dist/Banner.js ADDED
@@ -0,0 +1,4 @@
1
+ import { B as e } from "./Banner-B72lcEMo.js";
2
+ export {
3
+ e as Banner
4
+ };
@@ -0,0 +1,25 @@
1
+ import e from "react";
2
+ import { c as u } from "./cx-CcykAxZN.js";
3
+ import './CodeBlock.css';const p = "cEr", b = "cEb", d = "cEp", i = "cEa", N = "cEc", c = {
4
+ r: p,
5
+ b,
6
+ p: d,
7
+ a: i,
8
+ c: N
9
+ };
10
+ function k({
11
+ title: l,
12
+ code: n,
13
+ children: s,
14
+ onCopy: t,
15
+ copyLabel: r = "Копировать",
16
+ actions: a,
17
+ className: m,
18
+ ...o
19
+ }) {
20
+ const E = s ?? (n != null ? /* @__PURE__ */ e.createElement("code", null, n) : null);
21
+ return /* @__PURE__ */ e.createElement("div", { className: u(c.r, m), ...o }, l != null || t || a ? /* @__PURE__ */ e.createElement("div", { className: c.b }, /* @__PURE__ */ e.createElement("span", null, l ?? "Код"), /* @__PURE__ */ e.createElement("div", { className: c.a }, a, t ? /* @__PURE__ */ e.createElement("button", { type: "button", className: c.c, onClick: t }, r) : null)) : null, /* @__PURE__ */ e.createElement("pre", { className: c.p }, E));
22
+ }
23
+ export {
24
+ k as C
25
+ };
@@ -0,0 +1 @@
1
+ @layer elcrm-components{.cEr{border:1px solid var(--shell-border);border-radius:var(--shell-radius);background:var(--code-block-bg);overflow:hidden}.cEb{display:flex;justify-content:space-between;align-items:center;gap:var(--shell-gap-sm);padding:var(--code-block-bar-padding);border-bottom:1px solid var(--shell-border);font-size:var(--shell-font-size-sm);color:var(--shell-color-muted)}.cEp{margin:0;padding:var(--code-block-padding);overflow:auto;font-family:var(--code-block-font-family);font-size:var(--code-block-font-size);line-height:var(--code-block-line-height);color:var(--shell-color);white-space:pre}.cEa{display:inline-flex;align-items:center;gap:.35rem;flex-shrink:0}.cEc{border:0;background:transparent;color:var(--shell-color-accent);cursor:pointer;font:inherit;padding:0}.cEc:hover,.cEc:focus-visible{text-decoration:underline}}
@@ -0,0 +1,26 @@
1
+ import { default as React } from 'react';
2
+ export type CodeBlockProps = React.HTMLAttributes<HTMLDivElement> & {
3
+ /** Заголовок в полосе над кодом */
4
+ title?: React.ReactNode;
5
+ /** Текст без подсветки (если нет children) */
6
+ code?: string;
7
+ /** Подсветка / разметка — свой рендер в pre */
8
+ children?: React.ReactNode;
9
+ /** Кнопка «Копировать»; без onCopy не показывается */
10
+ onCopy?: () => void;
11
+ /** Подпись кнопки копирования */
12
+ copyLabel?: string;
13
+ /** Доп. действия справа в bar */
14
+ actions?: React.ReactNode;
15
+ };
16
+ /**
17
+ * Блок кода: bar + pre. Подсветку передаёт приложение через `children`.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * <CodeBlock title="Пример" code={snippet} onCopy={() => copy(snippet)} />
22
+ * ```
23
+ *
24
+ * Токены: `--code-block-*`, `--shell-border`.
25
+ */
26
+ export declare function CodeBlock({ title, code, children, onCopy, copyLabel, actions, className, ...rest }: CodeBlockProps): React.JSX.Element;
@@ -0,0 +1,4 @@
1
+ import { C as r } from "./CodeBlock-CRzVopIv.js";
2
+ export {
3
+ r as CodeBlock
4
+ };
@@ -0,0 +1,32 @@
1
+ import t from "react";
2
+ import { IconButton as f } from "@elcrm/button/IconButton";
3
+ import { Icons as p } from "@elcrm/icons";
4
+ import { Tooltip as u } from "@elcrm/tooltip";
5
+ const I = {
6
+ s: 16,
7
+ m: 18,
8
+ l: 20
9
+ };
10
+ function C({
11
+ name: c,
12
+ label: n,
13
+ tooltip: o,
14
+ iconSize: m,
15
+ size: e = "m",
16
+ tooltipPlacement: i,
17
+ ...s
18
+ }) {
19
+ const a = m ?? I[e], r = /* @__PURE__ */ t.createElement(
20
+ f,
21
+ {
22
+ label: n,
23
+ size: e,
24
+ icon: /* @__PURE__ */ t.createElement(p.Line, { name: c, size: a }),
25
+ ...s
26
+ }
27
+ );
28
+ return o === !1 ? r : /* @__PURE__ */ t.createElement(u, { content: o ?? n, placement: i }, r);
29
+ }
30
+ export {
31
+ C as I
32
+ };
@@ -0,0 +1,27 @@
1
+ import { default as React } from 'react';
2
+ import { TIconButton } from '@elcrm/button/IconButton';
3
+ import { TButtonSize } from '@elcrm/button';
4
+ import { TooltipPlacement } from '@elcrm/tooltip';
5
+ export type IconButtonProps = Omit<TIconButton, "icon" | "label" | "size"> & {
6
+ /** Имя из `icons update` / `Icons.Line` (в приложении — `IconLineName`) */
7
+ name: string;
8
+ /** Подпись: `aria-label` и текст tooltip по умолчанию */
9
+ label: string;
10
+ size?: TButtonSize;
11
+ /** Подсказка; `false` — без Tooltip (например, внутри toolbar с aria-label) */
12
+ tooltip?: React.ReactNode | false;
13
+ /** Размер SVG; по умолчанию от `size` кнопки */
14
+ iconSize?: number;
15
+ /** Сторона tooltip */
16
+ tooltipPlacement?: TooltipPlacement;
17
+ };
18
+ /**
19
+ * Иконка-кнопка: `Icons.Line` + {@link ShellIconButton} + {@link Tooltip}.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * <IconButton name="power" label="Выход" onClick={logout} />
24
+ * <IconButton name="copy_01" label="Копировать" tooltip="Скопировать CSS" onClick={copy} />
25
+ * ```
26
+ */
27
+ export declare function IconButton({ name, label, tooltip, iconSize, size, tooltipPlacement, ...rest }: IconButtonProps): React.JSX.Element;
@@ -0,0 +1,4 @@
1
+ import { I as n } from "./IconButton-DPjpBKJn.js";
2
+ export {
3
+ n as IconButton
4
+ };
@@ -0,0 +1,74 @@
1
+ import o from "react";
2
+ import { c as P } from "./cx-CcykAxZN.js";
3
+ import './SplitPane.css';function $(t, e, l, i) {
4
+ if (e <= 0) return t;
5
+ const r = l / e, c = 1 - i / e;
6
+ return c < r ? 0.5 : Math.max(r, Math.min(c, t));
7
+ }
8
+ const B = "cFr", C = "cFx", D = "cFy", H = "cFp", X = "cFh", n = {
9
+ r: B,
10
+ x: C,
11
+ y: D,
12
+ p: H,
13
+ h: X
14
+ }, z = 6;
15
+ function E() {
16
+ if (typeof document > "u") return z;
17
+ const t = getComputedStyle(document.documentElement).getPropertyValue("--split-handle-size").trim(), e = Number.parseFloat(t);
18
+ return Number.isFinite(e) && e > 0 ? e : z;
19
+ }
20
+ function V({
21
+ direction: t,
22
+ ratio: e,
23
+ onRatioChange: l,
24
+ minFirst: i = 140,
25
+ minSecond: r = 140,
26
+ first: c,
27
+ second: S,
28
+ className: b,
29
+ ...F
30
+ }) {
31
+ const m = o.useRef(null), R = t === "horizontal" ? "x" : "y", N = (u) => {
32
+ u.preventDefault();
33
+ const p = m.current;
34
+ if (!p) return;
35
+ const f = E(), s = p.getBoundingClientRect(), h = t === "horizontal" ? s.width - f : s.height - f, y = (a, L) => {
36
+ const M = t === "horizontal" ? a - s.left : L - s.top;
37
+ l($(M / h, h, i, r));
38
+ };
39
+ y(u.clientX, u.clientY);
40
+ const x = (a) => {
41
+ y(a.clientX, a.clientY);
42
+ }, v = () => {
43
+ document.removeEventListener("pointermove", x), document.removeEventListener("pointerup", v), document.body.style.cursor = "", document.body.style.userSelect = "";
44
+ };
45
+ document.body.style.cursor = t === "horizontal" ? "col-resize" : "row-resize", document.body.style.userSelect = "none", document.addEventListener("pointermove", x), document.addEventListener("pointerup", v);
46
+ }, d = E(), g = `calc((100% - ${d}px) * ${e})`, w = `calc((100% - ${d}px) * ${1 - e})`;
47
+ return /* @__PURE__ */ o.createElement(
48
+ "div",
49
+ {
50
+ ref: m,
51
+ className: P(n.r, R === "x" ? n.x : n.y, b),
52
+ ...F
53
+ },
54
+ /* @__PURE__ */ o.createElement("div", { className: n.p, style: { flexBasis: g } }, c),
55
+ /* @__PURE__ */ o.createElement(
56
+ "button",
57
+ {
58
+ type: "button",
59
+ className: n.h,
60
+ role: "separator",
61
+ "aria-orientation": t === "horizontal" ? "vertical" : "horizontal",
62
+ "aria-valuenow": Math.round(e * 100),
63
+ "aria-valuemin": 0,
64
+ "aria-valuemax": 100,
65
+ onPointerDown: N
66
+ }
67
+ ),
68
+ /* @__PURE__ */ o.createElement("div", { className: n.p, style: { flexBasis: w } }, S)
69
+ );
70
+ }
71
+ export {
72
+ V as S,
73
+ $ as c
74
+ };
@@ -0,0 +1 @@
1
+ @layer elcrm-components{.cFr{display:flex;min-height:0;min-width:0}.cFx{flex-direction:row}.cFy{flex-direction:column}.cFp{min-width:0;min-height:0;overflow:auto}.cFh{flex:0 0 var(--split-handle-size);margin:0;padding:0;border:0;background:var(--split-handle-bg);cursor:col-resize;touch-action:none}.cFy .cFh{cursor:row-resize}.cFh:hover,.cFh:focus-visible{background:var(--split-handle-bg-hover)}}
@@ -0,0 +1,29 @@
1
+ import { default as React } from 'react';
2
+ export type SplitPaneDirection = "horizontal" | "vertical";
3
+ export type SplitPaneProps = React.HTMLAttributes<HTMLDivElement> & {
4
+ direction: SplitPaneDirection;
5
+ /** Доля первой панели 0…1 */
6
+ ratio: number;
7
+ onRatioChange: (ratio: number) => void;
8
+ minFirst?: number;
9
+ minSecond?: number;
10
+ first: React.ReactNode;
11
+ second: React.ReactNode;
12
+ };
13
+ /**
14
+ * Две панели с перетаскиваемым разделителем.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * <SplitPane
19
+ * direction="horizontal"
20
+ * ratio={0.58}
21
+ * onRatioChange={setRatio}
22
+ * first={<Preview />}
23
+ * second={<Editor />}
24
+ * />
25
+ * ```
26
+ *
27
+ * Токены: `--split-handle-size`, `--split-handle-bg`.
28
+ */
29
+ export declare function SplitPane({ direction, ratio, onRatioChange, minFirst, minSecond, first, second, className, ...rest }: SplitPaneProps): React.JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { S as t, c as i } from "./SplitPane-DR7PCZ8f.js";
2
+ export {
3
+ t as SplitPane,
4
+ i as clampSplitRatio
5
+ };
@@ -0,0 +1,25 @@
1
+ import e from "react";
2
+ import { c as n } from "./cx-CcykAxZN.js";
3
+ import './Table.css';const r = "cDw", f = "cDt", m = "cDf", t = {
4
+ w: r,
5
+ t: f,
6
+ f: m
7
+ };
8
+ function w({
9
+ layout: c = "auto",
10
+ className: a,
11
+ children: o,
12
+ ...s
13
+ }) {
14
+ return /* @__PURE__ */ e.createElement("div", { className: t.w }, /* @__PURE__ */ e.createElement(
15
+ "table",
16
+ {
17
+ className: n(t.t, c === "fixed" && t.f, a),
18
+ ...s
19
+ },
20
+ o
21
+ ));
22
+ }
23
+ export {
24
+ w as T
25
+ };
package/dist/Table.css ADDED
@@ -0,0 +1 @@
1
+ @layer elcrm-components{.cDw{overflow:auto}.cDt{width:100%;border-collapse:collapse;font-size:var(--table-font-size);color:var(--shell-color)}.cDf{table-layout:fixed}.cDt th,.cDt td{padding:var(--table-cell-padding);border-bottom:1px solid var(--shell-border);text-align:left;vertical-align:top}.cDt th{color:var(--shell-color-muted);font-weight:var(--shell-font-weight);font-size:var(--table-head-font-size);text-transform:uppercase;letter-spacing:.04em}.cDt code{font-size:var(--table-code-font-size)}}
@@ -0,0 +1,29 @@
1
+ import { default as React } from 'react';
2
+ export type TableProps = React.TableHTMLAttributes<HTMLTableElement> & {
3
+ /** `fixed` — равномерные колонки, ширины через col/colgroup в children. */
4
+ layout?: "auto" | "fixed";
5
+ };
6
+ /**
7
+ * Таблица данных: обёртка со скроллом + стили shell.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * <Table>
12
+ * <thead>
13
+ * <tr>
14
+ * <th>Имя</th>
15
+ * <th>Тип</th>
16
+ * </tr>
17
+ * </thead>
18
+ * <tbody>
19
+ * <tr>
20
+ * <td><code>label</code></td>
21
+ * <td>string</td>
22
+ * </tr>
23
+ * </tbody>
24
+ * </Table>
25
+ * ```
26
+ *
27
+ * Токены: `--table-*`, `--shell-border`, `--shell-color`.
28
+ */
29
+ export declare function Table({ layout, className, children, ...rest }: TableProps): React.JSX.Element;
package/dist/Table.js ADDED
@@ -0,0 +1,4 @@
1
+ import { T as o } from "./Table-BoDr3X2d.js";
2
+ export {
3
+ o as Table
4
+ };
package/dist/index.css CHANGED
@@ -8,6 +8,8 @@
8
8
 
9
9
  @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:600;line-height:1;white-space:nowrap}.cjs{padding:2px var(--shell-gap-sm);font-size:var(--shell-font-size-sm);letter-spacing:.04em}.cjm{padding:.2rem .5rem;font-size:var(--shell-font-size-sm)}.cjl{padding:.3rem .65rem;font-size:var(--shell-font-size)}.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)}.cjo{flex-shrink:0;width:.45em;height:.45em;border-radius:50%;background:currentColor}}
10
10
 
11
+ @layer elcrm-components{.cLr{margin:0;padding:var(--banner-padding);border:1px solid var(--banner-border);border-radius:var(--shell-radius);background:var(--banner-bg);font-size:var(--shell-font-size-sm);color:var(--shell-color);line-height:1.45}.cLi{--banner-bg: color-mix(in srgb, var(--shell-color-accent) 8%, var(--shell-bg));--banner-border: color-mix(in srgb, var(--shell-color-accent) 35%, var(--shell-border))}.cLw{--banner-bg: color-mix(in srgb, var(--shell-color-warning) 10%, var(--shell-bg));--banner-border: color-mix(in srgb, var(--shell-color-warning) 40%, var(--shell-border))}.cLd{--banner-bg: color-mix(in srgb, var(--shell-color-danger) 10%, var(--shell-bg));--banner-border: color-mix(in srgb, var(--shell-color-danger) 40%, var(--shell-border))}.cLs{--banner-bg: color-mix(in srgb, var(--shell-color-success) 10%, var(--shell-bg));--banner-border: color-mix(in srgb, var(--shell-color-success) 40%, var(--shell-border))}.cLr code{font-size:.92em}}
12
+
11
13
  @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)}}
12
14
 
13
15
  @layer elcrm-components{.c0r{display:flex;flex-wrap:wrap;align-items:center;gap:var(--shell-gap-sm);list-style:none;margin:0;padding:0;font-size:var(--shell-font-size-sm);font-weight:var(--shell-font-weight);color:var(--shell-color-muted);line-height:1.3}.c0i{display:inline-flex;align-items:center;gap:var(--shell-gap-sm);min-width:0;color:inherit}.c0i:is(a,button){-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;padding:0;border:none;background:transparent;font:inherit;font-weight:inherit;color:inherit;cursor:pointer;text-decoration:none}.c0i:is(a,button):hover{color:var(--shell-color)}.c0c,.c0i[aria-current=page]{color:var(--shell-color-accent);cursor:default}.c0n{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:var(--shell-icon-size);height:var(--shell-icon-size);overflow:hidden;border-radius:calc(var(--shell-radius) * .5);color:inherit}.c0n img{width:100%;height:100%;object-fit:cover;display:block}.c0l{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.c0d{display:inline-flex;flex-shrink:0;width:.75rem;height:.75rem;color:var(--shell-color-muted)}.c0s{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;color:var(--shell-color-muted);-webkit-user-select:none;user-select:none}.c0v{width:.75rem;height:.75rem;display:block}.c0e{display:inline-flex;align-items:center;justify-content:center;min-width:1em;color:var(--shell-color-muted);letter-spacing:.05em}.c0e:is(button){-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;padding:.15rem .35rem;border:none;border-radius:calc(var(--shell-radius) * .4);background:transparent;font:inherit;color:inherit;cursor:pointer}.c0e:is(button):hover{background:var(--shell-background-hover);color:var(--shell-color)}}
@@ -16,6 +18,8 @@
16
18
 
17
19
  @layer elcrm-components{.c8r{display:flex;flex-direction:column;box-sizing:border-box;min-width:0;min-height:0;height:100%;overflow:hidden;background:var(--chat-background);border:var(--chat-border);border-radius:var(--chat-radius)}.c8l{width:var(--chat-list-width);max-width:100%}.c8g{width:100%}.c8h{flex:0 0 auto;padding:var(--chat-header-padding);border-bottom:var(--chat-border)}.c8b{flex:1 1 auto;min-height:0;overflow:auto;padding:var(--chat-body-padding)}.c8g .c8h{padding:var(--chat-messages-header-padding)}.c8g .c8b{display:flex;flex-direction:column;padding:var(--chat-messages-body-padding)}.c8f{flex:0 0 auto;padding:var(--chat-footer-padding);border-top:var(--chat-border)}.c8g .c8f{padding:var(--chat-messages-footer-padding)}.c8p{display:flex;align-items:stretch;gap:var(--chat-split-gap);min-height:0;height:100%}.c8p>*{min-height:0}}
18
20
 
21
+ @layer elcrm-components{.cEr{border:1px solid var(--shell-border);border-radius:var(--shell-radius);background:var(--code-block-bg);overflow:hidden}.cEb{display:flex;justify-content:space-between;align-items:center;gap:var(--shell-gap-sm);padding:var(--code-block-bar-padding);border-bottom:1px solid var(--shell-border);font-size:var(--shell-font-size-sm);color:var(--shell-color-muted)}.cEp{margin:0;padding:var(--code-block-padding);overflow:auto;font-family:var(--code-block-font-family);font-size:var(--code-block-font-size);line-height:var(--code-block-line-height);color:var(--shell-color);white-space:pre}.cEa{display:inline-flex;align-items:center;gap:.35rem;flex-shrink:0}.cEc{border:0;background:transparent;color:var(--shell-color-accent);cursor:pointer;font:inherit;padding:0}.cEc:hover,.cEc:focus-visible{text-decoration:underline}}
22
+
19
23
  @layer elcrm-components{.crr{position:relative;display:inline-flex;vertical-align:middle}.crt{display:inline-flex;align-items:center;gap:var(--shell-gap-sm);margin:0;padding:var(--shell-padding);box-sizing:border-box;font:inherit;font-size:var(--shell-font-size);font-weight:var(--shell-font-weight);color:var(--shell-color);background:var(--shell-background);border:1px solid var(--shell-border);border-radius:var(--shell-radius);cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1.2}.crt[data-size]{height:var(--control-height);min-height:var(--control-height);padding-block:0;box-sizing:border-box}.crt:hover{background:var(--shell-background-hover)}.crt[data-open=true]{border-color:var(--shell-color-accent);color:var(--shell-color-accent)}.crc{display:inline-flex;width:var(--shell-icon-size);height:var(--shell-icon-size);flex-shrink:0;color:var(--shell-color-muted)}.crt[data-open=true] .crc{color:var(--shell-color-accent)}.crp{min-width:0}.crh{margin:0;padding:var(--shell-padding);font-size:var(--shell-font-size-sm);font-weight:var(--shell-font-weight);color:var(--shell-color-muted);line-height:1.3}.crg{display:flex;flex-direction:column;gap:2px}.crd{height:0;margin:var(--shell-gap-sm) 0;border:0;border-top:1px solid var(--shell-border)}.cri{display:flex;align-items:center;gap:var(--shell-gap-sm);width:100%;margin:0;padding:var(--shell-padding);box-sizing:border-box;text-align:left;font:inherit;font-size:var(--shell-font-size);font-weight:500;color:var(--shell-color);background:transparent;border:none;border-radius:calc(var(--shell-radius) * .7);cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;line-height:1.35}.cri:hover:not(:disabled),.cri:focus-visible:not(:disabled){background:var(--shell-background-hover);outline:none}.cri[data-checked=true]{background:var(--shell-background-selected)}.cri[data-danger=true]{color:var(--shell-color-danger)}.cri[data-danger=true] .crn,.cri[data-danger=true] .crm{color:inherit}.cri:disabled,.cri[aria-disabled=true]{opacity:var(--shell-disabled-opacity);cursor:not-allowed}.crn,.crk{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:var(--shell-icon-size);height:var(--shell-icon-size);color:var(--shell-color-muted)}.crk{color:var(--shell-color-accent)}.crl{flex:1;min-width:0}.cru{flex-shrink:0;margin-left:auto;font-size:var(--shell-font-size-sm);color:var(--shell-color-muted)}.crm{display:inline-flex;flex-shrink:0;margin-left:auto;width:var(--shell-icon-size);height:var(--shell-icon-size);color:var(--shell-color-muted)}.crb{display:inline-flex;flex-shrink:0;width:var(--shell-status-size);height:var(--shell-status-size);border-radius:50%}.cro{background:var(--shell-color-success)}.crf{background:var(--shell-color-muted)}.crx{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;box-sizing:border-box;width:var(--shell-check-size);height:var(--shell-check-size);border:1px solid var(--shell-border);border-radius:calc(var(--shell-radius) * .4);background:var(--shell-background);color:var(--avatar-color)}.cry{border-color:var(--shell-color-accent);background:var(--shell-color-accent)}.crv{width:70%;height:70%;display:block}}
20
24
 
21
25
  @layer elcrm-components{.cpr{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--shell-gap);padding:var(--shell-padding);text-align:center;color:var(--shell-color-muted)}.cpi{display:flex;margin-bottom:var(--shell-gap-sm);color:var(--shell-color-muted)}.cpt{margin:0;font-size:var(--shell-font-size-lg);font-weight:var(--shell-font-weight);color:var(--shell-color);line-height:1.3}.cpd{margin:0;max-width:22rem;font-size:var(--shell-font-size);color:var(--shell-color-muted);line-height:1.45}.cpa{display:flex;flex-wrap:wrap;gap:var(--shell-gap-sm);justify-content:center;margin-top:var(--shell-gap)}}
@@ -58,12 +62,16 @@
58
62
 
59
63
  @layer elcrm-components{.c2r{box-sizing:border-box;display:flex;flex-direction:column;flex:1 1 auto;width:var(--sidebar-width, 248px);min-width:0;min-height:0;height:100%;max-height:100%;padding:var(--sidebar-pad-y, 16px) var(--sidebar-pad-x, 12px);gap:var(--shell-gap-sm, 8px);color:var(--shell-color);align-self:stretch}.c2b{display:flex;flex-direction:row;align-items:center;gap:var(--shell-gap);padding:4px 8px;min-width:0}.c2x{flex-shrink:0;margin-left:auto}.c2g{flex:1;min-height:0;display:flex;flex-direction:column;gap:var(--shell-gap-sm);overflow-y:auto;overflow-x:hidden;scrollbar-width:thin}.c2s{box-sizing:border-box;flex-shrink:0;padding:8px}.c2p{--sidebar-plain: 1}.c2r:not(.c2p) .c2s{background:var(--sidebar-block-bg);border:1px solid var(--sidebar-block-border);border-radius:var(--sidebar-block-radius);box-shadow:var(--sidebar-block-shadow)}.c2h{margin:2px 10px 6px;font-size:var(--sidebar-group-font-size);font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--shell-color-muted)}.c2n{margin:0;padding:0;list-style:none}.c2n>li{list-style:none}.c2n .c2i:is(button){position:relative;display:flex;width:100%;box-sizing:border-box;flex-direction:row;align-items:center;gap:8px;margin:0 0 1px;padding:var(--sidebar-item-padding);border:0;border-radius:8px;background:transparent;color:var(--shell-color-muted);font-family:inherit;font-size:var(--sidebar-item-font-size);font-weight:500;line-height:1.25;letter-spacing:0;text-align:left;cursor:pointer}.c2n .c2i:is(button):hover{color:var(--shell-color);background:var(--shell-background-hover)}.c2n .c2i:is(button).c2a,.c2n .c2i:is(button)[aria-current=page],.c2n .c2i:is(button)[data-active=true],.c2n .c2i:is(button).c2a:hover{color:var(--sidebar-item-active);background:var(--sidebar-item-active-bg)}.c2o{display:inline-flex;flex-shrink:0;align-items:center;justify-content:center;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size);color:inherit}.c2o :is(svg){display:block;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size)}.c2a .c2o{color:var(--sidebar-icon-active)}.c2l{flex:1;min-width:0}.c2d{flex-shrink:0;min-width:16px;height:16px;padding:0 4px;font-size:10px}.c2c{flex-shrink:0;width:12px;height:12px;margin-left:auto;color:var(--shell-color-muted);transition:transform .15s ease}.c2n .c2i:is(button)[data-open=true] .c2c{transform:rotate(180deg);color:inherit}.c2m{margin:0;padding:0 0 0 var(--sidebar-indent);list-style:none}.c2m>li{list-style:none}.c2f{margin-top:auto}.c2q{display:flex;width:100%;min-width:0;flex:0 0 auto;height:auto;align-items:center}.c2q>*{display:flex;width:100%;min-width:0;height:auto;align-items:center}.c2w{display:flex;width:100%;min-width:0;align-items:center}.c2u{display:flex;align-items:center;width:100%;min-width:0;gap:var(--shell-gap-sm);margin:0;padding:0;border:none;background:transparent;font:inherit;color:inherit;cursor:pointer;text-align:left}.c2k{flex-shrink:0;width:var(--sidebar-icon-size);height:var(--sidebar-icon-size);color:var(--shell-color-muted)}.c2v{margin-top:var(--shell-gap-sm);font-size:11px;color:var(--shell-color-muted);text-align:center}@media (max-width: 900px){.c2r{width:72px;padding:12px 8px}.c2l,.c2h,.c2v,.c2c,.c2m{display:none}.c2b{flex-direction:column;justify-content:center;align-items:center;gap:8px;padding:4px 0}.c2x{margin-left:0}.c2s{padding:6px}.c2n .c2i{justify-content:center;align-items:center;gap:0;width:100%;min-height:40px;padding:10px 0}.c2n .c2d{position:absolute;top:4px;right:4px;min-width:14px;height:14px;padding:0 4px;font-size:.625rem;line-height:14px;pointer-events:none}}}
60
64
 
65
+ @layer elcrm-components{.cFr{display:flex;min-height:0;min-width:0}.cFx{flex-direction:row}.cFy{flex-direction:column}.cFp{min-width:0;min-height:0;overflow:auto}.cFh{flex:0 0 var(--split-handle-size);margin:0;padding:0;border:0;background:var(--split-handle-bg);cursor:col-resize;touch-action:none}.cFy .cFh{cursor:row-resize}.cFh:hover,.cFh:focus-visible{background:var(--split-handle-bg-hover)}}
66
+
61
67
  @layer elcrm-components{.c1r{box-sizing:border-box;min-width:0;gap:var(--shell-gap)}.c1c,.c1g{width:100%}.c1c{display:flex;flex-direction:column}.c1h{display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;width:auto;max-width:100%}.c1g{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,var(--stack-grid-min)),1fr))}.c1n{display:grid;width:100%;align-items:stretch;grid-template-columns:var(--stack-columns-template)}}
62
68
 
63
69
  @layer elcrm-components{.c4r{display:flex;flex-direction:column;gap:6px}.c4l{font-size:var(--shell-font-size-sm);font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--shell-color-muted);line-height:1.2}.c4e{color:var(--shell-color)}.c4v{font-size:var(--stat-value-size);font-weight:700;letter-spacing:-.03em;line-height:1.1;color:var(--shell-color)}.c4a .c4v{color:var(--shell-color-accent)}.c4u .c4v{color:var(--shell-color-success)}.c4w .c4v{color:var(--shell-color-warning)}.c4d .c4v{color:var(--shell-color-danger)}}
64
70
 
65
71
  @layer elcrm-components{.ctr{display:flex;flex-direction:column;gap:var(--shell-gap);width:100%;min-width:0}.ctb{display:flex;align-items:flex-end;gap:var(--shell-gap);border-bottom:1px solid var(--shell-border);min-width:0}.ctn{display:flex;align-items:stretch;gap:var(--shell-gap-lg);flex:1 1 auto;min-width:0;overflow-x:auto;scrollbar-width:thin}.ctt{-webkit-appearance:none;-moz-appearance:none;appearance:none;display:inline-flex;align-items:center;gap:var(--shell-gap-sm);flex:0 0 auto;margin:0 0 -1px;padding:var(--shell-padding-block) .15rem;border:none;border-bottom:2px solid transparent;background:transparent;color:var(--shell-color-muted);font:inherit;font-size:var(--shell-font-size);font-weight:500;white-space:nowrap;cursor:pointer}.ctt:hover:not(:disabled){color:var(--shell-color)}.cta{color:var(--shell-color);border-bottom-color:var(--shell-color-accent)}.ctt:disabled{opacity:var(--shell-disabled-opacity);cursor:not-allowed}.cte{display:inline-flex;align-items:center;justify-content:center;min-width:1.15em;height:1.15em;padding:0 .35em;border-radius:999px;background:var(--shell-color-danger);color:var(--avatar-color);font-size:var(--sidebar-group-font-size);font-style:normal;font-weight:700;line-height:1}.cts{flex:0 0 auto;display:flex;align-items:center;padding-bottom:var(--shell-gap-sm)}.ctm{min-width:0;width:100%}}
66
72
 
73
+ @layer elcrm-components{.cDw{overflow:auto}.cDt{width:100%;border-collapse:collapse;font-size:var(--table-font-size);color:var(--shell-color)}.cDf{table-layout:fixed}.cDt th,.cDt td{padding:var(--table-cell-padding);border-bottom:1px solid var(--shell-border);text-align:left;vertical-align:top}.cDt th{color:var(--shell-color-muted);font-weight:var(--shell-font-weight);font-size:var(--table-head-font-size);text-transform:uppercase;letter-spacing:.04em}.cDt code{font-size:var(--table-code-font-size)}}
74
+
67
75
  @layer elcrm-components{.c6r{display:flex;flex-direction:column;gap:2px;min-width:0;text-align:left}.c6t{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}.c6d{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}.c6s .c6t{font-size:var(--shell-font-size-sm)}.c6l .c6t{font-size:var(--shell-font-size-lg)}.c6l .c6d{font-size:var(--shell-font-size)}}
68
76
 
69
77
  @layer elcrm-components{.cCr{display:flex;flex-wrap:wrap;align-items:center;gap:var(--toolbar-gap);width:100%;min-width:0;box-sizing:border-box;--field-width: auto}.cCr>[data-field]{flex:0 1 auto;width:auto;min-width:0;max-width:100%}.cCr>[data-field=search]{flex:1 1 var(--field-search-min-width, 10rem);width:auto!important;max-width:none}.cCr[data-width=s]{display:inline-flex;width:auto;max-width:100%}.cCr[data-align=center]{justify-content:center}.cCr[data-align=end]{justify-content:flex-end}.cCr[data-align=between]{justify-content:space-between}.cCr[data-size=s]{--control-height: var(--control-height-s);--field-height: var(--control-height-s);--control-font-size: 13px;--button-height: var(--button-height-s);--button-height-m: var(--button-height-s);--button-padding: var(--button-padding-s);--button-size-m: var(--button-size-s)}.cCr[data-size=l]{--control-height: var(--control-height-l);--field-height: var(--control-height-l);--button-height: var(--button-height-l);--button-height-m: var(--button-height-l);--button-size-m: var(--button-size-l)}}
package/dist/index.d.ts CHANGED
@@ -81,6 +81,16 @@ export { Healthmap } from './Healthmap';
81
81
  export type { HealthmapProps, HealthmapData, HealthmapDay, HealthmapUnit, } from './Healthmap';
82
82
  export { PanelInfo } from './PanelInfo';
83
83
  export type { PanelInfoProps } from './PanelInfo';
84
+ export { Table } from './Table';
85
+ export type { TableProps } from './Table';
86
+ export { CodeBlock } from './CodeBlock';
87
+ export type { CodeBlockProps } from './CodeBlock';
88
+ export { SplitPane, clampSplitRatio } from './SplitPane';
89
+ export type { SplitPaneProps, SplitPaneDirection } from './SplitPane';
90
+ export { Banner } from './Banner';
91
+ export type { BannerProps, BannerTone } from './Banner';
92
+ export { IconButton } from './IconButton';
93
+ export type { IconButtonProps } from './IconButton';
84
94
  export { acquireOverlayZIndex, releaseOverlayZIndex, peekOverlayZIndex, } from './overlayZ';
85
95
  export { createLazyResolver } from './lazyRoute';
86
96
  export type { LazyRouteChunk } from './lazyRoute';
@@ -81,6 +81,16 @@ export { Healthmap } from './Healthmap';
81
81
  export type { HealthmapProps, HealthmapData, HealthmapDay, HealthmapUnit, } from './Healthmap';
82
82
  export { PanelInfo } from './PanelInfo';
83
83
  export type { PanelInfoProps } from './PanelInfo';
84
+ export { Table } from './Table';
85
+ export type { TableProps } from './Table';
86
+ export { CodeBlock } from './CodeBlock';
87
+ export type { CodeBlockProps } from './CodeBlock';
88
+ export { SplitPane, clampSplitRatio } from './SplitPane';
89
+ export type { SplitPaneProps, SplitPaneDirection } from './SplitPane';
90
+ export { Banner } from './Banner';
91
+ export type { BannerProps, BannerTone } from './Banner';
92
+ export { IconButton } from './IconButton';
93
+ export type { IconButtonProps } from './IconButton';
84
94
  export { acquireOverlayZIndex, releaseOverlayZIndex, peekOverlayZIndex, } from './overlayZ';
85
95
  export { createLazyResolver } from './lazyRoute';
86
96
  export type { LazyRouteChunk } from './lazyRoute';