@@ -4,8 +4,8 @@ import {Input} from 'web/components/widgets/input'
44import { Button } from 'web/components/buttons/button'
55import clsx from 'clsx'
66import { useEffect , useMemo , useState } from 'react'
7- import { useT } from " web/lib/locale" ;
8- import { toKey } from " common/parsing" ;
7+ import { useT } from ' web/lib/locale'
8+ import { toKey } from ' common/parsing'
99
1010export const MultiCheckbox = ( props : {
1111 // Map of label -> value
@@ -20,14 +20,27 @@ export const MultiCheckbox = (props: {
2020 // - string: the stored value for the new option; label will be the input text
2121 // - { key, value }: explicit label (key) and stored value
2222 // - null/undefined to indicate failure/cancellation
23- addOption ?: ( label : string ) => string | { key : string ; value : string } | null | undefined
23+ addOption ?: (
24+ label : string
25+ ) => string | { key : string ; value : string } | null | undefined
2426 addPlaceholder ?: string
2527 translationPrefix ?: string
2628} ) => {
27- const { choices, selected, onChange, className, optionsClassName, addOption, addPlaceholder, translationPrefix} = props
29+ const {
30+ choices,
31+ selected,
32+ onChange,
33+ className,
34+ optionsClassName,
35+ addOption,
36+ addPlaceholder,
37+ translationPrefix,
38+ } = props
2839
2940 // Keep a local merged copy to allow optimistic adds while remaining in sync with props
30- const [ localChoices , setLocalChoices ] = useState < { [ key : string ] : string } > ( choices )
41+ const [ localChoices , setLocalChoices ] = useState < { [ key : string ] : string } > (
42+ choices
43+ )
3144 useEffect ( ( ) => {
3245 setLocalChoices ( ( prev ) => {
3346 // If incoming choices changed, merge them with any locally added that still don't collide
@@ -56,7 +69,9 @@ export const MultiCheckbox = (props: {
5669 let q = newLabel . trim ( )
5770 q = translateOption ( q , q ) . toLowerCase ( )
5871 if ( ! q ) return entries
59- return entries . filter ( ( [ key , value ] ) => translateOption ( key , value ) . toLowerCase ( ) . includes ( q ) )
72+ return entries . filter ( ( [ key , value ] ) =>
73+ translateOption ( key , value ) . toLowerCase ( ) . includes ( q )
74+ )
6075 } , [ addOption , entries , newLabel ] )
6176
6277 const submitAdd = async ( ) => {
@@ -68,8 +83,10 @@ export const MultiCheckbox = (props: {
6883 return
6984 }
7085 // prevent duplicate by label or by value already selected
71- const existingEntry = Object . entries ( localChoices ) . find ( ( [ key , value ] ) =>
72- translateOption ( key , value ) . toLowerCase ( ) === translateOption ( label , label ) . toLowerCase ( )
86+ const existingEntry = Object . entries ( localChoices ) . find (
87+ ( [ key , value ] ) =>
88+ translateOption ( key , value ) . toLowerCase ( ) ===
89+ translateOption ( label , label ) . toLowerCase ( )
7390 )
7491
7592 if ( existingEntry ) {
@@ -88,12 +105,13 @@ export const MultiCheckbox = (props: {
88105 setAdding ( false )
89106 return
90107 }
91- const { key, value} = typeof result === 'string' ? { key : label , value : result } : result
108+ const { key, value} =
109+ typeof result === 'string' ? { key : label , value : result } : result
92110 setLocalChoices ( ( prev ) => ( { ...prev , [ key ] : value } ) )
93111 // auto-select newly added option if not already selected
94112 if ( ! selected . includes ( value ) ) onChange ( [ ...selected , value ] )
95113 setNewLabel ( '' )
96- } catch ( e ) {
114+ } catch ( _e ) {
97115 setError ( t ( 'multi-checkbox.add_failed' , 'Failed to add option.' ) )
98116 } finally {
99117 setAdding ( false )
@@ -106,7 +124,10 @@ export const MultiCheckbox = (props: {
106124 < Row className = "items-center gap-2" >
107125 < Input
108126 value = { newLabel }
109- placeholder = { addPlaceholder ?? t ( 'multi-checkbox.search_or_add' , 'Search or add' ) }
127+ placeholder = {
128+ addPlaceholder ??
129+ t ( 'multi-checkbox.search_or_add' , 'Search or add' )
130+ }
110131 onChange = { ( e ) => {
111132 setNewLabel ( e . target . value )
112133 setError ( null )
@@ -119,7 +140,12 @@ export const MultiCheckbox = (props: {
119140 } }
120141 className = "h-10"
121142 />
122- < Button size = "sm" onClick = { submitAdd } loading = { adding } disabled = { adding } >
143+ < Button
144+ size = "sm"
145+ onClick = { submitAdd }
146+ loading = { adding }
147+ disabled = { adding }
148+ >
123149 { t ( 'common.add' , 'Add' ) }
124150 </ Button >
125151 { error && < span className = "text-sm text-error" > { error } </ span > }
@@ -144,9 +170,12 @@ export const MultiCheckbox = (props: {
144170 </ Row >
145171 { addOption && newLabel . trim ( ) && filteredEntries . length === 0 && (
146172 < div className = "px-2 text-sm text-ink-500" >
147- { t ( 'multi-checkbox.no_matching_options' , 'No matching options, feel free to add it.' ) }
173+ { t (
174+ 'multi-checkbox.no_matching_options' ,
175+ 'No matching options, feel free to add it.'
176+ ) }
148177 </ div >
149178 ) }
150179 </ div >
151180 )
152- }
181+ }
0 commit comments