@cloud-ru/ds-uikit-product-welcome-tour 1.1.0 → 1.2.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 +6 -0
- package/README.md +5 -0
- package/dist/cjs/components/WelcomeTour/WelcomeTour.d.ts +1 -1
- package/dist/cjs/components/WelcomeTour/WelcomeTour.js +3 -2
- package/dist/cjs/components/WelcomeTour/utils.d.ts +2 -1
- package/dist/cjs/components/WelcomeTour/utils.js +2 -1
- package/dist/cjs/helperComponents/TourHint/TourHint.js +2 -2
- package/dist/cjs/helperComponents/TourHint/types.d.ts +2 -0
- package/dist/cjs/types.d.ts +8 -0
- package/dist/esm/components/WelcomeTour/WelcomeTour.d.ts +1 -1
- package/dist/esm/components/WelcomeTour/WelcomeTour.js +3 -2
- package/dist/esm/components/WelcomeTour/utils.d.ts +2 -1
- package/dist/esm/components/WelcomeTour/utils.js +2 -1
- package/dist/esm/helperComponents/TourHint/TourHint.js +2 -2
- package/dist/esm/helperComponents/TourHint/types.d.ts +2 -0
- package/dist/esm/types.d.ts +8 -0
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/components/WelcomeTour/WelcomeTour.tsx +3 -1
- package/src/components/WelcomeTour/utils.ts +9 -1
- package/src/helperComponents/TourHint/TourHint.tsx +2 -2
- package/src/helperComponents/TourHint/types.ts +2 -0
- package/src/types.ts +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 1.2.0 (2026-09-03)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **FF-8762:** add showStepIndicator prop to welcome tour ([f4beeb2](https://github.com/cloud-ru-tech/snack-v2/commit/f4beeb2d72919d58312cf2a7a00822812517ae27))
|
|
11
|
+
|
|
6
12
|
# 1.1.0 (2026-09-02)
|
|
7
13
|
|
|
8
14
|
### Features
|
package/README.md
CHANGED
|
@@ -33,6 +33,8 @@
|
|
|
33
33
|
|
|
34
34
|
Все слоты необязательные, кроме `target`. Индикатор прогресса появляется автоматически, когда шагов больше одного, и остаётся неинтерактивным — он показывает позицию в туре, навигация идёт кнопками.
|
|
35
35
|
|
|
36
|
+
`showStepIndicator={false}` убирает индикатор вместе с озвучкой позиции для скринридера. Это нужно туру, у которого длина неизвестна заранее: шаг с ненайденной целью тур пропускает на лету (адаптив скрыл блок, раздел недоступен по правам), а пересчитать общее число он не может — «2 из 5» тогда врёт. Когда все шаги гарантированно доступны, индикатор оставляют: он показывает, сколько ещё идти.
|
|
37
|
+
|
|
36
38
|
### Placement (default `bottom`)
|
|
37
39
|
|
|
38
40
|
`steps[i].placement` задаёт положение подсказки относительно целевого элемента: `top`, `bottom`, `left`, `right` и их варианты `-start` / `-end`, а также `auto` (сторона подбирается автоматически) и `center` (подсказка по центру экрана — для шага без привязки к элементу). Если выбранной стороне не хватает места, подсказка разворачивается на противоположную.
|
|
@@ -236,6 +238,7 @@ export function WithoutBackButton() {
|
|
|
236
238
|
| `open` | `boolean` | — | Запущен ли тур. Управляемый режим. |
|
|
237
239
|
| `portalContainer` | `HTMLElement \| null` | — | Контейнер для портала. По умолчанию — контейнер из `PortalContextProvider` либо `document.body`. |
|
|
238
240
|
| `scrollOffset` | `number` | `20` | Отступ при скролле к целевому элементу, px. |
|
|
241
|
+
| `showStepIndicator` | `boolean` | `true` | Показывать ли индикатор прогресса. Он и так появляется только у тура длиннее одного <br/> шага; `false` убирает его вместе с озвучкой позиции для скринридера — это нужно там, <br/> где часть шагов может отвалиться на лету (цели нет на странице, шаг пропускается), <br/> и «2 из 5» окажется неправдой. |
|
|
239
242
|
| `spotlightPadding` | `TourSpotlightPadding` | `10` | Отступ выреза от границ целевого элемента для всех шагов. Шаг переопределяет своим <br/> `spotlightPadding`. |
|
|
240
243
|
| `stepIndex` | `number` | — | Индекс текущего шага. Управляемый режим. |
|
|
241
244
|
| `steps` | `TourStep` | — | Шаги тура. |
|
|
@@ -290,6 +293,8 @@ export function WithoutBackButton() {
|
|
|
290
293
|
- ❌ Указывать `target` на элемент за пределами вьюпорта или появляющийся асинхронно — шаг не найдёт цель.
|
|
291
294
|
- ✅ Формулировать шаг одним действием: что это и зачем нажимать.
|
|
292
295
|
- ❌ Складывать в `content` абзац справки — для этого есть документация раздела.
|
|
296
|
+
- ✅ Скрывать индикатор (`showStepIndicator={false}`), если часть шагов может оказаться недоступной.
|
|
297
|
+
- ❌ Показывать «2 из 5» туру, который на узком экране проходит за три шага.
|
|
293
298
|
- ✅ Оставлять `skip`: пользователь должен уметь выйти в любой момент.
|
|
294
299
|
- ❌ Делать тур безвыходным (`buttons` только с `primary`) в обязательном онбординге.
|
|
295
300
|
|
|
@@ -12,4 +12,4 @@ import { WelcomeTourProps } from '../../types';
|
|
|
12
12
|
* `data-test-id` компонент не принимает: слоты подсказки адресуются через публичную
|
|
13
13
|
* константу `TEST_IDS`.
|
|
14
14
|
*/
|
|
15
|
-
export declare function WelcomeTour({ steps, open, defaultOpen, onOpenChange, stepIndex, defaultStepIndex, onStepChange, labels: componentLabels, buttons, scrollOffset, spotlightPadding, portalContainer, }: WelcomeTourProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare function WelcomeTour({ steps, open, defaultOpen, onOpenChange, stepIndex, defaultStepIndex, onStepChange, labels: componentLabels, buttons, showStepIndicator, scrollOffset, spotlightPadding, portalContainer, }: WelcomeTourProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -28,7 +28,7 @@ const FLOATING_OPTIONS = { shiftOptions: { crossAxis: true, padding: 16 } };
|
|
|
28
28
|
* `data-test-id` компонент не принимает: слоты подсказки адресуются через публичную
|
|
29
29
|
* константу `TEST_IDS`.
|
|
30
30
|
*/
|
|
31
|
-
function WelcomeTour({ steps, open, defaultOpen = false, onOpenChange, stepIndex, defaultStepIndex = 0, onStepChange, labels: componentLabels, buttons = DEFAULT_BUTTONS, scrollOffset, spotlightPadding, portalContainer, }) {
|
|
31
|
+
function WelcomeTour({ steps, open, defaultOpen = false, onOpenChange, stepIndex, defaultStepIndex = 0, onStepChange, labels: componentLabels, buttons = DEFAULT_BUTTONS, showStepIndicator = true, scrollOffset, spotlightPadding, portalContainer, }) {
|
|
32
32
|
const { t } = locale_1.welcomeTourLocale.useTranslations();
|
|
33
33
|
const portalContextRef = (0, portal_context_1.usePortalContext)();
|
|
34
34
|
const [isOpen, setOpen] = (0, utils_1.useUncontrolledProp)(open, defaultOpen, onOpenChange);
|
|
@@ -62,7 +62,8 @@ function WelcomeTour({ steps, open, defaultOpen = false, onOpenChange, stepIndex
|
|
|
62
62
|
labels: { next: t('next'), back: t('back'), finish: t('finish'), close: t('close') },
|
|
63
63
|
componentLabels,
|
|
64
64
|
buttons,
|
|
65
|
-
|
|
65
|
+
showStepIndicator,
|
|
66
|
+
}), [steps, t, componentLabels, buttons, showStepIndicator]);
|
|
66
67
|
const handleEvent = (0, react_1.useCallback)(({ action, controlled, type, index, status }) => {
|
|
67
68
|
switch (type) {
|
|
68
69
|
// Неуправляемый режим: индекс уже переключил движок, компонент сообщает о факте.
|
|
@@ -5,6 +5,7 @@ type ToJoyrideStepsParams = {
|
|
|
5
5
|
labels: TourLabels;
|
|
6
6
|
componentLabels?: Partial<TourLabels>;
|
|
7
7
|
buttons: TourButton[];
|
|
8
|
+
showStepIndicator: boolean;
|
|
8
9
|
};
|
|
9
10
|
/**
|
|
10
11
|
* Приводит статус движка к публичному `TourStatus`: наружу сообщаются только терминальные
|
|
@@ -18,5 +19,5 @@ export declare function resolveLabels(base: TourLabels, componentLabels?: Partia
|
|
|
18
19
|
* (`subtitle`, разрешённые подписи, набор кнопок), уезжают в `step.data` — оттуда
|
|
19
20
|
* их читает `TourHint`.
|
|
20
21
|
*/
|
|
21
|
-
export declare function toJoyrideSteps({ steps, labels, componentLabels, buttons }: ToJoyrideStepsParams): Step[];
|
|
22
|
+
export declare function toJoyrideSteps({ steps, labels, componentLabels, buttons, showStepIndicator, }: ToJoyrideStepsParams): Step[];
|
|
22
23
|
export {};
|
|
@@ -24,7 +24,7 @@ function resolveLabels(base, componentLabels, stepLabels) {
|
|
|
24
24
|
* (`subtitle`, разрешённые подписи, набор кнопок), уезжают в `step.data` — оттуда
|
|
25
25
|
* их читает `TourHint`.
|
|
26
26
|
*/
|
|
27
|
-
function toJoyrideSteps({ steps, labels, componentLabels, buttons }) {
|
|
27
|
+
function toJoyrideSteps({ steps, labels, componentLabels, buttons, showStepIndicator, }) {
|
|
28
28
|
return steps.map(({ target, title, subtitle, content, placement, width, spotlightTarget, spotlightPadding, labels: stepLabels, onBeforeShow, }) => ({
|
|
29
29
|
// Со списком целей подсказка цепляется за «зеркальный» узел: раскрытый список
|
|
30
30
|
// закрывается по клику мимо себя, то есть уже на `mousedown` по кнопке подсказки —
|
|
@@ -50,6 +50,7 @@ function toJoyrideSteps({ steps, labels, componentLabels, buttons }) {
|
|
|
50
50
|
subtitle,
|
|
51
51
|
labels: resolveLabels(labels, componentLabels, stepLabels),
|
|
52
52
|
buttons,
|
|
53
|
+
showStepIndicator,
|
|
53
54
|
},
|
|
54
55
|
}));
|
|
55
56
|
}
|
|
@@ -30,7 +30,7 @@ function TourHint({ backProps, closeProps, primaryProps, skipProps, tooltipProps
|
|
|
30
30
|
const contentId = (0, react_1.useId)();
|
|
31
31
|
// `Partial`, а не `TourStepData`: каст к полному типу прятал бы падение на
|
|
32
32
|
// `buttons.includes(...)` у шага, пришедшего мимо `toJoyrideSteps`.
|
|
33
|
-
const { subtitle, labels, buttons = [] } = (step.data ?? {});
|
|
33
|
+
const { subtitle, labels, buttons = [], showStepIndicator = true } = (step.data ?? {});
|
|
34
34
|
const backButtonProps = withoutNativeTitle(backProps);
|
|
35
35
|
const primaryButtonProps = withoutNativeTitle(primaryProps);
|
|
36
36
|
const closeButtonProps = withoutNativeTitle(closeProps);
|
|
@@ -45,6 +45,6 @@ function TourHint({ backProps, closeProps, primaryProps, skipProps, tooltipProps
|
|
|
45
45
|
(0, jsx_runtime_1.jsxs)("div", { ...tooltipProps, "aria-describedby": step.content ? contentId : undefined, "aria-labelledby": step.title ? titleId : undefined, className: styles_module_scss_1.default.hint, "data-test-id": constants_1.TEST_IDS.hint,
|
|
46
46
|
// Ширину шага движок отдаёт только в свои стили тултипа — у подсказки они свои.
|
|
47
47
|
// `max-width` не трогаем: он держит фолбэк по ширине экрана.
|
|
48
|
-
style: step.width !== undefined ? { width: step.width } : undefined, children: [(step.title || showSkip) && ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.header, children: [step.title && ((0, jsx_runtime_1.jsx)(typography_1.Typography, { as: 'div', id: titleId, variant: 'title', size: 'm', "data-test-id": constants_1.TEST_IDS.title, children: step.title })), showSkip && ((0, jsx_runtime_1.jsx)(button_1.Button, { ...skipButtonProps, className: styles_module_scss_1.default.close, appearance: button_1.APPEARANCE.Neutral, "aria-label": labels.close, "data-test-id": constants_1.TEST_IDS.closeIcon, icon: (0, jsx_runtime_1.jsx)(system_1.CrossSVG, {}), view: button_1.VIEW.Simple }))] })), subtitle && ((0, jsx_runtime_1.jsx)(typography_1.Typography, { as: 'p', className: styles_module_scss_1.default.subtitle, variant: 'title', size: 's', weight: 'thin', "data-test-id": constants_1.TEST_IDS.subtitle, children: subtitle })), step.content && ((0, jsx_runtime_1.jsx)(typography_1.Typography, { as: 'div', id: contentId, className: styles_module_scss_1.default.content, variant: 'body', size: 's', "data-test-id": constants_1.TEST_IDS.content, children: step.content })), (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.footer, children: [size > 1 && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: styles_module_scss_1.default.visuallyHidden, children: t('progress', { current: index + 1, total: size }) }), (0, jsx_runtime_1.jsx)(TourSteps_1.TourSteps, { current: index, total: size })] })), (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.actions, children: [showBack && ((0, jsx_runtime_1.jsx)(button_1.Button, { ...backButtonProps, appearance: button_1.APPEARANCE.Neutral, "data-test-id": constants_1.TEST_IDS.backButton, label: labels.back, view: button_1.VIEW.Outline })), showPrimary &&
|
|
48
|
+
style: step.width !== undefined ? { width: step.width } : undefined, children: [(step.title || showSkip) && ((0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.header, children: [step.title && ((0, jsx_runtime_1.jsx)(typography_1.Typography, { as: 'div', id: titleId, variant: 'title', size: 'm', "data-test-id": constants_1.TEST_IDS.title, children: step.title })), showSkip && ((0, jsx_runtime_1.jsx)(button_1.Button, { ...skipButtonProps, className: styles_module_scss_1.default.close, appearance: button_1.APPEARANCE.Neutral, "aria-label": labels.close, "data-test-id": constants_1.TEST_IDS.closeIcon, icon: (0, jsx_runtime_1.jsx)(system_1.CrossSVG, {}), view: button_1.VIEW.Simple }))] })), subtitle && ((0, jsx_runtime_1.jsx)(typography_1.Typography, { as: 'p', className: styles_module_scss_1.default.subtitle, variant: 'title', size: 's', weight: 'thin', "data-test-id": constants_1.TEST_IDS.subtitle, children: subtitle })), step.content && ((0, jsx_runtime_1.jsx)(typography_1.Typography, { as: 'div', id: contentId, className: styles_module_scss_1.default.content, variant: 'body', size: 's', "data-test-id": constants_1.TEST_IDS.content, children: step.content })), (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.footer, children: [showStepIndicator && size > 1 && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: styles_module_scss_1.default.visuallyHidden, children: t('progress', { current: index + 1, total: size }) }), (0, jsx_runtime_1.jsx)(TourSteps_1.TourSteps, { current: index, total: size })] })), (0, jsx_runtime_1.jsxs)("div", { className: styles_module_scss_1.default.actions, children: [showBack && ((0, jsx_runtime_1.jsx)(button_1.Button, { ...backButtonProps, appearance: button_1.APPEARANCE.Neutral, "data-test-id": constants_1.TEST_IDS.backButton, label: labels.back, view: button_1.VIEW.Outline })), showPrimary &&
|
|
49
49
|
(isLastStep ? ((0, jsx_runtime_1.jsx)(button_1.Button, { ...closeButtonProps, "data-test-id": constants_1.TEST_IDS.finishButton, label: labels.finish, view: button_1.VIEW.Filled })) : ((0, jsx_runtime_1.jsx)(button_1.Button, { ...primaryButtonProps, "data-test-id": constants_1.TEST_IDS.nextButton, label: labels.next, view: button_1.VIEW.Filled })))] })] })] }));
|
|
50
50
|
}
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -113,6 +113,14 @@ export type WelcomeTourProps = {
|
|
|
113
113
|
* @default ['back', 'primary', 'skip']
|
|
114
114
|
*/
|
|
115
115
|
buttons?: TourButton[];
|
|
116
|
+
/**
|
|
117
|
+
* Показывать ли индикатор прогресса. Он и так появляется только у тура длиннее одного
|
|
118
|
+
* шага; `false` убирает его вместе с озвучкой позиции для скринридера — это нужно там,
|
|
119
|
+
* где часть шагов может отвалиться на лету (цели нет на странице, шаг пропускается),
|
|
120
|
+
* и «2 из 5» окажется неправдой.
|
|
121
|
+
* @default true
|
|
122
|
+
*/
|
|
123
|
+
showStepIndicator?: boolean;
|
|
116
124
|
/**
|
|
117
125
|
* Отступ при скролле к целевому элементу, px.
|
|
118
126
|
* @default 20
|
|
@@ -12,4 +12,4 @@ import { WelcomeTourProps } from '../../types.js';
|
|
|
12
12
|
* `data-test-id` компонент не принимает: слоты подсказки адресуются через публичную
|
|
13
13
|
* константу `TEST_IDS`.
|
|
14
14
|
*/
|
|
15
|
-
export declare function WelcomeTour({ steps, open, defaultOpen, onOpenChange, stepIndex, defaultStepIndex, onStepChange, labels: componentLabels, buttons, scrollOffset, spotlightPadding, portalContainer, }: WelcomeTourProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare function WelcomeTour({ steps, open, defaultOpen, onOpenChange, stepIndex, defaultStepIndex, onStepChange, labels: componentLabels, buttons, showStepIndicator, scrollOffset, spotlightPadding, portalContainer, }: WelcomeTourProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -25,7 +25,7 @@ const FLOATING_OPTIONS = { shiftOptions: { crossAxis: true, padding: 16 } };
|
|
|
25
25
|
* `data-test-id` компонент не принимает: слоты подсказки адресуются через публичную
|
|
26
26
|
* константу `TEST_IDS`.
|
|
27
27
|
*/
|
|
28
|
-
export function WelcomeTour({ steps, open, defaultOpen = false, onOpenChange, stepIndex, defaultStepIndex = 0, onStepChange, labels: componentLabels, buttons = DEFAULT_BUTTONS, scrollOffset, spotlightPadding, portalContainer, }) {
|
|
28
|
+
export function WelcomeTour({ steps, open, defaultOpen = false, onOpenChange, stepIndex, defaultStepIndex = 0, onStepChange, labels: componentLabels, buttons = DEFAULT_BUTTONS, showStepIndicator = true, scrollOffset, spotlightPadding, portalContainer, }) {
|
|
29
29
|
const { t } = welcomeTourLocale.useTranslations();
|
|
30
30
|
const portalContextRef = usePortalContext();
|
|
31
31
|
const [isOpen, setOpen] = useUncontrolledProp(open, defaultOpen, onOpenChange);
|
|
@@ -59,7 +59,8 @@ export function WelcomeTour({ steps, open, defaultOpen = false, onOpenChange, st
|
|
|
59
59
|
labels: { next: t('next'), back: t('back'), finish: t('finish'), close: t('close') },
|
|
60
60
|
componentLabels,
|
|
61
61
|
buttons,
|
|
62
|
-
|
|
62
|
+
showStepIndicator,
|
|
63
|
+
}), [steps, t, componentLabels, buttons, showStepIndicator]);
|
|
63
64
|
const handleEvent = useCallback(({ action, controlled, type, index, status }) => {
|
|
64
65
|
switch (type) {
|
|
65
66
|
// Неуправляемый режим: индекс уже переключил движок, компонент сообщает о факте.
|
|
@@ -5,6 +5,7 @@ type ToJoyrideStepsParams = {
|
|
|
5
5
|
labels: TourLabels;
|
|
6
6
|
componentLabels?: Partial<TourLabels>;
|
|
7
7
|
buttons: TourButton[];
|
|
8
|
+
showStepIndicator: boolean;
|
|
8
9
|
};
|
|
9
10
|
/**
|
|
10
11
|
* Приводит статус движка к публичному `TourStatus`: наружу сообщаются только терминальные
|
|
@@ -18,5 +19,5 @@ export declare function resolveLabels(base: TourLabels, componentLabels?: Partia
|
|
|
18
19
|
* (`subtitle`, разрешённые подписи, набор кнопок), уезжают в `step.data` — оттуда
|
|
19
20
|
* их читает `TourHint`.
|
|
20
21
|
*/
|
|
21
|
-
export declare function toJoyrideSteps({ steps, labels, componentLabels, buttons }: ToJoyrideStepsParams): Step[];
|
|
22
|
+
export declare function toJoyrideSteps({ steps, labels, componentLabels, buttons, showStepIndicator, }: ToJoyrideStepsParams): Step[];
|
|
22
23
|
export {};
|
|
@@ -19,7 +19,7 @@ export function resolveLabels(base, componentLabels, stepLabels) {
|
|
|
19
19
|
* (`subtitle`, разрешённые подписи, набор кнопок), уезжают в `step.data` — оттуда
|
|
20
20
|
* их читает `TourHint`.
|
|
21
21
|
*/
|
|
22
|
-
export function toJoyrideSteps({ steps, labels, componentLabels, buttons }) {
|
|
22
|
+
export function toJoyrideSteps({ steps, labels, componentLabels, buttons, showStepIndicator, }) {
|
|
23
23
|
return steps.map(({ target, title, subtitle, content, placement, width, spotlightTarget, spotlightPadding, labels: stepLabels, onBeforeShow, }) => ({
|
|
24
24
|
// Со списком целей подсказка цепляется за «зеркальный» узел: раскрытый список
|
|
25
25
|
// закрывается по клику мимо себя, то есть уже на `mousedown` по кнопке подсказки —
|
|
@@ -45,6 +45,7 @@ export function toJoyrideSteps({ steps, labels, componentLabels, buttons }) {
|
|
|
45
45
|
subtitle,
|
|
46
46
|
labels: resolveLabels(labels, componentLabels, stepLabels),
|
|
47
47
|
buttons,
|
|
48
|
+
showStepIndicator,
|
|
48
49
|
},
|
|
49
50
|
}));
|
|
50
51
|
}
|
|
@@ -24,7 +24,7 @@ export function TourHint({ backProps, closeProps, primaryProps, skipProps, toolt
|
|
|
24
24
|
const contentId = useId();
|
|
25
25
|
// `Partial`, а не `TourStepData`: каст к полному типу прятал бы падение на
|
|
26
26
|
// `buttons.includes(...)` у шага, пришедшего мимо `toJoyrideSteps`.
|
|
27
|
-
const { subtitle, labels, buttons = [] } = (step.data ?? {});
|
|
27
|
+
const { subtitle, labels, buttons = [], showStepIndicator = true } = (step.data ?? {});
|
|
28
28
|
const backButtonProps = withoutNativeTitle(backProps);
|
|
29
29
|
const primaryButtonProps = withoutNativeTitle(primaryProps);
|
|
30
30
|
const closeButtonProps = withoutNativeTitle(closeProps);
|
|
@@ -39,6 +39,6 @@ export function TourHint({ backProps, closeProps, primaryProps, skipProps, toolt
|
|
|
39
39
|
_jsxs("div", { ...tooltipProps, "aria-describedby": step.content ? contentId : undefined, "aria-labelledby": step.title ? titleId : undefined, className: styles.hint, "data-test-id": TEST_IDS.hint,
|
|
40
40
|
// Ширину шага движок отдаёт только в свои стили тултипа — у подсказки они свои.
|
|
41
41
|
// `max-width` не трогаем: он держит фолбэк по ширине экрана.
|
|
42
|
-
style: step.width !== undefined ? { width: step.width } : undefined, children: [(step.title || showSkip) && (_jsxs("div", { className: styles.header, children: [step.title && (_jsx(Typography, { as: 'div', id: titleId, variant: 'title', size: 'm', "data-test-id": TEST_IDS.title, children: step.title })), showSkip && (_jsx(Button, { ...skipButtonProps, className: styles.close, appearance: APPEARANCE.Neutral, "aria-label": labels.close, "data-test-id": TEST_IDS.closeIcon, icon: _jsx(CrossSVG, {}), view: VIEW.Simple }))] })), subtitle && (_jsx(Typography, { as: 'p', className: styles.subtitle, variant: 'title', size: 's', weight: 'thin', "data-test-id": TEST_IDS.subtitle, children: subtitle })), step.content && (_jsx(Typography, { as: 'div', id: contentId, className: styles.content, variant: 'body', size: 's', "data-test-id": TEST_IDS.content, children: step.content })), _jsxs("div", { className: styles.footer, children: [size > 1 && (_jsxs(_Fragment, { children: [_jsx("span", { className: styles.visuallyHidden, children: t('progress', { current: index + 1, total: size }) }), _jsx(TourSteps, { current: index, total: size })] })), _jsxs("div", { className: styles.actions, children: [showBack && (_jsx(Button, { ...backButtonProps, appearance: APPEARANCE.Neutral, "data-test-id": TEST_IDS.backButton, label: labels.back, view: VIEW.Outline })), showPrimary &&
|
|
42
|
+
style: step.width !== undefined ? { width: step.width } : undefined, children: [(step.title || showSkip) && (_jsxs("div", { className: styles.header, children: [step.title && (_jsx(Typography, { as: 'div', id: titleId, variant: 'title', size: 'm', "data-test-id": TEST_IDS.title, children: step.title })), showSkip && (_jsx(Button, { ...skipButtonProps, className: styles.close, appearance: APPEARANCE.Neutral, "aria-label": labels.close, "data-test-id": TEST_IDS.closeIcon, icon: _jsx(CrossSVG, {}), view: VIEW.Simple }))] })), subtitle && (_jsx(Typography, { as: 'p', className: styles.subtitle, variant: 'title', size: 's', weight: 'thin', "data-test-id": TEST_IDS.subtitle, children: subtitle })), step.content && (_jsx(Typography, { as: 'div', id: contentId, className: styles.content, variant: 'body', size: 's', "data-test-id": TEST_IDS.content, children: step.content })), _jsxs("div", { className: styles.footer, children: [showStepIndicator && size > 1 && (_jsxs(_Fragment, { children: [_jsx("span", { className: styles.visuallyHidden, children: t('progress', { current: index + 1, total: size }) }), _jsx(TourSteps, { current: index, total: size })] })), _jsxs("div", { className: styles.actions, children: [showBack && (_jsx(Button, { ...backButtonProps, appearance: APPEARANCE.Neutral, "data-test-id": TEST_IDS.backButton, label: labels.back, view: VIEW.Outline })), showPrimary &&
|
|
43
43
|
(isLastStep ? (_jsx(Button, { ...closeButtonProps, "data-test-id": TEST_IDS.finishButton, label: labels.finish, view: VIEW.Filled })) : (_jsx(Button, { ...primaryButtonProps, "data-test-id": TEST_IDS.nextButton, label: labels.next, view: VIEW.Filled })))] })] })] }));
|
|
44
44
|
}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -113,6 +113,14 @@ export type WelcomeTourProps = {
|
|
|
113
113
|
* @default ['back', 'primary', 'skip']
|
|
114
114
|
*/
|
|
115
115
|
buttons?: TourButton[];
|
|
116
|
+
/**
|
|
117
|
+
* Показывать ли индикатор прогресса. Он и так появляется только у тура длиннее одного
|
|
118
|
+
* шага; `false` убирает его вместе с озвучкой позиции для скринридера — это нужно там,
|
|
119
|
+
* где часть шагов может отвалиться на лету (цели нет на странице, шаг пропускается),
|
|
120
|
+
* и «2 из 5» окажется неправдой.
|
|
121
|
+
* @default true
|
|
122
|
+
*/
|
|
123
|
+
showStepIndicator?: boolean;
|
|
116
124
|
/**
|
|
117
125
|
* Отступ при скролле к целевому элементу, px.
|
|
118
126
|
* @default 20
|