fix(PanelHeader): Replace FixedLayout with sticky position#6609
fix(PanelHeader): Replace FixedLayout with sticky position#6609
Conversation
size-limit report 📦
|
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
e2e tests |
👀 Docs deployed
Commit 49b6f96 |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #6609 +/- ##
==========================================
- Coverage 82.21% 82.20% -0.01%
==========================================
Files 331 331
Lines 10250 10246 -4
Branches 3439 3436 -3
==========================================
- Hits 8427 8423 -4
Misses 1823 1823
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Because it's the default value, so we don't need set it again. Also it breaks fixed prop as it doesn't allow to override position due to cascade.
221ba5c to
c6d079d
Compare
| * VKCOM | ||
| */ | ||
| .PanelHeader--vkcom { | ||
| position: relative; |
There was a problem hiding this comment.
Убрал, потому что иначе проп fixed не работает с платформой vkcom.
А не работает из-за того, что веса PanelHeader--fixed cо sticky и .PanelHeader--vkcom теперь одинаковы.
| display: block; | ||
| content: ''; | ||
| .PanelHeader--fixed { | ||
| position: sticky; |
There was a problem hiding this comment.
Возможно стоит добавить backface-visibility: hidden, сталкивался с багом то ли в сафари, то ли в хроме, когда стики то пропадает, то появляется. Мб сейчас уже ок, не смог найти инфы в инете поправлено ли.
Ссылки
|
Заметил, что если использовать PanelHeader в многоколоночном интерфейсе на широком экране на Android или iOS, передавая PanelHeader в свойство Screen.Recording.2024-03-01.at.16.33.26.movПеревожу пока в draft. Надо подумать. |
|
Другая причина не переходить полностью на Screen.Recording.2024-03-05.at.18.23.17.mov |
|
PR закрыт из-за отсутствия активности в течение последних 14 дней. Если это произошло по ошибке или изменения все ещё актуальны, откройте PR повторно. |
h2. `PanelHeader`
1. Заменил `FixedLayout` на `position: sticky` прямо в компоненте.
2. Перенёс `z-index` перманентно в корень, т.к. `position: sticky`
теперь применяется на `.host`. Это исправляет также перекрытие
`PanelHeaderContext` при `<PanelHeader fixed={false} />`.
3. Заменил компонент `Spacing` на `delimiter="spacing"` на отступ в CSS,
т.к. из-за него высота `PanelHeader` становится больше, появляется
невидимая область и из-за п.2 это теперь блокирует взаимодействие
с другими элементами в ситуации, когда частично зализает на них
(`<Spacing />` добавили в #3135).
h2. `SplitCol`
Для `<SplitCol fixed />` также заменяем `position: fixed` на `position: sticky`.
Также добавляем растягивание на `100vh` с вычетом `safe-area`
и с Graceful Degradation на [dvh](https://caniuse.com/?search=dvh).
h2. `SplitLayout`
Чтобы решить проблему когда стики шапка при `<SplitLayout header={<PanelHeader delimiter="none" />} />`
остается в рамках `100vh` (см. #6609 (comment)),
избавляемся от `height: 100%` у `<html>`, `<body>`, `.vkui__root`.
Вместо этого используем магию с Flexbox.
- на `<html>` `display: flex` + `min-height: 100%`, чтобы страница
растягивалась с учётом контента, а не области видимости;
- для `<body>` используем `flex: 1`, чтобы растягивался также как
и `<html>`, а также `display: flex` + `flex-direction: column`,
чтобы также растягивать потомков (об этом далее);
- для `.vkui__root` повторяем тоже самое, что и для `<body>`.
`height: 100%` у `AppRoot`, `SplitLayout` и так далее по каскаду
не трогаем, т.к. они растягиваются от `flex: 1`.
Ориентировался на статью https://stackoverflow.com/questions/30962863/holy-grail-layout-with-flex-and-always-visible-header.
h2. `PanelHeader`
1. Заменил `FixedLayout` на `position: sticky` прямо в компоненте.
2. Перенёс `z-index` перманентно в корень, т.к. `position: sticky`
теперь применяется на `.host`. Это исправляет также перекрытие
`PanelHeaderContext` при `<PanelHeader fixed={false} />`.
3. Заменил компонент `Spacing` на `delimiter="spacing"` на отступ в CSS,
т.к. из-за него высота `PanelHeader` становится больше, появляется
невидимая область и из-за п.2 это теперь блокирует взаимодействие
с другими элементами в ситуации, когда частично зализает на них
(`<Spacing />` добавили в #3135).
4. Сделал `Separator` плавающим элементом, чтобы он не занимал лишние
`0.3-0.5px` в потоке.
5. Удалил в стилях `FixedLayout` не существующий класс `.vkuiInternalPanelHeader__fixed`.
> [!NOTE]
>
> Помимо скриншотов `PanelHeader`, задело:
>
> - `Epic` – из-за п.4
> - `Panel` – из-за п.4
> - `PanelHeaderContext` – из-за п.4
> - `FixedLayout` – из-за п.1 и п.4
>
> Обновил их.
h2. `SplitCol`
Для `<SplitCol fixed />` также заменяем `position: fixed` на `position: sticky`.
Также добавляем растягивание на `100vh` с вычетом `safe-area`
и с Graceful Degradation на [dvh](https://caniuse.com/?search=dvh).
h2. `SplitLayout`
Чтобы решить проблему когда стики шапка при `<SplitLayout header={<PanelHeader delimiter="none" />} />`
остается в рамках `100vh` (см. #6609 (comment)),
избавляемся от `height: 100%` у `<html>`, `<body>`, `.vkui__root`.
Вместо этого используем магию с Flexbox.
- на `<html>` `display: flex` + `min-height: 100%`, чтобы страница
растягивалась с учётом контента, а не области видимости;
- для `<body>` удаляем `block-size: 100%` и задаём `display: flex`,
чтобы растягивался также потомки растягивались на всю высоту.
`height: 100%` у `.vkui__root`, `AppRoot`, `SplitLayout` и так далее
по каскаду – не трогаем, их логика остаётся прежней. Элементы должны
продолжать наследовать `height: 100%`.
Ориентировался на статью https://stackoverflow.com/questions/30962863/holy-grail-layout-with-flex-and-always-visible-header.
Добавил скриншотных тестов для проверки стики элементов. Заодно удалил
`dark` старых скриншотов, т.к. она не нужна в этих проверках.
h3. Ожидаемый эффект
Теперь высота всей страницы зависит от контента. На это можно повлиять
через указание какому-либо элементу высоту через единицы `vh` или `dvh`.
В частности, из-за этого для скриншотов `FixedLayout` делаем теперь
`expectScreenshotClippedToContent({ fullPage: false })`, т.к. внутри
функции `getBoundingClientRect()` отдаёт абсолютную высоту элемента.
h3. Что может сломаться?
- Получение области видимости через `document.body.clientHeight` или его
потомков с `height: 100%`. Необходимо заменить либо на
`document.documentElement.clientHeight`, либо на `window.innerHeight`.
```diff
- document.body.clientHeight
+ document.documentElement.clientHeight
// или
+ window.innerHeight
```
- Применение `position: absolute` на элементе на уровне `<body>`. Вместо
этого использовать `position: fixed`.
h2. Окружение
- **Storybook**: потребовалось перебить стиль `display: block`, который
они навешивают на `<body>`, потому что нам нужен `display: flex`.
- **Playwright**:
- добавил новых параметров для `AppDefaultWrapper` и
`screenshotWithClipToContent`, чтобы была возможность скриншотить
только область видимости.
- `index.ts` подключил `import '../src/styles/layout.css';`, чтобы
собирались новые CSS утилиты для раскладки.
h2. `PanelHeader`
1. Заменил `FixedLayout` на `position: sticky` прямо в компоненте.
2. Перенёс `z-index` перманентно в корень, т.к. `position: sticky`
теперь применяется на `.host`. Это исправляет также перекрытие
`PanelHeaderContext` при `<PanelHeader fixed={false} />`.
3. Заменил компонент `Spacing` на `delimiter="spacing"` на отступ в CSS,
т.к. из-за него высота `PanelHeader` становится больше, появляется
невидимая область и из-за п.2 это теперь блокирует взаимодействие
с другими элементами в ситуации, когда частично зализает на них
(`<Spacing />` добавили в #3135).
4. Сделал `Separator` плавающим элементом, чтобы он не занимал лишние
`0.3-0.5px` в потоке.
5. Удалил в стилях `FixedLayout` не существующий класс `.vkuiInternalPanelHeader__fixed`.
> [!NOTE]
>
> Помимо скриншотов `PanelHeader`, задело:
>
> - `Epic` – из-за п.4
> - `Panel` – из-за п.4
> - `PanelHeaderContext` – из-за п.4
> - `FixedLayout` – из-за п.1 и п.4
>
> Обновил их.
h2. `SplitCol`
Для `<SplitCol fixed />` также заменяем `position: fixed` на `position: sticky`.
Также добавляем растягивание на `100vh` с вычетом `safe-area`
и с Graceful Degradation на [dvh](https://caniuse.com/?search=dvh).
h2. `SplitLayout`
Чтобы решить проблему когда стики шапка при `<SplitLayout header={<PanelHeader delimiter="none" />} />`
остается в рамках `100vh` (см. #6609 (comment)),
избавляемся от `height: 100%` у `<html>` и `<body>`.
Вместо этого используем магию с Flexbox.
- на `<html>` `display: flex` + `min-height: 100%`, чтобы страница
растягивалась с учётом контента, а не области видимости;
- для `<body>` удаляем `block-size: 100%` и задаём `display: flex`,
чтобы растягивался также потомки растягивались на всю высоту.
`height: 100%` у `.vkui__root`, `AppRoot`, `SplitLayout` и так далее
по каскаду – не трогаем, их логика остаётся прежней. Элементы должны
продолжать наследовать `height: 100%`.
Ориентировался на статью https://stackoverflow.com/questions/30962863/holy-grail-layout-with-flex-and-always-visible-header.
Добавил скриншотных тестов для проверки стики элементов. Заодно удалил
`dark` старых скриншотов, т.к. она не нужна в этих проверках.
Помимо этого, решил перенести удаление свойств `popout` и `modal` на VKUI v9. А для `getRef` добавил эту пометку.
h3. Ожидаемый эффект
Теперь высота всей страницы зависит от контента. На это можно повлиять
через указание какому-либо элементу высоту через единицы `vh` или `dvh`.
В частности, из-за этого для скриншотов `FixedLayout` делаем теперь
`expectScreenshotClippedToContent({ fullPage: false })`, т.к. внутри
функции `getBoundingClientRect()` отдаёт абсолютную высоту элемента.
h3. Что может сломаться?
- Получение области видимости через `document.body.clientHeight` или его
потомков с `height: 100%`. Необходимо заменить либо на
`document.documentElement.clientHeight`, либо на `window.innerHeight`.
```diff
- document.body.clientHeight
+ document.documentElement.clientHeight
// или
+ window.innerHeight
```
- Применение `position: absolute` на элементе на уровне `<body>`. Необходимо
заменить на `position: fixed`.
h2. Окружение
- **Storybook**: потребовалось перебить стиль `display: block`, который
они навешивают на `<body>`, потому что нам нужен `display: flex`.
- **Playwright**:
- добавил новых параметров для `AppDefaultWrapper` и
`screenshotWithClipToContent`, чтобы была возможность скриншотить
только область видимости.
- `index.ts` подключил `import '../src/styles/layout.css';`, чтобы
собирались новые CSS утилиты для раскладки.
- resolve #9251 - fix #6588 - fix #3532 - close #8115 - resolve #3396 --- <!-- Чеклист. Лишние пункты можно удалить если изменения не подразумевают их наличие. Иначе, необходимо обоснование по каждому пункту. --> - ~[ ] Unit-тесты~ - [x] e2e-тесты - ~[ ] Дизайн-ревью~ - ~[ ] Документация фичи~ - [x] Release notes h3. `PanelHeader` 1. Заменил `FixedLayout` на `position: sticky` прямо в компоненте. 2. Перенёс `z-index` перманентно в корень, т.к. `position: sticky` теперь применяется на `.host`. Это исправляет также перекрытие `PanelHeaderContext` при `<PanelHeader fixed={false} />`. 3. Заменил компонент `Spacing` на `delimiter="spacing"` на отступ в CSS, т.к. из-за него высота `PanelHeader` становится больше, появляется невидимая область и из-за п.2 это теперь блокирует взаимодействие с другими элементами в ситуации, когда частично зализает на них (`<Spacing />` добавили в #3135). 4. Сделал `Separator` плавающим элементом, чтобы он не занимал лишние `0.3-0.5px` в потоке. 5. Удалил в стилях `FixedLayout` не существующий класс `.vkuiInternalPanelHeader__fixed`. > [!NOTE] > > Помимо скриншотов `PanelHeader`, задело: > > - `Epic` – из-за п.4 > - `Panel` – из-за п.4 > - `PanelHeaderContext` – из-за п.4 > - `FixedLayout` – из-за п.1 и п.4 > > Обновил их. h3. `SplitCol` Для `<SplitCol fixed />` также заменяем `position: fixed` на `position: sticky`. Также задаем минимальную высоту через [dvh](https://caniuse.com/?search=dvh) (с фолбеком на `100vh` с вычетом `safe-area`) и делаем его Flexbox'ом, чтобы потомки могли растягиваться на всю высоту через `flex: 1` вместо `block-size: 100%`. h3. `SplitLayout` Чтобы решить проблему когда стики шапка при `<SplitLayout header={<PanelHeader delimiter="none" />} />` остается в рамках `100vh` (см. #6609 (comment)), избавляемся от `height: 100%` у `<html>` и `<body>`. Вместо этого используем магию с Flexbox. - на `<html>` `display: flex` + `min-height: 100%`, чтобы страница растягивалась с учётом контента, а не области видимости; - для `<body>` удаляем `block-size: 100%` и задаём `display: flex`, чтобы высота зависела от содержимого, а потомки продолжали растягиваться через `block-size: 100%`. `height: 100%` у `.vkui__root`, `AppRoot`, `SplitLayout` и так далее по каскаду – не трогаем, их логика остаётся прежней. Элементы должны продолжать наследовать `height: 100%`. Ориентировался на статью https://stackoverflow.com/questions/30962863/holy-grail-layout-with-flex-and-always-visible-header. Добавил скриншотных тестов для проверки стики элементов. Заодно удалил `dark` старых скриншотов, т.к. она не нужна в этих проверках. Помимо этого, решил перенести удаление свойств `popout` и `modal` на VKUI v9. А для `getRef` добавил эту пометку. h4. Ожидаемый эффект Теперь высота всей страницы зависит от контента. На это можно повлиять через указание какому-либо элементу высоту через единицы `vh` или `dvh`. В частности, из-за этого для скриншотов `FixedLayout` делаем теперь `expectScreenshotClippedToContent({ fullPage: false })`, т.к. внутри функции `getBoundingClientRect()` отдаёт абсолютную высоту элемента. h4. Что может сломаться? - Получение области видимости через `document.body.clientHeight` или его потомков с `height: 100%`. Необходимо заменить либо на `document.documentElement.clientHeight`, либо на `window.innerHeight`. ```diff - document.body.clientHeight + document.documentElement.clientHeight // или + window.innerHeight ``` - Применение `position: absolute` на элементе на уровне `<body>`. Необходимо заменить на `position: fixed`. h3. Окружение - **Storybook**: потребовалось перебить стиль `display: block`, который они навешивают на `<body>`, потому что нам нужен `display: flex`. - **Playwright**: - добавил новых параметров для `AppDefaultWrapper` и `screenshotWithClipToContent`, чтобы была возможность скриншотить только область видимости. - `index.ts` подключил `import '../src/styles/layout.css';`, чтобы собирались новые CSS утилиты для раскладки. --- #h1. Release notes #h1. BREAKING CHANGE - PanelHeader: изменена реализация `fixed`, который закрепляет шапку в области видимости при скролле – вместо `position: fixed` используется `position: sticky`. Это потребовало изменение раскладки всей страницы – `height: 100%` на `<html>` и `<body>` удалён в пользу `display: flex` и теперь высота страницы зависит от содержимого. - Если вы получали высоту области видимости через `document.body.clientHeight` или на элементе с `height: 100%` по каскаду ниже, то замените такой код либо на [VIsualViewport](https://developer.mozilla.org/en-US/docs/Web/API/VisualViewport), либо на `document.documentElement.clientHeight`, либо на `window.innerHeight`. - Если вам нужно, чтобы какой-то из элементов растягивался на высоты области видимости, то используйте единицы измерения [`vh`](https://caniuse.com/?search=vh) или [`dvh`](https://caniuse.com/?search=dvh) вместо `%` (`height: 100%` → `height: 100dvh`) - SplitCol: - Изменена реализация `fixed`, который закрепляет колонку в области видимости при скролле – вместо `position: fixed` используется `position: sticky`. - Исправлена проблема когда переполненный контент при `fixed` обрезался – теперь высота `SplitCol` зависит от его содержимого. Чтобы растянуть потомок на всю колонку, используйте `flex-grow: 1` на этом потомке.
related (по поводу использования
position sticky): #2422 (comment) #2414 (comment)Описание
Убираем использование
FixedLayoutизPanelHeader, так как это провоцирует ререндер и сдвиг контента из-за того, чтоFixedLayoutадаптирует свою ширину под ширинуSplitCol.Только сейчас по браузерной поддержке мы можем использовать
position: sticky.Изменения
FixedLayoutнаposition: sticky.