Перейти к содержанию

StepperModal — многоступенчатая модалка

Расположение

src/components/ui/StepperModal.vue

Назначение

Переиспользуемый wizard-компонент для пошаговых форм. Оборачивает Modal.vue, добавляя навигацию по шагам с индикатором прогресса.

Props

PropТипПо умолчаниюОписание
stepsArray<{ key: string, title: string }>обязателенОписание шагов. key используется для именованных слотов
modelValueBooleanfalseВидимость модалки (v-model)
idStringID для Bootstrap modal
titleStringЗаголовок модалки. Если не указан — берётся title текущего шага
submitTextString'Создать'Текст кнопки на последнем шаге
nextTextString'Далее'Текст кнопки перехода на следующий шаг
backTextString'Назад'Текст кнопки возврата
stacking, breakpoint, forceDesktopПроброс в Modal
disabledNextBooleanБлокировка кнопки «Далее»
disabledSubmitBooleanБлокировка кнопки «Создать»
showLoaderBooleanЛоадер на кнопке «Создать»

Events

EventPayloadОписание
update:modelValueBooleanЗакрытие/открытие
submitНажатие финальной кнопки
step-changeNumber (индекс)Переход на другой шаг

Именованные слоты

Для каждого шага используется слот #step-{key}:

vue
<StepperModal :steps="[{ key: 'info', title: 'Информация' }, { key: 'confirm', title: 'Подтверждение' }]">
  <template #step-info>
    <!-- содержимое первого шага -->
  </template>
  <template #step-confirm>
    <!-- содержимое второго шага -->
  </template>
</StepperModal>

Динамические шаги

Массив steps может быть computed — компонент автоматически адаптируется при изменении набора шагов. Если текущий индекс выходит за границы нового массива, он корректируется.

Мобильное позиционирование кнопок

На мобилке кнопки «Назад / Далее / Создать» прижаты к низу видимой области модалки через mt-auto + динамический min-height.

Как работает: при открытии модалки, после завершения анимации ion-modal (~400ms), JS измеряет getBoundingClientRect().top контейнера и visualViewport.height, вычитает высоту sibling-элементов (пустой buttons wrapper из Modal.vue) и устанавливает точный min-height через inline style.

Ранее использовался хардкод calc(100svh - 80px), который ломался на разных устройствах из-за safe-area, отступов stacking-режима ion-modal и т.д.

expose

Компонент экспортирует currentStepIndex, goNext, goBack, goToFirstStepWithErrors для программной навигации.

Использование в проекте

  • CreateUpdatePortfolioModal.vue — создание портфеля (editMode использует обычную Modal).
    • Обычный портфель: 4 шага (тип → параметры → учёт валюты → уведомления)
    • Составной портфель: 3 шага (тип → параметры → уведомления)

Связь с currency_mode

Поле currency_mode портфеля (выбирается на шаге «Учёт валюты» при создании) влияет на CreateOperationModal.vue:

  • currency_mode.code === 'strict' ("Обязательный учет") → опция «Нет» скрыта из conversion_target_type, дефолт — «Валюта»
  • currency_mode.code === 'facultative' ("Валюта не важна") или null → поведение по умолчанию (дефолт — «Нет»)