go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/common/components/status_bar.ts (about)

     1  // Copyright 2020 The LUCI Authors.
     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  
    15  import { MobxLitElement } from '@adobe/lit-mobx';
    16  import { css, html } from 'lit';
    17  import { customElement } from 'lit/decorators.js';
    18  import { classMap } from 'lit/directives/class-map.js';
    19  import { styleMap } from 'lit/directives/style-map.js';
    20  import { makeObservable, observable } from 'mobx';
    21  
    22  export interface Component {
    23    color: string;
    24    weight: number;
    25  }
    26  
    27  @customElement('milo-status-bar')
    28  export class StatusBarElement extends MobxLitElement {
    29    @observable.ref
    30    components: Component[] = [];
    31  
    32    @observable.ref
    33    loading = false;
    34  
    35    constructor() {
    36      super();
    37      makeObservable(this);
    38    }
    39  
    40    private renderComponent(component: Component) {
    41      return html`
    42        <span
    43          class=${classMap({ loading: this.loading })}
    44          style=${styleMap({
    45            'flex-grow': component.weight.toString(),
    46            'background-color': component.color,
    47          })}
    48        >
    49        </span>
    50      `;
    51    }
    52  
    53    protected render() {
    54      return html`
    55        <div id="container">
    56          ${this.components.map((c) => this.renderComponent(c))}
    57        </div>
    58      `;
    59    }
    60  
    61    static styles = css`
    62      #container {
    63        display: flex;
    64        height: 5px;
    65      }
    66  
    67      .loading {
    68        background-image: linear-gradient(
    69          45deg,
    70          rgba(255, 255, 255, 0.15) 25%,
    71          transparent 25%,
    72          transparent 50%,
    73          rgba(255, 255, 255, 0.15) 50%,
    74          rgba(255, 255, 255, 0.15) 75%,
    75          transparent 75%,
    76          transparent
    77        );
    78        background-size: 1rem 1rem;
    79        animation: progress-bar-stripes 1s linear infinite;
    80      }
    81  
    82      @keyframes progress-bar-stripes {
    83        0% {
    84          background-position: 1rem 0;
    85        }
    86        100% {
    87          background-position: 0 0;
    88        }
    89      }
    90    `;
    91  }