/
SplitButton.tsx
146 lines (126 loc) · 3.42 KB
/
SplitButton.tsx
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import React from 'react';
import PropTypes from 'prop-types';
import Button, { ButtonType } from './Button';
import ButtonGroup from './ButtonGroup';
import Dropdown from './Dropdown';
import { PropsFromToggle } from './DropdownToggle';
import {
BsPrefixPropsWithChildren,
BsPrefixRefForwardingComponent,
} from './helpers';
export interface SplitButtonProps
extends PropsFromToggle,
BsPrefixPropsWithChildren {
id: string | number;
menuRole?: string;
onClick?: React.MouseEventHandler<this>;
renderMenuOnMount?: boolean;
rootCloseEvent?: 'click' | 'mousedown';
target?: string;
title: React.ReactNode;
toggleLabel?: string;
type?: ButtonType;
}
type SplitButton = BsPrefixRefForwardingComponent<'div', SplitButtonProps>;
const propTypes = {
/**
* An html id attribute for the Toggle button, necessary for assistive technologies, such as screen readers.
* @type {string|number}
* @required
*/
id: PropTypes.any,
/**
* Accessible label for the toggle; the value of `title` if not specified.
*/
toggleLabel: PropTypes.string,
/** An `href` passed to the non-toggle Button */
href: PropTypes.string,
/** An anchor `target` passed to the non-toggle Button */
target: PropTypes.string,
/** An `onClick` handler passed to the non-toggle Button */
onClick: PropTypes.func,
/** The content of the non-toggle Button. */
title: PropTypes.node.isRequired,
/** A `type` passed to the non-toggle Button */
type: PropTypes.string,
/** Disables both Buttons */
disabled: PropTypes.bool,
/** An ARIA accessible role applied to the Menu component. When set to 'menu', The dropdown */
menuRole: PropTypes.string,
/** Whether to render the dropdown menu in the DOM before the first time it is shown */
renderMenuOnMount: PropTypes.bool,
/**
* Which event when fired outside the component will cause it to be closed.
*
* _see [DropdownMenu](#menu-props) for more details_
*/
rootCloseEvent: PropTypes.string,
/** @ignore */
bsPrefix: PropTypes.string,
/** @ignore */
variant: PropTypes.string,
/** @ignore */
size: PropTypes.string,
};
const defaultProps = {
toggleLabel: 'Toggle dropdown',
type: 'button',
};
const SplitButton: SplitButton = React.forwardRef(
(
{
id,
bsPrefix,
size,
variant,
title,
type,
toggleLabel,
children,
onClick,
href,
target,
menuRole,
renderMenuOnMount,
rootCloseEvent,
...props
}: SplitButtonProps,
ref,
) => (
<Dropdown ref={ref} {...props} as={ButtonGroup}>
<Button
size={size}
variant={variant}
disabled={props.disabled}
bsPrefix={bsPrefix}
href={href}
target={target}
onClick={onClick}
type={type}
>
{title}
</Button>
<Dropdown.Toggle
split
id={id ? id.toString() : undefined}
size={size}
variant={variant}
disabled={props.disabled}
childBsPrefix={bsPrefix}
>
<span className="sr-only">{toggleLabel}</span>
</Dropdown.Toggle>
<Dropdown.Menu
role={menuRole}
renderOnMount={renderMenuOnMount}
rootCloseEvent={rootCloseEvent}
>
{children}
</Dropdown.Menu>
</Dropdown>
),
);
SplitButton.propTypes = propTypes;
SplitButton.defaultProps = defaultProps;
SplitButton.displayName = 'SplitButton';
export default SplitButton;