Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3 TreeView #6020

Merged
merged 57 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
a10cc8e
scaffolding
LFDanLu Mar 1, 2024
870767c
more style progress
LFDanLu Mar 2, 2024
d392e1b
add box shadow border styles
LFDanLu Mar 5, 2024
4eab1d3
add disabled styles and behavior
LFDanLu Mar 5, 2024
383f2c3
get rid of psudo element in favor of real element in prep for macros …
LFDanLu Mar 5, 2024
70e9327
get macro styles to work for tree
LFDanLu Mar 6, 2024
a3ec22e
remove old version in favor of macros
LFDanLu Mar 6, 2024
a939309
add dynamic support
LFDanLu Mar 6, 2024
1c987d5
add icons support, types, ref support and misc cleanup
LFDanLu Mar 7, 2024
3a415eb
fix lint and rename Tree file
LFDanLu Mar 7, 2024
9b582b3
add resizing story and fix text truncation/border cut off/addition pr…
LFDanLu Mar 7, 2024
61e3d0f
fix wiggle
LFDanLu Mar 7, 2024
7d6bbf7
add more stories, fix chevron grid sizing, add empty state centering
LFDanLu Mar 8, 2024
21ea542
progress in fixing build issue
LFDanLu Mar 8, 2024
4b6f40b
fix bugs from testing
LFDanLu Mar 12, 2024
57c5277
fix pointer
LFDanLu Mar 12, 2024
8b6c889
tentative announcement for grid list rows with links/actions
LFDanLu Mar 12, 2024
5e7a086
updating HCM, RTL and increasing row width for action button focus ring
LFDanLu Mar 19, 2024
b45ea90
weirdness with styles bleeding into the action menu, may need fix fro…
LFDanLu Mar 20, 2024
98c32e0
brainstorming some way to fix tree icon styles from making it to acti…
LFDanLu Mar 27, 2024
b336725
adding temp test setup and babel config update for macros, tests dont…
LFDanLu Mar 27, 2024
8ab0ffb
Tentative approach to get rid of ActionButton icon styles from being …
LFDanLu Mar 27, 2024
bfe77b5
chevron rotate animation
LFDanLu Mar 28, 2024
8314c41
bump babel so tests with macros can run
LFDanLu Apr 1, 2024
5105862
Merge branch 'main' of github.com:adobe/react-spectrum into S1_treeview
LFDanLu Apr 5, 2024
3e289b4
update treeview tests to match spectrum implementation
LFDanLu Apr 5, 2024
accf926
wrap up tests and clean up package json
LFDanLu Apr 5, 2024
51655dc
test skipping the tree tests to see if the 16 and 17 tests pass
LFDanLu Apr 5, 2024
bb06387
unskip tree tests, doesnt look like those are the problem
LFDanLu Apr 6, 2024
5d67f35
Merge branch 'main' of github.com:adobe/react-spectrum into S1_treeview
LFDanLu Apr 8, 2024
1e6430f
update types and fixes for removal of "all" support for expandable ke…
LFDanLu Apr 8, 2024
d82a7fd
bring back docs transformer for fork point
LFDanLu Apr 8, 2024
d0fe8a1
increasing timeout time to see if it helps the test failures
LFDanLu Apr 8, 2024
35fbda1
try running in band
LFDanLu Apr 8, 2024
746af85
Fix fork point
LFDanLu Apr 9, 2024
9371403
revert to "with" and pin parser
LFDanLu Apr 9, 2024
a24c7a4
fix build?
LFDanLu Apr 10, 2024
d8887f7
revert runInBand
LFDanLu Apr 10, 2024
336e5c9
adding increased timeout back
LFDanLu Apr 10, 2024
21c6444
try skipping TreeView test
LFDanLu Apr 10, 2024
6358462
lower timeout for RTL async utils so they finish before jest kills wo…
LFDanLu Apr 10, 2024
ddbbb10
set disabled/HCM color on grid cell and have children inherit this
LFDanLu Apr 10, 2024
72197da
make it so talkback cant focus the chevron if the row is completely d…
LFDanLu Apr 10, 2024
cb264a1
fix lint
LFDanLu Apr 10, 2024
0e3fe69
add chromatic and add timeout back in
LFDanLu Apr 10, 2024
d3070bc
test limiting jest workers
LFDanLu Apr 10, 2024
7cd91a6
Merge branch 'main' into S1_treeview
LFDanLu Apr 10, 2024
e896bb9
Merge branch 'main' of github.com:adobe/react-spectrum into S1_treeview
LFDanLu Apr 18, 2024
85d0f58
get rid of things added to pass the build now that we are using SWC
LFDanLu Apr 18, 2024
6b6492f
still need importAttributes for docs transformer?
LFDanLu Apr 18, 2024
896ad4c
Merge branch 'main' of github.com:adobe/react-spectrum into S1_treeview
LFDanLu Apr 22, 2024
c0e38b8
Address review comments
LFDanLu Apr 23, 2024
7213dfe
Merge branch 'main' into S1_treeview
LFDanLu Apr 23, 2024
6dd23aa
typo
LFDanLu Apr 23, 2024
77ac56a
Merge branch 'S1_treeview' of github.com:adobe/react-spectrum into S1…
LFDanLu Apr 23, 2024
503c6e3
fix import
LFDanLu Apr 23, 2024
3882ad3
Merge branch 'main' of github.com:adobe/react-spectrum into S1_treeview
LFDanLu Apr 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ module.exports = {
tsx: true,
importAssertions: true
},

