xref: /aosp_15_r20/external/perfetto/ui/src/widgets/chip.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker// Copyright (C) 2024 The Android Open Source Project
2*6dbdd20aSAndroid Build Coastguard Worker//
3*6dbdd20aSAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*6dbdd20aSAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*6dbdd20aSAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*6dbdd20aSAndroid Build Coastguard Worker//
7*6dbdd20aSAndroid Build Coastguard Worker//      http://www.apache.org/licenses/LICENSE-2.0
8*6dbdd20aSAndroid Build Coastguard Worker//
9*6dbdd20aSAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*6dbdd20aSAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*6dbdd20aSAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*6dbdd20aSAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*6dbdd20aSAndroid Build Coastguard Worker// limitations under the License.
14*6dbdd20aSAndroid Build Coastguard Worker
15*6dbdd20aSAndroid Build Coastguard Workerimport m from 'mithril';
16*6dbdd20aSAndroid Build Coastguard Workerimport {classNames} from '../base/classnames';
17*6dbdd20aSAndroid Build Coastguard Workerimport {HTMLAttrs, Intent, classForIntent} from './common';
18*6dbdd20aSAndroid Build Coastguard Workerimport {Icon} from './icon';
19*6dbdd20aSAndroid Build Coastguard Workerimport {Spinner} from './spinner';
20*6dbdd20aSAndroid Build Coastguard Worker
21*6dbdd20aSAndroid Build Coastguard Workerinterface CommonAttrs extends HTMLAttrs {
22*6dbdd20aSAndroid Build Coastguard Worker  // Use minimal padding, reducing the overall size of the chip by a few px.
23*6dbdd20aSAndroid Build Coastguard Worker  // Defaults to false.
24*6dbdd20aSAndroid Build Coastguard Worker  compact?: boolean;
25*6dbdd20aSAndroid Build Coastguard Worker  // Optional right icon.
26*6dbdd20aSAndroid Build Coastguard Worker  rightIcon?: string;
27*6dbdd20aSAndroid Build Coastguard Worker  // List of space separated class names forwarded to the icon.
28*6dbdd20aSAndroid Build Coastguard Worker  className?: string;
29*6dbdd20aSAndroid Build Coastguard Worker  // Show loading spinner instead of icon.
30*6dbdd20aSAndroid Build Coastguard Worker  // Defaults to false.
31*6dbdd20aSAndroid Build Coastguard Worker  loading?: boolean;
32*6dbdd20aSAndroid Build Coastguard Worker  // Whether to use a filled icon
33*6dbdd20aSAndroid Build Coastguard Worker  // Defaults to false;
34*6dbdd20aSAndroid Build Coastguard Worker  iconFilled?: boolean;
35*6dbdd20aSAndroid Build Coastguard Worker  // Indicate chip colouring by intent.
36*6dbdd20aSAndroid Build Coastguard Worker  // Defaults to undefined aka "None"
37*6dbdd20aSAndroid Build Coastguard Worker  intent?: Intent;
38*6dbdd20aSAndroid Build Coastguard Worker  // Turns the chip into a pill shape.
39*6dbdd20aSAndroid Build Coastguard Worker  rounded?: boolean;
40*6dbdd20aSAndroid Build Coastguard Worker}
41*6dbdd20aSAndroid Build Coastguard Worker
42*6dbdd20aSAndroid Build Coastguard Workerinterface IconChipAttrs extends CommonAttrs {
43*6dbdd20aSAndroid Build Coastguard Worker  // Icon chips require an icon.
44*6dbdd20aSAndroid Build Coastguard Worker  icon: string;
45*6dbdd20aSAndroid Build Coastguard Worker}
46*6dbdd20aSAndroid Build Coastguard Worker
47*6dbdd20aSAndroid Build Coastguard Workerinterface LabelChipAttrs extends CommonAttrs {
48*6dbdd20aSAndroid Build Coastguard Worker  // Label chips require a label.
49*6dbdd20aSAndroid Build Coastguard Worker  label: string;
50*6dbdd20aSAndroid Build Coastguard Worker  // Label chips can have an optional icon.
51*6dbdd20aSAndroid Build Coastguard Worker  icon?: string;
52*6dbdd20aSAndroid Build Coastguard Worker}
53*6dbdd20aSAndroid Build Coastguard Worker
54*6dbdd20aSAndroid Build Coastguard Workerexport type ChipAttrs = LabelChipAttrs | IconChipAttrs;
55*6dbdd20aSAndroid Build Coastguard Worker
56*6dbdd20aSAndroid Build Coastguard Workerexport class Chip implements m.ClassComponent<ChipAttrs> {
57*6dbdd20aSAndroid Build Coastguard Worker  view({attrs}: m.CVnode<ChipAttrs>) {
58*6dbdd20aSAndroid Build Coastguard Worker    const {
59*6dbdd20aSAndroid Build Coastguard Worker      icon,
60*6dbdd20aSAndroid Build Coastguard Worker      compact,
61*6dbdd20aSAndroid Build Coastguard Worker      rightIcon,
62*6dbdd20aSAndroid Build Coastguard Worker      className,
63*6dbdd20aSAndroid Build Coastguard Worker      iconFilled,
64*6dbdd20aSAndroid Build Coastguard Worker      intent = Intent.None,
65*6dbdd20aSAndroid Build Coastguard Worker      rounded,
66*6dbdd20aSAndroid Build Coastguard Worker      ...htmlAttrs
67*6dbdd20aSAndroid Build Coastguard Worker    } = attrs;
68*6dbdd20aSAndroid Build Coastguard Worker
69*6dbdd20aSAndroid Build Coastguard Worker    const label = 'label' in attrs ? attrs.label : undefined;
70*6dbdd20aSAndroid Build Coastguard Worker
71*6dbdd20aSAndroid Build Coastguard Worker    const classes = classNames(
72*6dbdd20aSAndroid Build Coastguard Worker      compact && 'pf-compact',
73*6dbdd20aSAndroid Build Coastguard Worker      classForIntent(intent),
74*6dbdd20aSAndroid Build Coastguard Worker      icon && !label && 'pf-icon-only',
75*6dbdd20aSAndroid Build Coastguard Worker      className,
76*6dbdd20aSAndroid Build Coastguard Worker      rounded && 'pf-rounded',
77*6dbdd20aSAndroid Build Coastguard Worker    );
78*6dbdd20aSAndroid Build Coastguard Worker
79*6dbdd20aSAndroid Build Coastguard Worker    return m(
80*6dbdd20aSAndroid Build Coastguard Worker      '.pf-chip',
81*6dbdd20aSAndroid Build Coastguard Worker      {
82*6dbdd20aSAndroid Build Coastguard Worker        ...htmlAttrs,
83*6dbdd20aSAndroid Build Coastguard Worker        className: classes,
84*6dbdd20aSAndroid Build Coastguard Worker      },
85*6dbdd20aSAndroid Build Coastguard Worker      this.renderIcon(attrs),
86*6dbdd20aSAndroid Build Coastguard Worker      rightIcon &&
87*6dbdd20aSAndroid Build Coastguard Worker        m(Icon, {
88*6dbdd20aSAndroid Build Coastguard Worker          className: 'pf-right-icon',
89*6dbdd20aSAndroid Build Coastguard Worker          icon: rightIcon,
90*6dbdd20aSAndroid Build Coastguard Worker          filled: iconFilled,
91*6dbdd20aSAndroid Build Coastguard Worker        }),
92*6dbdd20aSAndroid Build Coastguard Worker      label || '\u200B', // Zero width space keeps chip in-flow
93*6dbdd20aSAndroid Build Coastguard Worker    );
94*6dbdd20aSAndroid Build Coastguard Worker  }
95*6dbdd20aSAndroid Build Coastguard Worker
96*6dbdd20aSAndroid Build Coastguard Worker  private renderIcon(attrs: ChipAttrs): m.Children {
97*6dbdd20aSAndroid Build Coastguard Worker    const {icon, iconFilled} = attrs;
98*6dbdd20aSAndroid Build Coastguard Worker    const className = 'pf-left-icon';
99*6dbdd20aSAndroid Build Coastguard Worker    if (attrs.loading) {
100*6dbdd20aSAndroid Build Coastguard Worker      return m(Spinner, {className});
101*6dbdd20aSAndroid Build Coastguard Worker    } else if (icon) {
102*6dbdd20aSAndroid Build Coastguard Worker      return m(Icon, {className, icon, filled: iconFilled});
103*6dbdd20aSAndroid Build Coastguard Worker    } else {
104*6dbdd20aSAndroid Build Coastguard Worker      return undefined;
105*6dbdd20aSAndroid Build Coastguard Worker    }
106*6dbdd20aSAndroid Build Coastguard Worker  }
107*6dbdd20aSAndroid Build Coastguard Worker}
108*6dbdd20aSAndroid Build Coastguard Worker
109*6dbdd20aSAndroid Build Coastguard Worker/**
110*6dbdd20aSAndroid Build Coastguard Worker * Space chips out with a little gap between each one.
111*6dbdd20aSAndroid Build Coastguard Worker */
112*6dbdd20aSAndroid Build Coastguard Workerexport class ChipBar implements m.ClassComponent<HTMLAttrs> {
113*6dbdd20aSAndroid Build Coastguard Worker  view({attrs, children}: m.CVnode<HTMLAttrs>): m.Children {
114*6dbdd20aSAndroid Build Coastguard Worker    return m('.pf-chip-bar', attrs, children);
115*6dbdd20aSAndroid Build Coastguard Worker  }
116*6dbdd20aSAndroid Build Coastguard Worker}
117