summaryrefslogtreecommitdiffstats
path: root/devtools/client/accessibility/components/Button.js
blob: 92cd90a56c7124156703f01e72bca64f859b7144 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

const {
  Component,
} = require("resource://devtools/client/shared/vendor/react.js");
const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.js");
const {
  button,
  span,
} = require("resource://devtools/client/shared/vendor/react-dom-factories.js");

const defaultProps = {
  disabled: false,
  busy: false,
  title: null,
  children: null,
  className: "",
};

/**
 * Button component that handles keyboard in an accessible way. When user
 * uses the mouse to hover/click on the button, there is no focus
 * highlighting. However if the user uses a keyboard to focus on the button,
 * it will have focus highlighting in the form of an outline.
 */
class Button extends Component {
  static get propTypes() {
    return {
      disabled: PropTypes.bool,
      busy: PropTypes.bool,
      title: PropTypes.string,
      children: PropTypes.string,
      className: PropTypes.string,
    };
  }

  static get defaultProps() {
    return defaultProps;
  }

  render() {
    const className = [
      ...this.props.className.split(" "),
      "devtools-button",
    ].join(" ");
    const props = Object.assign({}, this.props, {
      className,
      "aria-busy": this.props.busy.toString(),
      busy: this.props.busy.toString(),
    });

    const classList = ["btn-content"];
    if (this.props.busy) {
      classList.push("devtools-throbber");
    }

    return button(
      props,
      span(
        {
          className: classList.join(" "),
          tabIndex: -1,
        },
        this.props.children
      )
    );
  }
}

function ToggleButton(props) {
  const {
    active,
    busy,
    disabled,
    label,
    className,
    onClick,
    onKeyDown,
    tooltip,
  } = props;
  const classList = [...className.split(" "), "toggle-button"];

  if (active) {
    classList.push("checked");
  }

  if (busy) {
    classList.push("devtools-throbber");
  }

  return button(
    {
      disabled,
      "aria-pressed": active === true,
      "aria-busy": busy,
      className: classList.join(" "),
      onClick,
      onKeyDown,
      title: tooltip,
    },
    label
  );
}

module.exports = {
  Button,
  ToggleButton,
};