1// Copyright (C) 2025 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import m from 'mithril'; 16import {HTMLAttrs} from './common'; 17import {assertExists} from '../base/logging'; 18 19export interface SettingsPageAttrs extends HTMLAttrs { 20 readonly title: string; 21 readonly stickyHeaderContent?: m.Children; 22} 23 24export class SettingsPage implements m.ClassComponent<SettingsPageAttrs> { 25 private observer?: IntersectionObserver; 26 27 view(vnode: m.Vnode<SettingsPageAttrs>) { 28 const { 29 title, 30 stickyHeaderContent: headerContent, 31 ...htmlAttrs 32 } = vnode.attrs; 33 return m( 34 '.pf-settings-page', 35 htmlAttrs, 36 m( 37 '.pf-settings-page__title', 38 m('.pf-settings-page__centred', m('h1', title)), 39 ), 40 m( 41 '.pf-settings-page__header', 42 m('.pf-settings-page__centred', headerContent), 43 ), 44 m( 45 '.pf-settings-page__content', 46 m('.pf-settings-page__centred', vnode.children), 47 ), 48 ); 49 } 50 51 oncreate(vnode: m.VnodeDOM<SettingsPageAttrs, this>) { 52 const canary = assertExists( 53 vnode.dom.querySelector('.pf-settings-page__title'), 54 ); 55 const header = assertExists( 56 vnode.dom.querySelector('.pf-settings-page__header'), 57 ); 58 59 this.observer = new IntersectionObserver( 60 ([entry]) => { 61 header.classList.toggle( 62 'pf-settings-page__header--stuck', 63 !entry.isIntersecting, 64 ); 65 }, 66 {threshold: [0]}, 67 ); 68 69 this.observer.observe(canary); 70 } 71 72 onremove() { 73 this.observer?.disconnect(); 74 } 75} 76