@elcrm/components 0.1.0 → 0.1.2
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 +66 -16
- package/dist/ActionGroup-ChKFW0mt.js +27 -0
- package/dist/ActionGroup.css +1 -0
- package/dist/ActionGroup.d.ts +42 -0
- package/dist/ActionGroup.js +4 -0
- package/dist/Avatar-loGgFt72.js +113 -0
- package/dist/Avatar.css +1 -1
- package/dist/Avatar.d.ts +9 -1
- package/dist/Avatar.js +3 -2
- package/dist/{AvatarGroup-DUe7-T3B.js → AvatarGroup-D1gnT3Od.js} +1 -1
- package/dist/AvatarGroup.js +1 -1
- package/dist/AvatarName-C1sIDPH-.js +66 -0
- package/dist/AvatarName.css +1 -1
- package/dist/AvatarName.d.ts +4 -1
- package/dist/AvatarName.js +1 -1
- package/dist/Badge-jp-9iNNL.js +28 -0
- package/dist/Badge.css +1 -1
- package/dist/Badge.d.ts +32 -17
- package/dist/Badge.js +1 -1
- package/dist/{Block-BAXh0PPp.js → Block-Bu7NEA0g.js} +1 -1
- package/dist/Block.js +1 -1
- package/dist/{Breadcrumb-D0wXkE38.js → Breadcrumb-CAM_e9LN.js} +3 -3
- package/dist/Breadcrumb.css +1 -1
- package/dist/Breadcrumb.js +1 -1
- package/dist/Card.css +1 -1
- package/dist/Card.d.ts +8 -1
- package/dist/{Column-DDaqX-A7.js → Column-BiogBDf8.js} +1 -1
- package/dist/Column.js +1 -1
- package/dist/Dropdown-CQBMF9aR.js +151 -0
- package/dist/Dropdown.css +1 -1
- package/dist/Dropdown.d.ts +3 -3
- package/dist/Dropdown.js +1 -1
- package/dist/Item-D4okhsfW.js +46 -0
- package/dist/Item.css +1 -1
- package/dist/Item.d.ts +8 -1
- package/dist/Item.js +1 -1
- package/dist/ItemColumn-M7a9L8CI.js +41 -0
- package/dist/ItemColumn.css +1 -0
- package/dist/ItemColumn.d.ts +61 -0
- package/dist/ItemColumn.js +4 -0
- package/dist/Layout-BQwEaeO0.js +22 -0
- package/dist/Layout.css +1 -1
- package/dist/Layout.d.ts +10 -5
- package/dist/Layout.js +1 -1
- package/dist/Menu-DpUvOl8Y.js +58 -0
- package/dist/Menu.css +1 -1
- package/dist/Menu.d.ts +15 -3
- package/dist/Menu.js +1 -1
- package/dist/PageHead-DgaJ1mXY.js +31 -0
- package/dist/PageHead.css +1 -1
- package/dist/PageHead.d.ts +28 -6
- package/dist/PageHead.js +1 -1
- package/dist/{PageShell-CghThHS3.js → PageShell-D9EZiO8o.js} +13 -11
- package/dist/PageShell.css +1 -1
- package/dist/PageShell.d.ts +11 -6
- package/dist/PageShell.js +1 -1
- package/dist/Popover-g2xTGubK.js +123 -0
- package/dist/Popover.css +1 -0
- package/dist/Popover.d.ts +54 -0
- package/dist/Popover.js +4 -0
- package/dist/PricingGroup-DgcdVSq8.js +126 -0
- package/dist/PricingGroup.css +1 -1
- package/dist/PricingGroup.js +1 -1
- package/dist/{PricingTable-DYTJG4AU.js → PricingTable-DALddSwM.js} +11 -11
- package/dist/PricingTable.css +1 -1
- package/dist/PricingTable.js +1 -1
- package/dist/{RadioGroup-DxoPHPIF.js → RadioGroup-D2UUOTkY.js} +25 -25
- package/dist/RadioGroup.css +1 -1
- package/dist/RadioGroup.js +1 -1
- package/dist/{Row--HIe6vb9.js → Row-DsQOVn18.js} +1 -1
- package/dist/Row.js +1 -1
- package/dist/Sidebar-DeqxYgxn.js +69 -0
- package/dist/Sidebar.css +1 -0
- package/dist/Sidebar.d.ts +83 -0
- package/dist/Sidebar.js +4 -0
- package/dist/Stack-XkmPSswj.js +53 -0
- package/dist/Stack.css +1 -1
- package/dist/Stack.d.ts +16 -4
- package/dist/Stack.js +3 -2
- package/dist/Stat-C5iZyEoo.js +27 -0
- package/dist/Stat.css +1 -0
- package/dist/Stat.d.ts +39 -0
- package/dist/Stat.js +4 -0
- package/dist/{TabSections-DL7DufKU.js → TabSections-Bf_sZo7b.js} +1 -1
- package/dist/TabSections.js +1 -1
- package/dist/TextGroup-DmhuyMR1.js +23 -0
- package/dist/TextGroup.css +1 -0
- package/dist/TextGroup.d.ts +35 -0
- package/dist/TextGroup.js +4 -0
- package/dist/dark.css +10 -0
- package/dist/index.css +27 -15
- package/dist/index.d.ts +17 -3
- package/dist/index.es.d.ts +73 -0
- package/dist/index.es.js +76 -59
- package/dist/light.css +10 -0
- package/dist/overlayZ.d.ts +9 -0
- package/dist/tokens.css +19 -0
- package/package.json +2 -2
- package/dist/Avatar-Jzan87XD.js +0 -101
- package/dist/AvatarName-KBbQrVta.js +0 -56
- package/dist/Badge-l6nUkl-H.js +0 -22
- package/dist/Dropdown-Cw5LKpcT.js +0 -168
- package/dist/Item-CaU4RW2G.js +0 -38
- package/dist/Layout-Xb3-xsmA.js +0 -18
- package/dist/Menu-DRBHvSdJ.js +0 -40
- package/dist/PageHead-Baz9BLuA.js +0 -22
- package/dist/PricingGroup-CiqQtzjd.js +0 -126
- package/dist/Stack-b0-XWwQ1.js +0 -31
package/README.md
CHANGED
|
@@ -17,7 +17,11 @@ import {
|
|
|
17
17
|
Footer,
|
|
18
18
|
List,
|
|
19
19
|
Item,
|
|
20
|
+
ItemColumn,
|
|
20
21
|
Card,
|
|
22
|
+
ActionGroup,
|
|
23
|
+
TextGroup,
|
|
24
|
+
Stat,
|
|
21
25
|
Stack,
|
|
22
26
|
Menu,
|
|
23
27
|
Loading,
|
|
@@ -37,6 +41,8 @@ import {
|
|
|
37
41
|
Breadcrumb,
|
|
38
42
|
PageHead,
|
|
39
43
|
PageShell,
|
|
44
|
+
Sidebar,
|
|
45
|
+
Popover,
|
|
40
46
|
createLazyResolver,
|
|
41
47
|
} from "@elcrm/components";
|
|
42
48
|
import type { PricingPlan } from "@elcrm/components";
|
|
@@ -56,28 +62,34 @@ import { RadioGroup } from "@elcrm/components/RadioGroup";
|
|
|
56
62
|
|
|
57
63
|
| | Назначение | Ключевые props |
|
|
58
64
|
| -------------------------------- | -------------------------------- | ---------------------------------------------------- |
|
|
59
|
-
| **Layout** | Оболочка страницы | `header`, `footer`, `children`
|
|
65
|
+
| **Layout** | Оболочка страницы | `sidebar`, `header`, `footer`, `children` |
|
|
60
66
|
| **Header** | Шапка со слотами | `brand`, `nav`, `search`, `actions` |
|
|
61
67
|
| **Footer** | Подвал | `children` |
|
|
62
68
|
| **Brand** | Название / логотип | `as`, `children`, `onClick` |
|
|
63
|
-
| **Avatar** | Фото или инициалы | `src`, `name
|
|
64
|
-
| **AvatarName** | Аватар + title + description | `title`, `description`, `name
|
|
69
|
+
| **Avatar** | Фото или инициалы | `src`, `name`, `size`, `radius`, `status`, `as` |
|
|
70
|
+
| **AvatarName** | Аватар + title + description | `title`, `description`, `radius`, `--avatar-name-*-color` |
|
|
65
71
|
| **AvatarGroup** | Стопка аватаров + «+N» | `items` (`value`/`title`/`name`), `max`, `add` |
|
|
66
|
-
| **Badge** | Метка / статус | `tone`, `children`
|
|
72
|
+
| **Badge** | Метка / статус | `tone`, `size`, `dot`, `children` |
|
|
67
73
|
| **RadioGroup** | Выбор одной опции-карточки | `items`, `value`, `indicator`, `indicatorSide` |
|
|
68
74
|
| **PricingGroup** | Тарифные карточки в ряд | `items` (`PricingPlan`), `selectable`, `value` |
|
|
69
75
|
| **PricingTable** | Сравнение тарифов (таблица) | те же `items` + `sections` |
|
|
70
|
-
| **Menu** | Навигация в шапке (не popover) | `items` (`value`), `value`, `onSelect`
|
|
71
|
-
| **Dropdown** | Выпадающее меню (items)
|
|
76
|
+
| **Menu** | Навигация в шапке (не popover) | `items` (`value`, `badge`: `0` скрыт), `value`, `onSelect`, `variant` (`plain`/`line`) |
|
|
77
|
+
| **Dropdown** | Выпадающее меню (items, portal) | `label`/`trigger`, `items`/`groups`, `onSelect` |
|
|
78
|
+
| **Popover** | Свой попап в portal | `trigger`, `children`, `align`, `open` |
|
|
72
79
|
| **Breadcrumb** | Хлебные крошки | `items`, `separator`, `collapseAfter` |
|
|
73
|
-
| **
|
|
74
|
-
| **
|
|
80
|
+
| **Sidebar** | Левое меню приложения | `groups`, `value`, `variant` (`cards`/`plain`) |
|
|
81
|
+
| **PageShell** | Каркас модуля (скролл + footer) | `wide`, `scroll`, `footer`, `children` |
|
|
82
|
+
| **PageHead** | Заголовок страницы + actions | `title`, `sup` (текст/Badge), `subtitle`, `actions`, `sticky`, `children` |
|
|
75
83
|
| **Section** | Блок контента / auth / подраздел | `title`, `description`, `icon`, `actions`, `variant` |
|
|
76
84
|
| **NavSections** | Сайдбар + lazy-панель | `groups` (`value`), `resolveSection`, `defaultValue` |
|
|
77
85
|
| **TabSections** | Горизонтальные вкладки + lazy | `items` (`value` + `badge`), `resolveSection` |
|
|
78
|
-
| **Card** | Карточка | `title`, `
|
|
79
|
-
| **
|
|
80
|
-
| **
|
|
86
|
+
| **Card** | Карточка | `title`, `--card-pointer` |
|
|
87
|
+
| **ActionGroup** | Тулбар действий | `label`, `items` и/или `children` |
|
|
88
|
+
| **TextGroup** | Title + description | `title`, `description`, `size` |
|
|
89
|
+
| **ItemColumn** | Иконка + столбик в Item | `icon`, `title`, `extra`, `aside`, `description`, `footer` / `meta`, `unread` |
|
|
90
|
+
| **Stat** | Карточка-метрика | `label`, `value`, `tone`, `labelMuted` |
|
|
91
|
+
| **List** / **Item** | Список и строка | List: `row`; Item: `as`, `active`, `variant` (`plain`/`card`) |
|
|
92
|
+
| **Stack** | Ряд / колонка / сетка | `direction`, `columns` (N или `["1fr", "100px"]`), `gap` |
|
|
81
93
|
| **Loading** | Плейсхолдер загрузки | `children` |
|
|
82
94
|
| **EmptyState** | Заглушка «нет данных» | `title`, `description`, `icon`, `actions` |
|
|
83
95
|
| **createLazyResolver** | Кэш `import()` секций | `(key) => import(…)` |
|
|
@@ -86,11 +98,45 @@ import { RadioGroup } from "@elcrm/components/RadioGroup";
|
|
|
86
98
|
|
|
87
99
|
`Block` / `Row` / `Column` — deprecated-обёртки над `Stack`. В проектах: `elcrm migrate components`.
|
|
88
100
|
|
|
101
|
+
### Sidebar
|
|
102
|
+
|
|
103
|
+
Левое меню приложения. `variant="cards"` — секции-карточки; `variant="plain"` — плоский список (backoffice). Иконки, колокольчик, тема, карточка пользователя — слоты приложения. Роутер не подключаем.
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
<Sidebar
|
|
107
|
+
variant="cards"
|
|
108
|
+
value={page}
|
|
109
|
+
onSelect={setPage}
|
|
110
|
+
brand={<Brand as="strong">App</Brand>}
|
|
111
|
+
extra={<Notifications.Bell />}
|
|
112
|
+
groups={[
|
|
113
|
+
{ value: "main", items: [{ value: "home", label: "Обзор", icon: <Icon /> }] },
|
|
114
|
+
{ value: "admin", title: "Админ", items: [{ value: "ops", label: "Операции" }] },
|
|
115
|
+
]}
|
|
116
|
+
footer={<AvatarName title="Паша" description="mail@…" />}
|
|
117
|
+
version="v 0.2.26"
|
|
118
|
+
/>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Токены: `--sidebar-width`, `--sidebar-item-font-size`, `--sidebar-item-padding`, `--sidebar-icon-size`, `--sidebar-group-font-size`, `--sidebar-item-active`. Для orange active в `plain` переопределите `--sidebar-item-active` в теме приложения.
|
|
122
|
+
|
|
89
123
|
### Stack
|
|
90
124
|
|
|
91
125
|
```tsx
|
|
92
126
|
<Stack gap="0.75rem">{/* колонка */}</Stack>
|
|
93
127
|
<Stack direction="row" gap={8}>{/* ряд */}</Stack>
|
|
128
|
+
<Stack direction="grid" gap={16}>{/* auto-fit, мин. ширина --stack-grid-min */}</Stack>
|
|
129
|
+
<Stack direction="grid" columns={3} gap={12}>{/* stretch; не height:100% у детей */}</Stack>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Card
|
|
133
|
+
|
|
134
|
+
Курсор задаёт приложение токеном `--card-pointer` (`auto` по умолчанию):
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
<Card title="Тенанты" style={{ ["--card-pointer" as string]: "pointer" }}>
|
|
138
|
+
12
|
|
139
|
+
</Card>
|
|
94
140
|
```
|
|
95
141
|
|
|
96
142
|
### RadioGroup
|
|
@@ -255,13 +301,13 @@ const sections = [
|
|
|
255
301
|
|
|
256
302
|
| | Роль |
|
|
257
303
|
| --- | --- |
|
|
258
|
-
| **PageShell** | Каркас модуля: скролл в body, опциональный footer снизу |
|
|
259
|
-
| **PageHead** | Строка title (+ subtitle) слева и actions
|
|
304
|
+
| **PageShell** | Каркас модуля: скролл в body (`scroll`, по умолчанию да), опциональный footer снизу |
|
|
305
|
+
| **PageHead** | Строка title (+ `sup` надстрочно, subtitle) слева и actions справа; `sticky` — прилипает к верху скролла |
|
|
260
306
|
| **Section** | Блок контента / auth-карточка / подраздел с title+description |
|
|
261
307
|
|
|
262
308
|
```tsx
|
|
263
|
-
<PageShell footer={<button type="button">Сохранить</button>}>
|
|
264
|
-
<PageHead title="Товары" subtitle="Каталог" actions={<button>Добавить</button>} />
|
|
309
|
+
<PageShell scroll footer={<button type="button">Сохранить</button>}>
|
|
310
|
+
<PageHead sticky title="Товары" sup={12} subtitle="Каталог" actions={<button>Добавить</button>} />
|
|
265
311
|
<Section title="Фильтры">{/* … */}</Section>
|
|
266
312
|
</PageShell>
|
|
267
313
|
```
|
|
@@ -407,7 +453,7 @@ const people = [
|
|
|
407
453
|
|
|
408
454
|
`Menu` — навигация в шапке (inline, не popover).
|
|
409
455
|
|
|
410
|
-
**Dropdown vs
|
|
456
|
+
**Dropdown vs Popover:** `Dropdown` — пункты `items`/`groups`. `Popover` — свой `children` в portal (тот же z-стек, что у `@elcrm/form`). `@elcrm/overlay` `Menu` — устаревший алиас `Popover`. Select — `@elcrm/form`, не overlay.
|
|
411
457
|
|
|
412
458
|
### Breadcrumb
|
|
413
459
|
|
|
@@ -449,6 +495,7 @@ const people = [
|
|
|
449
495
|
|
|
450
496
|
```tsx
|
|
451
497
|
<Layout
|
|
498
|
+
sidebar={<Sidebar groups={groups} value={page} onSelect={setPage} />}
|
|
452
499
|
header={
|
|
453
500
|
<Header
|
|
454
501
|
brand={<Brand onClick={() => {}}>App</Brand>}
|
|
@@ -563,6 +610,7 @@ const resolve = createLazyResolver((value) => import(`./sections/${value}.tsx`))
|
|
|
563
610
|
--shell-color-warning
|
|
564
611
|
--shell-border (= --line, только цвет)
|
|
565
612
|
--shell-background (= --panel)
|
|
613
|
+
--shell-bg фон страницы (sticky PageHead)
|
|
566
614
|
--shell-background-muted / -hover / -selected
|
|
567
615
|
--shell-shadow
|
|
568
616
|
```
|
|
@@ -576,6 +624,8 @@ const resolve = createLazyResolver((value) => import(`./sections/${value}.tsx`))
|
|
|
576
624
|
--avatar-size-s|m|l / --avatar-group-overlap
|
|
577
625
|
--dropdown-min-width / --dropdown-max-width / --dropdown-max-height
|
|
578
626
|
--pricing-card-min-width / --pricing-table-label-width
|
|
627
|
+
--card-pointer
|
|
628
|
+
--stack-grid-min
|
|
579
629
|
--row-gap / --column-gap
|
|
580
630
|
--popup-shadow
|
|
581
631
|
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import e from "react";
|
|
2
|
+
import { c as n } from "./cx-CcykAxZN.js";
|
|
3
|
+
import './ActionGroup.css';const s = "c5r", i = {
|
|
4
|
+
r: s
|
|
5
|
+
};
|
|
6
|
+
function p({
|
|
7
|
+
label: r,
|
|
8
|
+
items: o,
|
|
9
|
+
children: t,
|
|
10
|
+
className: a,
|
|
11
|
+
...c
|
|
12
|
+
}) {
|
|
13
|
+
return /* @__PURE__ */ e.createElement(
|
|
14
|
+
"div",
|
|
15
|
+
{
|
|
16
|
+
className: n(i.r, a),
|
|
17
|
+
role: "toolbar",
|
|
18
|
+
"aria-label": r,
|
|
19
|
+
...c
|
|
20
|
+
},
|
|
21
|
+
o,
|
|
22
|
+
t
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
p as A
|
|
27
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer elcrm-components{.c5r{display:flex;flex-wrap:nowrap;align-items:center;gap:var(--action-group-gap, var(--shell-gap-sm));flex:0 0 auto}}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Ряд действий в строке списка / карточке (`role="toolbar"`).
|
|
4
|
+
*
|
|
5
|
+
* Роли: тулбар иконок справа в Card. Кнопки — `@elcrm/button` / свои слоты,
|
|
6
|
+
* не нативный `<button>` в приложении.
|
|
7
|
+
*
|
|
8
|
+
* @param label подпись для `aria-label`
|
|
9
|
+
* @param items массив узлов (если нет — только `children`)
|
|
10
|
+
* @param children слот кнопок; можно вместе с `items` (сначала items)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <ActionGroup
|
|
15
|
+
* label="Действия: Иван"
|
|
16
|
+
* items={[
|
|
17
|
+
* <Button key="edit" variant="ghost" onClick={edit}>Изменить</Button>,
|
|
18
|
+
* <Button key="del" variant="ghost" onClick={remove}>Удалить</Button>,
|
|
19
|
+
* ]}
|
|
20
|
+
* />
|
|
21
|
+
*
|
|
22
|
+
* <ActionGroup label="Ещё">
|
|
23
|
+
* <Button variant="ghost">Копировать</Button>
|
|
24
|
+
* </ActionGroup>
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* Токены: `--action-group-gap` (иначе `--shell-gap-sm`).
|
|
28
|
+
*/
|
|
29
|
+
export type ActionGroupProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
30
|
+
/** Подпись тулбара (`aria-label`) */
|
|
31
|
+
label: string;
|
|
32
|
+
/** Кнопки массивом узлов */
|
|
33
|
+
items?: React.ReactNode[];
|
|
34
|
+
/** Свои кнопки / слоты */
|
|
35
|
+
children?: React.ReactNode;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Группа действий: `items` и/или `children`.
|
|
39
|
+
*
|
|
40
|
+
* @see Card, Stack, Item
|
|
41
|
+
*/
|
|
42
|
+
export declare function ActionGroup({ label, items, children, className, ...rest }: ActionGroupProps): React.JSX.Element;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import a from "react";
|
|
2
|
+
import { c as p } from "./cx-CcykAxZN.js";
|
|
3
|
+
import './Avatar.css';const h = "car", x = "cav", A = "cas", C = "cam", S = "cal", z = "caa", B = "cai", F = "cab", R = "cao", U = "caf", e = {
|
|
4
|
+
r: h,
|
|
5
|
+
v: x,
|
|
6
|
+
s: A,
|
|
7
|
+
m: C,
|
|
8
|
+
l: S,
|
|
9
|
+
a: z,
|
|
10
|
+
i: B,
|
|
11
|
+
b: F,
|
|
12
|
+
o: R,
|
|
13
|
+
f: U
|
|
14
|
+
};
|
|
15
|
+
function $(t) {
|
|
16
|
+
const n = t.trim();
|
|
17
|
+
if (!n) return "?";
|
|
18
|
+
const s = n.split(/\s+/).filter(Boolean);
|
|
19
|
+
return s.length >= 2 ? (s[0][0] + s[1][0]).toUpperCase() : n.slice(0, 2).toUpperCase();
|
|
20
|
+
}
|
|
21
|
+
function D(t) {
|
|
22
|
+
if (!(t == null || t === ""))
|
|
23
|
+
return {
|
|
24
|
+
"--avatar-radius": typeof t == "number" ? `${t}px` : t
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function j({ status: t }) {
|
|
28
|
+
return /* @__PURE__ */ a.createElement(
|
|
29
|
+
"span",
|
|
30
|
+
{
|
|
31
|
+
className: p(e.b, t === "online" ? e.o : e.f),
|
|
32
|
+
"data-status": t,
|
|
33
|
+
"aria-hidden": !0
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
function k({
|
|
38
|
+
src: t,
|
|
39
|
+
label: n,
|
|
40
|
+
children: s,
|
|
41
|
+
name: c,
|
|
42
|
+
status: o
|
|
43
|
+
}) {
|
|
44
|
+
const l = t != null && t !== "" ? /* @__PURE__ */ a.createElement("img", { className: e.i, src: t, alt: n ?? "", draggable: !1 }) : s ?? (c != null ? $(c) : "?");
|
|
45
|
+
return /* @__PURE__ */ a.createElement(a.Fragment, null, /* @__PURE__ */ a.createElement("span", { className: e.v }, l), o != null ? /* @__PURE__ */ a.createElement(j, { status: o }) : null);
|
|
46
|
+
}
|
|
47
|
+
function G(t) {
|
|
48
|
+
const {
|
|
49
|
+
src: n,
|
|
50
|
+
alt: s,
|
|
51
|
+
name: c,
|
|
52
|
+
size: o = "m",
|
|
53
|
+
status: l,
|
|
54
|
+
active: i,
|
|
55
|
+
children: b,
|
|
56
|
+
className: y,
|
|
57
|
+
radius: E,
|
|
58
|
+
as: f = "span",
|
|
59
|
+
style: N,
|
|
60
|
+
...m
|
|
61
|
+
} = t, g = o === "s" ? e.s : o === "l" ? e.l : e.m, u = p(e.r, g, i && e.a, y), r = s ?? c, d = { ...D(E), ...N }, v = /* @__PURE__ */ a.createElement(
|
|
62
|
+
k,
|
|
63
|
+
{
|
|
64
|
+
src: n,
|
|
65
|
+
label: r,
|
|
66
|
+
name: c,
|
|
67
|
+
status: l,
|
|
68
|
+
children: b
|
|
69
|
+
}
|
|
70
|
+
);
|
|
71
|
+
return f === "button" ? /* @__PURE__ */ a.createElement(
|
|
72
|
+
"button",
|
|
73
|
+
{
|
|
74
|
+
type: "button",
|
|
75
|
+
className: u,
|
|
76
|
+
"aria-label": r,
|
|
77
|
+
"data-active": i ? "true" : void 0,
|
|
78
|
+
"data-status": l,
|
|
79
|
+
style: d,
|
|
80
|
+
...m
|
|
81
|
+
},
|
|
82
|
+
v
|
|
83
|
+
) : f === "div" ? /* @__PURE__ */ a.createElement(
|
|
84
|
+
"div",
|
|
85
|
+
{
|
|
86
|
+
className: u,
|
|
87
|
+
role: r ? "img" : void 0,
|
|
88
|
+
"aria-label": r,
|
|
89
|
+
"data-active": i ? "true" : void 0,
|
|
90
|
+
"data-status": l,
|
|
91
|
+
style: d,
|
|
92
|
+
...m
|
|
93
|
+
},
|
|
94
|
+
v
|
|
95
|
+
) : /* @__PURE__ */ a.createElement(
|
|
96
|
+
"span",
|
|
97
|
+
{
|
|
98
|
+
className: u,
|
|
99
|
+
role: r ? "img" : void 0,
|
|
100
|
+
"aria-label": r,
|
|
101
|
+
"data-active": i ? "true" : void 0,
|
|
102
|
+
"data-status": l,
|
|
103
|
+
style: d,
|
|
104
|
+
...m
|
|
105
|
+
},
|
|
106
|
+
v
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
export {
|
|
110
|
+
G as A,
|
|
111
|
+
D as a,
|
|
112
|
+
$ as i
|
|
113
|
+
};
|
package/dist/Avatar.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer elcrm-components{.car{position:relative;box-sizing:border-box;display:inline-flex;flex-shrink:0;width:fit-content;height:fit-content;border-radius:var(--avatar-radius);-webkit-user-select:none;user-select:none;vertical-align:middle}.car:is(button){-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;padding:0;font:inherit;cursor:pointer;background:transparent;border:none}.cav{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;overflow:hidden;width:100%;height:100%;border-radius:inherit;border:var(--avatar-border);background:var(--avatar-background);color:var(--avatar-color);font-weight:var(--avatar-font-weight);line-height:1}.cas{width:var(--avatar-size-s);height:var(--avatar-size-s);font-size:var(--avatar-font-size-s)}.cas .cav{font-size:inherit}.cam{width:var(--avatar-size-m);height:var(--avatar-size-m);font-size:var(--avatar-font-size-m)}.cam .cav{font-size:inherit}.cal{width:var(--avatar-size-l);height:var(--avatar-size-l);font-size:var(--avatar-font-size-l)}.cal .cav{font-size:inherit}.caa .cav,.car[data-active=true] .cav{outline:var(--avatar-outline-active);outline-offset:var(--avatar-outline-offset)}.cai{width:100%;height:100%;object-fit:cover;display:block}.cab{position:absolute;right:0;bottom:0;box-sizing:border-box;width:var(--shell-status-size);height:var(--shell-status-size);border-radius:50%;border:2px solid var(--shell-background);pointer-events:none}.cas .cab{width:8px;height:8px}.cam .cab{width:var(--shell-status-size);height:var(--shell-status-size)}.cal .cab{width:12px;height:12px}.
|
|
1
|
+
@layer elcrm-components{.car{position:relative;box-sizing:border-box;display:inline-flex;flex-shrink:0;width:fit-content;height:fit-content;border-radius:var(--avatar-radius);-webkit-user-select:none;user-select:none;vertical-align:middle}.car:is(button){-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;padding:0;font:inherit;cursor:pointer;background:transparent;border:none}.cav{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;overflow:hidden;width:100%;height:100%;border-radius:inherit;border:var(--avatar-border);background:var(--avatar-background);color:var(--avatar-color);font-weight:var(--avatar-font-weight);line-height:1}.cas{width:var(--avatar-size-s);height:var(--avatar-size-s);font-size:var(--avatar-font-size-s)}.cas .cav{font-size:inherit}.cam{width:var(--avatar-size-m);height:var(--avatar-size-m);font-size:var(--avatar-font-size-m)}.cam .cav{font-size:inherit}.cal{width:var(--avatar-size-l);height:var(--avatar-size-l);font-size:var(--avatar-font-size-l)}.cal .cav{font-size:inherit}.caa .cav,.car[data-active=true] .cav{outline:var(--avatar-outline-active);outline-offset:var(--avatar-outline-offset)}.cai{width:100%;height:100%;object-fit:cover;display:block}.cab{position:absolute;right:0;bottom:0;box-sizing:border-box;width:var(--shell-status-size);height:var(--shell-status-size);border-radius:50%;border:2px solid var(--shell-background);pointer-events:none}.cas .cab{width:8px;height:8px}.cam .cab{width:var(--shell-status-size);height:var(--shell-status-size)}.cal .cab{width:12px;height:12px}.cao{background:var(--shell-color-success)}.caf{background:var(--shell-color-muted)}}
|
package/dist/Avatar.d.ts
CHANGED
|
@@ -30,11 +30,18 @@ type Common = {
|
|
|
30
30
|
status?: AvatarStatus;
|
|
31
31
|
/** Подсветка (например активный пункт шапки). */
|
|
32
32
|
active?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Скругление. Число — пиксели (`10` → `10px`), строка — любой CSS.
|
|
35
|
+
* Пишет `--avatar-radius` на корне (дефолт токена — круг, `999px`).
|
|
36
|
+
*/
|
|
37
|
+
radius?: number | string;
|
|
33
38
|
/** Кастомное содержимое вместо инициалов (если нет `src`). */
|
|
34
39
|
children?: React.ReactNode;
|
|
35
40
|
/** CSS-класс корня. */
|
|
36
41
|
className?: string;
|
|
37
42
|
};
|
|
43
|
+
/** Стиль `--avatar-radius` из пропа `radius`. */
|
|
44
|
+
export declare function avatarRadiusStyle(radius?: number | string): React.CSSProperties | undefined;
|
|
38
45
|
/**
|
|
39
46
|
* Props {@link Avatar}: корень как `button` | `span` | `div`.
|
|
40
47
|
*
|
|
@@ -59,7 +66,8 @@ export type AvatarProps = (Common & React.ButtonHTMLAttributes<HTMLButtonElement
|
|
|
59
66
|
* (`name` у Avatar остаётся только для инициалов);
|
|
60
67
|
* - {@link AvatarGroup} — стопка аватаров из `items`.
|
|
61
68
|
*
|
|
62
|
-
* CSS-токены: `--avatar-*` (в т.ч. `--avatar-size-s|m|l`).
|
|
69
|
+
* CSS-токены: `--avatar-*` (в т.ч. `--avatar-size-s|m|l`, `--avatar-radius`).
|
|
70
|
+
* Скругление: `radius={10}` или `style={{ ["--avatar-radius"]: "10px" }}`.
|
|
63
71
|
*
|
|
64
72
|
* @example
|
|
65
73
|
* ```tsx
|
package/dist/Avatar.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import n from "react";
|
|
2
|
-
import { A as f } from "./Avatar-
|
|
2
|
+
import { A as f } from "./Avatar-loGgFt72.js";
|
|
3
3
|
import { c as u } from "./cx-CcykAxZN.js";
|
|
4
4
|
import './AvatarGroup.css';const G = "cyr", I = "cyi", M = "cyo", R = "cyd", S = "cys", j = "cym", q = "cyl", l = {
|
|
5
5
|
r: G,
|
package/dist/AvatarGroup.js
CHANGED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import t from "react";
|
|
2
|
+
import { A as b } from "./Avatar-loGgFt72.js";
|
|
3
|
+
import { c as g } from "./cx-CcykAxZN.js";
|
|
4
|
+
import './AvatarName.css';const y = "czr", A = "czc", h = "czt", x = "czd", C = "czs", F = "czm", I = "czl", e = {
|
|
5
|
+
r: y,
|
|
6
|
+
c: A,
|
|
7
|
+
t: h,
|
|
8
|
+
d: x,
|
|
9
|
+
s: C,
|
|
10
|
+
m: F,
|
|
11
|
+
l: I
|
|
12
|
+
};
|
|
13
|
+
function R(s, n) {
|
|
14
|
+
if (s != null && s !== "") return s;
|
|
15
|
+
if (typeof n == "string") return n;
|
|
16
|
+
}
|
|
17
|
+
function k(s) {
|
|
18
|
+
const {
|
|
19
|
+
src: n,
|
|
20
|
+
name: c,
|
|
21
|
+
title: m,
|
|
22
|
+
description: i,
|
|
23
|
+
size: a = "m",
|
|
24
|
+
radius: f,
|
|
25
|
+
status: p,
|
|
26
|
+
className: z,
|
|
27
|
+
children: E,
|
|
28
|
+
as: u = "div",
|
|
29
|
+
...r
|
|
30
|
+
} = s, N = a === "s" ? e.s : a === "l" ? e.l : e.m, l = g(e.r, N, z), d = m ?? (typeof c == "string" ? c : void 0), v = R(c, m), o = /* @__PURE__ */ t.createElement(t.Fragment, null, /* @__PURE__ */ t.createElement(
|
|
31
|
+
b,
|
|
32
|
+
{
|
|
33
|
+
src: n,
|
|
34
|
+
name: v,
|
|
35
|
+
size: a,
|
|
36
|
+
radius: f,
|
|
37
|
+
status: p
|
|
38
|
+
}
|
|
39
|
+
), /* @__PURE__ */ t.createElement("span", { className: e.c }, d != null ? /* @__PURE__ */ t.createElement("span", { className: e.t }, d) : null, i != null ? /* @__PURE__ */ t.createElement("span", { className: e.d }, i) : null, E));
|
|
40
|
+
return u === "button" ? /* @__PURE__ */ t.createElement(
|
|
41
|
+
"button",
|
|
42
|
+
{
|
|
43
|
+
type: "button",
|
|
44
|
+
className: l,
|
|
45
|
+
...r
|
|
46
|
+
},
|
|
47
|
+
o
|
|
48
|
+
) : u === "a" ? /* @__PURE__ */ t.createElement(
|
|
49
|
+
"a",
|
|
50
|
+
{
|
|
51
|
+
className: l,
|
|
52
|
+
...r
|
|
53
|
+
},
|
|
54
|
+
o
|
|
55
|
+
) : /* @__PURE__ */ t.createElement(
|
|
56
|
+
"div",
|
|
57
|
+
{
|
|
58
|
+
className: l,
|
|
59
|
+
...r
|
|
60
|
+
},
|
|
61
|
+
o
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
export {
|
|
65
|
+
k as A
|
|
66
|
+
};
|
package/dist/AvatarName.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer elcrm-components{.czr{display:inline-flex;align-items:center;gap:var(--shell-gap);max-width:100%;text-align:left;vertical-align:middle}.czr:is(button,a){-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;padding:0;border:none;background:transparent;font:inherit;color:inherit;cursor:pointer;text-decoration:none}.czc{display:flex;flex-direction:column;gap:2px;min-width:0}.czt{margin:0;font-size:var(--shell-font-size);font-weight:var(--shell-font-weight);color:var(--shell-color);line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.czd{margin:0;font-size:var(--shell-font-size-sm);font-weight:400;color:var(--shell-color-muted);line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.czs{gap:var(--shell-gap-sm)}.czs .czt{font-size:var(--shell-font-size-sm)}.czm{gap:var(--shell-gap)}.czl{gap:var(--shell-gap-lg)}.czl .czt{font-size:var(--shell-font-size-lg)}.czl .czd{font-size:var(--shell-font-size)}}
|
|
1
|
+
@layer elcrm-components{.czr{display:inline-flex;align-items:center;gap:var(--shell-gap);max-width:100%;text-align:left;vertical-align:middle}.czr:is(button,a){-webkit-appearance:none;-moz-appearance:none;appearance:none;margin:0;padding:0;border:none;background:transparent;font:inherit;color:inherit;cursor:pointer;text-decoration:none}.czc{display:flex;flex-direction:column;gap:2px;min-width:0}.czt{margin:0;font-size:var(--shell-font-size);font-weight:var(--shell-font-weight);color:var(--avatar-name-title-color, var(--shell-color));line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.czd{margin:0;font-size:var(--shell-font-size-sm);font-weight:400;color:var(--avatar-name-description-color, var(--shell-color-muted));line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.czs{gap:var(--shell-gap-sm)}.czs .czt{font-size:var(--shell-font-size-sm)}.czm{gap:var(--shell-gap)}.czl{gap:var(--shell-gap-lg)}.czl .czt{font-size:var(--shell-font-size-lg)}.czl .czd{font-size:var(--shell-font-size)}}
|
package/dist/AvatarName.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ type Common = {
|
|
|
20
20
|
description?: React.ReactNode;
|
|
21
21
|
/** Размер: `s` | `m` | `l`. */
|
|
22
22
|
size?: "s" | "m" | "l";
|
|
23
|
+
/** Скругление аватара (`10` → `10px`). Токен `--avatar-radius`. */
|
|
24
|
+
radius?: number | string;
|
|
23
25
|
/** Статус у аватара. */
|
|
24
26
|
status?: AvatarStatus;
|
|
25
27
|
/** CSS-класс корня. */
|
|
@@ -50,7 +52,8 @@ export type AvatarNameProps = (Common & React.ButtonHTMLAttributes<HTMLButtonEle
|
|
|
50
52
|
*
|
|
51
53
|
* Канон: `title` / `description` для UI-текста; `name` — только инициалы.
|
|
52
54
|
*
|
|
53
|
-
* CSS-токены: `--
|
|
55
|
+
* CSS-токены: `--avatar-name-title-color`, `--avatar-name-description-color`,
|
|
56
|
+
* аватар — `--avatar-*`.
|
|
54
57
|
*
|
|
55
58
|
* @example
|
|
56
59
|
* ```tsx
|
package/dist/AvatarName.js
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import t from "react";
|
|
2
|
+
import { c as j } from "./cx-CcykAxZN.js";
|
|
3
|
+
import './Badge.css';const u = "cjr", i = "cjs", p = "cjm", w = "cjl", f = "cjn", g = "cja", N = "cju", h = "cjw", x = "cjd", z = "cjo", s = {
|
|
4
|
+
r: u,
|
|
5
|
+
s: i,
|
|
6
|
+
m: p,
|
|
7
|
+
l: w,
|
|
8
|
+
n: f,
|
|
9
|
+
a: g,
|
|
10
|
+
u: N,
|
|
11
|
+
w: h,
|
|
12
|
+
d: x,
|
|
13
|
+
o: z
|
|
14
|
+
};
|
|
15
|
+
function E(e) {
|
|
16
|
+
const {
|
|
17
|
+
tone: c = "neutral",
|
|
18
|
+
size: n = "m",
|
|
19
|
+
dot: o,
|
|
20
|
+
children: a,
|
|
21
|
+
className: r,
|
|
22
|
+
...l
|
|
23
|
+
} = e, m = c === "accent" ? s.a : c === "success" ? s.u : c === "warning" ? s.w : c === "danger" ? s.d : s.n, d = n === "s" ? s.s : n === "l" ? s.l : s.m;
|
|
24
|
+
return /* @__PURE__ */ t.createElement("span", { className: j(s.r, d, m, r), ...l }, o ? /* @__PURE__ */ t.createElement("span", { className: s.o, "aria-hidden": !0 }) : null, a);
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
E as B
|
|
28
|
+
};
|
package/dist/Badge.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer elcrm-components{.cjr{display:inline-flex;align-items:center;justify-content:center;gap:.25rem;padding:.2rem .5rem;border-radius:999px;border:0;font-size:var(--shell-font-size-sm);font-weight:var(--shell-font-
|
|
1
|
+
@layer elcrm-components{.cjr{display:inline-flex;align-items:center;justify-content:center;gap:.25rem;padding:.2rem .5rem;border-radius:999px;border:0;font-size:var(--shell-font-size-sm);font-weight: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}}
|
package/dist/Badge.d.ts
CHANGED
|
@@ -1,26 +1,41 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
+
/** Тон метки — те же смыслы, что у Stat */
|
|
3
|
+
export type BadgeTone = "neutral" | "accent" | "success" | "warning" | "danger";
|
|
4
|
+
/** Размер метки */
|
|
5
|
+
export type BadgeSize = "s" | "m" | "l";
|
|
6
|
+
export type BadgeProps = React.HTMLAttributes<HTMLSpanElement> & {
|
|
7
|
+
/**
|
|
8
|
+
* Цвет по смыслу.
|
|
9
|
+
* `neutral` | `accent` | `success` | `warning` | `danger`
|
|
10
|
+
*/
|
|
11
|
+
tone?: BadgeTone;
|
|
12
|
+
/**
|
|
13
|
+
* Размер пилюли.
|
|
14
|
+
* `s` — в строке списка; `m` — обычная; `l` — крупнее.
|
|
15
|
+
* По умолчанию `m`.
|
|
16
|
+
*/
|
|
17
|
+
size?: BadgeSize;
|
|
18
|
+
/** Точка статуса слева (цвет = `tone`) */
|
|
19
|
+
dot?: boolean;
|
|
20
|
+
/** Текст метки */
|
|
21
|
+
children?: React.ReactNode;
|
|
22
|
+
};
|
|
2
23
|
/**
|
|
3
|
-
* Компактная метка / статус (
|
|
24
|
+
* Компактная метка / статус (роль, состояние). Не заменяет Button.
|
|
4
25
|
*
|
|
5
|
-
*
|
|
26
|
+
* Props (`BadgeProps`):
|
|
27
|
+
* - `tone` — `neutral` | `accent` | `success` | `warning` | `danger`
|
|
28
|
+
* - `size` — `s` | `m` | `l` (по умолчанию `m`)
|
|
29
|
+
* - `dot` — точка слева (как online / offline)
|
|
30
|
+
* - `children` — текст метки
|
|
31
|
+
* - плюс атрибуты `span` (`className`, `style`, …)
|
|
6
32
|
*
|
|
7
33
|
* @example
|
|
8
34
|
* ```tsx
|
|
9
|
-
* <Badge tone="
|
|
10
|
-
* <Badge tone="
|
|
35
|
+
* <Badge tone="accent" size="s">ADMIN</Badge>
|
|
36
|
+
* <Badge tone="success" size="s" dot>online</Badge>
|
|
11
37
|
* ```
|
|
12
38
|
*
|
|
13
|
-
*
|
|
14
|
-
*/
|
|
15
|
-
export type BadgeProps = React.HTMLAttributes<HTMLSpanElement> & {
|
|
16
|
-
/** Визуальный тон */
|
|
17
|
-
tone?: "neutral" | "accent" | "success" | "warning" | "danger";
|
|
18
|
-
/** Текст или содержимое метки */
|
|
19
|
-
children?: React.ReactNode;
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Компактная метка / статус.
|
|
23
|
-
*
|
|
24
|
-
* @see Item, Card, Avatar
|
|
39
|
+
* @see Item, Card, Stat
|
|
25
40
|
*/
|
|
26
|
-
export declare function Badge(
|
|
41
|
+
export declare function Badge(props: BadgeProps): React.JSX.Element;
|
package/dist/Badge.js
CHANGED
package/dist/Block.js
CHANGED