transform: {
react: {
runtime: 'automatic'
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@
"exclude": [
"**/*.global.css",
"packages/@react-aria/example-theme/**",
"packages/@react-spectrum/style-macro-s1/**"
"packages/@react-spectrum/style-macro-s1/**",
"packages/@react-spectrum/tree/**"
]
},
"drafts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ governing permissions and limitations under the License.
&.spectrum-ActionGroup-item--iconOnly {
padding-inline-end: var(--spectrum-actionbutton-icon-padding-x);
}

.spectrum-ActionGroup-itemIcon {
padding-inline-end: 0;
}
}

&:focus {
Expand Down
4 changes: 4 additions & 0 deletions packages/@adobe/spectrum-css-temp/components/button/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ a.spectrum-ActionButton {
.spectrum-ActionButton-hold + .spectrum-Icon:last-child {
padding-inline-end: var(--spectrum-actionbutton-icon-padding-x);
}

.spectrum-ActionGroup-itemIcon {
padding-inline-end: 0;
}
}

.spectrum-ActionButton-hold {
Expand Down
4 changes: 4 additions & 0 deletions packages/@react-aria/gridlist/intl/ar-AE.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"hasActionAnnouncement": "row has action",
"hasLinkAnnouncement": "row has link: {link}"
}
4 changes: 4 additions & 0 deletions packages/@react-aria/gridlist/intl/en-US.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"hasActionAnnouncement": "row has action",
"hasLinkAnnouncement": "row has link: {link}"
}
16 changes: 14 additions & 2 deletions packages/@react-aria/gridlist/src/useGridListItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ import {focusSafely, getFocusableTreeWalker} from '@react-aria/focus';
import {getLastItem} from '@react-stately/collections';
import {getRowId, listMap} from './utils';
import {HTMLAttributes, KeyboardEvent as ReactKeyboardEvent, RefObject, useRef} from 'react';
// @ts-ignore
import intlMessages from '../intl/*.json';
import {isFocusVisible} from '@react-aria/interactions';
import type {ListState} from '@react-stately/list';
import {SelectableItemStates, useSelectableItem} from '@react-aria/selection';
import type {TreeState} from '@react-stately/tree';
import {useLocale} from '@react-aria/i18n';
import {useLocale, useLocalizedStringFormatter} from '@react-aria/i18n';

