Skip to content

Commit 8bdfb54

Browse files
committed
save point
1 parent 1b72a1d commit 8bdfb54

File tree

2 files changed

+63
-39
lines changed

2 files changed

+63
-39
lines changed

packages/@react-spectrum/s2/src/TreeView.tsx

+57-38
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@ import {
2626
import {Checkbox, IconContext, Text, TextContext} from '@react-spectrum/s2';
2727
import Chevron from '../ui-icons/Chevron';
2828
import {DOMRef, Key} from '@react-types/shared';
29-
import {focusRing, style} from '../style' with {type: 'macro'};
29+
import {colorMix, focusRing, lightDark, style} from '../style' with {type: 'macro'};
3030
import {isAndroid} from '@react-aria/utils';
3131
import React, {createContext, forwardRef, isValidElement, JSXElementConstructor, ReactElement, useContext, useRef} from 'react';
3232
import {StylesPropWithHeight, UnsafeStyles} from './style-utils';
3333
import {useButton} from '@react-aria/button';
3434
import {useDOMRef} from '@react-spectrum/utils';
3535
import {useLocale} from '@react-aria/i18n';
36+
import { raw } from '../style/style-macro';
3637

3738
interface S2TreeProps {
3839
isDetached?: boolean,
@@ -62,15 +63,15 @@ function useTreeRendererContext(): TreeRendererContextValue {
6263
}
6364

6465

65-
let InternalTreeContext = createContext({});
66+
let InternalTreeContext = createContext<{isDetached?: boolean}>({});
6667

6768

6869
// TODO: add animations for rows appearing and disappearing
6970

7071
// TODO: the below is needed so the borders of the top and bottom row isn't cut off if the TreeView is wrapped within a container by always reserving the 2px needed for the
7172
// keyboard focus ring. Perhaps find a different way of rendering the outlines since the top of the item doesn't
7273
// scroll into view due to how the ring is offset. Alternatively, have the tree render the top/bottom outline like it does in Listview
73-
const tree = style<Pick<TreeRenderProps, 'isEmpty'>>({
74+
const tree = style({
7475
borderWidth: 2,
7576
boxSizing: 'border-box',
7677
borderXWidth: 0,
@@ -91,8 +92,14 @@ const tree = style<Pick<TreeRenderProps, 'isEmpty'>>({
9192
height: {
9293
isEmpty: 'full'
9394
},
94-
display: {
95-
isEmpty: 'flex'
95+
display: 'flex',
96+
flexDirection: 'column',
97+
gap: {
98+
isDetached: 2
99+
},
100+
'--indent': {
101+
type: 'width',
102+
value: 16
96103
}
97104
});
98105

@@ -109,7 +116,11 @@ function TreeView(props: TreeViewProps, ref: DOMRef<HTMLDivElement>) {
109116
return (
110117
<TreeRendererContext.Provider value={{renderer}}>
111118
<InternalTreeContext.Provider value={{isDetached}}>
112-
<UNSTABLE_Tree {...props} className={({isEmpty}) => tree({isEmpty})} selectionBehavior="toggle" ref={domRef}>
119+
<UNSTABLE_Tree
120+
{...props}
121+
className={({isEmpty}) => tree({isEmpty, isDetached})}
122+
selectionBehavior="toggle"
123+
ref={domRef}>
113124
{props.children}
114125
</UNSTABLE_Tree>
115126
</InternalTreeContext.Provider>
@@ -121,6 +132,28 @@ interface TreeRowRenderProps extends TreeItemRenderProps {
121132
isLink?: boolean
122133
}
123134

135+
const selectedBackground = lightDark(colorMix('gray-25', 'informative-900', 10), colorMix('gray-25', 'informative-700', 10));
136+
const selectedActiveBackground = lightDark(colorMix('gray-25', 'informative-900', 15), colorMix('gray-25', 'informative-700', 15));
137+
138+
const rowBackgroundColor = {
139+
default: {
140+
default: 'gray-25',
141+
isQuiet: '--s2-container-bg'
142+
},
143+
isFocusVisibleWithin: colorMix('gray-25', 'gray-900', 7), // table-row-hover-color
144+
isHovered: colorMix('gray-25', 'gray-900', 7), // table-row-hover-color
145+
isPressed: colorMix('gray-25', 'gray-900', 10), // table-row-hover-color
146+
isSelected: {
147+
default: selectedBackground, // table-selected-row-background-color, opacity /10
148+
isFocusVisibleWithin: selectedActiveBackground, // table-selected-row-background-color, opacity /15
149+
isHovered: selectedActiveBackground, // table-selected-row-background-color, opacity /15
150+
isPressed: selectedActiveBackground // table-selected-row-background-color, opacity /15
151+
},
152+
forcedColors: {
153+
default: 'Background'
154+
}
155+
} as const;
156+
124157
const treeRow = style<TreeRowRenderProps>({
125158
position: 'relative',
126159
display: 'flex',
@@ -135,17 +168,23 @@ const treeRow = style<TreeRowRenderProps>({
135168
default: 'default',
136169
isLink: 'pointer'
137170
},
138-
// TODO: not sure where to get the equivalent colors here, for instance isHovered is spectrum 600 with 10% opacity but I don't think that exists in the theme
139-
backgroundColor: {
140-
isHovered: '[var(--spectrum-table-row-background-color-hover)]',
141-
isFocusVisibleWithin: '[var(--spectrum-table-row-background-color-hover)]',
142-
isPressed: '[var(--spectrum-table-row-background-color-down)]',
143-
isSelected: '[var(--spectrum-table-row-background-color-selected)]'
171+
backgroundColor: '--rowBackgroundColor',
172+
'--rowBackgroundColor': {
173+
type: 'backgroundColor',
174+
value: rowBackgroundColor
144175
},
145-
'--indent': {
146-
type: 'width',
147-
value: 16
148-
}
176+
'--rowFocusIndicatorColor': {
177+
type: 'outlineColor',
178+
value: {
179+
default: 'focus-ring',
180+
forcedColors: 'Highlight'
181+
}
182+
},
183+
borderTopWidth: 0,
184+
borderBottomWidth: 0,
185+
borderStartWidth: 0,
186+
borderEndWidth: 0,
187+
borderStyle: 'none'
149188
});
150189

151190
const treeCellGrid = style({
@@ -184,26 +223,6 @@ const treeContent = style({
184223
overflow: 'hidden'
185224
});
186225

187-
const treeRowOutline = style({
188-
...focusRing(),
189-
content: '',
190-
display: 'block',
191-
position: 'absolute',
192-
insetStart: '[8px]',
193-
insetEnd: '[8px]',
194-
top: {
195-
default: '[8px]',
196-
isFocusVisible: '[8px]',
197-
isSelected: {
198-
default: '[1px]',
199-
isFocusVisible: '[8px]'
200-
}
201-
},
202-
bottom: '[8px]',
203-
pointerEvents: 'none',
204-
forcedColorAdjust: 'none'
205-
});
206-
207226
export const TreeViewItem = <T extends object>(props: TreeViewItemProps<T>) => {
208227
let {
209228
children,
@@ -215,6 +234,7 @@ export const TreeViewItem = <T extends object>(props: TreeViewItemProps<T>) => {
215234
let content;
216235
let nestedRows;
217236
let {renderer} = useTreeRendererContext();
237+
let {isDetached} = useContext(InternalTreeContext);
218238
// TODO alternative api is that we have a separate prop for the TreeItems contents and expect the child to then be
219239
// a nested tree item
220240

@@ -247,7 +267,7 @@ export const TreeViewItem = <T extends object>(props: TreeViewItemProps<T>) => {
247267
className={renderProps => treeRow({
248268
...renderProps,
249269
isLink: !!href
250-
})}>
270+
}) + (renderProps.isFocusVisible && ' ' + raw('&:before { content: ""; display: inline-block; position: sticky; inset-inline-start: 0; width: 3px; height: 100%; margin-inline-end: -3px; margin-block-end: 1px; z-index: 3; background-color: var(--rowFocusIndicatorColor)'))}>
251271
<UNSTABLE_TreeItemContent>
252272
{({isExpanded, hasChildRows, selectionMode, selectionBehavior, isDisabled, isSelected, isFocusVisible}) => (
253273
<div className={treeCellGrid({isDisabled})}>
@@ -273,7 +293,6 @@ export const TreeViewItem = <T extends object>(props: TreeViewItemProps<T>) => {
273293
]}>
274294
{content}
275295
</Provider>
276-
<div className={treeRowOutline({isFocusVisible, isSelected})} />
277296
</div>
278297
)}
279298
</UNSTABLE_TreeItemContent>

packages/@react-spectrum/s2/stories/TreeView.stories.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,12 @@ export default meta;
6969

7070
const TreeExampleStatic = (args) => (
7171
<div style={{width: '300px', resize: 'both', height: '90vh', overflow: 'auto'}}>
72-
<TreeView {...args} disabledKeys={['projects-1']} aria-label="test static tree" onExpandedChange={action('onExpandedChange')} onSelectionChange={action('onSelectionChange')}>
72+
<TreeView
73+
{...args}
74+
disabledKeys={['projects-1']}
75+
aria-label="test static tree"
76+
onExpandedChange={action('onExpandedChange')}
77+
onSelectionChange={action('onSelectionChange')}>
7378
<TreeViewItem id="Photos" textValue="Photos">
7479
<Text>Photos</Text>
7580
<Folder />

0 commit comments

Comments
 (0)