@@ -11,9 +11,17 @@ import {
11
11
Text ,
12
12
TextInput ,
13
13
} from '@sanity/ui'
14
- import { type ChangeEvent , type KeyboardEvent , useCallback , useMemo , useRef , useState } from 'react'
14
+ import {
15
+ type ChangeEvent ,
16
+ type KeyboardEvent ,
17
+ type MouseEvent ,
18
+ useCallback ,
19
+ useMemo ,
20
+ useRef ,
21
+ useState ,
22
+ } from 'react'
15
23
import { LoadingBlock , type UserWithPermission , useTranslation } from 'sanity'
16
- import styled from 'styled-components'
24
+ import { styled } from 'styled-components'
17
25
18
26
import { MenuButton } from '../../../../../ui-components'
19
27
import { tasksLocaleNamespace } from '../../../../i18n'
@@ -31,6 +39,14 @@ function MentionUserMenuItem(props: {
31
39
const { user, onSelect, selected} = props
32
40
const handleSelect = useCallback ( ( ) => onSelect ( user . id ) , [ user , onSelect ] )
33
41
42
+ const handleCheckboxClick = useCallback (
43
+ ( e : MouseEvent < HTMLDivElement > ) => {
44
+ e . stopPropagation ( )
45
+ handleSelect ( )
46
+ } ,
47
+ [ handleSelect ] ,
48
+ )
49
+
34
50
return (
35
51
< MenuItem onClick = { handleSelect } padding = { 1 } >
36
52
< Flex align = "center" gap = { 3 } >
@@ -41,17 +57,7 @@ function MentionUserMenuItem(props: {
41
57
</ Text >
42
58
</ Flex >
43
59
< Box paddingX = { 2 } >
44
- < Checkbox
45
- onClick = { ( e ) => {
46
- e . stopPropagation ( )
47
- handleSelect ( )
48
- } }
49
- onChange = { ( e ) => {
50
- e . stopPropagation ( )
51
- handleSelect ( )
52
- } }
53
- checked = { selected }
54
- />
60
+ < Checkbox onClick = { handleCheckboxClick } checked = { selected } />
55
61
</ Box >
56
62
</ Flex >
57
63
</ MenuItem >
@@ -81,6 +87,9 @@ function TasksSubscribers({onSelect, value = []}: {onSelect: SelectItemHandler;
81
87
const [ searchTerm , setSearchTerm ] = useState < string > ( '' )
82
88
const { mentionOptions} = useMentionUser ( )
83
89
const inputRef = useRef < HTMLInputElement | null > ( null )
90
+ // This list will keep a local state of users who are initially subscribed and later added or removed.
91
+ // To always render them at the top
92
+ const [ subscribersList , setSubscribersList ] = useState ( value )
84
93
85
94
const handleSearchChange = useCallback ( ( event : ChangeEvent < HTMLInputElement > ) => {
86
95
setSearchTerm ( event . currentTarget . value )
@@ -89,22 +98,31 @@ function TasksSubscribers({onSelect, value = []}: {onSelect: SelectItemHandler;
89
98
const filteredOptions = useFilteredOptions ( { options : mentionOptions . data || [ ] , searchTerm} )
90
99
91
100
const selectedUsers = useMemo (
92
- ( ) => filteredOptions . filter ( ( user ) => value . includes ( user . id ) ) ,
93
- [ filteredOptions , value ] ,
101
+ ( ) => filteredOptions . filter ( ( user ) => subscribersList . includes ( user . id ) ) ,
102
+ [ filteredOptions , subscribersList ] ,
94
103
)
95
104
105
+ const handleSelect = useCallback (
106
+ ( id : string ) => {
107
+ if ( ! subscribersList . includes ( id ) ) {
108
+ setSubscribersList ( [ ...subscribersList , id ] )
109
+ }
110
+ onSelect ( id )
111
+ } ,
112
+ [ subscribersList , onSelect ] ,
113
+ )
96
114
const renderItem = useCallback (
97
115
( user : UserWithPermission ) => {
98
116
return (
99
117
< MentionUserMenuItem
100
118
user = { user }
101
- onSelect = { onSelect }
119
+ onSelect = { handleSelect }
102
120
key = { user . id }
103
121
selected = { value . includes ( user . id ) }
104
122
/>
105
123
)
106
124
} ,
107
- [ onSelect , value ] ,
125
+ [ handleSelect , value ] ,
108
126
)
109
127
const handleKeyDown = useCallback ( ( event : KeyboardEvent < HTMLElement > ) => {
110
128
// If target is input don't do anything
0 commit comments