@@ -9,13 +9,17 @@ import {
99 ListBoxItem ,
1010} from 'react-aria-components' ;
1111import { useEffect } from 'react' ;
12- // import { isEqual } from 'lodash';
13- // import { v4 as uuidv4 } from 'uuid';
12+ import {
13+ normalizeList ,
14+ denormalizeList ,
15+ } from '@kitconcept/volto-light-theme/helpers/listNormalizer' ;
1416
15- interface FileItem {
16- id : string ;
17- name : string ;
18- }
17+ type ListItem =
18+ | { title : string ; token : string }
19+ | { label : string ; value : string }
20+ | string ;
21+
22+ type ListBoxItem = { label : string ; id : string } ;
1923
2024const messages = defineMessages ( {
2125 optionsLabel : {
@@ -31,7 +35,7 @@ const messages = defineMessages({
3135interface DndListBoxProps {
3236 title : string ;
3337 'aria-label' : string ;
34- list : ListData < FileItem > ;
38+ list : ListData < ListBoxItem > ;
3539}
3640
3741function DndListBox ( props : DndListBoxProps ) {
@@ -44,7 +48,7 @@ function DndListBox(props: DndListBoxProps) {
4448 let item = list . getItem ( key ) ;
4549 return {
4650 'custom-app-type' : JSON . stringify ( item ) ,
47- 'text/plain' : item . name ,
51+ 'text/plain' : item . label ,
4852 } ;
4953 } ) ;
5054 } ,
@@ -111,7 +115,7 @@ function DndListBox(props: DndListBoxProps) {
111115 dragAndDropHooks = { dragAndDropHooks }
112116 renderEmptyState = { ( ) => 'Drop items here' }
113117 >
114- { ( item ) => < ListBoxItem > { item . name } </ ListBoxItem > }
118+ { ( item ) => < ListBoxItem > { item . label } </ ListBoxItem > }
115119 </ ListBox >
116120 ) ;
117121}
@@ -121,52 +125,39 @@ type ListFromListProps = {
121125 title ?: string ;
122126 optionsTitle ?: string ;
123127 valuesTitle ?: string ;
124- value ?: FileItem [ ] ;
125- options : FileItem [ ] ;
128+ value ?: ListItem [ ] ;
129+ options : ListItem [ ] ;
126130 required ?: boolean ;
127- default ?: FileItem [ ] ;
131+ default ?: ListItem [ ] ;
128132 'aria-label' : string ;
129- onChange : ( id : string , value : FileItem [ ] ) => void ;
133+ onChange : ( id : string , value : ListItem [ ] ) => void ;
130134} ;
131135
132136// Returns items in `list` that do NOT exist in `sublist` (by name and type, ignoring id)
133137function differenceByNameAndType (
134- list : FileItem [ ] ,
135- sublist : FileItem [ ] ,
136- ) : FileItem [ ] {
137- return list . filter ( ( item ) => ! sublist . some ( ( sub ) => sub . name === item . name ) ) ;
138+ list : ListBoxItem [ ] ,
139+ sublist : ListBoxItem [ ] ,
140+ ) : ListBoxItem [ ] {
141+ return list . filter ( ( item ) => ! sublist . some ( ( sub ) => sub . id === item . id ) ) ;
138142}
139143
140- // // Adds a unique "id" to each item if it doesn't have one, returns a new array (immutable)
141- // function addIds<T extends { id?: string }>(
142- // list: T[],
143- // ): (Omit<T, 'id'> & { id: string })[] {
144- // return list.map((item) =>
145- // item.id
146- // ? { ...(item as Omit<T, 'id'>), id: item.id }
147- // : { ...(item as Omit<T, 'id'>), id: uuidv4() },
148- // );
149- // }
150-
151- // // Removes the "id" property from each item, returns a new array (immutable)
152- // function removeIds<T extends { id?: string }>(list: T[]): Omit<T, 'id'>[] {
153- // return list.map(({ id, ...rest }) => ({ ...rest }));
154- // }
155-
156144function ListFromList ( props : ListFromListProps ) {
157145 const { options, value, onChange } = props ;
158146 const intl = useIntl ( ) ;
159147
160148 let optionsForDisplay = useListData ( {
161- initialItems : differenceByNameAndType ( options , value ) ,
149+ initialItems : differenceByNameAndType (
150+ normalizeList ( options ) ,
151+ normalizeList ( value ) ,
152+ ) ,
162153 } ) ;
163154
164155 let valueList = useListData ( {
165- initialItems : value || [ ] ,
156+ initialItems : normalizeList ( value ) || [ ] ,
166157 } ) ;
167158
168159 useEffect ( ( ) => {
169- onChange ( props . id , valueList . items ) ;
160+ onChange ( props . id , denormalizeList ( valueList . items ) ) ;
170161 // eslint-disable-next-line react-hooks/exhaustive-deps
171162 } , [ valueList . items ] ) ;
172163
@@ -176,19 +167,24 @@ function ListFromList(props: ListFromListProps) {
176167 const isSameByNameAndOrder =
177168 Array . isArray ( value ) &&
178169 value . length === valueList . items . length &&
179- value . every ( ( v , i ) => v . name === valueList . items [ i ] ?. name ) ;
170+ normalizeList ( value ) . every ( ( v , i ) => v . id === valueList . items [ i ] ?. id ) ;
180171
181172 if ( ! isSameByNameAndOrder ) {
182173 valueList . setSelectedKeys ( new Set ( ) ) ; // Clear selection if needed
183174 valueList . remove ( ...valueList . items . map ( ( item ) => item . id ) ) ;
184175 if ( value && value . length > 0 ) {
185- valueList . append ( ...value ) ;
176+ valueList . append ( ...normalizeList ( value ) ) ;
186177 }
187178 optionsForDisplay . setSelectedKeys ( new Set ( ) ) ; // Clear selection if needed
188179 optionsForDisplay . remove (
189180 ...optionsForDisplay . items . map ( ( item ) => item . id ) ,
190181 ) ;
191- optionsForDisplay . append ( ...differenceByNameAndType ( options , value ) ) ;
182+ optionsForDisplay . append (
183+ ...differenceByNameAndType (
184+ normalizeList ( options ) ,
185+ normalizeList ( value ) ,
186+ ) ,
187+ ) ;
192188 }
193189 // eslint-disable-next-line react-hooks/exhaustive-deps
194190 } , [ value ] ) ;
0 commit comments