+ Pellentesque magna tellus, dapibus vitae placerat nec, + viverra vel mi.{' '} + + Learn More + +
+icon
prop and use the label
prop.
+ */
+ assistiveText?: Partial<{
+ icon?: string;
+ }>;
+ /**
+ * Disables the button and adds disabled styling.
+ */
+ disabled?: boolean;
+ /**
+ * Icon associated with the stateful button. Accepts an `Icon` component
+ */
+ icon?: React.ReactNode;
+ /**
+ * Triggered when focus is removed.
+ */
+ onBlur?: (v: any) => any;
+ /**
+ * Triggered when the button is clicked.
+ */
+ onClick?: (v: any) => any;
+ /**
+ * Triggered when component is focused.
+ */
+ onFocus?: (v: any) => any;
+ /**
+ * Triggered when a key is pressed down
+ */
+ onKeyDown?: (v: any) => any;
+ /**
+ * Triggered when a key is pressed and released
+ */
+ onKeyPress?: (v: any) => any;
+ /**
+ * Triggered when a key is released
+ */
+ onKeyUp?: (v: any) => any;
+ /**
+ * Triggered when a mouse button is pressed down
+ */
+ onMouseDown?: (v: any) => any;
+ /**
+ * Triggered when a mouse arrow hovers
+ */
+ onMouseEnter?: (v: any) => any;
+ /**
+ * If true, button scales to 100% width on small form factors.
+ */
+ responsive?: boolean;
+ /**
+ * Initial label and icon (optional) of button.
+ */
+ stateOne?: Recordvariant='icon'
. For buttons with labels or buttons with labels and icons, pass data to the state props (ie. stateOne={{iconName: 'add', label: 'Join'}}
).
+ * Although not listed in the prop table, all `aria-*` props will be added to the button element if passed in.
+ * If no `aria-*` props are passed in, aria-live='polite'
is used for `icon` and `icon-filled` variants,
+ * and aria-live='assertive'
is used for the remaining variants.
+ */
+ function Component(props: Props): React.ReactElement;
+ export default Component;
+}
diff --git a/components/button-stateful/__docs__/__snapshots__/storybook-stories.storyshot b/components/button-stateful/__docs__/__snapshots__/storybook-stories.storyshot
new file mode 100644
index 0000000000..806e324c02
--- /dev/null
+++ b/components/button-stateful/__docs__/__snapshots__/storybook-stories.storyshot
@@ -0,0 +1,263 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`DOM snapshots SLDSButtonStateful Base 1`] = `
+icon
prop and use the label
prop.
+ */
+ assistiveText: _propTypes.default.shape({
+ icon: _propTypes.default.string
+ }),
+
+ /**
+ * Disables the button and adds disabled styling.
+ */
+ disabled: _propTypes.default.bool,
+
+ /**
+ * Icon associated with the stateful button. Accepts an `Icon` component
+ */
+ icon: _propTypes.default.node,
+
+ /**
+ * Triggered when focus is removed.
+ */
+ onBlur: _propTypes.default.func,
+
+ /**
+ * Triggered when the button is clicked.
+ */
+ onClick: _propTypes.default.func,
+
+ /**
+ * Triggered when component is focused.
+ */
+ onFocus: _propTypes.default.func,
+
+ /**
+ * Triggered when a key is pressed down
+ */
+ onKeyDown: _propTypes.default.func,
+
+ /**
+ * Triggered when a key is pressed and released
+ */
+ onKeyPress: _propTypes.default.func,
+
+ /**
+ * Triggered when a key is released
+ */
+ onKeyUp: _propTypes.default.func,
+
+ /**
+ * Triggered when a mouse button is pressed down
+ */
+ onMouseDown: _propTypes.default.func,
+
+ /**
+ * Triggered when a mouse arrow hovers
+ */
+ onMouseEnter: _propTypes.default.func,
+
+ /**
+ * If true, button scales to 100% width on small form factors.
+ */
+ responsive: _propTypes.default.bool,
+
+ /**
+ * Initial label and icon (optional) of button.
+ */
+ stateOne: _propTypes.default.object,
+
+ /**
+ * Selected label and icon (optional) of button.
+ */
+ stateTwo: _propTypes.default.object,
+
+ /**
+ * Deselect label and icon (optional) of button.
+ */
+ stateThree: _propTypes.default.object,
+
+ /**
+ * Write "-1" if you don't want the user to tab to the button.
+ */
+ tabIndex: _propTypes.default.string,
+
+ /**
+ * Different types of buttons
+ */
+ variant: _propTypes.default.oneOf(['base', 'neutral', 'brand', 'destructive', 'icon', 'icon-filled'])
+}; // i18n
+
+var defaultProps = {
+ assistiveText: {
+ icon: ''
+ },
+ disabled: false,
+ iconSize: 'medium',
+ responsive: false,
+ stateOne: {
+ iconName: 'add',
+ label: 'Follow'
+ },
+ stateTwo: {
+ iconName: 'check',
+ label: 'Following'
+ },
+ stateThree: {
+ iconName: 'close',
+ label: 'Unfollow'
+ }
+};
+/**
+ * The ButtonStateful component is a variant of the Lightning Design System Button component. It is used for buttons that have a state of unselected or selected.
+ * For icon buttons, use variant='icon'
. For buttons with labels or buttons with labels and icons, pass data to the state props (ie. stateOne={{iconName: 'add', label: 'Join'}}
).
+ * Although not listed in the prop table, all `aria-*` props will be added to the button element if passed in.
+ * If no `aria-*` props are passed in, aria-live='polite'
is used for `icon` and `icon-filled` variants,
+ * and aria-live='assertive'
is used for the remaining variants.
+ */
+
+var ButtonStateful = /*#__PURE__*/function (_React$Component) {
+ _inherits(ButtonStateful, _React$Component);
+
+ var _super = _createSuper(ButtonStateful);
+
+ function ButtonStateful(props) {
+ var _this;
+
+ _classCallCheck(this, ButtonStateful);
+
+ _this = _super.call(this, props);
+
+ _defineProperty(_assertThisInitialized(_this), "handleBlur", function (e) {
+ if (_this.props.onBlur) _this.props.onBlur(e);
+ e.currentTarget.blur();
+ });
+
+ _defineProperty(_assertThisInitialized(_this), "handleClick", function (e) {
+ if ((0, _lodash.default)(_this.props.onClick)) _this.props.onClick(e);
+
+ if (typeof _this.props.active !== 'boolean') {
+ _this.setState(function (prevState) {
+ return {
+ active: !prevState.active
+ };
+ });
+ }
+ });
+
+ _this.state = {
+ active: false
+ };
+ (0, _checkProps.default)(_constants.BUTTON_STATEFUL, props, _component.default);
+ return _this;
+ }
+
+ _createClass(ButtonStateful, [{
+ key: "getClassName",
+ value: function getClassName(active) {
+ return (0, _classnames.default)(this.props.className, 'slds-button', {
+ 'slds-button_neutral': this.props.variant !== 'icon' && this.props.variant !== 'icon-filled',
+ 'slds-button_inverse': this.props.variant === 'inverse',
+ 'slds-not-selected': !active,
+ 'slds-is-selected': active,
+ 'slds-max-small-button_stretch': this.props.responsive,
+ 'slds-button_icon-border': this.props.variant === 'icon',
+ 'slds-button_icon-border-filled': this.props.variant === 'icon-filled'
+ });
+ }
+ }, {
+ key: "render",
+ value: function render() {
+ var _this$props = this.props,
+ active = _this$props.active,
+ disabled = _this$props.disabled,
+ icon = _this$props.icon,
+ iconName = _this$props.iconName,
+ iconSize = _this$props.iconSize,
+ id = _this$props.id,
+ onFocus = _this$props.onFocus,
+ onKeyDown = _this$props.onKeyDown,
+ onKeyPress = _this$props.onKeyPress,
+ onKeyUp = _this$props.onKeyUp,
+ onMouseDown = _this$props.onMouseDown,
+ onMouseEnter = _this$props.onMouseEnter,
+ stateOne = _this$props.stateOne,
+ stateTwo = _this$props.stateTwo,
+ stateThree = _this$props.stateThree,
+ tabIndex = _this$props.tabIndex,
+ variant = _this$props.variant;
+ var defaultIconProps = {
+ disabled: disabled,
+ size: 'small',
+ className: 'slds-button__icon_stateful'
+ };
+ var iconAssistiveText = typeof this.props.assistiveText === 'string' ? this.props.assistiveText : _objectSpread(_objectSpread({}, defaultProps.assistiveText), this.props.assistiveText).icon;
+ var isActive = typeof active === 'boolean' ? active : this.state.active; // Accept aria-* props
+
+ var ariaProps = (0, _getAriaProps.default)(this.props);
+
+ if (variant === 'icon' || variant === 'icon-filled') {
+ // Default aria attribute for stateful button with icon, if none is specified
+ if (Object.keys(ariaProps).length === 0) {
+ ariaProps = {
+ 'aria-live': 'polite'
+ };
+ }
+
+ return /*#__PURE__*/_react.default.createElement("button", _extends({}, ariaProps, {
+ className: this.getClassName(isActive),
+ disabled: disabled,
+ id: id,
+ onBlur: this.handleBlur,
+ onClick: this.handleClick,
+ onFocus: onFocus,
+ onKeyDown: onKeyDown,
+ onKeyPress: onKeyPress,
+ onKeyUp: onKeyUp,
+ onMouseDown: onMouseDown,
+ onMouseEnter: onMouseEnter,
+ onMouseLeave: this.handleBlur,
+ tabIndex: tabIndex,
+ type: "button"
+ }), icon ? /*#__PURE__*/_react.default.cloneElement(icon, _objectSpread(_objectSpread({}, defaultIconProps), icon.props)) : /*#__PURE__*/_react.default.createElement(_buttonIcon.default, {
+ disabled: disabled,
+ name: iconName,
+ size: iconSize,
+ className: "slds-button__icon_stateful"
+ }), iconAssistiveText ? /*#__PURE__*/_react.default.createElement("span", {
+ className: "slds-assistive-text"
+ }, iconAssistiveText) : null);
+ }
+
+ defaultIconProps.position = 'left'; // Default aria attribute for stateful button, if none is specified
+
+ if (Object.keys(ariaProps).length === 0) {
+ ariaProps = {
+ 'aria-live': 'assertive'
+ };
+ }
+
+ return /*#__PURE__*/_react.default.createElement("button", _extends({}, ariaProps, {
+ className: this.getClassName(isActive),
+ disabled: disabled,
+ id: id,
+ onBlur: this.handleBlur,
+ onClick: this.handleClick,
+ onFocus: onFocus,
+ onKeyDown: onKeyDown,
+ onKeyPress: onKeyPress,
+ onKeyUp: onKeyUp,
+ onMouseEnter: onMouseEnter,
+ onMouseLeave: this.handleBlur,
+ tabIndex: tabIndex,
+ type: "button"
+ }), /*#__PURE__*/_react.default.createElement("span", {
+ className: "slds-text-not-selected"
+ }, stateOne.icon ? /*#__PURE__*/_react.default.cloneElement(stateOne.icon, _objectSpread(_objectSpread(_objectSpread({}, defaultIconProps), stateOne.icon.props), {}, {
+ size: 'small'
+ })) : /*#__PURE__*/_react.default.createElement(_buttonIcon.default, {
+ disabled: disabled,
+ name: stateOne.iconName,
+ size: "small",
+ position: "left",
+ className: "slds-button__icon_stateful"
+ }), stateOne.label), /*#__PURE__*/_react.default.createElement("span", {
+ className: "slds-text-selected"
+ }, stateTwo.icon ? /*#__PURE__*/_react.default.cloneElement(stateTwo.icon, _objectSpread(_objectSpread(_objectSpread({}, defaultIconProps), stateTwo.icon.props), {}, {
+ size: 'small'
+ })) : /*#__PURE__*/_react.default.createElement(_buttonIcon.default, {
+ disabled: disabled,
+ name: stateTwo.iconName,
+ size: "small",
+ position: "left",
+ className: "slds-button__icon_stateful"
+ }), stateTwo.label), /*#__PURE__*/_react.default.createElement("span", {
+ className: "slds-text-selected-focus"
+ }, stateThree.icon ? /*#__PURE__*/_react.default.cloneElement(stateThree.icon, _objectSpread(_objectSpread(_objectSpread({}, defaultIconProps), stateThree.icon.props), {}, {
+ size: 'small'
+ })) : /*#__PURE__*/_react.default.createElement(_buttonIcon.default, {
+ disabled: disabled,
+ name: stateThree.iconName,
+ size: "small",
+ position: "left",
+ className: "slds-button__icon_stateful"
+ }), stateThree.label));
+ }
+ }]);
+
+ return ButtonStateful;
+}(_react.default.Component);
+
+ButtonStateful.displayName = _constants.BUTTON_STATEFUL;
+ButtonStateful.propTypes = propTypes;
+ButtonStateful.defaultProps = defaultProps;
+var _default = ButtonStateful;
+exports.default = _default;
\ No newline at end of file
diff --git a/components/button.d.ts b/components/button.d.ts
new file mode 100644
index 0000000000..1191560e26
--- /dev/null
+++ b/components/button.d.ts
@@ -0,0 +1,163 @@
+declare module '@salesforce/design-system-react/components/button' {
+ import React from 'react';
+ type Props = {
+ /**
+ * **Assistive text for accessibility.**
+ * This object is merged with the default props object on every render.
+ * * `icon`: Text that is visually hidden but read aloud by screenreaders to tell the user what the icon means. If the button has an icon and a visible label, you can omit the assistiveText.icon
prop and use the label
prop.
+ */
+ assistiveText?: Partial<{
+ icon?: string;
+ }>;
+
+ /**
+ * Callback that passes in the DOM reference of the `