1- import React from 'react' ;
1+ import React , { useState } from 'react' ;
22import PropTypes from 'prop-types' ;
33import { DualListSelector } from '@patternfly/react-core' ;
44import { useFieldApi } from '@data-driven-forms/react-form-renderer' ;
55import isEqual from 'lodash/isEqual' ;
66
77import './dual-list-select.scss' ;
88import FormGroup from '../common/form-group' ;
9+ import DualListContext from './dual-list-context' ;
910
1011const DualList = ( props ) => {
11- const { label, isRequired, helperText, meta, description, hideLabel, id, input, FormGroupProps, options, getValueFromNode, ...rest } = useFieldApi ( {
12+ const {
13+ label,
14+ isRequired,
15+ helperText,
16+ meta,
17+ description,
18+ hideLabel,
19+ id,
20+ input,
21+ FormGroupProps,
22+ options,
23+ getValueFromNode,
24+ isSearchable,
25+ isSortable,
26+ ...rest
27+ } = useFieldApi ( {
1228 ...props ,
1329 isEqual : ( current , initial ) => isEqual ( [ ...( current || [ ] ) ] . sort ( ) , [ ...( initial || [ ] ) ] . sort ( ) )
1430 } ) ;
1531
32+ const [ sortConfig , setSortConfig ] = useState ( ( ) => ( { left : isSortable && 'asc' , right : isSortable && 'asc' } ) ) ;
33+
1634 const value = input . value || [ ] ;
1735
1836 let leftOptions ;
@@ -46,6 +64,18 @@ const DualList = (props) => {
4664 filterOption = ( option , input ) => ( option . value ? option . value . includes ( input ) : getValueFromNode ( option ) . includes ( input ) ) ;
4765 }
4866
67+ if ( isSortable ) {
68+ const sort = ( direction , a , b ) => ( direction === 'asc' ? a . localeCompare ( b ) : b . localeCompare ( a ) ) ;
69+
70+ if ( ! getValueFromNode ) {
71+ leftOptions = leftOptions . sort ( ( a , b ) => sort ( sortConfig . left , a . label || a , b . label || b ) ) ;
72+ rightOptions = rightOptions . sort ( ( a , b ) => sort ( sortConfig . right , a . label || a , b . label || b ) ) ;
73+ } else {
74+ leftOptions = leftOptions . sort ( ( a , b ) => sort ( sortConfig . left , getValueFromNode ( a . label || a ) , getValueFromNode ( b . label || b ) ) ) ;
75+ rightOptions = rightOptions . sort ( ( a , b ) => sort ( sortConfig . right , getValueFromNode ( a . label || a ) , getValueFromNode ( b . label || b ) ) ) ;
76+ }
77+ }
78+
4979 return (
5080 < FormGroup
5181 label = { label }
@@ -57,23 +87,24 @@ const DualList = (props) => {
5787 id = { id || input . name }
5888 FormGroupProps = { FormGroupProps }
5989 >
60- < DualListSelector
61- availableOptions = { leftOptions }
62- chosenOptions = { rightOptions }
63- onListChange = { onListChange }
64- id = { id || input . name }
65- isSearchable
66- { ...( getValueFromNode && {
67- addAll : onListChange ,
68- addSelected : onListChange ,
69- filterOption,
70- onOptionSelect : onListChange ,
71- removeAll : onListChange ,
72- removeSelected : onListChange
73- } ) }
74- { ...rest }
75- />
76- { JSON . stringify ( input . value , null , 2 ) }
90+ < DualListContext . Provider value = { { sortConfig, setSortConfig } } >
91+ < DualListSelector
92+ availableOptions = { leftOptions }
93+ chosenOptions = { rightOptions }
94+ onListChange = { onListChange }
95+ id = { id || input . name }
96+ isSearchable = { isSearchable }
97+ { ...( getValueFromNode && {
98+ addAll : onListChange ,
99+ addSelected : onListChange ,
100+ filterOption,
101+ onOptionSelect : onListChange ,
102+ removeAll : onListChange ,
103+ removeSelected : onListChange
104+ } ) }
105+ { ...rest }
106+ />
107+ </ DualListContext . Provider >
77108 </ FormGroup >
78109 ) ;
79110} ;
@@ -85,7 +116,9 @@ DualList.propTypes = {
85116 description : PropTypes . node ,
86117 hideLabel : PropTypes . bool ,
87118 id : PropTypes . string ,
88- getValueFromNode : PropTypes . func
119+ getValueFromNode : PropTypes . func ,
120+ isSearchable : PropTypes . bool ,
121+ isSortable : PropTypes . bool
89122} ;
90123
91124export default DualList ;
0 commit comments