Миграция с v7 на v8
🗑️ Удалённые типы и функции
withModalRootContext
Удалена функция withModalRootContext из ModalRoot.
VisuallyHidden: baseClassName
Удалено свойство baseClassName у компонента VisuallyHidden. Используйте стандартное свойство className.
🧩 Компоненты
ActionSheet
- Свойство
onCloseпереименовано вonClosed. - Добавлена поддержка
slotProps.iosCloseItemдля упрощения локализации кнопки “Отмена” на iOS.
Кнопка отмены на iOS рендерится отдельно от списка действий (вне ActionSheetItem). Теперь можно передавать свойства напрямую в ActionSheetDefaultIosCloseItem через slotProps.iosCloseItem без необходимости создавать обёртку.
Миграция
<ActionSheet
- onClose={() => {}}
+ onClosed={() => {}}
title="Заголовок"
>
<ActionSheetItem>Действие</ActionSheetItem>
</ActionSheet>Пример использования slotProps.iosCloseItem для локализации:
<ActionSheet
onClosed={() => setPopout(null)}
slotProps={{
iosCloseItem: {
children: i18n("cancel"),
},
}}
>
<ActionSheetItem onClick={handleAction}>Действие</ActionSheetItem>
</ActionSheet>Alert
Свойство onClose переименовано в onClosed.
Миграция
<Alert
title="Подтвердите действие"
description="Вы уверены?"
- onClose={() => setPopout(null)}
+ onClosed={() => setPopout(null)}
/>Snackbar
Свойство onClose переименовано в onClosed.
Миграция
<Snackbar
- onClose={() => setSnackbar(null)}
+ onClosed={() => setSnackbar(null)}
>
Сообщение
</Snackbar>PopoutWrapper
Свойство fixed удалено. Вместо него используйте свойство strategy.
Миграция
<PopoutWrapper
- fixed
/>
<PopoutWrapper
- fixed={true}
/>
<PopoutWrapper
- fixed={false}
+ strategy="none"
/>PanelHeader и SplitCol
Изменена реализация fixed — вместо position: fixed используется position: sticky. Это потребовало изменения
раскладки всей страницы — height: 100% на <html> и <body> удалён в пользу display: flex, и теперь
высота страницы зависит от содержимого.
Что может сломаться
-
Получение области видимости через
document.body.clientHeightили его потомков сheight: 100%. Необходимо заменить либо наdocument.documentElement.clientHeight, либо наwindow.innerHeight.- document.body.clientHeight + document.documentElement.clientHeight // или + window.innerHeight -
Чтобы какой-то из элементов растягивался на высоту области видимости, используйте единицы измерения
vhилиdvhвместо%.- height: 100% + height: 100dvh -
Для
SplitColсfixed: чтобы растянуть потомок на всю колонку, используйтеflex-grow: 1на этом потомке.
Textarea
Внутренние отступы синхронизированы с другими элементами форм. Компонент стал компактнее.
RichCell
Изменена структура компонента и уменьшена минимальная высота.
Структурные изменения:
- Свойство
afterтеперь всегда рендерится справа от компонента (вне основного контента), независимо от значенияafterAlign. - Добавлены новые свойства
metaиsubmetaдля отображения текста справа от основного контента внутри блока. - Если вы использовали
afterсafterAlign="start", замените его наmetaиsubmeta.
Изменение минимальной высоты:
| Режим | v7 | v8 |
|---|---|---|
| regular | 64px | 48px |
| compact | 60px | 44px |
Миграция
Если вы использовали after с afterAlign="start" (или не указывали afterAlign), замените на meta и submeta:
<RichCell
before={<Avatar size={48} />}
overTitle="онлайн"
subtitle="Санкт-Петербург"
- after="Текст"
- afterCaption="Подтекст"
- afterAlign="start"
+ meta="Текст"
+ submeta="Подтекст"
>
Имя пользователя
</RichCell>Если вы использовали after с afterAlign="center" или afterAlign="end", поведение остаётся прежним:
<RichCell
before={<Avatar size={48} />}
subtitle="Санкт-Петербург"
after={<Icon28Like />}
afterAlign="center"
>
Имя пользователя
</RichCell>Banner
Свойство imageTheme теперь по умолчанию имеет значение "auto" вместо "dark".
При значении "auto" тема изображения определяется автоматически на основе цветовой схемы приложения.
Миграция
Если вам нужно сохранить прежнее поведение, укажите imageTheme="dark":
<Banner
mode="image"
+ imageTheme="dark"
background={<div style={{ backgroundImage: 'url(...)' }} />}
>
Контент
</Banner>ContentBadge
Изменены цвета при appearance="neutral":
mode=“primary”:
- Было: текст
--color_text_primary, фон--color_background_secondary - Стало: текст
--color_text_contrast, фон--color_icon_secondary
mode=“secondary”:
- Было: текст
--color_text_subhead, фон--color_background_secondary - Стало: текст
--color_text_primary, фон--color_background_secondary_alpha
DateInput, DateRangeInput, CustomSelect
Свойство accessible теперь по умолчанию имеет значение true.
Calendar, CalendarRange
Изменён тип свойства onChange:
- onChange?: (value?: Date) => void
+ onChange?: (value: Date) => voidПроверка значения на undefined больше не требуется.
Миграция
<Calendar
- onChange={(value: Date | undefined) => {
- if (value) {
- setValue(value);
- }
- }}
+ onChange={(value: Date) => setValue(value)}
/>DateInput, DateRangeInput
Изменён тип свойства onChange:
- onChange?: (value?: Date) => void
+ onChange?: (value: Date | null) => voidЗначение null означает, что поле очищено. Значение undefined не используется,
так как оно зарезервировано для неконтролируемого состояния компонента.
📦 Изменение передачи свойств (restProps)
В ряде компонентов изменено поведение передачи дополнительных свойств (restProps). Теперь restProps
применяются к корневому элементу, а для передачи свойств во внутренние элементы используется slotProps.
Input, Search
Свойства getRef, data-* и aria-* атрибуты теперь нужно передавать через slotProps.input.
Миграция
<Input
- getRef={inputRef}
- data-testid="my-input"
- aria-label="Введите текст"
+ slotProps={{
+ input: {
+ getRootRef: inputRef,
+ "data-testid": "my-input",
+ "aria-label": "Введите текст"
+ }
+ }}
/>Textarea, WriteBar
Свойства getRef, data-* и aria-* атрибуты теперь нужно передавать через slotProps.textarea.
Миграция
<Textarea
- getRef={textareaRef}
- data-testid="my-textarea"
+ slotProps={{
+ textarea: {
+ getRootRef: textareaRef,
+ "data-testid": "my-textarea"
+ }
+ }}
/>Switch, Checkbox, Radio
Свойства getRef, data-*, aria-* атрибуты и специфичные для input свойства
(кроме checked, disabled, readOnly, required, name, value) теперь нужно
передавать через slotProps.input.
Миграция
<Checkbox
- getRef={checkboxRef}
- data-testid="my-checkbox"
- aria-describedby="hint"
+ slotProps={{
+ input: {
+ getRootRef: checkboxRef,
+ "data-testid": "my-checkbox",
+ "aria-describedby": "hint"
+ }
+ }}
>
Согласен
</Checkbox>
<Switch
- getRef={switchRef}
- data-testid="my-switch"
+ slotProps={{
+ input: {
+ getRootRef: switchRef,
+ "data-testid": "my-switch"
+ }
+ }}
/>
<Radio
- getRef={radioRef}
+ slotProps={{
+ input: {
+ getRootRef: radioRef
+ }
+ }}
>
Вариант
</Radio>File
Свойства getRef, data-* и aria-* атрибуты теперь нужно передавать через slotProps.input.
Миграция
<File
- getRef={fileRef}
- data-testid="file-input"
+ slotProps={{
+ input: {
+ getRootRef: fileRef,
+ "data-testid": "file-input"
+ }
+ }}
>
Выбрать файл
</File>CustomSelect, NativeSelect
Свойства restProps теперь применяются к корневому элементу, а не к внутреннему input.
Для передачи свойств во внутренний input используйте slotProps.input.
Миграция
<CustomSelect
- data-testid="select"
- aria-label="Выберите значение"
+ slotProps={{
+ input: {
+ "data-testid": "select",
+ "aria-label": "Выберите значение"
+ }
+ }}
options={options}
value={value}
onChange={onChange}
/>ChipsSelect, ChipsInput
Свойства для внутреннего input теперь передаются через slotProps.input.
Миграция
<ChipsSelect
- getRef={inputRef}
- data-testid="chips-select"
- aria-describedby="hint"
+ slotProps={{
+ input: {
+ getRootRef: inputRef,
+ "data-testid": "chips-select",
+ "aria-describedby": "hint"
+ }
+ }}
value={value}
onChange={onChange}
/>SplitLayout
Свойства restProps теперь применяются к корневому элементу, а не к внутреннему контейнеру content.
Для передачи свойств в контейнер используйте slotProps.content.
Миграция
<SplitLayout
- className="my-layout"
- data-testid="layout"
+ slotProps={{
+ content: {
+ className: "my-layout",
+ "data-testid": "layout"
+ }
+ }}
header={<PanelHeader />}
>
<SplitCol>Контент</SplitCol>
</SplitLayout>⚠️ Устаревшие API (deprecated)
Следующие API помечены как устаревшие и будут удалены в будущих версиях.
AdaptivityProvider
Свойства sizeX и sizeY теперь @deprecated, используйте density вместо sizeY, viewWidth={ViewWidth.MOBILE}
вместо sizeX="compact" и viewWidth={ViewWidth.SMALL_TABLET} вместо sizeX="regular"
Пример миграции
- <AdaptivityProvider sizeX="compact">
+ <AdaptivityProvider viewWidth={ViewWidth.MOBILE}>
- <AdaptivityProvider sizeX="regular">
+ <AdaptivityProvider viewWidth={ViewWidth.SMALL_TABLET}>
- <AdaptivityProvider sizeY="compact">
+ <AdaptivityProvider density="compact">
- <AdaptivityProvider sizeY="regular">
+ <AdaptivityProvider density="regular">
- <AdaptivityProvider sizeX="compact" sizeY="compact">
+ <AdaptivityProvider viewWidth={ViewWidth.MOBILE} density="compact">
- <AdaptivityProvider sizeX="regular" sizeY="regular">
+ <AdaptivityProvider viewWidth={ViewWidth.SMALL_TABLET} density="regular">
- <AppRootProvider sizeX="regular" sizeY="compact">
+ <AppRootProvider viewWidth={ViewWidth.SMALL_TABLET} density="compact">
- <AppRootProvider sizeX="compact" sizeY="regular">
+ <AppRootProvider viewWidth={ViewWidth.MOBILE} density="regular">ModalRoot
Компонент ModalRoot помечен как @deprecated. Используйте хук useModalManager
для императивного управления модальными окнами.
Миграция
- const [activeModal, setActiveModal] = useState(null);
-
- <ModalRoot activeModal={activeModal} onClose={() => setActiveModal(null)}>
- <ModalPage id="modal" onClose={() => setActiveModal(null)}>
- Контент
- </ModalPage>
- </ModalRoot>
+ const [modalApi, modalHolder] = useModalManager();
+
+ // Открытие модального окна
+ modalApi.openModalPage({
+ children: <div>Контент</div>,
+ });
+
+ // В JSX
+ {modalHolder}FixedLayout
Компонент FixedLayout помечен как @deprecated и будет удалён в v10. Используйте вместо него
Box со свойствами position="sticky" и insetBlockStart/insetBlockEnd.
Миграция
- <FixedLayout vertical="top">
+ <Box position="sticky" insetBlockStart={0}>
Content
- </FixedLayout>
+ </Box>
- <FixedLayout vertical="bottom">
+ <Box position="sticky" insetBlockEnd={0}>
Content
- </FixedLayout>
+ </Box>Flex.Item
Подкомпонент Flex.Item помечен как @deprecated. Используйте стандартные CSS свойства
или свойства компонента Box для управления дочерними элементами.
RichCell: afterCaption
Свойство afterCaption помечено как @deprecated. Используйте вместо него свойство submeta.
Миграция
<RichCell
- afterCaption="Подтекст"
+ submeta="Подтекст"
>
Контент
</RichCell>ActionSheetItem: mode=“cancel” и isCancelItem
Свойства mode="cancel" и isCancelItem отмечены как устаревшие.
Вместо использования ActionSheetItem с mode="cancel" или isCancelItem в качестве iosCloseItem, используйте:
slotProps.iosCloseItemвActionSheetдля передачи свойств в кнопку отмены- или свойство
iosCloseItemс компонентомActionSheetDefaultIosCloseItemдля полной кастомизации
Миграция
<ActionSheet
onClosed={() => setPopout(null)}
title="Выберите действие"
- iosCloseItem={
- <ActionSheetItem mode="cancel" onClick={() => setPopout(null)}>
- Отмена
- </ActionSheetItem>
- }
+ slotProps={{
+ iosCloseItem: {
+ children: "Отмена",
+ onClick: () => setPopout(null)
+ }
+ }}
+>
+ <ActionSheetItem onClick={handleAction}>Действие</ActionSheetItem>
</ActionSheet>Альтернативный вариант с использованием ActionSheetDefaultIosCloseItem напрямую:
<ActionSheet
onClosed={() => setPopout(null)}
title="Выберите действие"
- iosCloseItem={
- <ActionSheetItem mode="cancel" onClick={() => setPopout(null)}>
- Отмена
- </ActionSheetItem>
- }
+ iosCloseItem={
+ <ActionSheetDefaultIosCloseItem onClick={() => setPopout(null)}>
+ Отмена
+ </ActionSheetDefaultIosCloseItem>
+ }
>
<ActionSheetItem onClick={handleAction}>Действие</ActionSheetItem>
</ActionSheet>DateInput, DateRangeInput, CustomSelect: accessible
Свойство accessible помечено как @deprecated, так как теперь оно имеет значение true по умолчанию.