export interface AriaGridListItemOptions {
/** An object representing the list item. Contains all the relevant information that makes up the list row. */
Expand Down Expand Up @@ -65,6 +67,7 @@ export function useGridListItem<T>(props: AriaGridListItemOptions, state: ListSt
shouldSelectOnPressUp
} = props;

let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-aria/gridlist');
let {direction} = useLocale();
let {onAction, linkBehavior} = listMap.get(state);
let descriptionId = useSlotId();
Expand Down Expand Up @@ -226,11 +229,20 @@ export function useGridListItem<T>(props: AriaGridListItemOptions, state: ListSt
};

let linkProps = itemStates.hasAction ? getSyntheticLinkProps(node.props) : {};
let rowAnnouncement;
if (onAction) {
rowAnnouncement = stringFormatter.format('hasActionAnnouncement');
} else if (hasLink) {
rowAnnouncement = stringFormatter.format('hasLinkAnnouncement', {
link: node.props.href
});
}

let rowProps: DOMAttributes = mergeProps(itemProps, linkProps, {
role: 'row',
onKeyDownCapture: onKeyDown,
onFocus,
'aria-label': node.textValue || undefined,
'aria-label': [(node.textValue || undefined), rowAnnouncement].filter(Boolean).join(', '),
'aria-selected': state.selectionManager.canSelectItem(node.key) ? state.selectionManager.isSelected(node.key) : undefined,
'aria-disabled': state.selectionManager.isDisabled(node.key) || undefined,
'aria-labelledby': descriptionId && node.textValue ? `${getRowId(state, node.key)} ${descriptionId}` : undefined,
Expand Down
5 changes: 2 additions & 3 deletions packages/@react-spectrum/actiongroup/src/ActionGroup.tsx
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes to ActionGroup and ActionButton (and related css) is to avoid having icon slot provided classes provided from a parent (like TreeRow) from affecting the Icon rendered by the ActionButton. To do this, we clearSlots within ActionButton to stop icon slot props from propagating down but still preserve the text props passed down via slots for hideButtonText.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How did we avoid this problem in ListView?

Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,12 @@ function ActionGroupItem<T>({item, state, isDisabled, isEmphasized, staticColor,
text: {
id: hideButtonText ? textId : null,
isHidden: hideButtonText
},
icon: {
UNSAFE_className: hideButtonText ? classNames(styles, 'spectrum-ActionGroup-itemIcon') : null
}
}}>
<ActionButton
ref={ref}
// @ts-ignore (private)
hideButtonText={hideButtonText}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

womps :(

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeaaaah pretty annoying that I had to do this, open to any alternative ideas

UNSAFE_className={
classNames(
styles,
Expand Down
42 changes: 27 additions & 15 deletions packages/@react-spectrum/button/src/ActionButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* governing permissions and limitations under the License.
*/

import {classNames, SlotProvider, useFocusableRef, useSlotProps, useStyleProps} from '@react-spectrum/utils';
import {classNames, ClearSlots, SlotProvider, useFocusableRef, useSlotProps, useStyleProps} from '@react-spectrum/utils';
import CornerTriangle from '@spectrum-icons/ui/CornerTriangle';
import {FocusableRef} from '@react-types/shared';
import {FocusRing} from '@react-aria/focus';
Expand All @@ -26,6 +26,8 @@ import {useProviderProps} from '@react-spectrum/provider';
function ActionButton(props: SpectrumActionButtonProps, ref: FocusableRef<HTMLButtonElement>) {
props = useProviderProps(props);
props = useSlotProps(props, 'actionButton');
let textProps = useSlotProps({UNSAFE_className: classNames(styles, 'spectrum-ActionButton-label')}, 'text');

let {
isQuiet,
isDisabled,
Expand All @@ -34,6 +36,8 @@ function ActionButton(props: SpectrumActionButtonProps, ref: FocusableRef<HTMLBu
autoFocus,
// @ts-ignore (private)
holdAffordance,
// @ts-ignore (private)
hideButtonText,
...otherProps
} = props;

Expand Down Expand Up @@ -68,20 +72,28 @@ function ActionButton(props: SpectrumActionButtonProps, ref: FocusableRef<HTMLBu
{holdAffordance &&
<CornerTriangle UNSAFE_className={classNames(styles, 'spectrum-ActionButton-hold')} />
}
<SlotProvider
slots={{
icon: {
size: 'S',
UNSAFE_className: classNames(styles, 'spectrum-Icon')
},
text: {
UNSAFE_className: classNames(styles, 'spectrum-ActionButton-label')
}
}}>
{typeof children === 'string' || isTextOnly
? <Text>{children}</Text>
: children}
</SlotProvider>
<ClearSlots>
<SlotProvider
slots={{
icon: {
size: 'S',
UNSAFE_className: classNames(
styles,
'spectrum-Icon',
{
'spectrum-ActionGroup-itemIcon': hideButtonText
}
)
},
text: {
...textProps
}
}}>
{typeof children === 'string' || isTextOnly
? <Text>{children}</Text>
: children}
</SlotProvider>
</ClearSlots>
</button>
</FocusRing>
);
Expand Down
3 changes: 2 additions & 1 deletion packages/@react-spectrum/checkbox/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
"@react-types/checkbox": "^3.7.1",
"@react-types/shared": "^3.22.1",
"@spectrum-icons/ui": "^3.6.5",
"@swc/helpers": "^0.5.0"
"@swc/helpers": "^0.5.0",
"react-aria-components": "^1.1.1"
},
"devDependencies": {
"@adobe/spectrum-css-temp": "3.0.0-alpha.1"
Expand Down
8 changes: 5 additions & 3 deletions packages/@react-spectrum/checkbox/src/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* governing permissions and limitations under the License.
*/

import {CheckboxContext, useContextProps} from 'react-aria-components';
import {CheckboxGroupContext} from './context';
import CheckmarkSmall from '@spectrum-icons/ui/CheckmarkSmall';
import {classNames, useFocusableRef, useStyleProps} from '@react-spectrum/utils';
Expand All @@ -27,6 +28,10 @@ import {useToggleState} from '@react-stately/toggle';

function Checkbox(props: SpectrumCheckboxProps, ref: FocusableRef<HTMLLabelElement>) {
let originalProps = props;
let inputRef = useRef<HTMLInputElement>(null);
let domRef = useFocusableRef(ref, inputRef);

[props, domRef] = useContextProps(props, domRef, CheckboxContext);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RSP Checkbox need to be able to get the props from the RAC context setup by RAC Tree. Eventually be a moot point when we convert v3 to use RAC completely.

props = useProviderProps(props);
props = useFormProps(props);
let {
Expand All @@ -38,9 +43,6 @@ function Checkbox(props: SpectrumCheckboxProps, ref: FocusableRef<HTMLLabelEleme
} = props;
let {styleProps} = useStyleProps(otherProps);

let inputRef = useRef<HTMLInputElement>(null);
let domRef = useFocusableRef(ref, inputRef);

// Swap hooks depending on whether this checkbox is inside a CheckboxGroup.
// This is a bit unorthodox. Typically, hooks cannot be called in a conditional,
// but since the checkbox won't move in and out of a group, it should be safe.
Expand Down
2 changes: 1 addition & 1 deletion packages/@react-spectrum/style-macro-s1/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@react-spectrum/style-macro-s1",
"private": true,
"version": "3.5.3",
"version": "1.0.0-alpha.1",
"description": "Spectrum UI components in React",
"license": "Apache-2.0",
"source": "src/index.ts",
Expand Down
125 changes: 125 additions & 0 deletions packages/@react-spectrum/tree/chromatic/TreeView.chromatic-fc.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright 2024 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/

import {ActionGroup, Item} from '@react-spectrum/actiongroup';
import {ActionMenu} from '@react-spectrum/menu';
import Add from '@spectrum-icons/workflow/Add';
import Delete from '@spectrum-icons/workflow/Delete';
import Edit from '@spectrum-icons/workflow/Edit';
import FileTxt from '@spectrum-icons/workflow/FileTxt';
import Folder from '@spectrum-icons/workflow/Folder';
import React from 'react';
import {Text} from '@react-spectrum/text';
import {TreeView, TreeViewItem} from '../src';

export default {
title: 'TreeView'
};

function TestTree(props) {
return (
<div style={{width: '300px', height: '800px'}}>
<TreeView {...props} disabledKeys={['projects-1']} defaultExpandedKeys={['Photos', 'projects', 'projects-1']} aria-label="test static tree">
<TreeViewItem href="https://adobe.com/" id="Photos" textValue="Photos">
<Text>Photos</Text>
<Folder />
<ActionGroup>
<Item key="edit">
<Edit />
<Text>Edit</Text>
</Item>
<Item key="delete">
<Delete />
<Text>Delete</Text>
</Item>
</ActionGroup>
</TreeViewItem>
<TreeViewItem id="projects" textValue="Projects">
<Text>Projects</Text>
<Folder />
<ActionMenu>
<Item key="add">
<Add />
<Text>Add</Text>
</Item>
<Item key="delete">
<Delete />
<Text>Delete</Text>
</Item>
</ActionMenu>
<TreeViewItem id="projects-1" textValue="Projects-1">
<Text>Projects-1</Text>
<Folder />
<ActionGroup>
<Item key="edit">
<Edit />
<Text>Edit</Text>
</Item>
<Item key="delete">
<Delete />
<Text>Delete</Text>
</Item>
</ActionGroup>
<TreeViewItem id="projects-1A" textValue="Projects-1A">
<Text>Projects-1A</Text>
<FileTxt />
<ActionMenu>
<Item key="add">
<Add />
<Text>Add</Text>
</Item>
<Item key="delete">
<Delete />
<Text>Delete</Text>
</Item>
</ActionMenu>
</TreeViewItem>
</TreeViewItem>
<TreeViewItem id="projects-2" textValue="Projects-2">
<Text>Projects-2</Text>
<FileTxt />
<ActionGroup>
<Item key="edit">
<Edit />
<Text>Edit</Text>
</Item>
<Item key="delete">
<Delete />
<Text>Delete</Text>
</Item>
</ActionGroup>
</TreeViewItem>
<TreeViewItem id="projects-3" textValue="Projects-3">
<Text>Projects-3</Text>
<FileTxt />
</TreeViewItem>
</TreeViewItem>
</TreeView>
</div>
);
}

export const Default = () => (
<TestTree />
);

export const SelectionMode = () => (
<TestTree selectionMode="multiple" />
);

export const DisabledBehaviorAll = () => (
<TestTree disabledBehavior="all" selectionMode="multiple" />
);

export const HiglightSelectionWithDisabledBehaviorAll = () => (
<TestTree selectionStyle="highlight" selectionMode="multiple" disabledBehavior="all" />
);
Loading