@@ -5,8 +5,8 @@ import Flex from '@pages/components/Flex'
55import { selectAllSites } from '@service/site-service'
66import { cleanCond } from '@util/limit'
77import { extractHostname , isBrowserUrl } from '@util/pattern'
8- import { ElMessage , ElSelectV2 , ElText , type SelectV2Instance } from 'element-plus'
9- import { computed , defineComponent , ref , type StyleValue } from 'vue'
8+ import { ElMessage , ElSelectV2 , ElText , useNamespace , type SelectV2Instance } from 'element-plus'
9+ import { computed , defineComponent , onMounted , ref , type StyleValue } from 'vue'
1010
1111type Props = {
1212 onAdd : ( url : string ) => string | undefined
@@ -27,54 +27,80 @@ const fetchAllHosts = async () => {
2727 return Array . from ( hostSet )
2828}
2929
30- const useUrlSelect = ( ) => {
30+ const useUrlSelect = ( { onAdd } : Props ) => {
3131 const { data : allHosts } = useRequest ( fetchAllHosts )
3232 const [ input , onFilter ] = useDebounceState ( '' , 50 )
3333 const inputUrl = computed ( ( ) => {
34- const inputVal = input . value
35- return inputVal ? cleanCond ( inputVal ) : undefined
34+ const clean = cleanCond ( input . value )
35+ if ( ! clean ) return { }
36+ const slashIdx = clean . indexOf ( '/' )
37+ return slashIdx === - 1 ? { full : clean } : { full : clean , domain : clean . substring ( 0 , slashIdx ) }
3638 } )
3739
3840 const options = computed ( ( ) => {
39- const urlVal = inputUrl . value
41+ const { full , domain } = inputUrl . value
4042 const result : string [ ] = [ ]
41- if ( urlVal ) {
42- result . push ( urlVal )
43- allHosts . value ?. forEach ( host => host . includes ( urlVal ) && host !== urlVal && result . push ( host ) )
43+ if ( full ) {
44+ result . push ( full )
45+ domain && result . push ( domain )
46+ allHosts . value ?. forEach ( host => host . includes ( full ) && host !== full && host !== domain && result . push ( host ) )
4447 } else {
4548 allHosts . value ?. forEach ( h => result . push ( h ) )
4649 }
4750 return result . map ( value => ( { value, label : value } ) )
4851 } )
4952
50- return { options, onFilter }
51- }
52-
53- const SiteInput = defineComponent < Props > ( props => {
54- const { options, onFilter } = useUrlSelect ( )
55- const selectEl = ref < SelectV2Instance > ( )
53+ const selectInst = ref < SelectV2Instance > ( )
5654
5755 const warnAndFocus = ( msg : string ) => {
5856 ElMessage . warning ( msg )
59- selectEl . value ?. focus ( )
57+ selectInst . value ?. focus ( )
6058 }
6159
62- const handleAdd = ( url : string ) => {
63- const errMsg = props . onAdd ( url )
60+ const onSelected = ( url : string ) => {
61+ const errMsg = onAdd ( url )
6462 if ( errMsg ) {
6563 return warnAndFocus ( errMsg )
6664 } else {
67- selectEl . value ?. handleClear ( )
65+ selectInst . value ?. handleClear ( )
6866 }
6967 }
7068
69+ const selectNs = useNamespace ( 'select' )
70+
71+ onMounted ( ( ) => {
72+ const el = ( selectInst . value ?. $el as HTMLDivElement )
73+ if ( ! el ) return
74+ const input = el . querySelector ( 'input' )
75+ input ?. addEventListener ( 'keyup' , ev => {
76+ if ( ev . code !== 'Enter' ) return
77+ console . log ( `.${ selectNs . be ( 'dropdown' , 'item' ) } .is-hovering` )
78+ const hovered = el . querySelector ( `.${ selectNs . be ( 'dropdown' , 'item' ) } .is-hovering` )
79+ const first = options . value [ 0 ] ?. value
80+ if ( ! hovered && first ) {
81+ onSelected ( first )
82+ ev . stopImmediatePropagation ( )
83+ }
84+ } )
85+ } )
86+
87+ return {
88+ options, onFilter, onSelected,
89+ selectInst,
90+ }
91+ }
92+
93+ const SiteInput = defineComponent < Props > ( props => {
94+ const { options, onFilter, onSelected, selectInst } = useUrlSelect ( props )
95+
7196 return ( ) => (
7297 < Flex width = "100%" column gap = { 5 } >
7398 < ElSelectV2
7499 id = 'site-input' // used for e2e tests
75- onChange = { handleAdd }
76- ref = { selectEl } options = { options . value }
100+ onChange = { onSelected }
101+ ref = { selectInst } options = { options . value }
77102 filterable filterMethod = { onFilter }
103+ teleported = { false } // not teleported, need to find hovered item
78104 placeholder = "e.g. www.demo.com, *.demo.com, demo.com/blog/*, demo.com/**, +www.demo.com/blog/list"
79105 />
80106 < ElText style = { { textAlign : 'start' , width : '100%' , paddingInlineStart : '10px' } satisfies StyleValue } >
0 commit comments