11import {
2- Box , IconButton , ListItem , ListItemText ,
2+ Box , FilterOptionsState , IconButton , ListItem , ListItemIcon , ListItemText , createFilterOptions ,
33} from '@mui/material' ;
44import React , { useState } from 'react' ;
55import { Draggable } from 'react-beautiful-dnd' ;
66import DriveFileRenameOutlineIcon from '@mui/icons-material/DriveFileRenameOutline' ;
77import {
8+ AutocompleteElement ,
89 TextFieldElement , useWatch ,
910} from 'react-hook-form-mui' ;
1011import DeleteSweepIcon from '@mui/icons-material/DeleteSweep' ;
1112import DoneOutlineIcon from '@mui/icons-material/DoneOutline' ;
13+ import Icon from '@mdi/react' ;
1214import { IEntityConfig } from '../../store' ;
1315import IState from '../../types/state' ;
1416import type { TFormValues } from '../entities-form' ;
1517import EntityUtils from '../../utils/entity-utils' ;
18+ import icons , { getIconsPath } from './icons' ;
1619
1720interface DraggableListItemProps {
1821 entity : IEntityConfig ,
@@ -21,6 +24,11 @@ interface DraggableListItemProps {
2124 onRemove : ( ) => void ,
2225}
2326
27+ const OPTIONS_LIMIT = 100 ;
28+ const defaultFilterOptions = createFilterOptions ( ) ;
29+
30+ const filterOptions = ( options : unknown [ ] , state : FilterOptionsState < unknown > ) => defaultFilterOptions ( options , state ) . slice ( 0 , OPTIONS_LIMIT ) ;
31+
2432export default function DraggableListItem ( props : DraggableListItemProps ) {
2533 const {
2634 index, state, onRemove,
@@ -29,6 +37,9 @@ export default function DraggableListItem(props: DraggableListItemProps) {
2937 const [ editing , setEditing ] = useState < boolean > ( false ) ;
3038
3139 const entity = useWatch < TFormValues , `entities.${number } `> ( { name : `entities.${ index } ` } ) ;
40+ const autocompleteOptions = icons . map ( ( option ) => ( {
41+ label : option . name , id : option . name , path : option . path , aliases : option . aliases ,
42+ } ) ) ;
3243
3344 return (
3445 < Draggable
@@ -68,11 +79,47 @@ export default function DraggableListItem(props: DraggableListItemProps) {
6879 >
6980 {
7081 ! editing ? (
71- < ListItemText
72- primary = { EntityUtils . getEntityName ( entity , state ) }
73- />
82+ < >
83+ < ListItemIcon sx = { { minWidth : 36 } } >
84+ { entity . icon && < Icon path = { getIconsPath ( entity . icon ) } size = { 1 } /> }
85+ </ ListItemIcon >
86+ < ListItemText
87+ primary = { EntityUtils . getEntityName ( entity , state ) }
88+ />
89+ </ >
7490 ) : (
75- < TextFieldElement < TFormValues > name = { `entities.${ index } .label` } label = { state ?. attributes . friendly_name ?? entity . entity_id } />
91+ < >
92+ < AutocompleteElement < TFormValues >
93+ name = { `entities.${ index } .icon` }
94+ options = { autocompleteOptions }
95+ textFieldProps = { { fullWidth : true } }
96+ label = "Icon"
97+ matchId
98+ autocompleteProps = { {
99+ fullWidth : true ,
100+ filterOptions,
101+
102+ renderOption : ( optionProps , option , { selected } ) => (
103+ // eslint-disable-next-line react/jsx-props-no-spreading
104+ < ListItem { ...optionProps } key = { option . id } >
105+ < ListItemIcon >
106+ < Icon path = { option . path } size = { 1 } />
107+ </ ListItemIcon >
108+ < ListItemText
109+ primaryTypographyProps = { selected ? { fontWeight : 'bold' } : undefined }
110+ primary = { option . label }
111+ secondary = { option . aliases . join ( ', ' ) }
112+ />
113+ </ ListItem >
114+ ) ,
115+ } }
116+
117+ />
118+ < TextFieldElement < TFormValues >
119+ name = { `entities.${ index } .label` }
120+ label = { state ?. attributes . friendly_name ?? entity . entity_id }
121+ />
122+ </ >
76123 )
77124 }
78125 </ ListItem >
0 commit comments