Skip to content

Commit

Permalink
Extract from 7db1f2f844ebb2f2fa9fbfa73e790ba30f8b49e0
Browse files Browse the repository at this point in the history
  • Loading branch information
akeneo committed Jul 9, 2024
1 parent bfb688d commit 6205dab
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 9 deletions.
3 changes: 2 additions & 1 deletion lib/components/Tree/Tree.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { SyntheticEvent, ReactNode, PropsWithChildren } from 'react';
import { CheckboxChecked } from '../Checkbox/Checkbox';
declare type TreeProps<T = string> = {
value: T;
label: string;
isLeaf?: boolean;
selected?: boolean;
selected?: CheckboxChecked;
isLoading?: boolean;
selectable?: boolean;
readOnly?: boolean;
Expand Down
13 changes: 11 additions & 2 deletions lib/components/Tree/Tree.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/components/Tree/Tree.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "akeneo-design-system",
"version": "0.1.252",
"version": "0.1.253",
"description": "Akeneo design system",
"main": "lib/index.js",
"scripts": {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 22 additions & 1 deletion src/components/Tree/Tree.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ The Tree component uses its value to trigger onOpen, onClose and other events. B
{args => {
return (
<Tree value={'master'} label={'Master'} {...args}>
<Tree value={'tvs'} label={'TVs and projectors'} {...args}/>
<Tree value={'tvs'} label={'TVs and projectors'} {...args}>
<Tree value={'pc_monitors'} label={'PC Monitors'} isLeaf={true} {...args} />
</Tree>
<Tree value={'cameras'} label={'Cameras'} {...args}/>
<Tree value={'audio'} label={'Audio and Video'} {...args}/>
</Tree>
Expand Down Expand Up @@ -161,4 +163,23 @@ The Tree component uses its value to trigger onOpen, onClose and other events. B
</Story>
</Canvas>

## Variation on indeterminate checked when child is selected

<Canvas>
<Story name="IndeterminateChecked">
{args => {
return (
<>
<Tree {...args} label='Indeterminate' selectable={true}>
<Tree {...args} label='Child1' selectable={true} selected={true} />
<Tree {...args} label='Child2' selectable={true} />
</Tree>
<Tree {...args} label='All Checked' selectable={true}>
<Tree {...args} label='Child1' selectable={true} selected={true} />
<Tree {...args} label='Child2' selectable={true} selected={true}/>
</Tree>
</>
);
}}
</Story>
</Canvas>
17 changes: 14 additions & 3 deletions src/components/Tree/Tree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ type TreeProps<T = string> = {
value: T;
label: string;
isLeaf?: boolean;
selected?: boolean;
selected?: CheckboxChecked;
isLoading?: boolean;
selectable?: boolean;
readOnly?: boolean;
Expand Down Expand Up @@ -169,7 +169,18 @@ const Tree = <T,>({
subTrees.push(child);
});

const [isOpen, setOpen] = React.useState<boolean>(subTrees.length > 0);
if (subTrees.length > 0 && selectable) {
const selectedChildren = subTrees.filter(
(subTree: React.ReactElement<TreeProps<T>>) => subTree.props.selected === true
);
if (selectedChildren.length === subTrees.length) {
selected = true;
} else if (selectedChildren.length > 0) {
selected = 'mixed';
}
}

const [isOpen, setOpen] = React.useState<boolean>(_isRoot ? subTrees.length > 0 : false);

const handleOpen = React.useCallback(() => {
setOpen(true);
Expand Down Expand Up @@ -221,7 +232,7 @@ const Tree = <T,>({
{selectable && <NodeCheckbox checked={selected} onChange={handleSelect} readOnly={readOnly} />}

<LabelWithFolder onClick={handleClick} $selected={selected} title={label} aria-selected={selected}>
<TreeIcon isLoading={isLoading} isLeaf={isLeaf} selected={selected} />
<TreeIcon isLoading={isLoading} isLeaf={isLeaf} selected={selected === true || selected === 'mixed'} />
{label}
</LabelWithFolder>
</TreeLine>
Expand Down
26 changes: 26 additions & 0 deletions src/components/Tree/Tree.unit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,32 @@ test('it renders tree with children properly and is loading', () => {
expect(screen.getByText('Camcorders')).toBeInTheDocument();
});

test("it set selected to 'mixed' when a children is selected ", () => {
render(
<Tree value={'master'} label={'Master'} selected={true} selectable={true}>
<Tree value={'camcorders'} label={'Camcorders'} />
<Tree value={'radio'} label={'Radio'} isLeaf={true} selected={true} selectable={true} />
</Tree>
);

const masterTree = screen.getByText('Master');
expect(masterTree).toBeInTheDocument();
expect(masterTree.getAttribute('aria-selected')).toBe('mixed');
});

test("it set selected to 'true' when all children are selected ", () => {
render(
<Tree value={'master'} label={'Master'} selected={true} selectable={true}>
<Tree value={'camcorders'} label={'Camcorders'} selected={true} selectable={true} />
<Tree value={'radio'} label={'Radio'} isLeaf={true} selected={true} selectable={true} />
</Tree>
);

const masterTree = screen.getByText('Master');
expect(masterTree).toBeInTheDocument();
expect(masterTree.getAttribute('aria-selected')).toBe('true');
});

test('Tree supports ...rest props', () => {
render(<Tree value={'master'} label={'Master'} data-testid="my_value" />);
expect(screen.getByTestId('my_value')).toBeInTheDocument();
Expand Down

0 comments on commit 6205dab

Please sign in to comment.