@atlaskit/button
Version:
A button triggers an event or action. They let users know what will happen next.
223 lines (221 loc) • 10.8 kB
JavaScript
/* button-base.tsx generated by @compiled/babel-plugin v0.39.1 */
import _extends from "@babel/runtime/helpers/extends";
import "./button-base.compiled.css";
import { ax, ix } from "@compiled/react/runtime";
import React, { useRef } from 'react';
import { cx } from '@atlaskit/css';
import mergeRefs from '@atlaskit/ds-lib/merge-refs';
import useAutoFocus from '@atlaskit/ds-lib/use-auto-focus';
import { useId } from '@atlaskit/ds-lib/use-id';
import { fg } from '@atlaskit/platform-feature-flags';
import { Pressable } from '@atlaskit/primitives/compiled';
import VisuallyHidden from '@atlaskit/visually-hidden';
import { SplitButtonContext, useSplitButtonContext } from '../../containers/split-button/split-button-context';
import blockEvents from './block-events';
import renderLoadingOverlay from './loading-overlay';
const LOADING_LABEL = ', Loading';
const styles = {
base: "_2rkofajl _11c8fhey _v5649dqc _189eidpf _1rjc12x7 _1e0c116y _vchhusvi _1bsb1wug _p12f1osq _kqswh2mm _4cvr1q9y _1bah1h6o _gy1p1b66 _1o9zidpf _4t3iviql _k48p1wq8 _y4tiutpp _bozgutpp _y3gn1h6o _s7n4nkob _14mj1kw7 _9v7aze3t _1tv3nqa1 _39yqe4h9 _11fnglyw _18postnw",
baseT26Shape: "_2rko1qi0",
linkDecorationUnset: "_4bfu1r31 _1hmsglyw _ajmmnqa1 _1a3b1r31 _4fprglyw _5goinqa1 _9oik1r31 _1bnxglyw _jf4cnqa1 _1nrm1r31 _c2waglyw _1iohnqa1",
disabled: "_80om13gf _syaz1gmx _30l31gmx _9h8h1gmx",
sharedDisabled: "_bfhk1fvb _irr31fvb _1di61fvb",
spacingCompact: "_1rjcv77o _gy1p1b66 _4t3i1k8s _y4tiutpp _bozgutpp _s7n4nkob",
spacingCompactT26Shape: "_2rko12b0",
circle: "_2rko1rr0",
fullWidth: "_1bsb1osq",
loading: "_80om15jw",
iconButton: "_4t3iviql _1bsbviql _y4tize3t _bozgze3t",
iconButtonCompact: "_4t3i1k8s _1bsb1k8s",
buttonIconBeforeWithHack: "_bozgu2gc",
buttonIconAfterWithHack: "_y4tiu2gc",
buttonIconBefore: "_bozgutpp _gy1p12x7",
buttonIconAfter: "_y4tiutpp _gy1p12x7",
splitButton: "_g0pbb4wl",
loadingOverlay: "_1reo15vq _18m915vq _1e0c1txw _kqswstnw _4cvr1h6o _1bah1h6o _u7coze3t _152tze3t _rjxpze3t _1e02ze3t",
navigationSplitButton: "_1bsb1tcg _bfhksm61 _y4ti12x7 _bozg12x7"
};
const defaultStyles = {
root: "_bfhksm61 _syazazsu _8l3m1l7x _aetrb3bt _1053azsu _f8pjazsu _30l3azsu _9h8hazsu",
interactive: "_irr31dpa _30l3azsu _1di6fcek _9h8hazsu",
disabled: "_bfhk1j28 _8l3mbk0g _irr31j28 _1di61j28"
};
const primaryStyles = {
root: "_bfhkomb0 _syaz15cr _105315cr _f8pj15cr _30l315cr _9h8h15cr",
interactive: "_30l315cr _irr31wqm _9h8h15cr _1di617hq"
};
const warningStyles = {
root: "_bfhk1ikc _syazal3n _1053al3n _f8pjal3n _30l3al3n _9h8hal3n",
interactive: "_30l3al3n _irr31j43 _9h8hal3n _1di6h4op"
};
const dangerStyles = {
root: "_bfhk1v7l _syaz15cr _105315cr _f8pj15cr _30l315cr _9h8h15cr",
interactive: "_30l315cr _irr31rwk _9h8h15cr _1di6yycf"
};
const discoveryStyles = {
root: "_bfhk1vbi _syaz15cr _105315cr _f8pj15cr _30l315cr _9h8h15cr",
interactive: "_30l315cr _irr37gr8 _9h8h15cr _1di61wu2"
};
const subtleStyles = {
root: "_bfhkqtfy _syazazsu _1053azsu _f8pjazsu _30l3azsu _9h8hazsu",
interactive: "_irr34mfv _30l3azsu _1di619qy _9h8hazsu",
disabled: "_bfhk1j28 _8l3mbk0g _irr31j28 _1di61j28"
};
const selectedStyles = {
root: "_bfhk15s3 _syaz1ldt _8l3mcoux _aetrb3bt _10531ldt _f8pj1ldt _30l31ldt _9h8h1ldt",
insideSplitButton: "_1pbycs5v",
interactive: "_irr3t71w _30l31pke _1di6yssv _9h8h1pke",
warning: "_bfhkvdtc _syaz16q2 _30l31pke _irr3vdtc _9h8h1pke _1di6vdtc",
danger: "_bfhkbeib _syaz1pke _30l31pke _irr3beib _9h8h1pke _1di6beib",
discovery: "_bfhk1g49 _syaz1pke _30l31pke _irr31g49 _9h8h1pke _1di61g49"
};
/**
* __button base__
*
* - Implements auto focus when enabled.
* - Appends the `onClick` event with UFO analytics tracking.
*
* @private
*/
const ButtonBase = /*#__PURE__*/React.forwardRef(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore: to unblock React 18.2.0 -> 18.3.1 version bump in Jira
({
appearance: propAppearance,
autoFocus = false,
isDisabled: propIsDisabled = false,
isLoading = false,
isSelected: propIsSelected = false,
isIconButton = false,
isCircle = false,
hasIconBefore = false,
hasIconAfter = false,
shouldFitContainer = false,
spacing: propSpacing = 'default',
ariaLabel,
ariaLabelledBy,
children,
interactionName,
onClick,
onMouseDown,
onMouseDownCapture,
onMouseUp,
onMouseUpCapture,
onKeyDown,
onKeyDownCapture,
onKeyUp,
onKeyUpCapture,
onTouchStart,
onTouchStartCapture,
onTouchEnd,
onTouchEndCapture,
onPointerDown,
onPointerDownCapture,
onPointerUp,
onPointerUpCapture,
onClickCapture,
testId,
analyticsContext,
componentName,
role,
onMouseOver,
onMouseOut,
onFocus,
onBlur,
onMouseMove,
type,
...unsafeRest
}, ref) => {
const localRef = useRef(null);
const splitButtonContext = useSplitButtonContext();
const loadingLabelId = useId();
const isSplitButton = Boolean(splitButtonContext);
const isNavigationSplitButton = (splitButtonContext === null || splitButtonContext === void 0 ? void 0 : splitButtonContext.isNavigationSplitButton) || false;
const isDefaultAppearanceSplitButton = (splitButtonContext === null || splitButtonContext === void 0 ? void 0 : splitButtonContext.appearance) === 'default';
const appearance = isDefaultAppearanceSplitButton ? 'subtle' : propAppearance || (splitButtonContext === null || splitButtonContext === void 0 ? void 0 : splitButtonContext.appearance) || 'default';
const spacing = (splitButtonContext === null || splitButtonContext === void 0 ? void 0 : splitButtonContext.spacing) || propSpacing;
const isDisabled = (splitButtonContext === null || splitButtonContext === void 0 ? void 0 : splitButtonContext.isDisabled) || propIsDisabled;
const isInteractive = !isDisabled && !isLoading;
// Also treat loading buttons as disabled
const isEffectivelyDisabled = isDisabled || isLoading;
const isSelected = propIsSelected && !isDisabled;
useAutoFocus(localRef, autoFocus);
// @ts-expect-error
const {
className: _className,
css: _css,
as: _as,
style: _style,
...saferRest
} = unsafeRest;
return /*#__PURE__*/React.createElement(Pressable, _extends({}, saferRest, {
componentName: componentName || 'button',
analyticsContext: analyticsContext,
role: role,
ref: mergeRefs([localRef, ref]),
xcss: cx(styles.base, fg('platform-dst-shape-theme-default') && styles.baseT26Shape, appearance === 'default' && defaultStyles.root, appearance === 'default' && isInteractive && defaultStyles.interactive, appearance === 'primary' && primaryStyles.root, appearance === 'primary' && isInteractive && primaryStyles.interactive, appearance === 'warning' && warningStyles.root, appearance === 'warning' && isInteractive && warningStyles.interactive, appearance === 'danger' && dangerStyles.root, appearance === 'danger' && isInteractive && dangerStyles.interactive, appearance === 'discovery' && discoveryStyles.root, appearance === 'discovery' && isInteractive && discoveryStyles.interactive, appearance === 'subtle' && subtleStyles.root, appearance === 'subtle' && isInteractive && subtleStyles.interactive, styles.linkDecorationUnset, isSelected && selectedStyles.root, isSelected && isSplitButton && selectedStyles.insideSplitButton, isSelected && isInteractive && selectedStyles.interactive,
// TODO: remove me once we kill color fallbacks
isSelected && appearance === 'danger' && selectedStyles.danger,
// TODO: remove me once we kill color fallbacks
isSelected && appearance === 'warning' && selectedStyles.warning,
// TODO: remove me once we kill color fallbacks
isSelected && appearance === 'discovery' && selectedStyles.discovery, isDisabled && styles.disabled, isDisabled && appearance !== 'default' && appearance !== 'subtle' && styles.sharedDisabled, isDisabled && appearance === 'default' && defaultStyles.disabled, isCircle && !isSplitButton && styles.circle, spacing === 'compact' && styles.spacingCompact, spacing === 'compact' && fg('platform-dst-shape-theme-default') && styles.spacingCompactT26Shape, shouldFitContainer && styles.fullWidth, hasIconBefore && !fg('platform-button-icon-spacing-cleanup') && styles.buttonIconBeforeWithHack,
//TODO Remove when platform-button-icon-spacing-cleanup is removed
hasIconAfter && !fg('platform-button-icon-spacing-cleanup') && styles.buttonIconAfterWithHack,
//TODO Remove when platform-button-icon-spacing-cleanup is removed
hasIconBefore && fg('platform-button-icon-spacing-cleanup') && styles.buttonIconBefore,
//to keep when platform-button-icon-spacing-cleanup is removed
hasIconAfter && fg('platform-button-icon-spacing-cleanup') && styles.buttonIconAfter,
//to keep when platform-button-icon-spacing-cleanup is removed
isIconButton && styles.iconButton, isIconButton && spacing === 'compact' && styles.iconButtonCompact, isLoading && styles.loading, isSplitButton && styles.splitButton, isNavigationSplitButton && styles.navigationSplitButton),
isDisabled: fg('platform-dst_fix_not_focusable_loading_button') ? isDisabled : isEffectivelyDisabled
}, fg('platform-dst_fix_not_focusable_loading_button') && {
'aria-live': 'polite'
}, isLoading && fg('platform-dst_fix_not_focusable_loading_button') && {
'aria-disabled': true
}, {
"aria-label": isLoading && ariaLabel && !ariaLabelledBy ? `${ariaLabel} ${LOADING_LABEL}` : ariaLabel,
"aria-labelledby": isLoading && ariaLabelledBy ? `${ariaLabelledBy} ${loadingLabelId}` : ariaLabelledBy,
onClick: onClick
}, blockEvents(isEffectivelyDisabled, {
onMouseDownCapture,
onMouseUpCapture,
onKeyDownCapture,
onKeyUpCapture,
onTouchStartCapture,
onTouchEndCapture,
onPointerDownCapture,
onPointerUpCapture,
onClickCapture
}), {
testId: testId,
onMouseOver: onMouseOver,
onFocus: onFocus,
onMouseMove: onMouseMove,
onBlur: onBlur,
type: type,
interactionName: interactionName,
onMouseDown: onMouseDown,
onMouseUp: onMouseUp,
onKeyDown: onKeyDown,
onMouseOut: onMouseOut,
onKeyUp: onKeyUp,
onTouchStart: onTouchStart,
onTouchEnd: onTouchEnd,
onPointerDown: onPointerDown,
onPointerUp: onPointerUp
}), /*#__PURE__*/React.createElement(SplitButtonContext.Provider, {
value: undefined
}, children, isLoading && /*#__PURE__*/React.createElement("span", {
className: ax([styles.loadingOverlay])
}, renderLoadingOverlay({
spacing: spacing,
appearance: appearance,
isDisabled: isDisabled,
isSelected: isSelected,
testId
})), isLoading && (ariaLabelledBy || !ariaLabel) && /*#__PURE__*/React.createElement(VisuallyHidden, {
id: loadingLabelId
}, LOADING_LABEL)));
});
export default ButtonBase;