diff --git a/.storybook/image-snapshots/expected/components_Button_Outline Buttons.png b/.storybook/image-snapshots/expected/components_Button_Outline Buttons.png index 80eae3bd4..c2fbdc9e3 100644 Binary files a/.storybook/image-snapshots/expected/components_Button_Outline Buttons.png and b/.storybook/image-snapshots/expected/components_Button_Outline Buttons.png differ diff --git a/.storybook/image-snapshots/expected/components_Button_Solid Buttons.png b/.storybook/image-snapshots/expected/components_Button_Solid Buttons.png index cacb314bd..4dfe176ec 100644 Binary files a/.storybook/image-snapshots/expected/components_Button_Solid Buttons.png and b/.storybook/image-snapshots/expected/components_Button_Solid Buttons.png differ diff --git a/.storybook/image-snapshots/expected/components_Button_Text Buttons.png b/.storybook/image-snapshots/expected/components_Button_Text Buttons.png index 6c6e5575e..8273097c9 100644 Binary files a/.storybook/image-snapshots/expected/components_Button_Text Buttons.png and b/.storybook/image-snapshots/expected/components_Button_Text Buttons.png differ diff --git a/.storybook/image-snapshots/expected/components_Datatable_internalComponents_ControlsModule_ControlButton_Default.png b/.storybook/image-snapshots/expected/components_Datatable_internalComponents_ControlsModule_ControlButton_Default.png index 265034d20..a1bb60b47 100644 Binary files a/.storybook/image-snapshots/expected/components_Datatable_internalComponents_ControlsModule_ControlButton_Default.png and b/.storybook/image-snapshots/expected/components_Datatable_internalComponents_ControlsModule_ControlButton_Default.png differ diff --git a/.storybook/image-snapshots/expected/components_SingleDatePicker_Open Datepicker.png b/.storybook/image-snapshots/expected/components_SingleDatePicker_Open Datepicker.png index 1840d3099..a22029b72 100644 Binary files a/.storybook/image-snapshots/expected/components_SingleDatePicker_Open Datepicker.png and b/.storybook/image-snapshots/expected/components_SingleDatePicker_Open Datepicker.png differ diff --git a/src/components/Accordion/AccordionCollapsible.tsx b/src/components/Accordion/AccordionCollapsible.tsx index 816f2d42f..9e2efd5ba 100644 --- a/src/components/Accordion/AccordionCollapsible.tsx +++ b/src/components/Accordion/AccordionCollapsible.tsx @@ -29,13 +29,6 @@ const Header = styled(Padbox)` &:hover { background-color: rgb(0 0 0 / 4%); } - - &:focus-visible { - position: relative; - z-index: 1; - outline: 4px solid ${getColor('primary.200')}; - border-radius: 4px; - } `; const Content = styled.div` diff --git a/src/components/Button/Button.stories.tsx b/src/components/Button/Button.stories.tsx index e28334773..942c43a70 100644 --- a/src/components/Button/Button.stories.tsx +++ b/src/components/Button/Button.stories.tsx @@ -54,9 +54,6 @@ export const SolidButtons: Story = () => ( - @@ -71,9 +68,6 @@ export const SolidButtons: Story = () => ( - @@ -88,9 +82,6 @@ export const SolidButtons: Story = () => ( - @@ -110,9 +101,6 @@ export const OutlineButtons: Story = () => ( - @@ -127,9 +115,6 @@ export const OutlineButtons: Story = () => ( - @@ -144,9 +129,6 @@ export const OutlineButtons: Story = () => ( - @@ -166,9 +148,6 @@ export const TextButtons: Story = () => ( - @@ -183,9 +162,6 @@ export const TextButtons: Story = () => ( - @@ -200,9 +176,6 @@ export const TextButtons: Story = () => ( - @@ -217,9 +190,6 @@ export const TextButtons: Story = () => ( - diff --git a/src/components/Card/Card.tsx b/src/components/Card/Card.tsx index c6d7a57ba..58a40a724 100644 --- a/src/components/Card/Card.tsx +++ b/src/components/Card/Card.tsx @@ -5,7 +5,7 @@ import { pipe, prop } from 'ramda'; import cls from 'classnames'; import { Padbox, Stack } from '../layout'; -import { getColor, getRadii, getShadow, getSpace, getToken } from '../../utils'; +import { getColor, getRadii, getShadow, getSpace } from '../../utils'; import { SpaceSize } from '../../theme/space.types'; import { CardProps, CardWrapperProps } from './Card.types'; import { CLX_COMPONENT } from '../../theme/constants'; @@ -17,12 +17,6 @@ const InteractiveCard = css` &:hover { box-shadow: 0px 10px 16px rgba(0, 0, 0, 0.07); } - &:focus-visible { - outline: 0; - box-shadow: 0px 10px 16px rgba(0, 0, 0, 0.07), - inset 0 0 0 1px ${getToken('color-action-primary')}; - border-color: ${getToken('color-action-primary')}; - } &:active { box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, 0.07); } diff --git a/src/components/Card/CardHeader.tsx b/src/components/Card/CardHeader.tsx index d8f299340..b1357b20f 100644 --- a/src/components/Card/CardHeader.tsx +++ b/src/components/Card/CardHeader.tsx @@ -34,13 +34,9 @@ export const CardIconButton = styled.button<{ props.as !== 'div' && css` cursor: pointer; - &:hover, - &:focus-visible { + &:hover { background-color: ${getColor('primary.50')}; } - &:focus { - outline: none; - } `} `; export const CardIconWrapper = styled(Padbox)` @@ -86,7 +82,6 @@ const StyledIcon = styled(Icon).withConfig<{ color: Color }>({ border-radius: 100%; color: ${({ color, theme }) => isNotUndefined(color) ? getColor(color, { theme }) : 'inherit'}; - &:focus-visible, &:hover { color: ${({ theme }) => getColor('neutral.700', { theme })}; } diff --git a/src/components/CloseButton/CloseButton.tsx b/src/components/CloseButton/CloseButton.tsx index 72ee14aa2..affbb49a2 100644 --- a/src/components/CloseButton/CloseButton.tsx +++ b/src/components/CloseButton/CloseButton.tsx @@ -41,12 +41,9 @@ const CloseButtonWrapper = styled.button` padding: ${getSpace(SpaceSizes.sm)}; color: ${({ $isInverted, theme }) => getColor($isInverted ? 'neutral.0' : 'neutral.1000', { theme })}; + outline-offset: ${getNegativeSpace(SpaceSizes.sm)}; - &:hover - ${/* sc-selector */ IconWrapper}, - &:focus - ${/* sc-selector */ IconWrapper} { - outline: none; + &:hover ${/* sc-selector */ IconWrapper} { background-color: ${(props) => transparentize(0.96, getColor('neutral.1000', props))}; } diff --git a/src/components/Collapsible/Collapsible.tsx b/src/components/Collapsible/Collapsible.tsx index 2d4355cc2..f48aaccda 100644 --- a/src/components/Collapsible/Collapsible.tsx +++ b/src/components/Collapsible/Collapsible.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import PropTypes from 'prop-types'; -import styled from 'styled-components'; +import styled, { css } from 'styled-components'; import { includes } from 'ramda'; import cls from 'classnames'; @@ -19,17 +19,17 @@ import { CLX_COMPONENT } from '../../theme/constants'; const Header = styled(Padbox)` width: 100%; cursor: pointer; + border-radius: ${getRadii('default')}; + ${({ $isOpen }) => + $isOpen && + css` + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + `} &:hover { background-color: rgb(0 0 0 / 4%); } - - &:focus-visible { - position: relative; - z-index: 1; - outline: 4px solid ${getColor('primary.200')}; - border-radius: ${getRadii('default')}; - } `; const HeaderContent = styled.div` @@ -73,6 +73,7 @@ const Collapsible: React.FC = ({ return (
= (args) => ( - Dropdown handler + + + ); Default.args = { diff --git a/src/components/HintTooltip/HintTooltip.tsx b/src/components/HintTooltip/HintTooltip.tsx index c2e2ed3f7..273877eb3 100644 --- a/src/components/HintTooltip/HintTooltip.tsx +++ b/src/components/HintTooltip/HintTooltip.tsx @@ -19,7 +19,6 @@ const StyledIcon = styled(Icon).withConfig<{ color: Color }>({ border-radius: 100%; color: ${({ color, theme }) => isNotUndefined(color) ? getColor(color, { theme }) : 'inherit'}; - &:focus-visible, &:hover { color: ${({ theme }) => getColor('neutral.700', { theme })}; } diff --git a/src/components/Pagination/PaginationItem.tsx b/src/components/Pagination/PaginationItem.tsx index 13a93b583..5c5ed4403 100644 --- a/src/components/Pagination/PaginationItem.tsx +++ b/src/components/Pagination/PaginationItem.tsx @@ -39,9 +39,6 @@ const StyledPaginationComponent = styled.button<{ &:last-of-type { margin-right: 0; } - &:focus { - outline: none; - } &:disabled { color: ${getColor('neutral.600')}; cursor: default; diff --git a/src/components/Pill/PillRemoveButton.tsx b/src/components/Pill/PillRemoveButton.tsx index 6f0f9a675..bf58c515f 100644 --- a/src/components/Pill/PillRemoveButton.tsx +++ b/src/components/Pill/PillRemoveButton.tsx @@ -23,7 +23,7 @@ const PillRemoveButtonWrapper = styled.button` border-radius: ${getRadii('circle')}; &:hover, - &:focus { + &:focus-visible { color: ${getColor('neutral.0')}; background-color: ${getColor('error.500')}; } diff --git a/src/components/Pill/PillWrapper.tsx b/src/components/Pill/PillWrapper.tsx index ca21bae3b..51e5ecff5 100644 --- a/src/components/Pill/PillWrapper.tsx +++ b/src/components/Pill/PillWrapper.tsx @@ -22,10 +22,8 @@ const StyledPillWrapper = styled(Padbox)` $isClickable && css` cursor: pointer; - &:hover, - &:focus { + &:hover { background-color: ${PillColors[$color][1]}; - outline: none; } `} `; diff --git a/src/components/Stepper/Step.tsx b/src/components/Stepper/Step.tsx index 2feb8b925..212a977fd 100644 --- a/src/components/Stepper/Step.tsx +++ b/src/components/Stepper/Step.tsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import styled, { css } from 'styled-components'; import { isNotUndefined } from 'ramda-adjunct'; -import { getColor, getSpace, pxToRem } from '../../utils'; +import { getColor, getRadii, getSpace, pxToRem } from '../../utils'; import { SpaceSizes } from '../../theme'; import { Text } from '../typographyLegacy/Text'; import { TextSizes, TextVariants } from '../typographyLegacy/Text/Text.enums'; @@ -25,18 +25,14 @@ const StepSummary = styled(Text)` const StepButton = styled.button` border: 0 none; background: transparent none; + border-radius: ${getRadii('default')}; &:hover { cursor: pointer; - } - &:focus { - outline: 0; - } - &:hover - ${/* sc-selector */ BulletCircle}, - &:focus + ${/* sc-selector */ BulletCircle} { - fill: ${getColor('primary.50')}; + fill: ${getColor('primary.50')}; + } } `; diff --git a/src/components/UserAvatar/UserAvatar.tsx b/src/components/UserAvatar/UserAvatar.tsx index db5249b0c..50179d2d7 100644 --- a/src/components/UserAvatar/UserAvatar.tsx +++ b/src/components/UserAvatar/UserAvatar.tsx @@ -41,10 +41,6 @@ const invertedAvatar = css` background-color: ${getColor('primary.50')}; color: ${getColor('neutral.900')}; } - &:focus { - background-color: ${getColor('neutral.0')}; - color: ${getColor('neutral.900')}; - } &:active { background-color: ${getColor('primary.200')}; color: ${getColor('neutral.900')}; diff --git a/src/components/_internal/BaseButton/BaseStyledButton.tsx b/src/components/_internal/BaseButton/BaseStyledButton.tsx index ef6af1689..8f9f8829e 100644 --- a/src/components/_internal/BaseButton/BaseStyledButton.tsx +++ b/src/components/_internal/BaseButton/BaseStyledButton.tsx @@ -12,7 +12,6 @@ import { import { BaseStyledButtonProps } from './BaseButton.types'; import { BaseButtonVariants } from './BaseButton.enums'; import { Padbox } from '../../layout'; -import { ButtonColors } from '../../Button/Button.enums'; /* * BUTTON VARIANTS @@ -28,11 +27,6 @@ const ButtonSolid = css` color: ${getToken(`color-action-text-solid`)}; background-color: ${(p) => getToken(`color-action-${p.$color}-hover`, p)}; } - &:focus-visible, - &.focus { - background-color: ${(p) => getToken(`color-action-${p.$color}-hover`, p)}; - outline: 4px solid ${(p) => getToken(`color-action-${p.$color}-focus`, p)}; - } &:disabled, &.disabled { @@ -53,12 +47,6 @@ const ButtonOutline = css` color: ${(p) => getToken(`color-action-${p.$color}-hover`, p)}; border-color: ${(p) => getToken(`color-action-${p.$color}-hover`, p)}; } - &:focus-visible, - &.focus { - color: ${(p) => getToken(`color-action-${p.$color}-hover`, p)}; - border-color: ${(p) => getToken(`color-action-${p.$color}-hover`, p)}; - outline: 4px solid ${(p) => getToken(`color-action-${p.$color}-focus`, p)}; - } &:disabled, &.disabled { @@ -67,34 +55,19 @@ const ButtonOutline = css` } `; -const isLinkLike = (color) => - color === ButtonColors.primary || color === ButtonColors.secondary - ? 'link-' - : ''; const ButtonText = css` background-color: transparent; border-color: transparent; padding-left: 0; padding-right: 0; font-weight: ${getFontWeight('semibold')}; - color: ${(p) => - getToken(`color-action-${isLinkLike(p.$color)}${p.$color}`, p)}; + color: ${(p) => getToken(`color-action-${p.$color}`, p)}; &:hover, &.hover { - color: ${(p) => - getToken(`color-action-${isLinkLike(p.$color)}${p.$color}-hover`, p)}; - } - &:focus-visible, - &.focus { - background-color: ${(p) => - getToken( - `color-action-${isLinkLike(p.$color)}background-${p.$color}-focus`, - p, - )}; - color: ${(p) => - getToken(`color-action-${isLinkLike(p.$color)}${p.$color}-hover`, p)}; - outline: none; + color: ${(p) => getToken(`color-action-${p.$color}-hover`, p)}; + background: ${(p) => + getToken(`color-action-background-${p.$color}-focus`, p)}; } &:disabled, @@ -139,9 +112,7 @@ const BaseStyledButton = styled(Padbox).withConfig({ css` width: ${pipe(getToken('size-action-size'), pxToRem)}; `}; - &:focus { - outline: 0; - } + ${({ $variant }) => buttonVariants[$variant]}; &, diff --git a/src/components/_internal/BaseDropdownMenu/DropdownMenu.tsx b/src/components/_internal/BaseDropdownMenu/DropdownMenu.tsx index 5a7a676fd..3d7c93a60 100644 --- a/src/components/_internal/BaseDropdownMenu/DropdownMenu.tsx +++ b/src/components/_internal/BaseDropdownMenu/DropdownMenu.tsx @@ -41,9 +41,8 @@ export const DropdownLink = styled(Padbox).withConfig({ text-align: left; &:hover, - &:focus { + &:focus-visible { background: ${getColor('primary.50')}; - outline: none; } `; diff --git a/src/components/_internal/BaseLink/BaseLink.ts b/src/components/_internal/BaseLink/BaseLink.ts index d3a9f17b3..871781924 100644 --- a/src/components/_internal/BaseLink/BaseLink.ts +++ b/src/components/_internal/BaseLink/BaseLink.ts @@ -14,18 +14,11 @@ export const LinkBaseStyles = css` white-space: nowrap; cursor: pointer; color: ${(p) => getToken(`color-action-link-${p.$color}`, p)}; + border-radius: ${getRadii('default')}; `; export const LinkHoverStyles = css` - color: ${(p) => getToken(`color-action-link-${p.$color}-hover`, p)}; - text-decoration: underline; -`; -export const LinkFocusStyles = css` - outline: 0; - color: ${(p) => getToken(`color-action-link-${p.$color}-hover`, p)}; + color: ${(p) => getToken(`color-action-${p.$color}-hover`, p)}; text-decoration: underline; - background-color: ${(p) => - getToken(`color-action-link-background-${p.$color}-focus`, p)}; - border-radius: ${getRadii('default')}; `; export const LinkActiveStyles = css` color: ${(p) => getToken(`color-action-link-${p.$color}-active`, p)}; diff --git a/src/components/_internal/BaseSingleDatePicker/styles.ts b/src/components/_internal/BaseSingleDatePicker/styles.ts index 2ffc89cdc..57ff613ed 100644 --- a/src/components/_internal/BaseSingleDatePicker/styles.ts +++ b/src/components/_internal/BaseSingleDatePicker/styles.ts @@ -90,20 +90,6 @@ export const datePickerStyles = css` font-weight: ${getFontWeight('bold')}; color: ${getColor('neutral.0')}; } - .react-datepicker__day:focus-visible { - background-color: ${getColor('primary.600')}; - border-radius: 4px; - font-weight: ${getFontWeight('bold')}; - color: ${getColor('neutral.0')}; - outline: 2px solid ${getColor('primary.200')}; - outline-offset: 2px; - position: relative; - } - .react-datepicker__day--in-range:focus-visible { - outline: 2px solid ${getColor('primary.200')}; - outline-offset: 2px; - position: relative; - } .react-datepicker__navigation { top: ${pxToRem(36)}; background: none; @@ -235,14 +221,6 @@ export const singleDatePickerStyles = css` color: ${getColor('neutral.0')}; border-radius: ${getRadii('default')}; } - .react-datepicker__day--range-start:focus-visible, - .react-datepicker__day--range-end:focus-visible, - .react-datepicker__day--selected:focus-visible { - background-color: ${getColor('primary.600')}; - outline: 2px solid ${getColor('primary.200')}; - outline-offset: 2px; - position: relative; - } .react-datepicker__year-wrapper { width: 224px; display: flex; diff --git a/src/components/_internal/BaseTable/BaseTable.styles.tsx b/src/components/_internal/BaseTable/BaseTable.styles.tsx index 476a1a5a8..b92b73bc9 100644 --- a/src/components/_internal/BaseTable/BaseTable.styles.tsx +++ b/src/components/_internal/BaseTable/BaseTable.styles.tsx @@ -12,12 +12,7 @@ import { getToken, pxToRem, } from '../../../utils'; -import { - LinkActiveStyles, - LinkBaseStyles, - LinkFocusStyles, - LinkHoverStyles, -} from '../BaseLink'; +import { LinkActiveStyles, LinkBaseStyles, LinkHoverStyles } from '../BaseLink'; const getRemToggleSize = memoizeWith( identity, @@ -44,11 +39,6 @@ export const BaseTableContainer = styled.div` background-color: ${getColor('neutral.300')}; border: 6px solid ${getColor('neutral.0')}; } - &:focus-visible { - outline-color: ${getColor('primary.500')}; - outline-style: solid; - outline-width: 2px; - } `; const DsLinkCell = css` @@ -58,10 +48,6 @@ const DsLinkCell = css` ${LinkHoverStyles}; } - &:focus-visible { - ${LinkFocusStyles}; - } - &:active { ${LinkActiveStyles}; } @@ -73,10 +59,6 @@ const DsLinkCell = css` &:hover { color: ${getToken(`link-color-text-secondary-hover`)}; } - &:focus-visible { - color: ${getToken(`link-color-text-secondary-hover`)}; - background-color: ${getToken(`link-color-background-secondary-focus`)}; - } &:active { color: ${getToken(`link-color-text-secondary-active`)}; } @@ -104,10 +86,6 @@ export const StyledBaseTable = styled.table.attrs({ $color: 'primary' })` background: ${getColor('neutral.0')}; padding: ${pxToRem(12, 8)}; - &:focus { - outline: none; - } - &.is-sticky { justify-content: center; flex: 0 0 auto; @@ -147,7 +125,6 @@ export const StyledBaseTable = styled.table.attrs({ $color: 'primary' })` color: ${getColor('neutral.900')}; &:hover, - &:focus-visible, &:active { background-color: ${getColor('primary.50')}; color: ${getColor('neutral.900')}; diff --git a/src/components/_internal/BaseTabs/BaseTabLabel.tsx b/src/components/_internal/BaseTabs/BaseTabLabel.tsx index 98e4da1ab..426185543 100644 --- a/src/components/_internal/BaseTabs/BaseTabLabel.tsx +++ b/src/components/_internal/BaseTabs/BaseTabLabel.tsx @@ -33,16 +33,6 @@ const underlineTab = css` ? setLightness(0.85, getColor($color, { theme })) : getToken('color-action-primary-focus')}; } - - &:focus-visible { - border-bottom-color: ${({ $color }) => - $color ? getColor($color) : getToken('color-action-primary')}; - font-weight: ${getFontWeight('semibold')}; - background-color: ${({ $color, theme }) => - $color - ? setLightness(0.95, getColor($color, { theme })) - : getToken('color-action-background-primary-focus')}; - } `; const textTab = css` @@ -56,9 +46,6 @@ const textTab = css` &:hover { color: ${getToken('color-action-link-primary-hover')}; } - &:focus-visible { - background-color: ${getToken('color-action-link-background-primary-focus')}; - } `; export const segmentedTabSelected = css` diff --git a/src/components/forms/Checkbox/Checkbox.tsx b/src/components/forms/Checkbox/Checkbox.tsx index b252dc5f3..fef95f2c2 100644 --- a/src/components/forms/Checkbox/Checkbox.tsx +++ b/src/components/forms/Checkbox/Checkbox.tsx @@ -68,7 +68,7 @@ const CheckboxInput = styled.input` } } - &:focus-visible + ${Box} { + &:focus + ${Box} { border: 2px solid ${getFormStyle('activeBorderColor')}; } diff --git a/src/components/forms/MultiValueInput/MultiValueInput.tsx b/src/components/forms/MultiValueInput/MultiValueInput.tsx index 62e9c7130..8db1ef54f 100644 --- a/src/components/forms/MultiValueInput/MultiValueInput.tsx +++ b/src/components/forms/MultiValueInput/MultiValueInput.tsx @@ -123,12 +123,11 @@ const ClearButton = styled.button` padding: ${pxToRem(0, 18)}; height: ${pxToRem(34)}; margin: ${pxToRem(1, 0)}; + outline-offset: 0; + border-top-right-radius: ${getRadii('default')}; + border-bottom-right-radius: ${getRadii('default')}; - &:focus { - outline: none; - } - &:hover, - &:focus-visible { + &:hover { color: ${getFormStyle('hoverIndicatorColor')}; } `; diff --git a/src/components/forms/Radio/Radio.tsx b/src/components/forms/Radio/Radio.tsx index 99f11dbf5..2496d460d 100644 --- a/src/components/forms/Radio/Radio.tsx +++ b/src/components/forms/Radio/Radio.tsx @@ -77,7 +77,7 @@ const RadioInput = styled.input` color: ${getFormStyle('disabledActiveColor')}; } - &:focus-visible + ${/* sc-selector */ RadioLabel}::before { + &:focus + ${/* sc-selector */ RadioLabel}::before { border: 2px solid ${getFormStyle('activeBorderColor')}; } diff --git a/src/components/forms/SelectableGroup/SelectableGroup.tsx b/src/components/forms/SelectableGroup/SelectableGroup.tsx index 656a50b5b..3cc4c52fa 100644 --- a/src/components/forms/SelectableGroup/SelectableGroup.tsx +++ b/src/components/forms/SelectableGroup/SelectableGroup.tsx @@ -41,7 +41,7 @@ const Input = styled.input` position: absolute; opacity: 0; - &:focus + ${Label} { + &:focus-visible + ${Label} { box-shadow: inset 0 0 0 2px ${getColor('primary.200')}; } &:focus:checked + ${Label} { diff --git a/src/components/typographyLegacy/Link/Link.tsx b/src/components/typographyLegacy/Link/Link.tsx index 881fbb9dc..e5a117fb1 100644 --- a/src/components/typographyLegacy/Link/Link.tsx +++ b/src/components/typographyLegacy/Link/Link.tsx @@ -10,7 +10,6 @@ import { LinkProps } from './Link.types'; import { LinkActiveStyles, LinkBaseStyles, - LinkFocusStyles, LinkHoverStyles, } from '../../_internal/BaseLink'; import { CLX_TYPOGRAPHY } from '../../../theme/constants'; @@ -40,10 +39,6 @@ const LinkRoot = styled.a` ${LinkHoverStyles}; } - &:focus-visible { - ${LinkFocusStyles}; - } - &:active { ${LinkActiveStyles}; } diff --git a/src/theme/GlobalStyles/GlobalStyles.tsx b/src/theme/GlobalStyles/GlobalStyles.tsx index 57e33c6d0..e0a4b07c8 100644 --- a/src/theme/GlobalStyles/GlobalStyles.tsx +++ b/src/theme/GlobalStyles/GlobalStyles.tsx @@ -1,7 +1,13 @@ import { createGlobalStyle } from 'styled-components'; import { BASE_FONT_SIZE, BASE_LINE_HEIGHT } from '../constants'; -import { getColor, getFontFamily, getFontWeight, pxToRem } from '../../utils'; +import { + getColor, + getFontFamily, + getFontWeight, + getToken, + pxToRem, +} from '../../utils'; import SpaceMonoRegularWoff2 from '../fonts/SpaceMono-Regular.woff2'; import SpaceMonoRegularWoff from '../fonts/SpaceMono-Regular.woff'; @@ -102,4 +108,15 @@ export default createGlobalStyle` p, h1, h2, h3, h4, h5, h6, blockquote, pre, ul, ol, li, table, tr, th, td, input, textarea { user-select: text; } + + /* global focus style */ + a, button, [tabindex="0"] { + outline-offset: ${getToken('action-focus-ring-offset')}; + } + a:focus, button:focus, [tabindex="0"]:focus { + outline: none; + } + a:focus-visible, button:focus-visible, [tabindex="0"]:focus-visible { + outline: ${getToken('action-focus-ring')}; + } `; diff --git a/src/theme/tokens.ts b/src/theme/tokens.ts index fd0dbcaea..eed3aff58 100644 --- a/src/theme/tokens.ts +++ b/src/theme/tokens.ts @@ -19,28 +19,32 @@ export const createTokens = ( colors: typeof themeColors, typography: Typography, ) => ({ + 'action-focus-ring': `2px solid ${colors.primary[600]}`, + 'action-focus-ring-offset': '1px', + 'color-action-primary': colors.primary[600], - 'color-action-secondary': colors.neutral[700], - 'color-action-success': colors.success[700], - 'color-action-danger': colors.error[500], 'color-action-primary-hover': colors.primary[800], - 'color-action-secondary-hover': colors.neutral[900], - 'color-action-success-hover': colors.success[800], - 'color-action-danger-hover': colors.error[600], 'color-action-primary-focus': colors.primary[200], + 'color-action-primary-active': colors.primary[800], + 'color-action-secondary': colors.neutral[1000], + 'color-action-secondary-hover': colors.neutral[1000], 'color-action-secondary-focus': colors.neutral[200], + 'color-action-secondary-active': colors.neutral[900], + 'color-action-success': colors.success[700], + 'color-action-success-hover': colors.success[800], 'color-action-success-focus': colors.success[100], + 'color-action-success-active': colors.success[900], + 'color-action-danger': colors.error[500], + 'color-action-danger-hover': colors.error[600], 'color-action-danger-focus': colors.error[100], + 'color-action-danger-active': colors.error[700], 'color-action-background-primary-focus': colors.primary[50], + 'color-action-background-primary-active': colors.primary[50], 'color-action-background-secondary-focus': colors.neutral[200], + 'color-action-background-secondary-active': colors.neutral[100], 'color-action-background-success-focus': colors.success[50], - 'color-action-background-danger-focus': colors.error[50], - 'color-action-primary-active': colors.primary[800], - 'color-action-secondary-active': colors.neutral[900], - 'color-action-success-active': colors.success[900], - 'color-action-danger-active': colors.error[700], - 'color-action-background-primary-active': colors.primary[50], 'color-action-background-success-active': colors.success[50], + 'color-action-background-danger-focus': colors.error[50], 'color-action-background-danger-active': colors.error[50], 'color-action-background-disabled': colors.neutral[300], 'color-action-text-disabled': colors.neutral[600], diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 79e27f774..d6dc99fa6 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -30,6 +30,7 @@ import { Depths } from '../theme/depths.types'; import { SpaceSize } from '../theme/space.types'; import { ColorTypes } from '../theme/colors.enums'; import { createRadii } from '../theme/radii'; +import { createTokens } from '../theme/tokens'; export type ThemeType = { theme?: DefaultTheme; @@ -139,7 +140,12 @@ export const getNegativeSpace = curry( export const capitalize = (string) => string.charAt(0).toUpperCase() + string.slice(1); -export const getToken = curry((name, { theme }: ThemeType): string => +type Tokens = keyof ReturnType; +type GetToken = { + (name: Tokens, { theme }: ThemeType): string; + (name: Tokens): ({ theme }: ThemeType) => string; +}; +export const getToken: GetToken = curry((name, { theme }: ThemeType): string => path(['tokens', name])(theme), );