-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TreeSelect Convert to Typescript. (#41536)
* [WIP] Refactaring to Typescript. * Fix types * use SelectControl type. * refactoring type. * Update packages/components/src/tree-select/stories/index.tsx Co-authored-by: Lena Morita <lena@jaguchi.com> * add changelog Co-authored-by: Tetsuaki Hamano / 浜野 哲明 <tetsuaki.hamano@gmail.com> Co-authored-by: Lena Morita <lena@jaguchi.com>
- Loading branch information
1 parent
9767234
commit cb13b43
Showing
9 changed files
with
220 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { unescape as unescapeString, repeat, flatMap, compact } from 'lodash'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useMemo } from '@wordpress/element'; | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import { SelectControl } from '../select-control'; | ||
import type { TreeSelectProps, Tree, SelectOptions } from './types'; | ||
|
||
function getSelectOptions( tree: Tree[], level = 0 ): SelectOptions { | ||
return flatMap( tree, ( treeNode ) => [ | ||
{ | ||
value: treeNode.id, | ||
label: | ||
repeat( '\u00A0', level * 3 ) + unescapeString( treeNode.name ), | ||
}, | ||
...getSelectOptions( treeNode.children || [], level + 1 ), | ||
] ); | ||
} | ||
|
||
/** | ||
* TreeSelect component is used to generate select input fields. | ||
* | ||
* @example | ||
* ```jsx | ||
* import { TreeSelect } from '@wordpress/components'; | ||
* import { useState } from '@wordpress/element'; | ||
* | ||
* const MyTreeSelect = () => { | ||
* const [ page, setPage ] = useState( 'p21' ); | ||
* | ||
* return ( | ||
* <TreeSelect | ||
* label="Parent page" | ||
* noOptionLabel="No parent page" | ||
* onChange={ ( newPage ) => setPage( newPage ) } | ||
* selectedId={ page } | ||
* tree={ [ | ||
* { | ||
* name: 'Page 1', | ||
* id: 'p1', | ||
* children: [ | ||
* { name: 'Descend 1 of page 1', id: 'p11' }, | ||
* { name: 'Descend 2 of page 1', id: 'p12' }, | ||
* ], | ||
* }, | ||
* { | ||
* name: 'Page 2', | ||
* id: 'p2', | ||
* children: [ | ||
* { | ||
* name: 'Descend 1 of page 2', | ||
* id: 'p21', | ||
* children: [ | ||
* { | ||
* name: 'Descend 1 of Descend 1 of page 2', | ||
* id: 'p211', | ||
* }, | ||
* ], | ||
* }, | ||
* ], | ||
* }, | ||
* ] } | ||
* /> | ||
* ); | ||
* } | ||
* ``` | ||
*/ | ||
export function TreeSelect( { | ||
label, | ||
noOptionLabel, | ||
onChange, | ||
selectedId, | ||
tree = [], | ||
...props | ||
}: TreeSelectProps ) { | ||
const options = useMemo( () => { | ||
return compact( [ | ||
noOptionLabel && { value: '', label: noOptionLabel }, | ||
...getSelectOptions( tree ), | ||
] ); | ||
}, [ noOptionLabel, tree ] ); | ||
|
||
return ( | ||
<SelectControl | ||
{ ...{ label, options, onChange } } | ||
value={ selectedId } | ||
{ ...props } | ||
/> | ||
); | ||
} | ||
|
||
export default TreeSelect; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import type { ComponentMeta, ComponentStory } from '@storybook/react'; | ||
import type { ComponentProps } from 'react'; | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useState } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import TreeSelect from '../'; | ||
|
||
const meta: ComponentMeta< typeof TreeSelect > = { | ||
title: 'Components/TreeSelect', | ||
component: TreeSelect, | ||
argTypes: { | ||
help: { control: { type: 'text' } }, | ||
label: { control: { type: 'text' } }, | ||
prefix: { control: { type: 'text' } }, | ||
suffix: { control: { type: 'text' } }, | ||
selectedId: { control: { type: null } }, | ||
}, | ||
parameters: { | ||
controls: { | ||
expanded: true, | ||
}, | ||
docs: { source: { state: 'open' } }, | ||
}, | ||
}; | ||
|
||
export default meta; | ||
|
||
const TreeSelectWithState: ComponentStory< typeof TreeSelect > = ( props ) => { | ||
const [ selection, setSelection ] = useState< | ||
ComponentProps< typeof TreeSelect >[ 'selectedId' ] | ||
>(); | ||
|
||
return ( | ||
<TreeSelect | ||
{ ...props } | ||
onChange={ setSelection } | ||
selectedId={ selection } | ||
/> | ||
); | ||
}; | ||
|
||
export const Default = TreeSelectWithState.bind( {} ); | ||
Default.args = { | ||
label: 'Label Text', | ||
noOptionLabel: 'No parent page', | ||
help: 'Help text to explain the select control.', | ||
tree: [ | ||
{ | ||
name: 'Page 1', | ||
id: 'p1', | ||
children: [ | ||
{ name: 'Descend 1 of page 1', id: 'p11' }, | ||
{ name: 'Descend 2 of page 1', id: 'p12' }, | ||
], | ||
}, | ||
{ | ||
name: 'Page 2', | ||
id: 'p2', | ||
children: [ | ||
{ | ||
name: 'Descend 1 of page 2', | ||
id: 'p21', | ||
children: [ | ||
{ | ||
name: 'Descend 1 of Descend 1 of page 2', | ||
id: 'p211', | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import type { ComponentProps } from 'react'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import type SelectControl from '../select-control'; | ||
import type { SelectControlProps } from '../select-control/types'; | ||
|
||
export type SelectOptions = Required< | ||
ComponentProps< typeof SelectControl > | ||
>[ 'options' ]; | ||
|
||
export interface Tree { | ||
id: string; | ||
name: string; | ||
children?: Tree[]; | ||
} | ||
|
||
export interface TreeSelectProps extends Omit< SelectControlProps, 'value' > { | ||
/** | ||
* If this property is added, an option will be added with this label to represent empty selection. | ||
*/ | ||
noOptionLabel?: string; | ||
/** | ||
* An array containing the tree objects with the possible nodes the user can select. | ||
*/ | ||
tree?: Tree[]; | ||
/** | ||
* The id of the currently selected node. | ||
*/ | ||
selectedId?: ComponentProps< typeof SelectControl >[ 'value' ]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters