Skip to content

Commit 118c639

Browse files
committed
ack PR comments
1 parent 9b4920d commit 118c639

File tree

5 files changed

+394
-395
lines changed

5 files changed

+394
-395
lines changed
File renamed without changes.

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/components/tool-command/tool-command.tsx

Lines changed: 123 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type CommandContextType = {
1818
registerItem: (id: string) => void
1919
unregisterItem: (id: string) => void
2020
selectItem: (id: string) => void
21+
handleKeyDown: (e: React.KeyboardEvent) => void
2122
}
2223

2324
const CommandContext = createContext<CommandContextType | undefined>(undefined)
@@ -30,6 +31,11 @@ const useCommandContext = () => {
3031
return context
3132
}
3233

34+
export const useCommandKeyDown = () => {
35+
const context = useContext(CommandContext)
36+
return context?.handleKeyDown
37+
}
38+
3339
interface CommandProps {
3440
children: ReactNode
3541
className?: string
@@ -59,126 +65,130 @@ interface CommandSeparatorProps {
5965
className?: string
6066
}
6167

62-
export const Command = React.forwardRef<HTMLDivElement, CommandProps>(
63-
({ children, className, filter, searchQuery: externalSearchQuery }, ref) => {
64-
const [internalSearchQuery, setInternalSearchQuery] = useState('')
65-
const [activeIndex, setActiveIndex] = useState(-1)
66-
const [items, setItems] = useState<string[]>([])
67-
const [filteredItems, setFilteredItems] = useState<string[]>([])
68-
69-
const searchQuery = externalSearchQuery ?? internalSearchQuery
70-
71-
const registerItem = useCallback((id: string) => {
72-
setItems((prev) => {
73-
if (prev.includes(id)) return prev
74-
return [...prev, id]
75-
})
76-
}, [])
77-
78-
const unregisterItem = useCallback((id: string) => {
79-
setItems((prev) => prev.filter((item) => item !== id))
80-
}, [])
81-
82-
const selectItem = useCallback(
83-
(id: string) => {
84-
const index = filteredItems.indexOf(id)
85-
if (index >= 0) {
86-
setActiveIndex(index)
87-
}
88-
},
89-
[filteredItems]
90-
)
91-
92-
useEffect(() => {
93-
if (!searchQuery) {
94-
setFilteredItems(items)
95-
return
96-
}
97-
98-
const filtered = items
99-
.map((item) => {
100-
const score = filter ? filter(item, searchQuery) : defaultFilter(item, searchQuery)
101-
return { item, score }
102-
})
103-
.filter((item) => item.score > 0)
104-
.sort((a, b) => b.score - a.score)
105-
.map((item) => item.item)
106-
107-
setFilteredItems(filtered)
108-
setActiveIndex(filtered.length > 0 ? 0 : -1)
109-
}, [searchQuery, items, filter])
110-
111-
useEffect(() => {
112-
if (activeIndex >= 0 && filteredItems[activeIndex]) {
113-
const activeElement = document.getElementById(filteredItems[activeIndex])
114-
if (activeElement) {
115-
activeElement.scrollIntoView({
116-
behavior: 'smooth',
117-
block: 'nearest',
118-
})
119-
}
68+
export function Command({
69+
children,
70+
className,
71+
filter,
72+
searchQuery: externalSearchQuery,
73+
}: CommandProps) {
74+
const [internalSearchQuery, setInternalSearchQuery] = useState('')
75+
const [activeIndex, setActiveIndex] = useState(-1)
76+
const [items, setItems] = useState<string[]>([])
77+
const [filteredItems, setFilteredItems] = useState<string[]>([])
78+
79+
const searchQuery = externalSearchQuery ?? internalSearchQuery
80+
81+
const registerItem = useCallback((id: string) => {
82+
setItems((prev) => {
83+
if (prev.includes(id)) return prev
84+
return [...prev, id]
85+
})
86+
}, [])
87+
88+
const unregisterItem = useCallback((id: string) => {
89+
setItems((prev) => prev.filter((item) => item !== id))
90+
}, [])
91+
92+
const selectItem = useCallback(
93+
(id: string) => {
94+
const index = filteredItems.indexOf(id)
95+
if (index >= 0) {
96+
setActiveIndex(index)
12097
}
121-
}, [activeIndex, filteredItems])
98+
},
99+
[filteredItems]
100+
)
122101

123-
const defaultFilter = useCallback((value: string, search: string): number => {
124-
const normalizedValue = value.toLowerCase()
125-
const normalizedSearch = search.toLowerCase()
102+
useEffect(() => {
103+
if (!searchQuery) {
104+
setFilteredItems(items)
105+
return
106+
}
126107

127-
if (normalizedValue === normalizedSearch) return 1
128-
if (normalizedValue.startsWith(normalizedSearch)) return 0.8
129-
if (normalizedValue.includes(normalizedSearch)) return 0.6
130-
return 0
131-
}, [])
108+
const filtered = items.filter((item) => {
109+
const score = filter ? filter(item, searchQuery) : defaultFilter(item, searchQuery)
110+
return score > 0
111+
})
132112

133-
const handleKeyDown = useCallback(
134-
(e: React.KeyboardEvent) => {
135-
if (filteredItems.length === 0) return
113+
setFilteredItems(filtered)
114+
setActiveIndex(filtered.length > 0 ? 0 : -1)
115+
}, [searchQuery, items, filter])
136116

137-
switch (e.key) {
138-
case 'ArrowDown':
139-
e.preventDefault()
140-
setActiveIndex((prev) => (prev + 1) % filteredItems.length)
141-
break
142-
case 'ArrowUp':
117+
useEffect(() => {
118+
if (activeIndex >= 0 && filteredItems[activeIndex]) {
119+
const activeElement = document.getElementById(filteredItems[activeIndex])
120+
if (activeElement) {
121+
activeElement.scrollIntoView({
122+
behavior: 'smooth',
123+
block: 'nearest',
124+
})
125+
}
126+
}
127+
}, [activeIndex, filteredItems])
128+
129+
const defaultFilter = useCallback((value: string, search: string): number => {
130+
const normalizedValue = value.toLowerCase()
131+
const normalizedSearch = search.toLowerCase()
132+
133+
if (normalizedValue === normalizedSearch) return 1
134+
if (normalizedValue.startsWith(normalizedSearch)) return 0.8
135+
if (normalizedValue.includes(normalizedSearch)) return 0.6
136+
return 0
137+
}, [])
138+
139+
const handleKeyDown = useCallback(
140+
(e: React.KeyboardEvent) => {
141+
if (filteredItems.length === 0) return
142+
143+
switch (e.key) {
144+
case 'ArrowDown':
145+
e.preventDefault()
146+
setActiveIndex((prev) => (prev + 1) % filteredItems.length)
147+
break
148+
case 'ArrowUp':
149+
e.preventDefault()
150+
setActiveIndex((prev) => (prev - 1 + filteredItems.length) % filteredItems.length)
151+
break
152+
case 'Enter':
153+
if (activeIndex >= 0) {
143154
e.preventDefault()
144-
setActiveIndex((prev) => (prev - 1 + filteredItems.length) % filteredItems.length)
145-
break
146-
case 'Enter':
147-
if (activeIndex >= 0) {
148-
e.preventDefault()
149-
document.getElementById(filteredItems[activeIndex])?.click()
150-
}
151-
break
152-
}
153-
},
154-
[filteredItems, activeIndex]
155-
)
156-
157-
const contextValue = useMemo(
158-
() => ({
159-
searchQuery,
160-
setSearchQuery: setInternalSearchQuery,
161-
activeIndex,
162-
setActiveIndex,
163-
filteredItems,
164-
registerItem,
165-
unregisterItem,
166-
selectItem,
167-
}),
168-
[searchQuery, activeIndex, filteredItems, registerItem, unregisterItem, selectItem]
169-
)
170-
171-
return (
172-
<CommandContext.Provider value={contextValue}>
173-
<div ref={ref} className={cn('flex w-full flex-col', className)} onKeyDown={handleKeyDown}>
174-
{children}
175-
</div>
176-
</CommandContext.Provider>
177-
)
178-
}
179-
)
155+
document.getElementById(filteredItems[activeIndex])?.click()
156+
}
157+
break
158+
}
159+
},
160+
[filteredItems, activeIndex]
161+
)
162+
163+
const contextValue = useMemo(
164+
() => ({
165+
searchQuery,
166+
setSearchQuery: setInternalSearchQuery,
167+
activeIndex,
168+
setActiveIndex,
169+
filteredItems,
170+
registerItem,
171+
unregisterItem,
172+
selectItem,
173+
handleKeyDown,
174+
}),
175+
[
176+
searchQuery,
177+
activeIndex,
178+
filteredItems,
179+
registerItem,
180+
unregisterItem,
181+
selectItem,
182+
handleKeyDown,
183+
]
184+
)
180185

181-
Command.displayName = 'Command'
186+
return (
187+
<CommandContext.Provider value={contextValue}>
188+
<div className={cn('flex w-full flex-col', className)}>{children}</div>
189+
</CommandContext.Provider>
190+
)
191+
}
182192

183193
export function CommandList({ children, className }: CommandListProps) {
184194
return <div className={cn(className)}>{children}</div>

0 commit comments

Comments
 (0)