Skip to content

Commit

Permalink
feat: implement :focus-visible for Tree component with targeted foc…
Browse files Browse the repository at this point in the history
…us style for non-pointer devices
  • Loading branch information
cheton committed Aug 28, 2023
1 parent a54ce75 commit 5d5380f
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 26 deletions.
23 changes: 2 additions & 21 deletions packages/react/src/tree/TreeItemContent.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { useMergeRefs } from '@tonic-ui/react-hooks';
import { callEventHandlers } from '@tonic-ui/utils';
import { ensureArray } from 'ensure-type';
import React, { forwardRef, useCallback, useMemo } from 'react';
import React, { forwardRef, useCallback } from 'react';
import { Box } from '../box';
import { useTheme } from '../theme';
import { useTreeItemContentStyle } from './styles';
import useTree from './useTree';
import useTreeItem from './useTreeItem';
Expand All @@ -12,12 +10,10 @@ const TreeItemContent = forwardRef((
{
onClick: onClickProp,
onMouseDown: onMouseDownProp,
sx: sxProp,
...rest
},
ref,
) => {
const { sizes } = useTheme();
const {
multiSelect,
} = useTree();
Expand Down Expand Up @@ -63,29 +59,14 @@ const TreeItemContent = forwardRef((
}, [isDisabled]);

const tabIndex = -1;
const styleProps = useTreeItemContentStyle({ isDisabled, isSelected, tabIndex });
const sxProps = useMemo(() => ([
{
pl: `calc(${nodeDepth} * ${sizes['6x']} + ${sizes['3x']})`,
pr: `calc(${sizes['3x']})`,
':focus-visible': {
borderStyle: 'solid',
borderWidth: '1h',
pl: `calc(${nodeDepth} * ${sizes['6x']} + ${sizes['3x']} - ${sizes['1h']})`,
pr: `calc(${sizes['3x']} - ${sizes['1h']})`,
py: `calc(${sizes['2x']} - ${sizes['1h']})`,
},
},
...ensureArray(sxProp),
]), [nodeDepth, sizes, sxProp]);
const styleProps = useTreeItemContentStyle({ isDisabled, isSelected, nodeDepth, tabIndex });

return (
<Box
ref={combinedRef}
onClick={callEventHandlers(onClickProp, onClick)}
onMouseDown={callEventHandlers(onMouseDownProp, onMouseDown)}
tabIndex={tabIndex}
sx={sxProps}
{...styleProps}
{...rest}
/>
Expand Down
12 changes: 7 additions & 5 deletions packages/react/src/tree/styles.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useColorMode } from '../color-mode';
import { useTheme } from '../theme';

const useTreeItemStyle = () => {
return {
Expand All @@ -8,8 +9,10 @@ const useTreeItemStyle = () => {
const useTreeItemContentStyle = ({
isDisabled,
isSelected,
nodeDepth,
tabIndex,
}) => {
const { colors, sizes } = useTheme();
const [colorMode] = useColorMode();
const color = {
dark: 'white:primary',
Expand All @@ -19,7 +22,7 @@ const useTreeItemContentStyle = ({
dark: 'rgba(255, 255, 255, 0.12)',
light: 'rgba(0, 0, 0, 0.12)',
}[colorMode];
const focusBorderColor = {
const focusBoxShadowColor = {
dark: 'blue:60',
light: 'blue:60',
}[colorMode];
Expand All @@ -42,16 +45,15 @@ const useTreeItemContentStyle = ({
alignItems: 'center',
outline: (tabIndex < 0) ? 0 : undefined, // Remove the default outline for tabindex="-1"
px: '3x',
pl: `calc(${nodeDepth} * ${sizes['6x']} + ${sizes['3x']})`,
py: '2x',
userSelect: 'none',
width: '100%',
_hover: {
backgroundColor: !isDisabled ? hoverBackgroundColor : undefined,
},
_focus: {
borderColor: focusBorderColor,

// Note: The border will be added in TreeItemContent
_focusVisible: {
boxShadow: `inset 0 0 0 ${sizes['1h']} ${colors[focusBoxShadowColor]}`,
},
};
};
Expand Down

0 comments on commit 5d5380f

Please sign in to comment.