Skip to content

Commit d3762e8

Browse files
lukasbachlukasbachbot
and
lukasbachbot
authored
feat: call onFocusItem with first item if focused item is missing (#363) (#426)
* feat: call onFocusItem with first item if focused item is missing (#363) * v2.5.1-alpha.0 * chore: tidy up after prerelease * feat: fix invalid droptarget at bottom of tree (#363) --------- Co-authored-by: lukasbachbot <[email protected]>
1 parent 39572cb commit d3762e8

File tree

13 files changed

+111
-58
lines changed

13 files changed

+111
-58
lines changed

lerna-publish-summary.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[{"packageName":"react-complex-tree-autodemo","version":"2.5.0"},{"packageName":"react-complex-tree-blueprintjs-renderers","version":"2.5.0"},{"packageName":"react-complex-tree","version":"2.5.0"}]
1+
[{"packageName":"react-complex-tree-autodemo","version":"2.5.1-alpha.0"},{"packageName":"react-complex-tree-blueprintjs-renderers","version":"2.5.1-alpha.0"},{"packageName":"react-complex-tree","version":"2.5.1-alpha.0"}]

lerna.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"packages": ["packages/*"],
33
"npmClient": "yarn",
44
"useWorkspaces": true,
5-
"version": "2.5.0"
5+
"version": "2.5.1-alpha.0"
66
}

next-release-notes.md

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
<!--
2-
### Breaking Changes
3-
4-
### Features
5-
61
### Bug Fixes and Improvements
7-
8-
### Other Changes
9-
-->
2+
- If a tree environment renders without an item defined as focused in its `viewState` parameter, it will invoke the `onFocusItem`
3+
prop with the first item in the tree during its render. In the past, this was implicitly and silently set in the `viewState` prop,
4+
now this assignment is triggered explicitly with the handler call (#363)
5+
- Fixed a bug where an additional invalid drop target would be available at the bottom-most location when dragging via keyboard interactions (#363)

packages/autodemo/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-complex-tree-autodemo",
3-
"version": "2.5.0",
3+
"version": "2.5.1-alpha.0",
44
"main": "lib/index.js",
55
"types": "lib/index.d.ts",
66
"repository": {
@@ -23,10 +23,10 @@
2323
"@types/react-dom": "^18.0.7",
2424
"babel-jest": "^27.5.1",
2525
"babel-loader": "^9.1.0",
26-
"demodata": "^2.5.0",
26+
"demodata": "^2.5.1-alpha.0",
2727
"jest": "^26.6.3",
2828
"react": "^18.2.0",
29-
"react-complex-tree": "^2.5.0",
29+
"react-complex-tree": "^2.5.1-alpha.0",
3030
"react-dom": "^18.2.0",
3131
"react-test-renderer": "^18.2.0",
3232
"ts-node": "^10.7.0",

packages/blueprintjs-renderers/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-complex-tree-blueprintjs-renderers",
3-
"version": "2.5.0",
3+
"version": "2.5.1-alpha.0",
44
"main": "lib/index.js",
55
"types": "lib/index.d.ts",
66
"repository": {
@@ -26,10 +26,10 @@
2626
"@types/react-dom": "^18.0.7",
2727
"babel-jest": "^27.5.1",
2828
"babel-loader": "^9.1.0",
29-
"demodata": "^2.5.0",
29+
"demodata": "^2.5.1-alpha.0",
3030
"jest": "^26.6.3",
3131
"react": "^18.2.0",
32-
"react-complex-tree": "^2.5.0",
32+
"react-complex-tree": "^2.5.1-alpha.0",
3333
"react-dom": "^18.2.0",
3434
"react-test-renderer": "^18.2.0",
3535
"ts-node": "^10.7.0",

packages/core/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-complex-tree",
3-
"version": "2.5.0",
3+
"version": "2.5.1-alpha.0",
44
"main": "lib/cjs/index.js",
55
"module": "lib/esm/index.js",
66
"esnext": "lib/esnext/index.js",
@@ -35,7 +35,7 @@
3535
"babel-jest": "^27.5.1",
3636
"babel-loader": "^9.1.0",
3737
"cpy-cli": "^3.1.1",
38-
"demodata": "^2.5.0",
38+
"demodata": "^2.5.1-alpha.0",
3939
"jest": "^29.2.2",
4040
"jest-dom": "^4.0.0",
4141
"jest-environment-jsdom": "^29.2.2",

packages/core/src/controlledEnvironment/ControlledTreeEnvironment.tsx

+16-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react';
2-
import { useContext } from 'react';
2+
import { useContext, useEffect } from 'react';
33
import {
44
ControlledTreeEnvironmentProps,
55
TreeEnvironmentContextProps,
@@ -21,26 +21,24 @@ export const ControlledTreeEnvironment = React.forwardRef<
2121
>((props, ref) => {
2222
const environmentContextProps = useControlledTreeEnvironmentProps(props);
2323

24-
const { viewState } = props;
24+
const { viewState, onFocusItem } = props;
2525

2626
// Make sure that every tree view state has a focused item
27-
for (const treeId of Object.keys(environmentContextProps.trees)) {
28-
// TODO if the focus item is dragged out of the tree and is not within the expanded items
29-
// TODO of that tree, the tree does not show any focus item anymore.
30-
// Fix: use linear items to see if focus item is visible, and reset if not. Only refresh that
31-
// information when the viewstate changes
32-
if (
33-
!viewState[treeId]?.focusedItem &&
34-
environmentContextProps.trees[treeId]
35-
) {
36-
viewState[treeId] = {
37-
...viewState[treeId],
38-
focusedItem:
39-
props.items[environmentContextProps.trees[treeId].rootItem]
40-
?.children?.[0],
41-
};
27+
useEffect(() => {
28+
for (const treeId of Object.keys(environmentContextProps.trees)) {
29+
const firstItemIndex =
30+
props.items[environmentContextProps.trees[treeId].rootItem]
31+
?.children?.[0];
32+
const firstItem = firstItemIndex && props.items[firstItemIndex];
33+
if (
34+
!viewState[treeId]?.focusedItem &&
35+
environmentContextProps.trees[treeId] &&
36+
firstItem
37+
) {
38+
onFocusItem?.(firstItem, treeId, false);
39+
}
4240
}
43-
}
41+
}, [environmentContextProps.trees, onFocusItem, props.items, viewState]);
4442

4543
return (
4644
<TreeEnvironmentContext.Provider value={environmentContextProps}>

packages/core/src/drag/DragAndDropProvider.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ export const DragAndDropProvider: React.FC<React.PropsWithChildren> = ({
282282
if (environment.activeTreeId) {
283283
setProgrammaticDragIndex(oldIndex =>
284284
Math.min(
285-
viableDragPositions[environment.activeTreeId!].length,
285+
viableDragPositions[environment.activeTreeId!].length - 1,
286286
oldIndex + 1
287287
)
288288
);
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { Meta } from '@storybook/react';
2+
import React, { useState } from 'react';
3+
import { longTree } from 'demodata';
4+
import { Tree } from '../tree/Tree';
5+
import { ControlledTreeEnvironment } from '../controlledEnvironment/ControlledTreeEnvironment';
6+
import { TreeItemIndex } from '../types';
7+
8+
export default {
9+
title: 'Core/Issue Report Reproduction',
10+
} as Meta;
11+
12+
export const Issue363 = () => {
13+
const [focusedItem, setFocusedItem] = useState<TreeItemIndex>();
14+
const [expandedItems, setExpandedItems] = useState<TreeItemIndex[]>([]);
15+
const [selectedItems, setSelectedItems] = useState<TreeItemIndex[]>([]);
16+
return (
17+
<ControlledTreeEnvironment<string>
18+
canDragAndDrop
19+
canDropOnFolder
20+
canReorderItems
21+
items={longTree.items}
22+
getItemTitle={item => item.data}
23+
onFocusItem={item => {
24+
setFocusedItem(item.index);
25+
console.log(`Focused item: ${item.index}`);
26+
}}
27+
onSelectItems={items => {
28+
setSelectedItems(items);
29+
}}
30+
onExpandItem={item => {
31+
setExpandedItems([...expandedItems, item.index]);
32+
}}
33+
onCollapseItem={item => {
34+
setExpandedItems(expandedItems.filter(i => i !== item.index));
35+
}}
36+
viewState={{
37+
'tree-1': {
38+
focusedItem,
39+
expandedItems,
40+
selectedItems,
41+
},
42+
}}
43+
>
44+
<button type="button">Focusable element</button>
45+
<Tree treeId="tree-1" rootItem="root" treeLabel="Tree Example" />
46+
<pre>
47+
{JSON.stringify(
48+
{
49+
focusedItem,
50+
expandedItems,
51+
selectedItems,
52+
},
53+
null,
54+
2
55+
)}
56+
</pre>
57+
</ControlledTreeEnvironment>
58+
);
59+
};

packages/core/test/dnd-restrictions.spec.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ describe('dnd restrictions', () => {
118118

119119
describe('canDrag', () => {
120120
it('respects disabled value', async () => {
121-
const canDrag = jest.fn(items => items[0].data !== 'aab');
121+
const canDrag = jest.fn(items => items[0]?.data !== 'aab');
122122
const test = await new TestUtil().renderOpenTree({
123123
canDrag,
124124
});
@@ -131,7 +131,7 @@ describe('dnd restrictions', () => {
131131
});
132132

133133
it('works for other item', async () => {
134-
const canDrag = jest.fn(items => items[0].data !== 'aab');
134+
const canDrag = jest.fn(items => items[0]?.data !== 'aab');
135135
const test = await new TestUtil().renderOpenTree({
136136
canDrag,
137137
});

packages/demodata/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "demodata",
3-
"version": "2.5.0",
3+
"version": "2.5.1-alpha.0",
44
"main": "lib/index.js",
55
"repository": {
66
"type": "git",

packages/docs/package.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "docs",
3-
"version": "2.5.0",
3+
"version": "2.5.1-alpha.0",
44
"private": true,
55
"scripts": {
66
"docusaurus": "docusaurus",
@@ -21,17 +21,17 @@
2121
"@mdx-js/react": "^1.6.21",
2222
"@svgr/webpack": "^6.5.1",
2323
"clsx": "^1.1.1",
24-
"demodata": "^2.5.0",
24+
"demodata": "^2.5.1-alpha.0",
2525
"docusaurus-plugin-react-docgen-typescript": "^1.0.2",
2626
"docusaurus-plugin-typedoc": "^0.18.0",
2727
"file-loader": "^6.2.0",
2828
"iframe-resizer": "^4.3.2",
2929
"iframe-resizer-react": "^1.1.0",
3030
"prism-react-renderer": "^1.2.1",
3131
"react": "^18.2.0",
32-
"react-complex-tree": "^2.5.0",
33-
"react-complex-tree-autodemo": "^2.5.0",
34-
"react-complex-tree-blueprintjs-renderers": "^2.5.0",
32+
"react-complex-tree": "^2.5.1-alpha.0",
33+
"react-complex-tree-autodemo": "^2.5.1-alpha.0",
34+
"react-complex-tree-blueprintjs-renderers": "^2.5.1-alpha.0",
3535
"react-docgen-typescript": "^2.2.2",
3636
"react-dom": "^18.2.0",
3737
"typedoc": "^0.23.18",

yarn.lock

+13-13
Original file line numberDiff line numberDiff line change
@@ -11803,7 +11803,7 @@ __metadata:
1180311803
languageName: node
1180411804
linkType: hard
1180511805

11806-
"demodata@^2.5.0, demodata@workspace:packages/demodata":
11806+
"demodata@^2.5.1-alpha.0, demodata@workspace:packages/demodata":
1180711807
version: 0.0.0-use.local
1180811808
resolution: "demodata@workspace:packages/demodata"
1180911809
dependencies:
@@ -12029,17 +12029,17 @@ __metadata:
1202912029
"@mdx-js/react": ^1.6.21
1203012030
"@svgr/webpack": ^6.5.1
1203112031
clsx: ^1.1.1
12032-
demodata: ^2.5.0
12032+
demodata: ^2.5.1-alpha.0
1203312033
docusaurus-plugin-react-docgen-typescript: ^1.0.2
1203412034
docusaurus-plugin-typedoc: ^0.18.0
1203512035
file-loader: ^6.2.0
1203612036
iframe-resizer: ^4.3.2
1203712037
iframe-resizer-react: ^1.1.0
1203812038
prism-react-renderer: ^1.2.1
1203912039
react: ^18.2.0
12040-
react-complex-tree: ^2.5.0
12041-
react-complex-tree-autodemo: ^2.5.0
12042-
react-complex-tree-blueprintjs-renderers: ^2.5.0
12040+
react-complex-tree: ^2.5.1-alpha.0
12041+
react-complex-tree-autodemo: ^2.5.1-alpha.0
12042+
react-complex-tree-blueprintjs-renderers: ^2.5.1-alpha.0
1204312043
react-docgen-typescript: ^2.2.2
1204412044
react-dom: ^18.2.0
1204512045
typedoc: ^0.23.18
@@ -21548,7 +21548,7 @@ __metadata:
2154821548
languageName: node
2154921549
linkType: hard
2155021550

21551-
"react-complex-tree-autodemo@^2.5.0, react-complex-tree-autodemo@workspace:packages/autodemo":
21551+
"react-complex-tree-autodemo@^2.5.1-alpha.0, react-complex-tree-autodemo@workspace:packages/autodemo":
2155221552
version: 0.0.0-use.local
2155321553
resolution: "react-complex-tree-autodemo@workspace:packages/autodemo"
2155421554
dependencies:
@@ -21562,18 +21562,18 @@ __metadata:
2156221562
"@types/react-dom": ^18.0.7
2156321563
babel-jest: ^27.5.1
2156421564
babel-loader: ^9.1.0
21565-
demodata: ^2.5.0
21565+
demodata: ^2.5.1-alpha.0
2156621566
jest: ^26.6.3
2156721567
react: ^18.2.0
21568-
react-complex-tree: ^2.5.0
21568+
react-complex-tree: ^2.5.1-alpha.0
2156921569
react-dom: ^18.2.0
2157021570
react-test-renderer: ^18.2.0
2157121571
ts-node: ^10.7.0
2157221572
typescript: 4.9.3
2157321573
languageName: unknown
2157421574
linkType: soft
2157521575

21576-
"react-complex-tree-blueprintjs-renderers@^2.5.0, react-complex-tree-blueprintjs-renderers@workspace:packages/blueprintjs-renderers":
21576+
"react-complex-tree-blueprintjs-renderers@^2.5.1-alpha.0, react-complex-tree-blueprintjs-renderers@workspace:packages/blueprintjs-renderers":
2157721577
version: 0.0.0-use.local
2157821578
resolution: "react-complex-tree-blueprintjs-renderers@workspace:packages/blueprintjs-renderers"
2157921579
dependencies:
@@ -21589,10 +21589,10 @@ __metadata:
2158921589
"@types/react-dom": ^18.0.7
2159021590
babel-jest: ^27.5.1
2159121591
babel-loader: ^9.1.0
21592-
demodata: ^2.5.0
21592+
demodata: ^2.5.1-alpha.0
2159321593
jest: ^26.6.3
2159421594
react: ^18.2.0
21595-
react-complex-tree: ^2.5.0
21595+
react-complex-tree: ^2.5.1-alpha.0
2159621596
react-dom: ^18.2.0
2159721597
react-test-renderer: ^18.2.0
2159821598
ts-node: ^10.7.0
@@ -21640,7 +21640,7 @@ __metadata:
2164021640
languageName: unknown
2164121641
linkType: soft
2164221642

21643-
"react-complex-tree@^2.5.0, react-complex-tree@workspace:packages/core":
21643+
"react-complex-tree@^2.5.1-alpha.0, react-complex-tree@workspace:packages/core":
2164421644
version: 0.0.0-use.local
2164521645
resolution: "react-complex-tree@workspace:packages/core"
2164621646
dependencies:
@@ -21658,7 +21658,7 @@ __metadata:
2165821658
babel-jest: ^27.5.1
2165921659
babel-loader: ^9.1.0
2166021660
cpy-cli: ^3.1.1
21661-
demodata: ^2.5.0
21661+
demodata: ^2.5.1-alpha.0
2166221662
jest: ^29.2.2
2166321663
jest-dom: ^4.0.0
2166421664
jest-environment-jsdom: ^29.2.2

0 commit comments

Comments
 (0)