UNPKG

@atlaskit/button

Version:

A button triggers an event or action. They let users know what will happen next.

349 lines (347 loc) 11.1 kB
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766 import { fg } from '@atlaskit/platform-feature-flags/fg'; const gridSize = 8; const HAS_DISABLED_BACKGROUND = ['default', 'primary', 'danger', 'warning']; const heights = { default: `${32 / 14}em`, // 32px compact: `${24 / 14}em`, none: 'auto' }; const lineHeights = { default: heights.default, compact: heights.compact, none: 'inherit' }; const padding = { // 10px gutter default: `0 ${gridSize + gridSize / 4}px`, compact: `0 ${gridSize + gridSize / 4}px`, none: '0' }; const singleIconPadding = { // 2px gutter compact: `0 ${gridSize / 4}px`, default: `0 ${gridSize / 4}px`, none: '0' }; const verticalAlign = { default: 'middle', compact: 'middle', none: 'baseline' }; const defaultAfterStyles = { borderRadius: 'inherit', inset: "var(--ds-space-0, 0px)", borderStyle: 'solid', borderWidth: "var(--ds-border-width, 1px)", pointerEvents: 'none', position: 'absolute' }; const defaultStyles = { background: "var(--ds-background-neutral-subtle, #00000000)", color: "var(--ds-text, #292A2E)", '&::after': { ...defaultAfterStyles, content: '""', borderColor: "var(--ds-border, #0B120E24)" }, '&:hover': { background: "var(--ds-background-neutral-hovered, #0B120E24)" }, '&:active': { background: "var(--ds-background-neutral-pressed, #080F214A)" }, '&[data-has-overlay="true"]:not([disabled]):hover': { background: "var(--ds-background-neutral-subtle, #00000000)" }, '&:disabled[disabled]': { background: "var(--ds-background-neutral-subtle, #00000000)" }, '&:disabled[disabled]:hover': { background: "var(--ds-background-neutral-subtle, #00000000)" }, '&:disabled[disabled]:active': { background: "var(--ds-background-neutral-subtle, #00000000)" } }; const primaryStyles = { background: "var(--ds-background-brand-bold, #1868DB)", color: "var(--ds-text-inverse, #FFFFFF)", '&:hover': { background: "var(--ds-background-brand-bold-hovered, #1558BC)" }, '&:active': { background: "var(--ds-background-brand-bold-pressed, #144794)" }, '&[data-has-overlay="true"]:not([disabled]):hover': { background: "var(--ds-background-brand-bold, #1868DB)" } }; const linkStyles = { background: 'transparent', color: "var(--ds-link, #1868DB)", '&:hover': { color: "var(--ds-link, #1868DB)", textDecoration: 'underline' }, '&:active': { color: "var(--ds-link-pressed, #1558BC)", textDecoration: 'underline' } }; const subtleStyles = { background: 'transparent', color: "var(--ds-text-subtle, #505258)", '&:hover': { background: "var(--ds-background-neutral-subtle-hovered, #0515240F)" }, '&:active': { background: "var(--ds-background-neutral-subtle-pressed, #0B120E24)" }, '&[data-has-overlay="true"]:not([disabled]):hover': { background: 'transparent' } }; const subtleLinkStyles = { background: 'transparent', color: "var(--ds-text-subtle, #505258)", '&:hover': { background: 'transparent', color: "var(--ds-text-subtle, #505258)", textDecoration: 'underline' }, '&:active': { background: 'transparent', color: "var(--ds-text, #292A2E)", textDecoration: 'underline' } }; const warningStyles = { background: "var(--ds-background-warning-bold, #FBC828)", color: "var(--ds-text-warning-inverse, #292A2E)", '&:hover': { background: "var(--ds-background-warning-bold-hovered, #FCA700)" }, '&:active': { background: "var(--ds-background-warning-bold-pressed, #F68909)" }, '&[data-has-overlay="true"]:not([disabled]):hover': { background: "var(--ds-background-warning-bold, #FBC828)" } }; const dangerStyles = { background: "var(--ds-background-danger-bold, #C9372C)", color: "var(--ds-text-inverse, #FFFFFF)", '&:hover': { background: "var(--ds-background-danger-bold-hovered, #AE2E24)" }, '&:active': { background: "var(--ds-background-danger-bold-pressed, #872821)" }, '&[data-has-overlay="true"]:not([disabled]):hover': { background: "var(--ds-background-danger-bold, #C9372C)" } }; const selectedStyles = { background: "var(--ds-background-selected, #E9F2FE)", color: "var(--ds-text-selected, #1868DB)", '&:not([disabled])::after': { ...defaultAfterStyles, content: '""', borderColor: "var(--ds-border-selected, #1868DB)" } }; /** * Anchor-text-color variants applied when the legacy `Button` is rendered as * an `<a>` (via `href`). Each `<variant>WithAnchorTextColorStyles` is a * self-contained appearance object that adds explicit `color` / * `text-decoration` on the base, `:hover`, and `:active` states, preventing * browser default or ambient anchor styles from overriding the button's * intended text color or adding an unwanted underline. * * Gated by `platform-dst-legacy-button-anchor-text-color` and used *instead* * of the base `<variant>Styles`. When cleaning up the gate: delete the base * `<variant>Styles` and rename the `WithAnchorTextColor` variant to replace * it. * * Link-like variants (`link`, `subtle-link`) keep their intentional underline * on `:hover` / `:active`. */ const defaultWithAnchorTextColorStyles = { ...defaultStyles, textDecoration: 'none', '&:hover': { ...defaultStyles['&:hover'], color: "var(--ds-text, #292A2E)", textDecoration: 'none' }, '&:active': { ...defaultStyles['&:active'], color: "var(--ds-text, #292A2E)", textDecoration: 'none' } }; const primaryWithAnchorTextColorStyles = { ...primaryStyles, textDecoration: 'none', '&:hover': { ...primaryStyles['&:hover'], color: "var(--ds-text-inverse, #FFFFFF)", textDecoration: 'none' }, '&:active': { ...primaryStyles['&:active'], color: "var(--ds-text-inverse, #FFFFFF)", textDecoration: 'none' } }; const linkWithAnchorTextColorStyles = { ...linkStyles, textDecoration: 'none' }; const subtleWithAnchorTextColorStyles = { ...subtleStyles, textDecoration: 'none', '&:hover': { ...subtleStyles['&:hover'], color: "var(--ds-text-subtle, #505258)", textDecoration: 'none' }, '&:active': { ...subtleStyles['&:active'], color: "var(--ds-text-subtle, #505258)", textDecoration: 'none' } }; const subtleLinkWithAnchorTextColorStyles = { ...subtleLinkStyles, textDecoration: 'none' }; const warningWithAnchorTextColorStyles = { ...warningStyles, textDecoration: 'none', '&:hover': { ...warningStyles['&:hover'], color: "var(--ds-text-warning-inverse, #292A2E)", textDecoration: 'none' }, '&:active': { ...warningStyles['&:active'], color: "var(--ds-text-warning-inverse, #292A2E)", textDecoration: 'none' } }; const dangerWithAnchorTextColorStyles = { ...dangerStyles, textDecoration: 'none', '&:hover': { ...dangerStyles['&:hover'], color: "var(--ds-text-inverse, #FFFFFF)", textDecoration: 'none' }, '&:active': { ...dangerStyles['&:active'], color: "var(--ds-text-inverse, #FFFFFF)", textDecoration: 'none' } }; const hasOverlayStyles = { '&[data-has-overlay="true"]': { cursor: 'default', textDecoration: 'none' } }; export function getCss({ appearance, spacing, isSelected, shouldFitContainer, isOnlySingleIcon }) { const baseAppearanceStyles = fg('platform-dst-legacy-button-anchor-text-color') ? { ...(appearance === 'default' && defaultWithAnchorTextColorStyles), ...(appearance === 'primary' && primaryWithAnchorTextColorStyles), ...(appearance === 'link' && linkWithAnchorTextColorStyles), ...(appearance === 'subtle' && subtleWithAnchorTextColorStyles), ...(appearance === 'subtle-link' && subtleLinkWithAnchorTextColorStyles), ...(appearance === 'warning' && warningWithAnchorTextColorStyles), ...(appearance === 'danger' && dangerWithAnchorTextColorStyles) } : { ...(appearance === 'default' && defaultStyles), ...(appearance === 'primary' && primaryStyles), ...(appearance === 'link' && linkStyles), ...(appearance === 'subtle' && subtleStyles), ...(appearance === 'subtle-link' && subtleLinkStyles), ...(appearance === 'warning' && warningStyles), ...(appearance === 'danger' && dangerStyles) }; const appearanceStyles = appearance === 'default' && fg('platform-dst-tokens-finesse') ? { ...baseAppearanceStyles, '&:hover': { ...baseAppearanceStyles['&:hover'], background: "var(--ds-background-neutral-subtle-hovered, #0515240F)" }, '&:active': { ...baseAppearanceStyles['&:active'], background: "var(--ds-background-neutral-subtle-pressed, #0B120E24)" } } : baseAppearanceStyles; const activeStyles = appearanceStyles['&:active']; return { // 0px margin added to css-reset alignItems: 'baseline', borderWidth: 0, borderRadius: "var(--ds-radius-medium, 6px)", boxSizing: 'border-box', display: 'inline-flex', fontSize: 'inherit', fontStyle: 'normal', // Chrome recently changed button so that they use 'arial' as the font family fontFamily: 'inherit', fontWeight: "var(--ds-font-weight-medium, 500)", // margin for button has been applied to css reset maxWidth: '100%', // Needed to position overlay position: 'relative', textAlign: 'center', textDecoration: 'none', transition: fg('platform-dst-motion-uplift-button') ? `${"var(--ds-button-hovered, background-color border-color 150ms cubic-bezier(0.4, 1, 0.6, 1))"}, box-shadow 0.15s cubic-bezier(0.47, 0.03, 0.49, 1.38)` : 'background 0.1s ease-out, box-shadow 0.15s cubic-bezier(0.47, 0.03, 0.49, 1.38)', whiteSpace: 'nowrap', cursor: 'pointer', height: heights[spacing], lineHeight: lineHeights[spacing], padding: isOnlySingleIcon ? singleIconPadding[spacing] : padding[spacing], verticalAlign: verticalAlign[spacing], width: shouldFitContainer ? '100%' : 'auto', // justifyContent required for shouldFitContainer buttons with an icon inside justifyContent: 'center', ...(isSelected ? selectedStyles : { ...appearanceStyles, ...(activeStyles && fg('platform-dst-motion-uplift-button') && { '&:active': { ...activeStyles, transition: "var(--ds-button-pressed, background-color border-color 150ms cubic-bezier(0.4, 1, 0.6, 1))" } }), '&[disabled]': { color: "var(--ds-text-disabled, #080F214A)", backgroundColor: HAS_DISABLED_BACKGROUND.includes(appearance) ? "var(--ds-background-disabled, #0515240F)" : 'transparent', cursor: 'not-allowed', textDecoration: 'none', '&:hovered': { backgroundColor: HAS_DISABLED_BACKGROUND.includes(appearance) ? "var(--ds-background-disabled, #0515240F)" : 'transparent' }, '&:active': { backgroundColor: HAS_DISABLED_BACKGROUND.includes(appearance) ? "var(--ds-background-disabled, #0515240F)" : 'transparent' } }, ...hasOverlayStyles }), '&::-moz-focus-inner': { border: 0, margin: 0, padding: 0 } }; }