• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2023 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 {classNames} from '../classnames';
17import {Icon} from './icon';
18import {Popup} from './popup';
19
20interface CommonAttrs {
21  // Always show the button as if the "active" pseudo class were applied, which
22  // makes the button look permanently pressed.
23  // Useful for when the button represents some toggleable state, such as
24  // showing/hiding a popup menu.
25  // Defaults to false.
26  active?: boolean;
27  // Use minimal padding, reducing the overall size of the button by a few px.
28  // Defaults to false.
29  compact?: boolean;
30  // Reduces button decorations.
31  // Defaults to false.
32  minimal?: boolean;
33  // Make the button appear greyed out block any interaction with it. No events
34  // will be fired.
35  // Defaults to false.
36  disabled?: boolean;
37  // Optional right icon.
38  rightIcon?: string;
39  // List of space separated class names forwarded to the icon.
40  className?: string;
41  // Allow clicking this button to close parent popups.
42  // Defaults to false.
43  dismissPopup?: boolean;
44  // Remaining attributes forwarded to the underlying HTML <button>.
45  [htmlAttrs: string]: any;
46}
47
48interface IconButtonAttrs extends CommonAttrs {
49  // Icon buttons require an icon.
50  icon: string;
51}
52
53interface LabelButtonAttrs extends CommonAttrs {
54  // Label buttons require a label.
55  label: string;
56  // Label buttons can have an optional icon.
57  icon?: string;
58}
59
60export type ButtonAttrs = LabelButtonAttrs|IconButtonAttrs;
61
62export class Button implements m.ClassComponent<ButtonAttrs> {
63  view({attrs}: m.CVnode<ButtonAttrs>) {
64    const {
65      label,
66      icon,
67      active = false,
68      compact = false,
69      minimal = false,
70      disabled = false,
71      rightIcon,
72      className,
73      dismissPopup = false,
74      ...htmlAttrs
75    } = attrs;
76
77    const classes = classNames(
78        'pf-button',
79        active && 'pf-active',
80        compact && 'pf-compact',
81        minimal && 'pf-minimal',
82        (icon && !label) && 'pf-icon-only',
83        dismissPopup && Popup.DISMISS_POPUP_GROUP_CLASS,
84        className,
85    );
86
87    return m(
88        'button' + (disabled ? '[disabled]' : ''),
89        {
90          class: classes,
91          ...htmlAttrs,
92        },
93        icon && m(Icon, {className: 'pf-left-icon', icon}),
94        rightIcon && m(Icon, {className: 'pf-right-icon', icon: rightIcon}),
95        label || '\u200B',  // Zero width space keeps button in-flow
96    );
97  }
98}
99