@import '../../../styles/design-tokens'; // Full-width: снимаем max-width канвы SharePoint — и в workbench (dev), и на живой // странице. !important оправдан: перебиваем встроенные стили канвы, иначе их не снять. // Если после обновления платформы ширина вернётся — проверить актуальные селекторы в DevTools. :global { #workbenchPageContent, .CanvasComponent.LCS .CanvasZone { max-width: 100% !important; } // ---- Печать ---- // Печать идёт в ОТДЕЛЬНОМ чистом окне (см. shared/ui/PrintButton): документ // .rp-print-root переносится туда со стилями страницы, поэтому скролл-контейнеры // и высота SharePoint печать не режут. Здесь — только вид полей на печати // (read-only без серой заливки), эти правила применяются и в окне печати. @media print { .rp-print-root input, .rp-print-root textarea, .rp-print-root select { background: transparent !important; color: #000 !important; border-color: #ccc !important; } // У выбранного человека в PeoplePicker (Fluent) есть кнопка «×». В окне печати // svg-иконки скрыты, а стили Fluent туда не копируются — остаётся пустая // системная кнопка-квадратик под ФИО. На печати удалять некого — скрываем. .rp-print-root .ms-PickerItem-removeButton { display: none !important; } } } .requestPortal { font-family: $font-sans; font-size: $fs-body; line-height: 1.55; color: $gray-900; -webkit-font-smoothing: antialiased; box-sizing: border-box; // Полная ширина обеспечивается через "supportsFullBleed": true в манифесте // + размещение web part в полноширинной секции (как в projects-list). // Корень занимает 100% контейнера, без CSS-трюков с 100vw. width: 100%; // App-shell «edge-to-edge»: рейл примыкает к левому краю, отступы — внутри main. padding: 0; } .teams { // Задел под специфику Teams-контекста; пока совпадает с базовым. font-family: $font-sans; } // Раскладка: боковой рейл (side) на всю высоту + основная область (main). .layout { display: flex; align-items: flex-start; // рейл больше НЕ тянется по контенту — см. .side width: 100%; min-height: 78vh; // «присутствие» рейла даже когда контента мало } // Рейл-колонка. // // Здесь сходятся два требования, которые по отдельности решаются по-разному: // // 1. Градиент рейла не должен менять оттенок от высоты соседней колонки. Раньше // колонка тянулась по .main (align-items: stretch), и, например, доп. фильтр // по статусу на вкладке «Инициированные мной» делал .main чуть выше — фон // Sidebar (градиент от своей же высоты, см. $grad-header в @tnsu/ui-kit) // заметно менял тон. Поэтому САМ РЕЙЛ прибит к высоте окна (100vh) и от // содержимого рядом больше не зависит. // 2. Под рейлом не должно быть белого провала на длинных таблицах. Прежняя // версия задавала height:100vh самой КОЛОНКЕ — и всё, что ниже первого // экрана, оставалось непрокрашенным: на длинном списке заявок рейл выглядел // обрезанным. Ставку на sticky тут держать нельзя: в SharePoint прокручивается // не окно, а внутренний контейнер страницы, и sticky там нередко не // включается вовсе — тогда рейл просто уезжает вверх вместе с контентом. // // Отсюда разделение: КОЛОНКА тянется во всю высоту раскладки и закрашена // $navy-800 — это цвет, которым градиент рейла заканчивается (на 85% и до // конца), поэтому стык с липкой частью не виден. РЕЙЛ внутри — sticky на 100vh // поверх этой заливки. Не включился sticky — под рейлом всё равно та же // заливка, а не белизна. // // На мобильном брейкпоинте сам Sidebar уходит в position:fixed (см. // @tnsu/ui-kit) — там эти правила уже не действуют, см. @media ниже. .side { flex: 0 0 auto; display: flex; align-self: stretch; background: $navy-800; // Прямой потомок — корень Sidebar из @tnsu/ui-kit (своего класса снаружи не // видно, поэтому селектор по структуре, а не по имени). > * { position: sticky; top: 0; height: 100vh; } } .main { flex: 1 1 auto; min-width: 0; // чтобы контент не распирал колонку display: flex; flex-direction: column; padding: $sp-5 $sp-6 $sp-8; } .tabsWrap { margin-bottom: $sp-6; } // Раздел «Новая заявка», когда открыта другая вкладка. Именно скрытие, а не // размонтирование: заполненная форма должна пережить переключение вкладок // (см. RequestPortal.tsx). display:none выводит содержимое и из потока, и из // последовательности табуляции — скрытая форма не ловит фокус с клавиатуры. .hiddenPane { display: none; } // Мобильная кнопка-бургер (открывает выезжающий Sidebar). На десктопе скрыта. .mobileNav { display: none; margin-bottom: $sp-4; } // < 768px: рейл превращается в выезжающий drawer (см. @tnsu/ui-kit Sidebar). Он // position:fixed и выходит из потока — колонка .side схлопывается сама, main // занимает всю ширину. Показываем бургер в шапке контента. @media (max-width: 768px) { .layout { min-height: 0; } .mobileNav { display: block; } // Снимаем десктопные правила рейла явно. Здесь ui-kit сам делает Sidebar // position:fixed (top/bottom/left), и наш sticky+100vh спорил бы с ним при // равной специфичности — исход решался бы порядком подключения стилей. // Заливка колонки тоже не нужна: колонка схлопнута, drawer красит себя сам. .side { align-self: flex-start; background: none; > * { position: static; height: auto; } } } // Полоса отладочной подмены личности (см. shared/impersonation.ts). Красная и // во всю ширину намеренно: это не подсказка, а предупреждение о том, что портал // показывает не ваши данные — незаметная плашка тут хуже, чем никакой. .impersonationBar { padding: $sp-3 $sp-4; margin-bottom: $sp-4; border: 1px solid $red-500; border-radius: $r-md; background: rgba($red-500, .08); color: $navy-900; font-size: $fs-sm; line-height: 1.45; } // Стили конкретных фич живут в features//.module.scss. // Здесь — только оболочка (root + раскладка колонок), общая для всех фич.