• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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