@astral/ui 4.83.0 → 4.85.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/_mocks/LoggerMock/LoggerMock.d.ts +16 -0
- package/_mocks/LoggerMock/LoggerMock.js +18 -0
- package/_mocks/LoggerMock/index.d.ts +1 -0
- package/_mocks/LoggerMock/index.js +1 -0
- package/components/ConfigProvider/ConfigProvider.d.ts +7 -1
- package/components/ConfigProvider/ConfigProvider.js +14 -8
- package/components/DashboardLayout/Header/useLogic/useLogic.d.ts +1 -1
- package/components/HintPopover/HintPopover.d.ts +6 -0
- package/components/HintPopover/HintPopover.js +23 -0
- package/components/HintPopover/constants.d.ts +4 -0
- package/components/HintPopover/constants.js +5 -0
- package/components/HintPopover/index.d.ts +2 -0
- package/components/HintPopover/index.js +1 -0
- package/components/HintPopover/public.d.ts +2 -0
- package/components/HintPopover/public.js +1 -0
- package/components/HintPopover/styles.d.ts +38 -0
- package/components/HintPopover/styles.js +69 -0
- package/components/HintPopover/types.d.ts +24 -0
- package/components/HintPopover/types.js +1 -0
- package/components/NewPopover/NewPopover.d.ts +1 -1
- package/components/NewPopover/NewPopover.js +5 -4
- package/components/NewPopover/constants.d.ts +11 -0
- package/components/NewPopover/constants.js +11 -0
- package/components/NewPopover/styles.js +35 -30
- package/components/NewPopover/types.d.ts +5 -0
- package/components/NewPopover/useLogic/useLogic.d.ts +4 -3
- package/components/NewPopover/useLogic/useLogic.js +17 -8
- package/components/NewPopover/useLogic/utils/getArrowPadding/getArrowPadding.d.ts +14 -0
- package/components/NewPopover/useLogic/utils/getArrowPadding/getArrowPadding.js +12 -0
- package/components/NewPopover/useLogic/utils/getArrowPadding/index.d.ts +1 -0
- package/components/NewPopover/useLogic/utils/getArrowPadding/index.js +1 -0
- package/components/NewPopover/useLogic/utils/getPopoverCssVars/getPopoverCssVars.d.ts +2 -0
- package/components/NewPopover/useLogic/utils/getPopoverCssVars/getPopoverCssVars.js +6 -0
- package/components/NewPopover/useLogic/utils/getPopoverCssVars/index.d.ts +1 -0
- package/components/NewPopover/useLogic/utils/getPopoverCssVars/index.js +1 -0
- package/components/NewPopover/useLogic/utils/resolveAnchorNode/resolveAnchorNode.d.ts +6 -0
- package/components/NewPopover/useLogic/utils/resolveAnchorNode/resolveAnchorNode.js +8 -0
- package/components/Onboarding/Onboarding.js +13 -3
- package/components/Onboarding/core/ExitController/ExitController.d.ts +3 -1
- package/components/Onboarding/core/ExitController/ExitController.js +4 -1
- package/components/Onboarding/core/OnboardingTour/OnboardingTour.d.ts +3 -1
- package/components/Onboarding/core/OnboardingTour/OnboardingTour.js +25 -4
- package/components/Onboarding/core/ProgressStorage/ProgressStorage.d.ts +3 -1
- package/components/Onboarding/core/ProgressStorage/ProgressStorage.js +8 -4
- package/components/Onboarding/ui/StepStrategy/steps/HighlightStep/HighlightStep.js +3 -4
- package/components/Onboarding/ui/StepStrategy/steps/HighlightStep/styles.d.ts +6 -22
- package/components/Onboarding/ui/StepStrategy/steps/HighlightStep/styles.js +2 -45
- package/node/_mocks/LoggerMock/LoggerMock.d.ts +16 -0
- package/node/_mocks/LoggerMock/LoggerMock.js +23 -0
- package/node/_mocks/LoggerMock/index.d.ts +1 -0
- package/node/_mocks/LoggerMock/index.js +17 -0
- package/node/components/ConfigProvider/ConfigProvider.d.ts +7 -1
- package/node/components/ConfigProvider/ConfigProvider.js +13 -7
- package/node/components/DashboardLayout/Header/useLogic/useLogic.d.ts +1 -1
- package/node/components/HintPopover/HintPopover.d.ts +6 -0
- package/node/components/HintPopover/HintPopover.js +27 -0
- package/node/components/HintPopover/constants.d.ts +4 -0
- package/node/components/HintPopover/constants.js +8 -0
- package/node/components/HintPopover/index.d.ts +2 -0
- package/node/components/HintPopover/index.js +5 -0
- package/node/components/HintPopover/public.d.ts +2 -0
- package/node/components/HintPopover/public.js +5 -0
- package/node/components/HintPopover/styles.d.ts +38 -0
- package/node/components/HintPopover/styles.js +72 -0
- package/node/components/HintPopover/types.d.ts +24 -0
- package/node/components/HintPopover/types.js +2 -0
- package/node/components/NewPopover/NewPopover.d.ts +1 -1
- package/node/components/NewPopover/NewPopover.js +5 -4
- package/node/components/NewPopover/constants.d.ts +11 -0
- package/node/components/NewPopover/constants.js +12 -1
- package/node/components/NewPopover/styles.js +34 -29
- package/node/components/NewPopover/types.d.ts +5 -0
- package/node/components/NewPopover/useLogic/useLogic.d.ts +4 -3
- package/node/components/NewPopover/useLogic/useLogic.js +18 -9
- package/node/components/NewPopover/useLogic/utils/getArrowPadding/getArrowPadding.d.ts +14 -0
- package/node/components/NewPopover/useLogic/utils/getArrowPadding/getArrowPadding.js +16 -0
- package/node/components/NewPopover/useLogic/utils/getArrowPadding/index.d.ts +1 -0
- package/node/components/NewPopover/useLogic/utils/getArrowPadding/index.js +17 -0
- package/node/components/NewPopover/useLogic/utils/getPopoverCssVars/getPopoverCssVars.d.ts +2 -0
- package/node/components/NewPopover/useLogic/utils/getPopoverCssVars/getPopoverCssVars.js +10 -0
- package/node/components/NewPopover/useLogic/utils/getPopoverCssVars/index.d.ts +1 -0
- package/node/components/NewPopover/useLogic/utils/getPopoverCssVars/index.js +5 -0
- package/node/components/NewPopover/useLogic/utils/resolveAnchorNode/resolveAnchorNode.d.ts +6 -0
- package/node/components/NewPopover/{utils → useLogic/utils/resolveAnchorNode}/resolveAnchorNode.js +2 -2
- package/node/components/Onboarding/Onboarding.js +13 -3
- package/node/components/Onboarding/core/ExitController/ExitController.d.ts +3 -1
- package/node/components/Onboarding/core/ExitController/ExitController.js +4 -1
- package/node/components/Onboarding/core/OnboardingTour/OnboardingTour.d.ts +3 -1
- package/node/components/Onboarding/core/OnboardingTour/OnboardingTour.js +25 -4
- package/node/components/Onboarding/core/ProgressStorage/ProgressStorage.d.ts +3 -1
- package/node/components/Onboarding/core/ProgressStorage/ProgressStorage.js +8 -4
- package/node/components/Onboarding/ui/StepStrategy/steps/HighlightStep/HighlightStep.js +1 -2
- package/node/components/Onboarding/ui/StepStrategy/steps/HighlightStep/styles.d.ts +6 -22
- package/node/components/Onboarding/ui/StepStrategy/steps/HighlightStep/styles.js +3 -46
- package/node/services/Logger/Logger.d.ts +45 -0
- package/node/services/Logger/Logger.js +72 -0
- package/node/services/Logger/index.d.ts +10 -0
- package/node/services/Logger/index.js +17 -0
- package/package.json +1 -1
- package/services/Logger/Logger.d.ts +45 -0
- package/services/Logger/Logger.js +68 -0
- package/services/Logger/index.d.ts +10 -0
- package/services/Logger/index.js +12 -0
- package/components/NewPopover/utils/resolveAnchorNode.d.ts +0 -6
- package/components/NewPopover/utils/resolveAnchorNode.js +0 -8
- package/node/components/NewPopover/utils/resolveAnchorNode.d.ts +0 -6
- /package/components/NewPopover/{utils → useLogic/utils/resolveAnchorNode}/index.d.ts +0 -0
- /package/components/NewPopover/{utils → useLogic/utils/resolveAnchorNode}/index.js +0 -0
- /package/node/components/NewPopover/{utils → useLogic/utils/resolveAnchorNode}/index.d.ts +0 -0
- /package/node/components/NewPopover/{utils → useLogic/utils/resolveAnchorNode}/index.js +0 -0
|
@@ -9,8 +9,9 @@ exports.ExitController = void 0;
|
|
|
9
9
|
* (ConfirmExit); закрытие происходит только по confirm.
|
|
10
10
|
*/
|
|
11
11
|
class ExitController {
|
|
12
|
-
constructor(params) {
|
|
12
|
+
constructor(params, logger) {
|
|
13
13
|
this.params = params;
|
|
14
|
+
this.logger = logger;
|
|
14
15
|
this.confirming = false;
|
|
15
16
|
/**
|
|
16
17
|
* Запрос на закрытие — показывает ConfirmExit. Повторные вызовы во время
|
|
@@ -20,6 +21,7 @@ class ExitController {
|
|
|
20
21
|
if (this.confirming) {
|
|
21
22
|
return;
|
|
22
23
|
}
|
|
24
|
+
this.logger.debug('Запрошен выход из тура, показано подтверждение');
|
|
23
25
|
this.confirming = true;
|
|
24
26
|
this.params.onChange();
|
|
25
27
|
};
|
|
@@ -40,6 +42,7 @@ class ExitController {
|
|
|
40
42
|
if (!this.confirming) {
|
|
41
43
|
return;
|
|
42
44
|
}
|
|
45
|
+
this.logger.debug('Выход из тура отменён');
|
|
43
46
|
this.confirming = false;
|
|
44
47
|
this.params.onChange();
|
|
45
48
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Logger } from '../../../../services/Logger';
|
|
1
2
|
import { type ErrorService } from '../../../services/ErrorService';
|
|
2
3
|
import { type OnboardingTourConfig, type Step, type StepHandles, type TourProgress } from '../../types';
|
|
3
4
|
import { type ActiveStepStore } from '../ActiveStepStore';
|
|
@@ -13,6 +14,7 @@ export declare class OnboardingTour<TSteps extends readonly Step[] = readonly St
|
|
|
13
14
|
private readonly progressStorage;
|
|
14
15
|
private readonly activeStepStore;
|
|
15
16
|
private readonly errorService;
|
|
17
|
+
private readonly logger;
|
|
16
18
|
private readonly navigator;
|
|
17
19
|
private readonly resolver;
|
|
18
20
|
private readonly stepsController;
|
|
@@ -22,7 +24,7 @@ export declare class OnboardingTour<TSteps extends readonly Step[] = readonly St
|
|
|
22
24
|
* Типобезопасный доступ к шагам по их именам.
|
|
23
25
|
*/
|
|
24
26
|
readonly steps: StepHandles<TSteps>;
|
|
25
|
-
constructor(config: OnboardingTourConfig<TSteps>, progressStorage: ProgressStorage, activeStepStore: ActiveStepStore, errorService: ErrorService);
|
|
27
|
+
constructor(config: OnboardingTourConfig<TSteps>, progressStorage: ProgressStorage, activeStepStore: ActiveStepStore, errorService: ErrorService, logger: Logger);
|
|
26
28
|
/**
|
|
27
29
|
* Запуск тура с первого шага.
|
|
28
30
|
*/
|
|
@@ -12,11 +12,12 @@ const StepsController_1 = require("../StepsController");
|
|
|
12
12
|
* состояние активного шага в store своего экземпляра онбординга.
|
|
13
13
|
*/
|
|
14
14
|
class OnboardingTour {
|
|
15
|
-
constructor(config, progressStorage, activeStepStore, errorService) {
|
|
15
|
+
constructor(config, progressStorage, activeStepStore, errorService, logger) {
|
|
16
16
|
this.config = config;
|
|
17
17
|
this.progressStorage = progressStorage;
|
|
18
18
|
this.activeStepStore = activeStepStore;
|
|
19
19
|
this.errorService = errorService;
|
|
20
|
+
this.logger = logger;
|
|
20
21
|
this.status = 'idle';
|
|
21
22
|
/**
|
|
22
23
|
* Запуск тура с первого шага.
|
|
@@ -24,8 +25,10 @@ class OnboardingTour {
|
|
|
24
25
|
this.start = async () => {
|
|
25
26
|
const persisted = await this.progressStorage.load();
|
|
26
27
|
if (persisted?.isDismissed) {
|
|
28
|
+
this.logger.info('Тур пропущен: ранее закрыт пользователем');
|
|
27
29
|
return;
|
|
28
30
|
}
|
|
31
|
+
this.logger.info('Тур запущен');
|
|
29
32
|
this.exitController.reset();
|
|
30
33
|
this.navigator.reset();
|
|
31
34
|
this.enterCurrentStep();
|
|
@@ -35,8 +38,10 @@ class OnboardingTour {
|
|
|
35
38
|
*/
|
|
36
39
|
this.resume = () => {
|
|
37
40
|
if (this.status !== 'waiting-resume') {
|
|
41
|
+
this.logger.debug('resume проигнорирован: тур не на паузе');
|
|
38
42
|
return;
|
|
39
43
|
}
|
|
44
|
+
this.logger.debug('Тур возобновлён после паузы');
|
|
40
45
|
this.status = 'running';
|
|
41
46
|
this.publishStep();
|
|
42
47
|
};
|
|
@@ -45,6 +50,7 @@ class OnboardingTour {
|
|
|
45
50
|
*/
|
|
46
51
|
this.restore = async () => {
|
|
47
52
|
const persisted = await this.progressStorage.load();
|
|
53
|
+
this.logger.info('Тур восстановлен');
|
|
48
54
|
this.exitController.reset();
|
|
49
55
|
this.navigator.reset();
|
|
50
56
|
// Пройденный тур переигрываем с начала; иначе продолжаем с сохранённого шага.
|
|
@@ -151,6 +157,7 @@ class OnboardingTour {
|
|
|
151
157
|
*/
|
|
152
158
|
this.resetProgress = async () => {
|
|
153
159
|
await this.progressStorage.reset();
|
|
160
|
+
this.logger.debug('Прогресс тура сброшен');
|
|
154
161
|
};
|
|
155
162
|
/**
|
|
156
163
|
* Возвращает сохранённый прогресс тура
|
|
@@ -170,12 +177,14 @@ class OnboardingTour {
|
|
|
170
177
|
isDismissed: true,
|
|
171
178
|
});
|
|
172
179
|
}
|
|
180
|
+
this.logger.info('Тур закрыт', { reason });
|
|
173
181
|
this.status = 'idle';
|
|
174
182
|
this.exitController.reset();
|
|
175
183
|
this.releaseStep();
|
|
176
184
|
this.config.onClose?.(reason);
|
|
177
185
|
};
|
|
178
186
|
this.handleError = (error) => {
|
|
187
|
+
this.logger.error('Ошибка тура', error);
|
|
179
188
|
this.errorService.captureException(error, {
|
|
180
189
|
place: 'Onboarding',
|
|
181
190
|
tourName: this.config.name,
|
|
@@ -188,17 +197,22 @@ class OnboardingTour {
|
|
|
188
197
|
this.resolver = new StepResolver_1.StepResolver(config);
|
|
189
198
|
this.stepsController = new StepsController_1.StepsController(config.steps, (stepName) => this.refreshStep(stepName));
|
|
190
199
|
this.steps = this.stepsController.handles;
|
|
191
|
-
|
|
200
|
+
const exitParams = {
|
|
192
201
|
close: () => this.exit('dismissed'),
|
|
193
202
|
onChange: () => this.publishStep(),
|
|
194
|
-
}
|
|
203
|
+
};
|
|
204
|
+
this.exitController = new ExitController_1.ExitController(exitParams, this.logger);
|
|
195
205
|
}
|
|
196
206
|
/**
|
|
197
207
|
* Разрешена ли навигация сейчас: тур показан на экране и владеет активным
|
|
198
208
|
* шагом store
|
|
199
209
|
*/
|
|
200
210
|
canNavigate() {
|
|
201
|
-
|
|
211
|
+
const isNavigable = this.status === 'running' && this.activeStepStore.isActiveTour(this);
|
|
212
|
+
if (!isNavigable) {
|
|
213
|
+
this.logger.debug('Навигация проигнорирована: тур неактивен');
|
|
214
|
+
}
|
|
215
|
+
return isNavigable;
|
|
202
216
|
}
|
|
203
217
|
/**
|
|
204
218
|
* Переход к текущему шагу. Шаг с `waitForResume` ставит тур в ожидание
|
|
@@ -207,16 +221,23 @@ class OnboardingTour {
|
|
|
207
221
|
enterCurrentStep() {
|
|
208
222
|
// Показывать нечего: у тура нет ни одного видимого (не-пропущенного) шага.
|
|
209
223
|
if (this.navigator.total === 0) {
|
|
224
|
+
this.logger.warn('Нет ни одного видимого шага, тур не показан');
|
|
210
225
|
this.status = 'idle';
|
|
211
226
|
this.releaseStep();
|
|
212
227
|
return;
|
|
213
228
|
}
|
|
214
229
|
const step = this.navigator.current;
|
|
215
230
|
if (step.waitForResume) {
|
|
231
|
+
this.logger.debug('Ожидание resume', { step: step.name });
|
|
216
232
|
this.status = 'waiting-resume';
|
|
217
233
|
this.releaseStep();
|
|
218
234
|
return;
|
|
219
235
|
}
|
|
236
|
+
this.logger.debug('Показан шаг', {
|
|
237
|
+
step: step.name,
|
|
238
|
+
position: this.navigator.position,
|
|
239
|
+
total: this.navigator.total,
|
|
240
|
+
});
|
|
220
241
|
this.status = 'running';
|
|
221
242
|
this.publishStep();
|
|
222
243
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Logger } from '../../../../services/Logger';
|
|
1
2
|
import { type SaveStrategy, type TourProgress } from '../../types';
|
|
2
3
|
/**
|
|
3
4
|
* Обёртка над переданной SaveStrategy, изолирующая тур от исключений хранилища
|
|
@@ -9,8 +10,9 @@ import { type SaveStrategy, type TourProgress } from '../../types';
|
|
|
9
10
|
*/
|
|
10
11
|
export declare class ProgressStorage {
|
|
11
12
|
private readonly strategy;
|
|
13
|
+
private readonly logger;
|
|
12
14
|
private saving;
|
|
13
|
-
constructor(strategy: SaveStrategy);
|
|
15
|
+
constructor(strategy: SaveStrategy, logger: Logger);
|
|
14
16
|
load(): Promise<TourProgress | null>;
|
|
15
17
|
save(state: TourProgress): Promise<void>;
|
|
16
18
|
/**
|
|
@@ -18,8 +18,9 @@ const CLEARED_STATE = {
|
|
|
18
18
|
* `load()` ждёт текущее сохранение, поэтому читает уже применённое состояние.
|
|
19
19
|
*/
|
|
20
20
|
class ProgressStorage {
|
|
21
|
-
constructor(strategy) {
|
|
21
|
+
constructor(strategy, logger) {
|
|
22
22
|
this.strategy = strategy;
|
|
23
|
+
this.logger = logger;
|
|
23
24
|
this.saving = Promise.resolve();
|
|
24
25
|
}
|
|
25
26
|
async load() {
|
|
@@ -28,7 +29,9 @@ class ProgressStorage {
|
|
|
28
29
|
try {
|
|
29
30
|
return await this.strategy.load();
|
|
30
31
|
}
|
|
31
|
-
catch {
|
|
32
|
+
catch (error) {
|
|
33
|
+
// Ошибка хранилища не должна ронять тур, но остаётся видимой в логах.
|
|
34
|
+
this.logger.warn('Ошибка чтения прогресса из хранилища', error);
|
|
32
35
|
return null;
|
|
33
36
|
}
|
|
34
37
|
}
|
|
@@ -52,8 +55,9 @@ class ProgressStorage {
|
|
|
52
55
|
try {
|
|
53
56
|
await write();
|
|
54
57
|
}
|
|
55
|
-
catch {
|
|
56
|
-
// Ошибка хранилища не должна ронять
|
|
58
|
+
catch (error) {
|
|
59
|
+
// Ошибка хранилища не должна ронять тур, но остаётся видимой в логах.
|
|
60
|
+
this.logger.warn('Ошибка записи прогресса в хранилище', error);
|
|
57
61
|
}
|
|
58
62
|
});
|
|
59
63
|
return this.saving;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.HighlightStep = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const CrossOutlineMd_1 = require("../../../../../../icons/CrossOutlineMd");
|
|
6
5
|
const Typography_1 = require("../../../../../Typography");
|
|
7
6
|
const StepFooter_1 = require("../StepFooter");
|
|
8
7
|
const styles_1 = require("./styles");
|
|
@@ -18,6 +17,6 @@ const HighlightStep = ({ activeStep, isClosing, geometry, }) => {
|
|
|
18
17
|
if (!anchorEl) {
|
|
19
18
|
return null;
|
|
20
19
|
}
|
|
21
|
-
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: shouldShowPopover && ((0, jsx_runtime_1.jsx)(styles_1.StepPopover, {
|
|
20
|
+
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: shouldShowPopover && ((0, jsx_runtime_1.jsx)(styles_1.StepPopover, { variant: "light", isOpen: isOpen, disableAutoFocus: true, anchorEl: anchorEl, placement: step.position, onClose: handleClose, contentRef: setPopoverNode, title: step.title, action: (0, jsx_runtime_1.jsx)(StepFooter_1.StepFooter, { activeStep: activeStep }), children: step.content && ((0, jsx_runtime_1.jsx)(Typography_1.Typography, { component: "div", variant: "body1", color: "grey", colorIntensity: "900", children: step.content })) })) }));
|
|
22
21
|
};
|
|
23
22
|
exports.HighlightStep = HighlightStep;
|
|
@@ -1,25 +1,9 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
export declare const StepPopover: import("@emotion/styled/dist/declarations/src/types").StyledComponent<Omit<import("../../../../../NewPopover").NewPopoverProps, "title" | "hasArrow" | "disableMobileDrawer"> & {
|
|
3
|
+
variant?: import("../../../../../HintPopover").HintPopoverVariant | undefined;
|
|
4
|
+
title?: import("react").ReactNode;
|
|
5
|
+
action?: import("react").ReactNode;
|
|
6
|
+
contentRef?: import("react").Ref<HTMLDivElement> | undefined;
|
|
7
|
+
} & {
|
|
6
8
|
theme?: import("@emotion/react").Theme | undefined;
|
|
7
9
|
}, {}, {}>;
|
|
8
|
-
export declare const PopoverBody: import("@emotion/styled/dist/declarations/src/types").StyledComponent<{
|
|
9
|
-
theme?: import("@emotion/react").Theme | undefined;
|
|
10
|
-
as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
|
|
11
|
-
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
12
|
-
export declare const CloseButton: import("@emotion/styled/dist/declarations/src/types").StyledComponent<Omit<import("../../../../..").WithoutEmotionSpecific<import("@mui/material").ButtonProps>, "color" | "component" | "size" | "variant" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple"> & {
|
|
13
|
-
variant?: "light" | "link" | "text" | "contained" | "outlined" | undefined;
|
|
14
|
-
loading?: boolean | undefined;
|
|
15
|
-
color?: "primary" | "success" | "warning" | "error" | "grey" | undefined;
|
|
16
|
-
component?: import("react").ElementType | undefined;
|
|
17
|
-
selected?: boolean | undefined;
|
|
18
|
-
size?: "large" | "medium" | undefined;
|
|
19
|
-
} & Omit<import("react").DetailedHTMLProps<import("react").ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, ""> & import("react").RefAttributes<HTMLButtonElement> & {
|
|
20
|
-
theme?: import("@emotion/react").Theme | undefined;
|
|
21
|
-
}, {}, {}>;
|
|
22
|
-
export declare const Content: import("@emotion/styled/dist/declarations/src/types").StyledComponent<{
|
|
23
|
-
theme?: import("@emotion/react").Theme | undefined;
|
|
24
|
-
as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
|
|
25
|
-
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
@@ -1,59 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const
|
|
5
|
-
const NewPopover_1 = require("../../../../../NewPopover");
|
|
3
|
+
exports.StepPopover = void 0;
|
|
4
|
+
const HintPopover_1 = require("../../../../../HintPopover");
|
|
6
5
|
const constants_1 = require("../../../../../NewPopover/constants");
|
|
7
6
|
const styled_1 = require("../../../../../styled");
|
|
8
7
|
const constants_2 = require("../../../../constants");
|
|
9
|
-
|
|
10
|
-
* Popover шага, z-index над overlay, быстрое закрытие.
|
|
11
|
-
*/
|
|
12
|
-
exports.StepPopover = (0, styled_1.styled)(NewPopover_1.NewPopover) `
|
|
8
|
+
exports.StepPopover = (0, styled_1.styled)(HintPopover_1.HintPopover) `
|
|
13
9
|
&& {
|
|
14
10
|
z-index: ${({ theme }) => theme.zIndex.tooltip + constants_2.ONBOARDING_Z_INDEX_OFFSET.popover};
|
|
15
11
|
}
|
|
16
|
-
|
|
17
|
-
.${constants_1.popoverClassnames.innerContainer} {
|
|
18
|
-
border-radius: calc(${({ theme }) => theme.shape.medium} * 2);
|
|
19
|
-
}
|
|
20
12
|
|
|
21
13
|
.${constants_1.popoverClassnames.animatedWrapper}:not(.${constants_1.popoverClassnames.animatedWrapperOpen}) {
|
|
22
14
|
animation-duration: ${({ theme }) => theme.transitions.duration.shortest}ms;
|
|
23
15
|
}
|
|
24
16
|
`;
|
|
25
|
-
exports.PopoverBody = styled_1.styled.div `
|
|
26
|
-
position: relative;
|
|
27
|
-
|
|
28
|
-
width: 400px;
|
|
29
|
-
padding: ${({ theme }) => theme.spacing(6)};
|
|
30
|
-
|
|
31
|
-
border-radius: calc(${({ theme }) => theme.shape.medium} * 2);
|
|
32
|
-
|
|
33
|
-
/* Фокус-трап ставит фокус на контейнер, браузерную рамку убираем. */
|
|
34
|
-
&:focus {
|
|
35
|
-
outline: none;
|
|
36
|
-
}
|
|
37
|
-
`;
|
|
38
|
-
exports.CloseButton = (0, styled_1.styled)(IconButton_1.IconButton) `
|
|
39
|
-
position: absolute;
|
|
40
|
-
top: ${({ theme }) => theme.spacing(6)};
|
|
41
|
-
right: ${({ theme }) => theme.spacing(6)};
|
|
42
|
-
`;
|
|
43
|
-
exports.Content = styled_1.styled.div `
|
|
44
|
-
display: flex;
|
|
45
|
-
flex-direction: column;
|
|
46
|
-
gap: ${({ theme }) => theme.spacing(4)};
|
|
47
|
-
|
|
48
|
-
margin-bottom: ${({ theme }) => theme.spacing(6)};
|
|
49
|
-
|
|
50
|
-
&:last-child {
|
|
51
|
-
margin-bottom: 0;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/* Резерв справа под крестик — только у верхнего элемента (заголовок, а если
|
|
55
|
-
его нет — текст) */
|
|
56
|
-
& > *:first-of-type {
|
|
57
|
-
padding-right: ${({ theme }) => theme.spacing(10)};
|
|
58
|
-
}
|
|
59
|
-
`;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type LogLevel = 'error' | 'warn' | 'info' | 'debug';
|
|
2
|
+
export type LogThreshold = LogLevel | 'silent';
|
|
3
|
+
export type LogContext = Readonly<Record<string, unknown>>;
|
|
4
|
+
export type LoggerOptions = {
|
|
5
|
+
context?: LogContext;
|
|
6
|
+
};
|
|
7
|
+
export type CreateLoggerOptions = LoggerOptions & {
|
|
8
|
+
name: string;
|
|
9
|
+
level?: LogThreshold;
|
|
10
|
+
};
|
|
11
|
+
export type ConfigureOptions = {
|
|
12
|
+
level?: LogThreshold;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Логгер.
|
|
16
|
+
* Формат логов: `{пакет}: {иконка} [{scope}]: {сообщение}`.
|
|
17
|
+
* */
|
|
18
|
+
export declare class Logger {
|
|
19
|
+
private readonly name;
|
|
20
|
+
private readonly scope;
|
|
21
|
+
private readonly context;
|
|
22
|
+
private readonly parent;
|
|
23
|
+
private level?;
|
|
24
|
+
private readonly console;
|
|
25
|
+
private constructor();
|
|
26
|
+
static create: ({ name, context, level, }: CreateLoggerOptions) => Logger;
|
|
27
|
+
/**
|
|
28
|
+
* Меняет уровень пакета.
|
|
29
|
+
* Без `level` — сброс к env-дефолту.
|
|
30
|
+
* Возвращает функцию отмены — вернёт прежний уровень.
|
|
31
|
+
* */
|
|
32
|
+
configure: (options?: ConfigureOptions) => () => void;
|
|
33
|
+
/** Дочерний логгер: добавляет `scope`, наследует уровень корня. */
|
|
34
|
+
child: (scope: string, options?: LoggerOptions) => Logger;
|
|
35
|
+
/** Дойдёт ли лог такого уровня до консоли. */
|
|
36
|
+
isLevelEnabled: (level: LogLevel) => boolean;
|
|
37
|
+
success: (message: string, ...data: unknown[]) => void;
|
|
38
|
+
info: (message: string, ...data: unknown[]) => void;
|
|
39
|
+
warn: (message: string, ...data: unknown[]) => void;
|
|
40
|
+
debug: (message: string, ...data: unknown[]) => void;
|
|
41
|
+
error: (message: string, ...data: unknown[]) => void;
|
|
42
|
+
/** Свой уровень → уровень родителя по цепочке → env-дефолт. */
|
|
43
|
+
private effectiveLevel;
|
|
44
|
+
private print;
|
|
45
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// biome-ignore-all lint/suspicious/noConsole: Logger — единственная точка вывода в консоль
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Logger = void 0;
|
|
5
|
+
/** Приоритет уровней. Лог виден, если его приоритет ≤ порога. */
|
|
6
|
+
const LOG_LEVEL_PRIORITY = {
|
|
7
|
+
silent: 0,
|
|
8
|
+
error: 1,
|
|
9
|
+
warn: 2,
|
|
10
|
+
info: 3,
|
|
11
|
+
debug: 4,
|
|
12
|
+
};
|
|
13
|
+
/** Порог по умолчанию для каждого окружения. */
|
|
14
|
+
const DEFAULT_LOG_LEVEL_BY_ENV = {
|
|
15
|
+
production: 'error',
|
|
16
|
+
test: 'silent',
|
|
17
|
+
development: 'warn',
|
|
18
|
+
};
|
|
19
|
+
/** Порог для текущего окружения. */
|
|
20
|
+
const getEnvLevel = () => DEFAULT_LOG_LEVEL_BY_ENV[process.env.NODE_ENV ?? 'development'] ?? 'warn';
|
|
21
|
+
/**
|
|
22
|
+
* Логгер.
|
|
23
|
+
* Формат логов: `{пакет}: {иконка} [{scope}]: {сообщение}`.
|
|
24
|
+
* */
|
|
25
|
+
class Logger {
|
|
26
|
+
constructor(name, scope, context, parent, level, console = globalThis.console) {
|
|
27
|
+
this.name = name;
|
|
28
|
+
this.scope = scope;
|
|
29
|
+
this.context = context;
|
|
30
|
+
this.parent = parent;
|
|
31
|
+
this.level = level;
|
|
32
|
+
this.console = console;
|
|
33
|
+
/**
|
|
34
|
+
* Меняет уровень пакета.
|
|
35
|
+
* Без `level` — сброс к env-дефолту.
|
|
36
|
+
* Возвращает функцию отмены — вернёт прежний уровень.
|
|
37
|
+
* */
|
|
38
|
+
this.configure = (options = {}) => {
|
|
39
|
+
const previousLevel = this.level;
|
|
40
|
+
this.level = options.level;
|
|
41
|
+
return () => {
|
|
42
|
+
this.level = previousLevel;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
/** Дочерний логгер: добавляет `scope`, наследует уровень корня. */
|
|
46
|
+
this.child = (scope, options) => {
|
|
47
|
+
return new Logger(this.name,
|
|
48
|
+
// склеиваем scope: `Onboarding` → `Onboarding Tour`.
|
|
49
|
+
this.scope ? `${this.scope} ${scope}` : scope, { ...this.context, ...options?.context }, this, undefined, this.console);
|
|
50
|
+
};
|
|
51
|
+
/** Дойдёт ли лог такого уровня до консоли. */
|
|
52
|
+
this.isLevelEnabled = (level) => LOG_LEVEL_PRIORITY[level] <= LOG_LEVEL_PRIORITY[this.effectiveLevel()];
|
|
53
|
+
this.success = (message, ...data) => this.print('info', '✅', this.console.log, message, data);
|
|
54
|
+
this.info = (message, ...data) => this.print('info', 'ℹ️', this.console.log, message, data);
|
|
55
|
+
this.warn = (message, ...data) => this.print('warn', '⚠️', this.console.warn, message, data);
|
|
56
|
+
this.debug = (message, ...data) => this.print('debug', '🐞', this.console.log, message, data);
|
|
57
|
+
this.error = (message, ...data) => this.print('error', '❌', this.console.error, message, data);
|
|
58
|
+
/** Свой уровень → уровень родителя по цепочке → env-дефолт. */
|
|
59
|
+
this.effectiveLevel = () => this.level ?? this.parent?.effectiveLevel() ?? getEnvLevel();
|
|
60
|
+
this.print = (level, icon, sink, message, data) => {
|
|
61
|
+
if (!this.isLevelEnabled(level)) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const prefix = this.name ? `${this.name}: ` : '';
|
|
65
|
+
const scope = this.scope ? ` [${this.scope}]:` : '';
|
|
66
|
+
const withContext = Object.keys(this.context).length === 0 ? data : [...data, this.context];
|
|
67
|
+
sink(`${prefix}${icon}${scope} ${message}`, ...withContext);
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.Logger = Logger;
|
|
72
|
+
Logger.create = ({ name, context = {}, level, }) => new Logger(name, undefined, { ...context }, null, level);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Logger, type ConfigureOptions, type CreateLoggerOptions, type LogContext, type LoggerOptions, type LogLevel, type LogThreshold } from './Logger';
|
|
2
|
+
export { Logger, type ConfigureOptions, type CreateLoggerOptions, type LogContext, type LoggerOptions, type LogLevel, type LogThreshold, };
|
|
3
|
+
/**
|
|
4
|
+
* Фабрика Logger для `@astral/ui`: сервисы и компоненты получают инстанс через DI.
|
|
5
|
+
*/
|
|
6
|
+
export declare const createLogger: (scope: string, options?: LoggerOptions) => Logger;
|
|
7
|
+
/**
|
|
8
|
+
* (Пере)-Настройка логгера пакета `@astral/ui` — вызывает `ConfigProvider`.
|
|
9
|
+
*/
|
|
10
|
+
export declare const configureLogger: (options?: ConfigureOptions) => () => void;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configureLogger = exports.createLogger = exports.Logger = void 0;
|
|
4
|
+
const Logger_1 = require("./Logger");
|
|
5
|
+
Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return Logger_1.Logger; } });
|
|
6
|
+
// Корневой логгер пакета @astral/ui.
|
|
7
|
+
const uiLogger = Logger_1.Logger.create({ name: '@astral/ui' });
|
|
8
|
+
/**
|
|
9
|
+
* Фабрика Logger для `@astral/ui`: сервисы и компоненты получают инстанс через DI.
|
|
10
|
+
*/
|
|
11
|
+
const createLogger = (scope, options) => uiLogger.child(scope, options);
|
|
12
|
+
exports.createLogger = createLogger;
|
|
13
|
+
/**
|
|
14
|
+
* (Пере)-Настройка логгера пакета `@astral/ui` — вызывает `ConfigProvider`.
|
|
15
|
+
*/
|
|
16
|
+
const configureLogger = (options) => uiLogger.configure(options);
|
|
17
|
+
exports.configureLogger = configureLogger;
|
package/package.json
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type LogLevel = 'error' | 'warn' | 'info' | 'debug';
|
|
2
|
+
export type LogThreshold = LogLevel | 'silent';
|
|
3
|
+
export type LogContext = Readonly<Record<string, unknown>>;
|
|
4
|
+
export type LoggerOptions = {
|
|
5
|
+
context?: LogContext;
|
|
6
|
+
};
|
|
7
|
+
export type CreateLoggerOptions = LoggerOptions & {
|
|
8
|
+
name: string;
|
|
9
|
+
level?: LogThreshold;
|
|
10
|
+
};
|
|
11
|
+
export type ConfigureOptions = {
|
|
12
|
+
level?: LogThreshold;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Логгер.
|
|
16
|
+
* Формат логов: `{пакет}: {иконка} [{scope}]: {сообщение}`.
|
|
17
|
+
* */
|
|
18
|
+
export declare class Logger {
|
|
19
|
+
private readonly name;
|
|
20
|
+
private readonly scope;
|
|
21
|
+
private readonly context;
|
|
22
|
+
private readonly parent;
|
|
23
|
+
private level?;
|
|
24
|
+
private readonly console;
|
|
25
|
+
private constructor();
|
|
26
|
+
static create: ({ name, context, level, }: CreateLoggerOptions) => Logger;
|
|
27
|
+
/**
|
|
28
|
+
* Меняет уровень пакета.
|
|
29
|
+
* Без `level` — сброс к env-дефолту.
|
|
30
|
+
* Возвращает функцию отмены — вернёт прежний уровень.
|
|
31
|
+
* */
|
|
32
|
+
configure: (options?: ConfigureOptions) => () => void;
|
|
33
|
+
/** Дочерний логгер: добавляет `scope`, наследует уровень корня. */
|
|
34
|
+
child: (scope: string, options?: LoggerOptions) => Logger;
|
|
35
|
+
/** Дойдёт ли лог такого уровня до консоли. */
|
|
36
|
+
isLevelEnabled: (level: LogLevel) => boolean;
|
|
37
|
+
success: (message: string, ...data: unknown[]) => void;
|
|
38
|
+
info: (message: string, ...data: unknown[]) => void;
|
|
39
|
+
warn: (message: string, ...data: unknown[]) => void;
|
|
40
|
+
debug: (message: string, ...data: unknown[]) => void;
|
|
41
|
+
error: (message: string, ...data: unknown[]) => void;
|
|
42
|
+
/** Свой уровень → уровень родителя по цепочке → env-дефолт. */
|
|
43
|
+
private effectiveLevel;
|
|
44
|
+
private print;
|
|
45
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// biome-ignore-all lint/suspicious/noConsole: Logger — единственная точка вывода в консоль
|
|
2
|
+
/** Приоритет уровней. Лог виден, если его приоритет ≤ порога. */
|
|
3
|
+
const LOG_LEVEL_PRIORITY = {
|
|
4
|
+
silent: 0,
|
|
5
|
+
error: 1,
|
|
6
|
+
warn: 2,
|
|
7
|
+
info: 3,
|
|
8
|
+
debug: 4,
|
|
9
|
+
};
|
|
10
|
+
/** Порог по умолчанию для каждого окружения. */
|
|
11
|
+
const DEFAULT_LOG_LEVEL_BY_ENV = {
|
|
12
|
+
production: 'error',
|
|
13
|
+
test: 'silent',
|
|
14
|
+
development: 'warn',
|
|
15
|
+
};
|
|
16
|
+
/** Порог для текущего окружения. */
|
|
17
|
+
const getEnvLevel = () => DEFAULT_LOG_LEVEL_BY_ENV[process.env.NODE_ENV ?? 'development'] ?? 'warn';
|
|
18
|
+
/**
|
|
19
|
+
* Логгер.
|
|
20
|
+
* Формат логов: `{пакет}: {иконка} [{scope}]: {сообщение}`.
|
|
21
|
+
* */
|
|
22
|
+
export class Logger {
|
|
23
|
+
constructor(name, scope, context, parent, level, console = globalThis.console) {
|
|
24
|
+
this.name = name;
|
|
25
|
+
this.scope = scope;
|
|
26
|
+
this.context = context;
|
|
27
|
+
this.parent = parent;
|
|
28
|
+
this.level = level;
|
|
29
|
+
this.console = console;
|
|
30
|
+
/**
|
|
31
|
+
* Меняет уровень пакета.
|
|
32
|
+
* Без `level` — сброс к env-дефолту.
|
|
33
|
+
* Возвращает функцию отмены — вернёт прежний уровень.
|
|
34
|
+
* */
|
|
35
|
+
this.configure = (options = {}) => {
|
|
36
|
+
const previousLevel = this.level;
|
|
37
|
+
this.level = options.level;
|
|
38
|
+
return () => {
|
|
39
|
+
this.level = previousLevel;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
/** Дочерний логгер: добавляет `scope`, наследует уровень корня. */
|
|
43
|
+
this.child = (scope, options) => {
|
|
44
|
+
return new Logger(this.name,
|
|
45
|
+
// склеиваем scope: `Onboarding` → `Onboarding Tour`.
|
|
46
|
+
this.scope ? `${this.scope} ${scope}` : scope, { ...this.context, ...options?.context }, this, undefined, this.console);
|
|
47
|
+
};
|
|
48
|
+
/** Дойдёт ли лог такого уровня до консоли. */
|
|
49
|
+
this.isLevelEnabled = (level) => LOG_LEVEL_PRIORITY[level] <= LOG_LEVEL_PRIORITY[this.effectiveLevel()];
|
|
50
|
+
this.success = (message, ...data) => this.print('info', '✅', this.console.log, message, data);
|
|
51
|
+
this.info = (message, ...data) => this.print('info', 'ℹ️', this.console.log, message, data);
|
|
52
|
+
this.warn = (message, ...data) => this.print('warn', '⚠️', this.console.warn, message, data);
|
|
53
|
+
this.debug = (message, ...data) => this.print('debug', '🐞', this.console.log, message, data);
|
|
54
|
+
this.error = (message, ...data) => this.print('error', '❌', this.console.error, message, data);
|
|
55
|
+
/** Свой уровень → уровень родителя по цепочке → env-дефолт. */
|
|
56
|
+
this.effectiveLevel = () => this.level ?? this.parent?.effectiveLevel() ?? getEnvLevel();
|
|
57
|
+
this.print = (level, icon, sink, message, data) => {
|
|
58
|
+
if (!this.isLevelEnabled(level)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const prefix = this.name ? `${this.name}: ` : '';
|
|
62
|
+
const scope = this.scope ? ` [${this.scope}]:` : '';
|
|
63
|
+
const withContext = Object.keys(this.context).length === 0 ? data : [...data, this.context];
|
|
64
|
+
sink(`${prefix}${icon}${scope} ${message}`, ...withContext);
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
Logger.create = ({ name, context = {}, level, }) => new Logger(name, undefined, { ...context }, null, level);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Logger, type ConfigureOptions, type CreateLoggerOptions, type LogContext, type LoggerOptions, type LogLevel, type LogThreshold } from './Logger';
|
|
2
|
+
export { Logger, type ConfigureOptions, type CreateLoggerOptions, type LogContext, type LoggerOptions, type LogLevel, type LogThreshold, };
|
|
3
|
+
/**
|
|
4
|
+
* Фабрика Logger для `@astral/ui`: сервисы и компоненты получают инстанс через DI.
|
|
5
|
+
*/
|
|
6
|
+
export declare const createLogger: (scope: string, options?: LoggerOptions) => Logger;
|
|
7
|
+
/**
|
|
8
|
+
* (Пере)-Настройка логгера пакета `@astral/ui` — вызывает `ConfigProvider`.
|
|
9
|
+
*/
|
|
10
|
+
export declare const configureLogger: (options?: ConfigureOptions) => () => void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Logger, } from './Logger';
|
|
2
|
+
export { Logger, };
|
|
3
|
+
// Корневой логгер пакета @astral/ui.
|
|
4
|
+
const uiLogger = Logger.create({ name: '@astral/ui' });
|
|
5
|
+
/**
|
|
6
|
+
* Фабрика Logger для `@astral/ui`: сервисы и компоненты получают инстанс через DI.
|
|
7
|
+
*/
|
|
8
|
+
export const createLogger = (scope, options) => uiLogger.child(scope, options);
|
|
9
|
+
/**
|
|
10
|
+
* (Пере)-Настройка логгера пакета `@astral/ui` — вызывает `ConfigProvider`.
|
|
11
|
+
*/
|
|
12
|
+
export const configureLogger = (options) => uiLogger.configure(options);
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Резолвит anchorEl в DOM-ноду, если это возможно.
|
|
3
|
-
* Для virtual-элементов вернёт null.
|
|
4
|
-
*/
|
|
5
|
-
export const resolveAnchorNode = (anchorEl) => {
|
|
6
|
-
const value = typeof anchorEl === 'function' ? anchorEl() : anchorEl;
|
|
7
|
-
return value instanceof Node ? value : null;
|
|
8
|
-
};
|