@elcrm/components 0.2.7 → 0.2.9

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
@@ -31,6 +31,7 @@ import {
31
31
  ItemColumn,
32
32
  Card,
33
33
  ActionGroup,
34
+ Toolbar,
34
35
  TextGroup,
35
36
  Stat,
36
37
  Stack,
@@ -101,7 +102,8 @@ import { RadioGroup } from "@elcrm/components/RadioGroup";
101
102
  | **NavSections** | Сайдбар + lazy-панель | `groups` (`value`), `resolveSection`, `defaultValue` |
102
103
  | **TabSections** | Горизонтальные вкладки + lazy | `items` (`value` + `badge`), `resolveSection` |
103
104
  | **Card** | Карточка | `title`, `--card-pointer` |
104
- | **ActionGroup** | Тулбар действий | `label`, `items` и/или `children` |
105
+ | **ActionGroup** | Ряд иконок в карточке | `label`, `items` и/или `children` |
106
+ | **Toolbar** | Фильтры одной высоты | `size`, `width` (`l` = 100%, `s` = по контенту), `align`, `label`, `children` |
105
107
  | **TextGroup** | Title + description | `title`, `description`, `size` |
106
108
  | **ItemColumn** | Иконка + столбик в Item | `icon`, `title`, `extra`, `aside`, `description`, `footer` / `meta`, `unread` |
107
109
  | **Stat** | Карточка-метрика | `label`, `value`, `tone`, `labelMuted` |
@@ -737,6 +739,7 @@ const resolve = createLazyResolver(
737
739
  --pricing-card-min-width / --pricing-table-label-width
738
740
  --card-pointer
739
741
  --stack-grid-min
742
+ --toolbar-gap
740
743
  --healthmap-cell / --healthmap-gap / --healthmap-l0…l4
741
744
  --panel-info-width / --panel-info-width-min / --panel-info-overlay-max / --panel-info-backdrop
742
745
  --row-gap / --column-gap
@@ -1,30 +1,31 @@
1
1
  import e from "react";
2
- import { C as f } from "./CheckIcon-FdB8fMEF.js";
3
- import { c as m } from "./cx-CcykAxZN.js";
4
- import { P as j } from "./Popover-DWdvZTuA.js";
5
- import { u as I } from "./useControllableValue-CWqH1kpM.js";
6
- import './Dropdown.css';const M = "crr", P = "crt", R = "crc", W = "crp", z = "crh", F = "crg", G = "crd", T = "cri", V = "crn", q = "crm", A = "crk", H = "crl", J = "cru", K = "crb", Q = "cro", U = "crf", X = "crx", Y = "cry", Z = "crv", n = {
7
- r: M,
8
- t: P,
9
- c: R,
10
- p: W,
11
- h: z,
12
- g: F,
13
- d: G,
14
- i: T,
15
- n: V,
16
- m: q,
17
- k: A,
18
- l: H,
19
- u: J,
20
- b: K,
21
- o: Q,
22
- f: U,
23
- x: X,
24
- y: Y,
25
- v: Z
2
+ import { C as E } from "./CheckIcon-FdB8fMEF.js";
3
+ import { c as p } from "./cx-CcykAxZN.js";
4
+ import { P as M } from "./Popover-DWdvZTuA.js";
5
+ import { u as P } from "./Toolbar-C1zAk9ak.js";
6
+ import { u as R } from "./useControllableValue-CWqH1kpM.js";
7
+ import './Dropdown.css';const T = "crr", W = "crt", F = "crc", G = "crp", V = "crh", q = "crg", A = "crd", H = "cri", J = "crn", K = "crm", Q = "crk", U = "crl", X = "cru", Y = "crb", Z = "cro", _ = "crf", $ = "crx", S = "cry", ee = "crv", n = {
8
+ r: T,
9
+ t: W,
10
+ c: F,
11
+ p: G,
12
+ h: V,
13
+ g: q,
14
+ d: A,
15
+ i: H,
16
+ n: J,
17
+ m: K,
18
+ k: Q,
19
+ l: U,
20
+ u: X,
21
+ b: Y,
22
+ o: Z,
23
+ f: _,
24
+ x: $,
25
+ y: S,
26
+ v: ee
26
27
  };
27
- function _() {
28
+ function ne() {
28
29
  return /* @__PURE__ */ e.createElement("svg", { className: n.c, viewBox: "0 0 12 12", "aria-hidden": !0 }, /* @__PURE__ */ e.createElement(
29
30
  "path",
30
31
  {
@@ -37,7 +38,7 @@ function _() {
37
38
  }
38
39
  ));
39
40
  }
40
- function $() {
41
+ function ce() {
41
42
  return /* @__PURE__ */ e.createElement("svg", { className: n.m, viewBox: "0 0 12 12", "aria-hidden": !0 }, /* @__PURE__ */ e.createElement(
42
43
  "path",
43
44
  {
@@ -50,74 +51,76 @@ function $() {
50
51
  }
51
52
  ));
52
53
  }
53
- function S({ item: a }) {
54
- return a.checkbox ? /* @__PURE__ */ e.createElement("span", { className: m(n.x, a.checked && n.y), "aria-hidden": !0 }, a.checked ? /* @__PURE__ */ e.createElement(f, { className: n.v }) : null) : a.checked ? /* @__PURE__ */ e.createElement("span", { className: n.k, "aria-hidden": !0 }, /* @__PURE__ */ e.createElement(f, { className: n.v })) : a.status != null ? /* @__PURE__ */ e.createElement(
54
+ function re({ item: a }) {
55
+ return a.checkbox ? /* @__PURE__ */ e.createElement("span", { className: p(n.x, a.checked && n.y), "aria-hidden": !0 }, a.checked ? /* @__PURE__ */ e.createElement(E, { className: n.v }) : null) : a.checked ? /* @__PURE__ */ e.createElement("span", { className: n.k, "aria-hidden": !0 }, /* @__PURE__ */ e.createElement(E, { className: n.v })) : a.status != null ? /* @__PURE__ */ e.createElement(
55
56
  "span",
56
57
  {
57
- className: m(n.b, a.status === "online" ? n.o : n.f),
58
+ className: p(n.b, a.status === "online" ? n.o : n.f),
58
59
  "aria-hidden": !0
59
60
  }
60
61
  ) : a.icon != null ? /* @__PURE__ */ e.createElement("span", { className: n.n }, a.icon) : null;
61
62
  }
62
- function ee(a, t, l) {
63
+ function ae(a, t, l) {
63
64
  return t != null && t.length > 0 ? l != null && t[0] && t[0].title == null ? [{ ...t[0], title: l }, ...t.slice(1)] : t : a != null && a.length > 0 ? [{ title: l, items: a }] : l != null ? [{ title: l, items: [] }] : [];
64
65
  }
65
- function le({
66
+ function ie({
66
67
  items: a,
67
68
  groups: t,
68
69
  trigger: l,
69
70
  label: o,
70
- hideChevron: E = !1,
71
- title: v,
71
+ hideChevron: v = !1,
72
+ title: b,
72
73
  align: k = "end",
73
- placement: b = "auto",
74
- open: N,
75
- defaultOpen: x = !1,
76
- onOpenChange: C,
77
- closeOnSelect: y = !0,
74
+ placement: N = "auto",
75
+ open: x,
76
+ defaultOpen: C = !1,
77
+ onOpenChange: y,
78
+ closeOnSelect: g = !0,
78
79
  disabled: u = !1,
80
+ size: L,
79
81
  onSelect: d,
80
- className: g
82
+ className: z
81
83
  }) {
82
- const [i = !1, p] = I(
83
- N,
84
+ const i = P(), w = L ?? (i == null ? void 0 : i.size), [h = !1, f] = R(
84
85
  x,
85
- C
86
- ), L = ee(a, t, v), w = (r) => {
86
+ C,
87
+ y
88
+ ), O = ae(a, t, b), B = (r) => {
87
89
  var c;
88
90
  if (r.disabled) return;
89
- (c = r.onClick) == null || c.call(r), d == null || d(r.value, r), r.checkbox || r.submenu || !y || p(!1);
90
- }, O = l ?? /* @__PURE__ */ e.createElement(
91
+ (c = r.onClick) == null || c.call(r), d == null || d(r.value, r), r.checkbox || r.submenu || !g || f(!1);
92
+ }, D = l ?? /* @__PURE__ */ e.createElement(
91
93
  "button",
92
94
  {
93
95
  type: "button",
94
96
  className: n.t,
95
- "data-open": i ? "true" : void 0,
97
+ "data-size": w,
98
+ "data-open": h ? "true" : void 0,
96
99
  disabled: u,
97
100
  "aria-haspopup": "menu",
98
- "aria-expanded": i
101
+ "aria-expanded": h
99
102
  },
100
103
  o,
101
- E ? null : /* @__PURE__ */ e.createElement(_, null)
104
+ v ? null : /* @__PURE__ */ e.createElement(ne, null)
102
105
  );
103
106
  return /* @__PURE__ */ e.createElement(
104
- j,
107
+ M,
105
108
  {
106
- className: m(n.r, g),
107
- open: i,
109
+ className: p(n.r, z),
110
+ open: h,
108
111
  onOpenChange: (r) => {
109
- u || p(r);
112
+ u || f(r);
110
113
  },
111
114
  align: k,
112
- placement: b,
113
- trigger: O,
115
+ placement: N,
116
+ trigger: D,
114
117
  label: typeof o == "string" ? o : void 0,
115
118
  disabled: u
116
119
  },
117
- /* @__PURE__ */ e.createElement("div", { className: n.p, "data-align": k }, L.map((r, h) => /* @__PURE__ */ e.createElement(e.Fragment, { key: h }, h > 0 ? /* @__PURE__ */ e.createElement("hr", { className: n.d }) : null, /* @__PURE__ */ e.createElement("div", { className: n.g, role: "group" }, r.title != null ? /* @__PURE__ */ e.createElement("p", { className: n.h }, r.title) : null, r.items.map((c) => {
118
- const B = r.items.some(
120
+ /* @__PURE__ */ e.createElement("div", { className: n.p, "data-align": k }, O.map((r, m) => /* @__PURE__ */ e.createElement(e.Fragment, { key: m }, m > 0 ? /* @__PURE__ */ e.createElement("hr", { className: n.d }) : null, /* @__PURE__ */ e.createElement("div", { className: n.g, role: "group" }, r.title != null ? /* @__PURE__ */ e.createElement("p", { className: n.h }, r.title) : null, r.items.map((c) => {
121
+ const j = r.items.some(
119
122
  (s) => s.checked || s.checkbox || s.status != null || s.icon != null
120
- ), D = /* @__PURE__ */ e.createElement(S, { item: c });
123
+ ), I = /* @__PURE__ */ e.createElement(re, { item: c });
121
124
  return /* @__PURE__ */ e.createElement(
122
125
  "button",
123
126
  {
@@ -129,16 +132,16 @@ function le({
129
132
  "data-danger": c.danger ? "true" : void 0,
130
133
  disabled: c.disabled,
131
134
  "aria-checked": c.checked != null || c.checkbox ? !!c.checked : void 0,
132
- onClick: () => w(c)
135
+ onClick: () => B(c)
133
136
  },
134
- B ? D ?? /* @__PURE__ */ e.createElement("span", { className: n.n, "aria-hidden": !0 }) : null,
137
+ j ? I ?? /* @__PURE__ */ e.createElement("span", { className: n.n, "aria-hidden": !0 }) : null,
135
138
  c.label != null ? /* @__PURE__ */ e.createElement("span", { className: n.l }, c.label) : null,
136
139
  c.shortcut != null ? /* @__PURE__ */ e.createElement("span", { className: n.u }, c.shortcut) : null,
137
- c.submenu ? /* @__PURE__ */ e.createElement($, null) : null
140
+ c.submenu ? /* @__PURE__ */ e.createElement(ce, null) : null
138
141
  );
139
142
  })))))
140
143
  );
141
144
  }
142
145
  export {
143
- le as D
146
+ ie as D
144
147
  };
package/dist/Dropdown.css CHANGED
@@ -1 +1 @@
1
- @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: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}}
1
+ @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}}
@@ -1,4 +1,5 @@
1
1
  import { default as React } from 'react';
2
+ import { UiSize } from './types';
2
3
  /**
3
4
  * Пункт выпадающего меню {@link Dropdown}.
4
5
  *
@@ -82,6 +83,11 @@ export type DropdownProps = Omit<React.HTMLAttributes<HTMLDivElement>, "onChange
82
83
  closeOnSelect?: boolean;
83
84
  /** Заблокировать триггер. */
84
85
  disabled?: boolean;
86
+ /**
87
+ * Высота встроенного триггера (`--control-height`).
88
+ * Внутри {@link Toolbar} берётся из тулбара, если не задан.
89
+ */
90
+ size?: UiSize;
85
91
  /** Выбор пункта: `value` + сам item. */
86
92
  onSelect?: (value: string, item: DropdownItem) => void;
87
93
  };
@@ -127,4 +133,4 @@ export type DropdownProps = Omit<React.HTMLAttributes<HTMLDivElement>, "onChange
127
133
  * />
128
134
  * ```
129
135
  */
130
- export declare function Dropdown({ items, groups, trigger, label, hideChevron, title, align, placement, open: openProp, defaultOpen, onOpenChange, closeOnSelect, disabled, onSelect, className, }: DropdownProps): React.JSX.Element;
136
+ export declare function Dropdown({ items, groups, trigger, label, hideChevron, title, align, placement, open: openProp, defaultOpen, onOpenChange, closeOnSelect, disabled, size: sizeProp, onSelect, className, }: DropdownProps): React.JSX.Element;
package/dist/Dropdown.js CHANGED
@@ -1,4 +1,4 @@
1
- import { D as p } from "./Dropdown-CPTE4EEx.js";
1
+ import { D as p } from "./Dropdown-DosvDR13.js";
2
2
  export {
3
3
  p as Dropdown
4
4
  };
@@ -1,6 +1,6 @@
1
1
  import e from "react";
2
2
  import { B as h } from "./Badge-jp-9iNNL.js";
3
- import { D as w } from "./Dropdown-CPTE4EEx.js";
3
+ import { D as w } from "./Dropdown-DosvDR13.js";
4
4
  import { I as y } from "./Item-D4okhsfW.js";
5
5
  import { b as C } from "./badgeText-CRzlIzi3.js";
6
6
  import { c as u } from "./cx-CcykAxZN.js";
package/dist/Sidebar.js CHANGED
@@ -1,4 +1,4 @@
1
- import { S as e } from "./Sidebar-1EH4XCEl.js";
1
+ import { S as e } from "./Sidebar-BgZiGEDH.js";
2
2
  export {
3
3
  e as Sidebar
4
4
  };
@@ -0,0 +1,42 @@
1
+ import t from "react";
2
+ import { c as i } from "./cx-CcykAxZN.js";
3
+ import './Toolbar.css';const m = "cCr", f = {
4
+ r: m
5
+ }, a = t.createContext(null);
6
+ function x() {
7
+ return t.useContext(a);
8
+ }
9
+ function s(e, n) {
10
+ return t.Children.map(e, (r) => t.isValidElement(r) ? r.type === t.Fragment ? s(
11
+ r.props.children,
12
+ n
13
+ ) : typeof r.type == "string" || r.props.size != null ? r : t.cloneElement(r, { size: n }) : r);
14
+ }
15
+ function C({
16
+ size: e = "s",
17
+ label: n = "Тулбар",
18
+ align: r = "start",
19
+ width: o = "l",
20
+ className: l,
21
+ children: p,
22
+ ...u
23
+ }) {
24
+ return /* @__PURE__ */ t.createElement(a.Provider, { value: { size: e } }, /* @__PURE__ */ t.createElement(
25
+ "div",
26
+ {
27
+ className: i(f.r, l),
28
+ role: "toolbar",
29
+ "aria-label": n,
30
+ "data-size": e,
31
+ "data-align": r,
32
+ "data-width": o,
33
+ ...u
34
+ },
35
+ s(p, e)
36
+ ));
37
+ }
38
+ export {
39
+ C as T,
40
+ s as a,
41
+ x as u
42
+ };
@@ -0,0 +1 @@
1
+ @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)}}
@@ -0,0 +1,63 @@
1
+ import { default as React } from 'react';
2
+ import { UiSize } from './types';
3
+ /** Контекст размера тулбара — дети без своего `size` его подхватывают. */
4
+ export type ToolbarContextValue = {
5
+ size: UiSize;
6
+ };
7
+ /** Размер ближайшего {@link Toolbar}, либо `null` вне тулбара. */
8
+ export declare function useToolbar(): ToolbarContextValue | null;
9
+ export type ToolbarAlign = "start" | "center" | "end" | "between";
10
+ /** Ширина ряда: `l` — 100%, `s` — по содержимому (как `width` у Button). */
11
+ export type ToolbarWidth = "s" | "l";
12
+ export type ToolbarProps = Omit<React.HTMLAttributes<HTMLDivElement>, "children"> & {
13
+ /**
14
+ * Общий размер вложенных Field / Search / Button / Dropdown / Badge.
15
+ * Явный `size` у ребёнка важнее.
16
+ * @default "s"
17
+ */
18
+ size?: UiSize;
19
+ /** Подпись для `aria-label`. */
20
+ label?: string;
21
+ /**
22
+ * Направление ряда (`justify-content`).
23
+ * @default "start"
24
+ */
25
+ align?: ToolbarAlign;
26
+ /**
27
+ * Ширина корня: `l` — `100%` (фильтры над списком),
28
+ * `s` — по контенту (компактный ряд, не растягивать).
29
+ * @default "l"
30
+ */
31
+ width?: ToolbarWidth;
32
+ /**
33
+ * Узлы тулбара (`*Field`, `Search`, `Button`, `Dropdown`, …).
34
+ * Компонентам без `size` прокидывается размер тулбара.
35
+ */
36
+ children?: React.ReactNode;
37
+ };
38
+ /** Прокинуть `size` прямым детям-компонентам, если у них его ещё нет. */
39
+ export declare function applyToolbarSize(node: React.ReactNode, size: UiSize): React.ReactNode;
40
+ /**
41
+ * Ряд контролов одной высоты: поиск, поля, кнопки, меню.
42
+ *
43
+ * Роли: Toolbar = фильтры / действия над списком (`PageHead.children`).
44
+ * Иконки в карточке — `ActionGroup`.
45
+ *
46
+ * Пакет не зависит от `@elcrm/form` / `@elcrm/button`:
47
+ * размер уходит пропом `size` и токенами `--field-height` / `--button-height-*`.
48
+ *
49
+ * @example
50
+ * ```tsx
51
+ * <Toolbar size="s" align="end" label="Фильтры">
52
+ * <Search value={q} onValue={setQ} />
53
+ * <Button label="Создать" />
54
+ * </Toolbar>
55
+ * <Toolbar width="s" align="center">
56
+ * <Button label="Отмена" />
57
+ * <Button label="Сохранить" />
58
+ * </Toolbar>
59
+ * ```
60
+ *
61
+ * Токены: `--toolbar-gap`, `--control-height-*`, `--button-height-*`.
62
+ */
63
+ export declare function Toolbar({ size, label, align, width, className, children, ...rest }: ToolbarProps): React.JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { T as r, a as l, u as s } from "./Toolbar-C1zAk9ak.js";
2
+ export {
3
+ r as Toolbar,
4
+ l as applyToolbarSize,
5
+ s as useToolbar
6
+ };
package/dist/index.css CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
  @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
18
 
19
- @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: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}}
19
+ @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
20
 
21
21
  @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)}}
22
22
 
@@ -65,3 +65,5 @@
65
65
  @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
66
 
67
67
  @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
+
69
+ @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
@@ -14,6 +14,8 @@ export { Card } from './Card';
14
14
  export type { CardProps } from './Card';
15
15
  export { ActionGroup } from './ActionGroup';
16
16
  export type { ActionGroupProps } from './ActionGroup';
17
+ export { Toolbar, useToolbar, applyToolbarSize } from './Toolbar';
18
+ export type { ToolbarProps, ToolbarAlign, ToolbarWidth, ToolbarContextValue, } from './Toolbar';
17
19
  export { TextGroup } from './TextGroup';
18
20
  export type { TextGroupProps } from './TextGroup';
19
21
  export { Stat } from './Stat';
@@ -14,6 +14,8 @@ export { Card } from './Card';
14
14
  export type { CardProps } from './Card';
15
15
  export { ActionGroup } from './ActionGroup';
16
16
  export type { ActionGroupProps } from './ActionGroup';
17
+ export { Toolbar, useToolbar, applyToolbarSize } from './Toolbar';
18
+ export type { ToolbarProps, ToolbarAlign, ToolbarWidth, ToolbarContextValue, } from './Toolbar';
17
19
  export { TextGroup } from './TextGroup';
18
20
  export type { TextGroupProps } from './TextGroup';
19
21
  export { Stat } from './Stat';