[{"data":1,"prerenderedAt":254},["ShallowReactive",2],{"docs:\u002Fdocs\u002Fpatterns\u002Foverlays":3},{"id":4,"title":5,"body":6,"component":241,"dependsOn":242,"description":243,"emitDescriptions":244,"extension":245,"meta":246,"navigation":247,"order":248,"path":249,"seo":250,"status":251,"stem":252,"__hash__":253},"docs\u002Fdocs\u002Fpatterns\u002Foverlays.md","Оверлеї та фокус",{"type":7,"value":8,"toc":232},"minimark",[9,25,30,45,66,70,80,83,93,104,108,118,129,135,139,153,160,171,175,190,197,203,207,221],[10,11,12,16,17,20,21,24],"p",{},[13,14,15],"code",{},"UiModal",", ",[13,18,19],{},"UiDrawer"," і ",[13,22,23],{},"UiConfirmDialog"," не мають власної логіки оверлея.\nУся вона в чотирьох композаблах, які вони ділять. Через це вкладені оверлеї\nпрацюють правильно — а це саме те, що ламалося у вихідних проєктах.",[26,27,29],"h2",{"id":28},"проблема-яку-це-розвязує","Проблема, яку це розв'язує",[10,31,32,33,36,37,40,41,44],{},"Раніше кожен компонент рахував ",[13,34,35],{},"z-index"," сам: модалка мала власний стек від\n1001, drawer — захардкоджений ",[13,38,39],{},"z-[1000]",", діалог підтвердження — ",[13,42,43],{},"99999",".\nНаслідки:",[46,47,48,57,60,63],"ul",{},[49,50,51,52,56],"li",{},"drawer, відкритий ",[53,54,55],"strong",{},"із"," модалки, опинявся під нею;",[49,58,59],{},"два drawer'и один над одним розрулювалися лише порядком у DOM;",[49,61,62],{},"Escape закривав усі відкриті оверлеї одразу;",[49,64,65],{},"закриття внутрішнього оверлея розблоковувало прокрутку фону, поки\nзовнішній ще відкритий.",[26,67,69],{"id":68},"шкала-z-index","Шкала z-index",[71,72,77],"pre",{"className":73,"code":75,"language":76},[74],"language-text","1000  перший оверлей\n1010  другий (крок 10)\n1020  третій\n…\n1100  випадайки UiSelect\n9999  тости\n","text",[13,78,75],{"__ignoreMap":79},"",[10,81,82],{},"Крок 10 лишає місце для внутрішніх шарів панелі — sticky-шапки, футера.",[10,84,85,88,89,92],{},[13,86,87],{},"1100"," для випадайок обране так, щоб перші ~10 оверлеїв лишалися ",[53,90,91],{},"нижче",":\nселект усередині модалки має бути видимим над нею.",[10,94,95,96,99,100,103],{},"Тости на ",[13,97,98],{},"9999"," і з ",[13,101,102],{},"data-overlay-ignore"," — вони мусять лишатися\nклікабельними навіть під відкритою модалкою.",[26,105,107],{"id":106},"шар-знімається-одразу-z-index-після-анімації","Шар знімається одразу, z-index — після анімації",[10,109,110,111,114,115,117],{},"Це найнеочевидніша частина. При закритті шар виходить зі стеку ",[53,112,113],{},"негайно",",\nа його ",[13,116,35],{}," лишається зафіксованим до кінця анімації виходу.",[10,119,120,121,124,125,128],{},"Якби шар чекав завершення анімації, будь-який незавершений ",[13,122,123],{},"leave","\n(перервана анімація, фонова вкладка) лишав би мертвий запис у стеку. Тоді\n",[13,126,127],{},"isTopmost"," брехав би, і Escape перестав би закривати видимий оверлей.",[10,130,131,132,134],{},"Заморожування ",[13,133,35],{}," потрібне з іншого боку: без нього панель, що\nзакривається, пірнула б під сусідній оверлей посеред анімації.",[26,136,138],{"id":137},"прокрутка-блокується-з-лічильником","Прокрутка блокується з лічильником",[10,140,141,144,145,148,149,152],{},[13,142,143],{},"position: fixed",", а не ",[13,146,147],{},"overflow: hidden"," — на iOS Safari ",[13,150,151],{},"overflow"," не\nзупиняє «гумовий» скрол фону.",[10,154,155,156,159],{},"Лічильник тримачів означає, що фон розблоковується лише коли закрився\n",[53,157,158],{},"останній"," оверлей.",[10,161,162,163,166,167,170],{},"Позиція прокрутки зберігається і відновлюється, а ",[13,164,165],{},"scroll-behavior","\nпримусово ставиться в ",[13,168,169],{},"auto"," — інакше повернення на місце анімувалося б.",[26,172,174],{"id":173},"пастка-фокуса-розуміє-телепорти","Пастка фокуса розуміє телепорти",[10,176,177,178,181,182,185,186,189],{},"Головний нюанс. ",[13,179,180],{},"UiSelect"," рендерить випадайку прямо в ",[13,183,184],{},"\u003Cbody>"," — тобто\nформально ",[53,187,188],{},"поза"," панеллю модалки.",[10,191,192,193,196],{},"Тому «фон» визначається не як «усе поза контейнером», а як «те, що ця пастка\nсама позначила ",[13,194,195],{},"inert"," у момент активації». Елементи, які з'явилися пізніше\n— та сама випадайка — лишаються клікабельними й фокусованими.",[10,198,199,200,202],{},"Вкладеність працює за принципом LIFO: коли поверх drawer'а відкривається\nмодалка, її пастка позначає ",[13,201,195],{}," і корінь drawer'а теж, а при закритті\nвідновлює рівно те, що змінила сама.",[26,204,206],{"id":205},"різні-дефолти-closeonbackdrop","Різні дефолти closeOnBackdrop",[10,208,209,211,212,16,215,211,217,220],{},[13,210,15],{}," — ",[13,213,214],{},"true",[13,216,19],{},[13,218,219],{},"false",". Це не непослідовність: модалка\nзазвичай інформаційна, і випадкове закриття нічого не коштує. Drawer майже\nзавжди містить форму, де це втрата введеного.",[10,222,223,224,227,228,231],{},"Обидва вимагають, щоб натискання і ",[53,225,226],{},"почалося",", і ",[53,229,230],{},"закінчилося"," на фоні.\nБез цього виділення тексту зсередини панелі з відпусканням мишки над фоном\nзакриває вікно разом із незбереженою формою.",{"title":79,"searchDepth":233,"depth":233,"links":234},2,[235,236,237,238,239,240],{"id":28,"depth":233,"text":29},{"id":68,"depth":233,"text":69},{"id":106,"depth":233,"text":107},{"id":137,"depth":233,"text":138},{"id":173,"depth":233,"text":174},{"id":205,"depth":233,"text":206},null,[],"Спільний стек шарів, лічильник блокування прокрутки і пастка фокуса, що розуміє телепорти.",{},"md",{},true,1,"\u002Fdocs\u002Fpatterns\u002Foverlays",{"title":5,"description":243},"stable","docs\u002Fpatterns\u002Foverlays","ATln1aaziIebuXn0iym5hyHzXVnhjktc_Ky2-WaseNw",1788072641417]