@cloud-ru/ds-ai-queue 1.0.0
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/CHANGELOG.md +8 -0
- package/LICENSE +201 -0
- package/README.md +56 -0
- package/dist/cjs/AiQueue.d.ts +3 -0
- package/dist/cjs/AiQueue.js +29 -0
- package/dist/cjs/AiQueueStepStatus.d.ts +7 -0
- package/dist/cjs/AiQueueStepStatus.js +25 -0
- package/dist/cjs/constants.d.ts +15 -0
- package/dist/cjs/constants.js +22 -0
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.js +19 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/style.css +148 -0
- package/dist/cjs/styles.module.css +148 -0
- package/dist/cjs/types.d.ts +38 -0
- package/dist/cjs/types.js +2 -0
- package/dist/cjs/utils.d.ts +3 -0
- package/dist/cjs/utils.js +29 -0
- package/dist/esm/AiQueue.d.ts +3 -0
- package/dist/esm/AiQueue.js +23 -0
- package/dist/esm/AiQueueStepStatus.d.ts +7 -0
- package/dist/esm/AiQueueStepStatus.js +19 -0
- package/dist/esm/constants.d.ts +15 -0
- package/dist/esm/constants.js +19 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/style.css +148 -0
- package/dist/esm/styles.module.css +148 -0
- package/dist/esm/types.d.ts +38 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/utils.d.ts +3 -0
- package/dist/esm/utils.js +25 -0
- package/dist/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.esm.tsbuildinfo +1 -0
- package/package.json +45 -0
- package/src/AiQueue.tsx +84 -0
- package/src/AiQueueStepStatus.tsx +27 -0
- package/src/constants.ts +23 -0
- package/src/index.ts +3 -0
- package/src/styles.module.scss +145 -0
- package/src/types.ts +47 -0
- package/src/utils.ts +33 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
.root{
|
|
2
|
+
position:relative;
|
|
3
|
+
display:flex;
|
|
4
|
+
flex-direction:column;
|
|
5
|
+
row-gap:0;
|
|
6
|
+
align-items:stretch;
|
|
7
|
+
width:100%;
|
|
8
|
+
padding-top:var(--sn-primitive-dimension-4, 4px);
|
|
9
|
+
border-radius:var(--sn-density-radius-2xs, var(--sn-primitive-dimension-4, 4px));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.root[data-open]{
|
|
13
|
+
row-gap:var(--sn-primitive-dimension-8, 8px);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.trigger{
|
|
17
|
+
font-family:var(--sn-thin-label-s-fontFamily, var(--sn-brand-font-fontFamily-thin-label, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
|
|
18
|
+
font-weight:var(--sn-thin-label-s-fontWeight, var(--sn-theme-typography-fontWeight-thin-label-s, var(--sn-brand-font-fontWeight-light-thin-label-s, var(--sn-primitive-font-fontWeightValue-450, 450))));
|
|
19
|
+
line-height:var(--sn-thin-label-s-lineHeight, var(--sn-density-typography-roleLabel-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)));
|
|
20
|
+
font-size:var(--sn-thin-label-s-fontSize, var(--sn-density-typography-roleLabel-fontSizeS, var(--sn-primitive-font-fontSize-14, 14px)));
|
|
21
|
+
letter-spacing:var(--sn-thin-label-s-letterSpacing, var(--sn-primitive-font-letterSpacing-s, 0px));
|
|
22
|
+
paragraph-spacing:var(--sn-thin-label-s-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize11, 5px));
|
|
23
|
+
cursor:pointer;
|
|
24
|
+
display:flex;
|
|
25
|
+
-moz-column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
26
|
+
column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
27
|
+
align-items:center;
|
|
28
|
+
width:100%;
|
|
29
|
+
min-width:0;
|
|
30
|
+
margin:0;
|
|
31
|
+
padding:0;
|
|
32
|
+
border:0;
|
|
33
|
+
border-radius:var(--sn-density-radius-2xs, var(--sn-primitive-dimension-4, 4px));
|
|
34
|
+
color:var(--sn-theme-color-available-version-textSecondary, var(--sn-brand-color-text-version-secondary, rgba(65, 66, 78, 0.8)));
|
|
35
|
+
text-align:left;
|
|
36
|
+
-webkit-appearance:none;
|
|
37
|
+
-moz-appearance:none;
|
|
38
|
+
appearance:none;
|
|
39
|
+
background:transparent;
|
|
40
|
+
outline:none;
|
|
41
|
+
}
|
|
42
|
+
.trigger:focus-visible{
|
|
43
|
+
outline:var(--sn-primitive-strokeWeight-strokeSemiBold, 2px) solid var(--sn-theme-color-primary-accent, var(--sn-brand-color-primary-55, var(--sn-brandRole-color-brandA-55, var(--sn-primitive-color-brandA-55, #389f74))));
|
|
44
|
+
outline-offset:0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.summary{
|
|
48
|
+
overflow:hidden;
|
|
49
|
+
display:inline-flex;
|
|
50
|
+
-moz-column-gap:var(--sn-primitive-dimension-2, 2px);
|
|
51
|
+
column-gap:var(--sn-primitive-dimension-2, 2px);
|
|
52
|
+
align-items:center;
|
|
53
|
+
text-overflow:ellipsis;
|
|
54
|
+
white-space:nowrap;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.chevron{
|
|
58
|
+
flex-shrink:0;
|
|
59
|
+
color:var(--sn-theme-color-available-version-textTertiary, var(--sn-brand-color-text-version-tertiary, rgba(65, 66, 78, 0.5490196078)));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.content{
|
|
63
|
+
max-height:140px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.steps{
|
|
67
|
+
display:flex;
|
|
68
|
+
flex-direction:column;
|
|
69
|
+
row-gap:var(--sn-primitive-dimension-8, 8px);
|
|
70
|
+
align-items:stretch;
|
|
71
|
+
padding-right:var(--sn-primitive-dimension-8, 8px);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.step{
|
|
75
|
+
display:flex;
|
|
76
|
+
-moz-column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
77
|
+
column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
78
|
+
align-items:center;
|
|
79
|
+
width:100%;
|
|
80
|
+
min-width:0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.stepStatus{
|
|
84
|
+
display:inline-flex;
|
|
85
|
+
flex-shrink:0;
|
|
86
|
+
align-items:center;
|
|
87
|
+
justify-content:center;
|
|
88
|
+
width:var(--sn-primitive-dimension-16, 16px);
|
|
89
|
+
height:var(--sn-primitive-dimension-16, 16px);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.stepStatusIcon{
|
|
93
|
+
width:100%;
|
|
94
|
+
height:100%;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.stepStatusSuccess{
|
|
98
|
+
color:var(--sn-theme-color-primary-accent, var(--sn-brand-color-primary-55, var(--sn-brandRole-color-brandA-55, var(--sn-primitive-color-brandA-55, #389f74))));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.stepStatusError{
|
|
102
|
+
color:var(--sn-theme-color-red-accent, var(--sn-primitive-color-red-55, #d52e33));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.stepStatusProgress{
|
|
106
|
+
color:var(--sn-theme-color-blue-accent, var(--sn-primitive-color-blue-55, #4387e2));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.stepStatusPending{
|
|
110
|
+
box-sizing:border-box;
|
|
111
|
+
width:var(--sn-primitive-dimension-8, 8px);
|
|
112
|
+
height:var(--sn-primitive-dimension-8, 8px);
|
|
113
|
+
border:var(--sn-primitive-strokeWeight-strokeRegular, 1px) solid var(--sn-theme-color-neutral-decor, var(--sn-brand-color-neutral-80, var(--sn-primitive-color-gray-80, #e3e5ed)));
|
|
114
|
+
border-radius:var(--sn-density-radius-2xs, var(--sn-primitive-dimension-4, 4px));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.stepLabel{
|
|
118
|
+
font-family:var(--sn-thin-label-s-fontFamily, var(--sn-brand-font-fontFamily-thin-label, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
|
|
119
|
+
font-weight:var(--sn-thin-label-s-fontWeight, var(--sn-theme-typography-fontWeight-thin-label-s, var(--sn-brand-font-fontWeight-light-thin-label-s, var(--sn-primitive-font-fontWeightValue-450, 450))));
|
|
120
|
+
line-height:var(--sn-thin-label-s-lineHeight, var(--sn-density-typography-roleLabel-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)));
|
|
121
|
+
font-size:var(--sn-thin-label-s-fontSize, var(--sn-density-typography-roleLabel-fontSizeS, var(--sn-primitive-font-fontSize-14, 14px)));
|
|
122
|
+
letter-spacing:var(--sn-thin-label-s-letterSpacing, var(--sn-primitive-font-letterSpacing-s, 0px));
|
|
123
|
+
paragraph-spacing:var(--sn-thin-label-s-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize11, 5px));
|
|
124
|
+
overflow:hidden;
|
|
125
|
+
flex:1 1 auto;
|
|
126
|
+
min-width:0;
|
|
127
|
+
color:var(--sn-theme-color-available-version-textMain, var(--sn-brand-color-text-version-main, #41424e));
|
|
128
|
+
text-overflow:ellipsis;
|
|
129
|
+
white-space:nowrap;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.step[data-state=progress] .stepLabel{
|
|
133
|
+
font-family:var(--sn-regular-label-s-fontFamily, var(--sn-brand-font-fontFamily-regular-label, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
|
|
134
|
+
font-weight:var(--sn-regular-label-s-fontWeight, var(--sn-theme-typography-fontWeight-regular-label-s, var(--sn-brand-font-fontWeight-light-regular-label-s, var(--sn-primitive-font-fontWeightValue-500, 500))));
|
|
135
|
+
line-height:var(--sn-regular-label-s-lineHeight, var(--sn-density-typography-roleLabel-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)));
|
|
136
|
+
font-size:var(--sn-regular-label-s-fontSize, var(--sn-density-typography-roleLabel-fontSizeS, var(--sn-primitive-font-fontSize-14, 14px)));
|
|
137
|
+
letter-spacing:var(--sn-regular-label-s-letterSpacing, var(--sn-primitive-font-letterSpacing-s, 0px));
|
|
138
|
+
paragraph-spacing:var(--sn-regular-label-s-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize11, 5px));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.step[data-state=error] .stepLabel,
|
|
142
|
+
.step[data-state=done] .stepLabel{
|
|
143
|
+
color:var(--sn-theme-color-available-version-textTertiary, var(--sn-brand-color-text-version-tertiary, rgba(65, 66, 78, 0.5490196078)));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.step[data-state=done] .stepLabel{
|
|
147
|
+
text-decoration:line-through;
|
|
148
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ValueOf, WithSupportProps } from '@cloud-ru/ds-utils';
|
|
2
|
+
import type { ComponentPropsWithoutRef } from 'react';
|
|
3
|
+
import { AI_QUEUE_STEP_STATE } from './constants';
|
|
4
|
+
export type AiQueueStepState = ValueOf<typeof AI_QUEUE_STEP_STATE>;
|
|
5
|
+
export type AiQueueStep = {
|
|
6
|
+
id?: string | number;
|
|
7
|
+
label: string;
|
|
8
|
+
state?: AiQueueStepState;
|
|
9
|
+
};
|
|
10
|
+
export type AiQueueSummary = {
|
|
11
|
+
total?: number;
|
|
12
|
+
planned?: number;
|
|
13
|
+
progress?: number;
|
|
14
|
+
done?: number;
|
|
15
|
+
};
|
|
16
|
+
export type AiQueueLabels = {
|
|
17
|
+
tasks: string;
|
|
18
|
+
planned: string;
|
|
19
|
+
inProgress: string;
|
|
20
|
+
done: string;
|
|
21
|
+
};
|
|
22
|
+
export type AiQueueOwnProps = {
|
|
23
|
+
/** Шаги очереди. */
|
|
24
|
+
steps?: AiQueueStep[];
|
|
25
|
+
/** Принудительные счётчики в заголовке; если не заданы, считаются по `steps`. */
|
|
26
|
+
summary?: AiQueueSummary;
|
|
27
|
+
/** Контролируемое состояние раскрытия. */
|
|
28
|
+
open?: boolean;
|
|
29
|
+
/** Начальное состояние раскрытия в uncontrolled-режиме. */
|
|
30
|
+
defaultOpen?: boolean;
|
|
31
|
+
/** Коллбек изменения раскрытия. */
|
|
32
|
+
onOpenChange?: (open: boolean) => void;
|
|
33
|
+
/** Тексты счётчика в заголовке. */
|
|
34
|
+
labels?: Partial<AiQueueLabels>;
|
|
35
|
+
/** Дополнительный CSS-класс корня. */
|
|
36
|
+
className?: string;
|
|
37
|
+
};
|
|
38
|
+
export type AiQueueProps = WithSupportProps<AiQueueOwnProps & Omit<ComponentPropsWithoutRef<'div'>, keyof AiQueueOwnProps | 'children'>>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveStepState = resolveStepState;
|
|
4
|
+
exports.calculateSummary = calculateSummary;
|
|
5
|
+
const constants_1 = require("./constants");
|
|
6
|
+
function resolveStepState(state) {
|
|
7
|
+
return state ?? constants_1.AI_QUEUE_STEP_STATE.Planned;
|
|
8
|
+
}
|
|
9
|
+
function calculateSummary(steps) {
|
|
10
|
+
return steps.reduce((acc, step) => {
|
|
11
|
+
const state = resolveStepState(step.state);
|
|
12
|
+
acc.total += 1;
|
|
13
|
+
if (state === constants_1.AI_QUEUE_STEP_STATE.Planned) {
|
|
14
|
+
acc.planned += 1;
|
|
15
|
+
}
|
|
16
|
+
if (state === constants_1.AI_QUEUE_STEP_STATE.Progress) {
|
|
17
|
+
acc.progress += 1;
|
|
18
|
+
}
|
|
19
|
+
if (state === constants_1.AI_QUEUE_STEP_STATE.Done) {
|
|
20
|
+
acc.done += 1;
|
|
21
|
+
}
|
|
22
|
+
return acc;
|
|
23
|
+
}, {
|
|
24
|
+
total: 0,
|
|
25
|
+
planned: 0,
|
|
26
|
+
progress: 0,
|
|
27
|
+
done: 0,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { AiButtonChevron } from '@cloud-ru/ds-ai-button-chevron';
|
|
3
|
+
import { Scroll } from '@cloud-ru/ds-scroll';
|
|
4
|
+
import { useUncontrolledProp } from '@cloud-ru/ds-utils';
|
|
5
|
+
import cn from 'classnames';
|
|
6
|
+
import { useMemo } from 'react';
|
|
7
|
+
import { AiQueueStepStatus } from './AiQueueStepStatus.js';
|
|
8
|
+
import { DEFAULT_LABELS, TEST_IDS } from './constants.js';
|
|
9
|
+
import styles from './styles.module.css';
|
|
10
|
+
import { calculateSummary, resolveStepState } from './utils.js';
|
|
11
|
+
export function AiQueue({ className, steps = [], summary, labels, open: openProp, defaultOpen = false, onOpenChange, 'data-test-id': dataTestId = TEST_IDS.root, ...rest }) {
|
|
12
|
+
const [open, setOpen] = useUncontrolledProp(openProp, defaultOpen, onOpenChange);
|
|
13
|
+
const mergedLabels = { ...DEFAULT_LABELS, ...labels };
|
|
14
|
+
const derivedSummary = useMemo(() => calculateSummary(steps), [steps]);
|
|
15
|
+
const total = summary?.total ?? derivedSummary.total;
|
|
16
|
+
const planned = summary?.planned ?? derivedSummary.planned;
|
|
17
|
+
const progress = summary?.progress ?? derivedSummary.progress;
|
|
18
|
+
const done = summary?.done ?? derivedSummary.done;
|
|
19
|
+
return (_jsxs("div", { ...rest, className: cn(styles.root, className), "data-open": open || undefined, "data-test-id": dataTestId, children: [_jsxs("button", { type: 'button', className: styles.trigger, "aria-expanded": open, "data-test-id": TEST_IDS.trigger, onClick: () => setOpen(!open), children: [_jsxs("span", { className: styles.summary, "data-test-id": TEST_IDS.summary, children: [_jsx("span", { children: total }), _jsx("span", { children: mergedLabels.tasks }), _jsx("span", { children: "(" }), _jsx("span", { children: planned }), _jsx("span", { children: mergedLabels.planned }), _jsx("span", { children: "/" }), _jsx("span", { children: progress }), _jsx("span", { children: mergedLabels.inProgress }), _jsx("span", { children: "/" }), _jsx("span", { children: done }), _jsx("span", { children: mergedLabels.done }), _jsx("span", { children: ")" })] }), _jsx(AiButtonChevron, { opened: open, interactive: false, className: styles.chevron })] }), open && steps.length > 0 && (_jsx(Scroll, { size: 's', barHideStrategy: 'leave', className: styles.content, "data-test-id": TEST_IDS.content, children: _jsx("div", { className: styles.steps, children: steps.map((step, index) => {
|
|
20
|
+
const state = resolveStepState(step.state);
|
|
21
|
+
return (_jsxs("div", { className: styles.step, "data-state": state, "data-test-id": `${TEST_IDS.step}-${index}`, children: [_jsx("span", { className: styles.stepStatus, "aria-hidden": true, children: _jsx(AiQueueStepStatus, { state: state }) }), _jsx("span", { className: styles.stepLabel, children: step.label })] }, step.id ?? `${index}-${step.label}`));
|
|
22
|
+
}) }) }))] }));
|
|
23
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { CheckSVG, CrossSVG } from '@cloud-ru/ds-icons/interface/system';
|
|
3
|
+
import { Sun, SUN_SIZE } from '@cloud-ru/ds-loader';
|
|
4
|
+
import cn from 'classnames';
|
|
5
|
+
import { AI_QUEUE_STEP_STATE } from './constants.js';
|
|
6
|
+
import styles from './styles.module.css';
|
|
7
|
+
const STEP_STATUS_ICON_SIZE = 16;
|
|
8
|
+
export function AiQueueStepStatus({ state }) {
|
|
9
|
+
switch (state) {
|
|
10
|
+
case AI_QUEUE_STEP_STATE.Done:
|
|
11
|
+
return _jsx(CheckSVG, { size: STEP_STATUS_ICON_SIZE, className: cn(styles.stepStatusIcon, styles.stepStatusSuccess) });
|
|
12
|
+
case AI_QUEUE_STEP_STATE.Error:
|
|
13
|
+
return _jsx(CrossSVG, { size: STEP_STATUS_ICON_SIZE, className: cn(styles.stepStatusIcon, styles.stepStatusError) });
|
|
14
|
+
case AI_QUEUE_STEP_STATE.Progress:
|
|
15
|
+
return _jsx(Sun, { size: SUN_SIZE.XS, className: cn(styles.stepStatusIcon, styles.stepStatusProgress) });
|
|
16
|
+
default:
|
|
17
|
+
return _jsx("span", { className: styles.stepStatusPending });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AiQueueLabels } from './types.js';
|
|
2
|
+
export declare const AI_QUEUE_STEP_STATE: {
|
|
3
|
+
readonly Planned: "planned";
|
|
4
|
+
readonly Progress: "progress";
|
|
5
|
+
readonly Done: "done";
|
|
6
|
+
readonly Error: "error";
|
|
7
|
+
};
|
|
8
|
+
export declare const DEFAULT_LABELS: AiQueueLabels;
|
|
9
|
+
export declare const TEST_IDS: {
|
|
10
|
+
readonly root: "ai-queue";
|
|
11
|
+
readonly trigger: "ai-queue__trigger";
|
|
12
|
+
readonly summary: "ai-queue__summary";
|
|
13
|
+
readonly content: "ai-queue__content";
|
|
14
|
+
readonly step: "ai-queue__step";
|
|
15
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const AI_QUEUE_STEP_STATE = {
|
|
2
|
+
Planned: 'planned',
|
|
3
|
+
Progress: 'progress',
|
|
4
|
+
Done: 'done',
|
|
5
|
+
Error: 'error',
|
|
6
|
+
};
|
|
7
|
+
export const DEFAULT_LABELS = {
|
|
8
|
+
tasks: 'задач',
|
|
9
|
+
planned: 'запланировано',
|
|
10
|
+
inProgress: 'в процессе',
|
|
11
|
+
done: 'готово',
|
|
12
|
+
};
|
|
13
|
+
export const TEST_IDS = {
|
|
14
|
+
root: 'ai-queue',
|
|
15
|
+
trigger: 'ai-queue__trigger',
|
|
16
|
+
summary: 'ai-queue__summary',
|
|
17
|
+
content: 'ai-queue__content',
|
|
18
|
+
step: 'ai-queue__step',
|
|
19
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
.root{
|
|
2
|
+
position:relative;
|
|
3
|
+
display:flex;
|
|
4
|
+
flex-direction:column;
|
|
5
|
+
row-gap:0;
|
|
6
|
+
align-items:stretch;
|
|
7
|
+
width:100%;
|
|
8
|
+
padding-top:var(--sn-primitive-dimension-4, 4px);
|
|
9
|
+
border-radius:var(--sn-density-radius-2xs, var(--sn-primitive-dimension-4, 4px));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.root[data-open]{
|
|
13
|
+
row-gap:var(--sn-primitive-dimension-8, 8px);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.trigger{
|
|
17
|
+
font-family:var(--sn-thin-label-s-fontFamily, var(--sn-brand-font-fontFamily-thin-label, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
|
|
18
|
+
font-weight:var(--sn-thin-label-s-fontWeight, var(--sn-theme-typography-fontWeight-thin-label-s, var(--sn-brand-font-fontWeight-light-thin-label-s, var(--sn-primitive-font-fontWeightValue-450, 450))));
|
|
19
|
+
line-height:var(--sn-thin-label-s-lineHeight, var(--sn-density-typography-roleLabel-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)));
|
|
20
|
+
font-size:var(--sn-thin-label-s-fontSize, var(--sn-density-typography-roleLabel-fontSizeS, var(--sn-primitive-font-fontSize-14, 14px)));
|
|
21
|
+
letter-spacing:var(--sn-thin-label-s-letterSpacing, var(--sn-primitive-font-letterSpacing-s, 0px));
|
|
22
|
+
paragraph-spacing:var(--sn-thin-label-s-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize11, 5px));
|
|
23
|
+
cursor:pointer;
|
|
24
|
+
display:flex;
|
|
25
|
+
-moz-column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
26
|
+
column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
27
|
+
align-items:center;
|
|
28
|
+
width:100%;
|
|
29
|
+
min-width:0;
|
|
30
|
+
margin:0;
|
|
31
|
+
padding:0;
|
|
32
|
+
border:0;
|
|
33
|
+
border-radius:var(--sn-density-radius-2xs, var(--sn-primitive-dimension-4, 4px));
|
|
34
|
+
color:var(--sn-theme-color-available-version-textSecondary, var(--sn-brand-color-text-version-secondary, rgba(65, 66, 78, 0.8)));
|
|
35
|
+
text-align:left;
|
|
36
|
+
-webkit-appearance:none;
|
|
37
|
+
-moz-appearance:none;
|
|
38
|
+
appearance:none;
|
|
39
|
+
background:transparent;
|
|
40
|
+
outline:none;
|
|
41
|
+
}
|
|
42
|
+
.trigger:focus-visible{
|
|
43
|
+
outline:var(--sn-primitive-strokeWeight-strokeSemiBold, 2px) solid var(--sn-theme-color-primary-accent, var(--sn-brand-color-primary-55, var(--sn-brandRole-color-brandA-55, var(--sn-primitive-color-brandA-55, #389f74))));
|
|
44
|
+
outline-offset:0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.summary{
|
|
48
|
+
overflow:hidden;
|
|
49
|
+
display:inline-flex;
|
|
50
|
+
-moz-column-gap:var(--sn-primitive-dimension-2, 2px);
|
|
51
|
+
column-gap:var(--sn-primitive-dimension-2, 2px);
|
|
52
|
+
align-items:center;
|
|
53
|
+
text-overflow:ellipsis;
|
|
54
|
+
white-space:nowrap;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.chevron{
|
|
58
|
+
flex-shrink:0;
|
|
59
|
+
color:var(--sn-theme-color-available-version-textTertiary, var(--sn-brand-color-text-version-tertiary, rgba(65, 66, 78, 0.5490196078)));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.content{
|
|
63
|
+
max-height:140px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.steps{
|
|
67
|
+
display:flex;
|
|
68
|
+
flex-direction:column;
|
|
69
|
+
row-gap:var(--sn-primitive-dimension-8, 8px);
|
|
70
|
+
align-items:stretch;
|
|
71
|
+
padding-right:var(--sn-primitive-dimension-8, 8px);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.step{
|
|
75
|
+
display:flex;
|
|
76
|
+
-moz-column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
77
|
+
column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
78
|
+
align-items:center;
|
|
79
|
+
width:100%;
|
|
80
|
+
min-width:0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.stepStatus{
|
|
84
|
+
display:inline-flex;
|
|
85
|
+
flex-shrink:0;
|
|
86
|
+
align-items:center;
|
|
87
|
+
justify-content:center;
|
|
88
|
+
width:var(--sn-primitive-dimension-16, 16px);
|
|
89
|
+
height:var(--sn-primitive-dimension-16, 16px);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.stepStatusIcon{
|
|
93
|
+
width:100%;
|
|
94
|
+
height:100%;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.stepStatusSuccess{
|
|
98
|
+
color:var(--sn-theme-color-primary-accent, var(--sn-brand-color-primary-55, var(--sn-brandRole-color-brandA-55, var(--sn-primitive-color-brandA-55, #389f74))));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.stepStatusError{
|
|
102
|
+
color:var(--sn-theme-color-red-accent, var(--sn-primitive-color-red-55, #d52e33));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.stepStatusProgress{
|
|
106
|
+
color:var(--sn-theme-color-blue-accent, var(--sn-primitive-color-blue-55, #4387e2));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.stepStatusPending{
|
|
110
|
+
box-sizing:border-box;
|
|
111
|
+
width:var(--sn-primitive-dimension-8, 8px);
|
|
112
|
+
height:var(--sn-primitive-dimension-8, 8px);
|
|
113
|
+
border:var(--sn-primitive-strokeWeight-strokeRegular, 1px) solid var(--sn-theme-color-neutral-decor, var(--sn-brand-color-neutral-80, var(--sn-primitive-color-gray-80, #e3e5ed)));
|
|
114
|
+
border-radius:var(--sn-density-radius-2xs, var(--sn-primitive-dimension-4, 4px));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.stepLabel{
|
|
118
|
+
font-family:var(--sn-thin-label-s-fontFamily, var(--sn-brand-font-fontFamily-thin-label, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
|
|
119
|
+
font-weight:var(--sn-thin-label-s-fontWeight, var(--sn-theme-typography-fontWeight-thin-label-s, var(--sn-brand-font-fontWeight-light-thin-label-s, var(--sn-primitive-font-fontWeightValue-450, 450))));
|
|
120
|
+
line-height:var(--sn-thin-label-s-lineHeight, var(--sn-density-typography-roleLabel-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)));
|
|
121
|
+
font-size:var(--sn-thin-label-s-fontSize, var(--sn-density-typography-roleLabel-fontSizeS, var(--sn-primitive-font-fontSize-14, 14px)));
|
|
122
|
+
letter-spacing:var(--sn-thin-label-s-letterSpacing, var(--sn-primitive-font-letterSpacing-s, 0px));
|
|
123
|
+
paragraph-spacing:var(--sn-thin-label-s-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize11, 5px));
|
|
124
|
+
overflow:hidden;
|
|
125
|
+
flex:1 1 auto;
|
|
126
|
+
min-width:0;
|
|
127
|
+
color:var(--sn-theme-color-available-version-textMain, var(--sn-brand-color-text-version-main, #41424e));
|
|
128
|
+
text-overflow:ellipsis;
|
|
129
|
+
white-space:nowrap;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.step[data-state=progress] .stepLabel{
|
|
133
|
+
font-family:var(--sn-regular-label-s-fontFamily, var(--sn-brand-font-fontFamily-regular-label, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
|
|
134
|
+
font-weight:var(--sn-regular-label-s-fontWeight, var(--sn-theme-typography-fontWeight-regular-label-s, var(--sn-brand-font-fontWeight-light-regular-label-s, var(--sn-primitive-font-fontWeightValue-500, 500))));
|
|
135
|
+
line-height:var(--sn-regular-label-s-lineHeight, var(--sn-density-typography-roleLabel-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)));
|
|
136
|
+
font-size:var(--sn-regular-label-s-fontSize, var(--sn-density-typography-roleLabel-fontSizeS, var(--sn-primitive-font-fontSize-14, 14px)));
|
|
137
|
+
letter-spacing:var(--sn-regular-label-s-letterSpacing, var(--sn-primitive-font-letterSpacing-s, 0px));
|
|
138
|
+
paragraph-spacing:var(--sn-regular-label-s-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize11, 5px));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.step[data-state=error] .stepLabel,
|
|
142
|
+
.step[data-state=done] .stepLabel{
|
|
143
|
+
color:var(--sn-theme-color-available-version-textTertiary, var(--sn-brand-color-text-version-tertiary, rgba(65, 66, 78, 0.5490196078)));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.step[data-state=done] .stepLabel{
|
|
147
|
+
text-decoration:line-through;
|
|
148
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
.root{
|
|
2
|
+
position:relative;
|
|
3
|
+
display:flex;
|
|
4
|
+
flex-direction:column;
|
|
5
|
+
row-gap:0;
|
|
6
|
+
align-items:stretch;
|
|
7
|
+
width:100%;
|
|
8
|
+
padding-top:var(--sn-primitive-dimension-4, 4px);
|
|
9
|
+
border-radius:var(--sn-density-radius-2xs, var(--sn-primitive-dimension-4, 4px));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.root[data-open]{
|
|
13
|
+
row-gap:var(--sn-primitive-dimension-8, 8px);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.trigger{
|
|
17
|
+
font-family:var(--sn-thin-label-s-fontFamily, var(--sn-brand-font-fontFamily-thin-label, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
|
|
18
|
+
font-weight:var(--sn-thin-label-s-fontWeight, var(--sn-theme-typography-fontWeight-thin-label-s, var(--sn-brand-font-fontWeight-light-thin-label-s, var(--sn-primitive-font-fontWeightValue-450, 450))));
|
|
19
|
+
line-height:var(--sn-thin-label-s-lineHeight, var(--sn-density-typography-roleLabel-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)));
|
|
20
|
+
font-size:var(--sn-thin-label-s-fontSize, var(--sn-density-typography-roleLabel-fontSizeS, var(--sn-primitive-font-fontSize-14, 14px)));
|
|
21
|
+
letter-spacing:var(--sn-thin-label-s-letterSpacing, var(--sn-primitive-font-letterSpacing-s, 0px));
|
|
22
|
+
paragraph-spacing:var(--sn-thin-label-s-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize11, 5px));
|
|
23
|
+
cursor:pointer;
|
|
24
|
+
display:flex;
|
|
25
|
+
-moz-column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
26
|
+
column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
27
|
+
align-items:center;
|
|
28
|
+
width:100%;
|
|
29
|
+
min-width:0;
|
|
30
|
+
margin:0;
|
|
31
|
+
padding:0;
|
|
32
|
+
border:0;
|
|
33
|
+
border-radius:var(--sn-density-radius-2xs, var(--sn-primitive-dimension-4, 4px));
|
|
34
|
+
color:var(--sn-theme-color-available-version-textSecondary, var(--sn-brand-color-text-version-secondary, rgba(65, 66, 78, 0.8)));
|
|
35
|
+
text-align:left;
|
|
36
|
+
-webkit-appearance:none;
|
|
37
|
+
-moz-appearance:none;
|
|
38
|
+
appearance:none;
|
|
39
|
+
background:transparent;
|
|
40
|
+
outline:none;
|
|
41
|
+
}
|
|
42
|
+
.trigger:focus-visible{
|
|
43
|
+
outline:var(--sn-primitive-strokeWeight-strokeSemiBold, 2px) solid var(--sn-theme-color-primary-accent, var(--sn-brand-color-primary-55, var(--sn-brandRole-color-brandA-55, var(--sn-primitive-color-brandA-55, #389f74))));
|
|
44
|
+
outline-offset:0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.summary{
|
|
48
|
+
overflow:hidden;
|
|
49
|
+
display:inline-flex;
|
|
50
|
+
-moz-column-gap:var(--sn-primitive-dimension-2, 2px);
|
|
51
|
+
column-gap:var(--sn-primitive-dimension-2, 2px);
|
|
52
|
+
align-items:center;
|
|
53
|
+
text-overflow:ellipsis;
|
|
54
|
+
white-space:nowrap;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.chevron{
|
|
58
|
+
flex-shrink:0;
|
|
59
|
+
color:var(--sn-theme-color-available-version-textTertiary, var(--sn-brand-color-text-version-tertiary, rgba(65, 66, 78, 0.5490196078)));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.content{
|
|
63
|
+
max-height:140px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.steps{
|
|
67
|
+
display:flex;
|
|
68
|
+
flex-direction:column;
|
|
69
|
+
row-gap:var(--sn-primitive-dimension-8, 8px);
|
|
70
|
+
align-items:stretch;
|
|
71
|
+
padding-right:var(--sn-primitive-dimension-8, 8px);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.step{
|
|
75
|
+
display:flex;
|
|
76
|
+
-moz-column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
77
|
+
column-gap:var(--sn-primitive-dimension-4, 4px);
|
|
78
|
+
align-items:center;
|
|
79
|
+
width:100%;
|
|
80
|
+
min-width:0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.stepStatus{
|
|
84
|
+
display:inline-flex;
|
|
85
|
+
flex-shrink:0;
|
|
86
|
+
align-items:center;
|
|
87
|
+
justify-content:center;
|
|
88
|
+
width:var(--sn-primitive-dimension-16, 16px);
|
|
89
|
+
height:var(--sn-primitive-dimension-16, 16px);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.stepStatusIcon{
|
|
93
|
+
width:100%;
|
|
94
|
+
height:100%;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.stepStatusSuccess{
|
|
98
|
+
color:var(--sn-theme-color-primary-accent, var(--sn-brand-color-primary-55, var(--sn-brandRole-color-brandA-55, var(--sn-primitive-color-brandA-55, #389f74))));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.stepStatusError{
|
|
102
|
+
color:var(--sn-theme-color-red-accent, var(--sn-primitive-color-red-55, #d52e33));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.stepStatusProgress{
|
|
106
|
+
color:var(--sn-theme-color-blue-accent, var(--sn-primitive-color-blue-55, #4387e2));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.stepStatusPending{
|
|
110
|
+
box-sizing:border-box;
|
|
111
|
+
width:var(--sn-primitive-dimension-8, 8px);
|
|
112
|
+
height:var(--sn-primitive-dimension-8, 8px);
|
|
113
|
+
border:var(--sn-primitive-strokeWeight-strokeRegular, 1px) solid var(--sn-theme-color-neutral-decor, var(--sn-brand-color-neutral-80, var(--sn-primitive-color-gray-80, #e3e5ed)));
|
|
114
|
+
border-radius:var(--sn-density-radius-2xs, var(--sn-primitive-dimension-4, 4px));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.stepLabel{
|
|
118
|
+
font-family:var(--sn-thin-label-s-fontFamily, var(--sn-brand-font-fontFamily-thin-label, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
|
|
119
|
+
font-weight:var(--sn-thin-label-s-fontWeight, var(--sn-theme-typography-fontWeight-thin-label-s, var(--sn-brand-font-fontWeight-light-thin-label-s, var(--sn-primitive-font-fontWeightValue-450, 450))));
|
|
120
|
+
line-height:var(--sn-thin-label-s-lineHeight, var(--sn-density-typography-roleLabel-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)));
|
|
121
|
+
font-size:var(--sn-thin-label-s-fontSize, var(--sn-density-typography-roleLabel-fontSizeS, var(--sn-primitive-font-fontSize-14, 14px)));
|
|
122
|
+
letter-spacing:var(--sn-thin-label-s-letterSpacing, var(--sn-primitive-font-letterSpacing-s, 0px));
|
|
123
|
+
paragraph-spacing:var(--sn-thin-label-s-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize11, 5px));
|
|
124
|
+
overflow:hidden;
|
|
125
|
+
flex:1 1 auto;
|
|
126
|
+
min-width:0;
|
|
127
|
+
color:var(--sn-theme-color-available-version-textMain, var(--sn-brand-color-text-version-main, #41424e));
|
|
128
|
+
text-overflow:ellipsis;
|
|
129
|
+
white-space:nowrap;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.step[data-state=progress] .stepLabel{
|
|
133
|
+
font-family:var(--sn-regular-label-s-fontFamily, var(--sn-brand-font-fontFamily-regular-label, var(--sn-primitive-fontFamily-brandA-sans, SB Sans Interface)));
|
|
134
|
+
font-weight:var(--sn-regular-label-s-fontWeight, var(--sn-theme-typography-fontWeight-regular-label-s, var(--sn-brand-font-fontWeight-light-regular-label-s, var(--sn-primitive-font-fontWeightValue-500, 500))));
|
|
135
|
+
line-height:var(--sn-regular-label-s-lineHeight, var(--sn-density-typography-roleLabel-lineHeightS, var(--sn-primitive-font-lineHeight-by14, 20px)));
|
|
136
|
+
font-size:var(--sn-regular-label-s-fontSize, var(--sn-density-typography-roleLabel-fontSizeS, var(--sn-primitive-font-fontSize-14, 14px)));
|
|
137
|
+
letter-spacing:var(--sn-regular-label-s-letterSpacing, var(--sn-primitive-font-letterSpacing-s, 0px));
|
|
138
|
+
paragraph-spacing:var(--sn-regular-label-s-paragraphSpacing, var(--sn-primitive-font-paragraphSpacing-byFontSize11, 5px));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.step[data-state=error] .stepLabel,
|
|
142
|
+
.step[data-state=done] .stepLabel{
|
|
143
|
+
color:var(--sn-theme-color-available-version-textTertiary, var(--sn-brand-color-text-version-tertiary, rgba(65, 66, 78, 0.5490196078)));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.step[data-state=done] .stepLabel{
|
|
147
|
+
text-decoration:line-through;
|
|
148
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ValueOf, WithSupportProps } from '@cloud-ru/ds-utils';
|
|
2
|
+
import type { ComponentPropsWithoutRef } from 'react';
|
|
3
|
+
import { AI_QUEUE_STEP_STATE } from './constants.js';
|
|
4
|
+
export type AiQueueStepState = ValueOf<typeof AI_QUEUE_STEP_STATE>;
|
|
5
|
+
export type AiQueueStep = {
|
|
6
|
+
id?: string | number;
|
|
7
|
+
label: string;
|
|
8
|
+
state?: AiQueueStepState;
|
|
9
|
+
};
|
|
10
|
+
export type AiQueueSummary = {
|
|
11
|
+
total?: number;
|
|
12
|
+
planned?: number;
|
|
13
|
+
progress?: number;
|
|
14
|
+
done?: number;
|
|
15
|
+
};
|
|
16
|
+
export type AiQueueLabels = {
|
|
17
|
+
tasks: string;
|
|
18
|
+
planned: string;
|
|
19
|
+
inProgress: string;
|
|
20
|
+
done: string;
|
|
21
|
+
};
|
|
22
|
+
export type AiQueueOwnProps = {
|
|
23
|
+
/** Шаги очереди. */
|
|
24
|
+
steps?: AiQueueStep[];
|
|
25
|
+
/** Принудительные счётчики в заголовке; если не заданы, считаются по `steps`. */
|
|
26
|
+
summary?: AiQueueSummary;
|
|
27
|
+
/** Контролируемое состояние раскрытия. */
|
|
28
|
+
open?: boolean;
|
|
29
|
+
/** Начальное состояние раскрытия в uncontrolled-режиме. */
|
|
30
|
+
defaultOpen?: boolean;
|
|
31
|
+
/** Коллбек изменения раскрытия. */
|
|
32
|
+
onOpenChange?: (open: boolean) => void;
|
|
33
|
+
/** Тексты счётчика в заголовке. */
|
|
34
|
+
labels?: Partial<AiQueueLabels>;
|
|
35
|
+
/** Дополнительный CSS-класс корня. */
|
|
36
|
+
className?: string;
|
|
37
|
+
};
|
|
38
|
+
export type AiQueueProps = WithSupportProps<AiQueueOwnProps & Omit<ComponentPropsWithoutRef<'div'>, keyof AiQueueOwnProps | 'children'>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|