1
+ import { Editor as MonacoEditor } from "@monaco-editor/react" ;
2
+ import {
3
+ CheckIcon ,
4
+ ChevronDownIcon ,
5
+ CopyIcon ,
6
+ FileJsonIcon ,
7
+ SettingsIcon ,
8
+ ZapIcon ,
9
+ } from "lucide-react" ;
10
+ import { type FC , useEffect , useState } from "react" ;
1
11
import { Button } from "@/client/components/Button" ;
2
12
import {
3
13
DropdownMenu ,
@@ -13,71 +23,50 @@ import {
13
23
TooltipContent ,
14
24
TooltipTrigger ,
15
25
} from "@/client/components/Tooltip" ;
26
+ import { useEditor } from "@/client/contexts/editor" ;
16
27
import { useTheme } from "@/client/contexts/theme" ;
17
- import { multiSelect , radio , switchInput , textInput } from "@/client/snippets" ;
18
- import type { ParameterFormType } from "@/gen/types" ;
28
+ import { type SnippetFunc , snippets } from "@/client/snippets" ;
29
+ import type { ParameterWithSource } from "@/gen/types" ;
19
30
import { cn } from "@/utils/cn" ;
20
- import { Editor as MonacoEditor } from "@monaco-editor/react" ;
21
- import {
22
- CheckIcon ,
23
- ChevronDownIcon ,
24
- CopyIcon ,
25
- FileJsonIcon ,
26
- RadioIcon ,
27
- SettingsIcon ,
28
- SquareMousePointerIcon ,
29
- TextCursorInputIcon ,
30
- ToggleLeftIcon ,
31
- ZapIcon ,
32
- } from "lucide-react" ;
33
- import { type FC , useEffect , useRef , useState } from "react" ;
34
- import { useEditor } from "@/client/contexts/editor" ;
35
31
36
32
type EditorProps = {
37
33
code : string ;
38
34
setCode : React . Dispatch < React . SetStateAction < string > > ;
35
+ parameters : ParameterWithSource [ ] ;
39
36
} ;
40
37
41
- export const Editor : FC < EditorProps > = ( { code, setCode } ) => {
38
+ export const Editor : FC < EditorProps > = ( { code, setCode, parameters } ) => {
42
39
const { appliedTheme } = useTheme ( ) ;
43
40
const editorRef = useEditor ( ) ;
44
41
45
- const [ codeCopied , setCodeCopied ] = useState ( ( ) => false ) ;
46
- const copyTimeoutId = useRef < ReturnType < typeof setTimeout > | undefined > (
47
- undefined ,
48
- ) ;
49
-
50
42
const [ tab , setTab ] = useState ( ( ) => "code" ) ;
51
43
44
+ const [ codeCopied , setCodeCopied ] = useState ( ( ) => false ) ;
45
+
52
46
const onCopy = ( ) => {
53
47
navigator . clipboard . writeText ( code ) ;
54
48
setCodeCopied ( ( ) => true ) ;
55
49
} ;
56
50
57
- const onAddSnippet = ( formType : ParameterFormType ) => {
58
- if ( formType === "input" ) {
59
- setCode ( `${ code . trimEnd ( ) } \n\n${ textInput } \n` ) ;
60
- } else if ( formType === "radio" ) {
61
- setCode ( `${ code . trimEnd ( ) } \n\n${ radio } \n` ) ;
62
- } else if ( formType === "multi-select" ) {
63
- setCode ( `${ code . trimEnd ( ) } \n\n${ multiSelect } \n` ) ;
64
- } else if ( formType === "switch" ) {
65
- setCode ( `${ code . trimEnd ( ) } \n\n${ switchInput } \n` ) ;
66
- }
51
+ const onAddSnippet = ( name : string , snippet : SnippetFunc ) => {
52
+ const nameCount = parameters . filter ( ( p ) => p . name . startsWith ( name ) ) . length ;
53
+
54
+ const nextInOrder = 1 + Math . max ( 0 , ...parameters . map ( ( p ) => p . order ) ) ;
55
+ const newName = nameCount > 0 ? `${ name } -${ nameCount } ` : name ;
56
+ const newSnippet = snippet ( newName , nextInOrder ) ;
57
+ setCode ( `${ code . trimEnd ( ) } \n\n${ newSnippet } \n` ) ;
67
58
} ;
68
59
69
60
useEffect ( ( ) => {
70
61
if ( ! codeCopied ) {
71
62
return ;
72
63
}
73
64
74
- clearTimeout ( copyTimeoutId . current ) ;
75
-
76
- copyTimeoutId . current = setTimeout ( ( ) => {
65
+ const copyTimeoutId = setTimeout ( ( ) => {
77
66
setCodeCopied ( ( ) => false ) ;
78
67
} , 1000 ) ;
79
68
80
- return ( ) => clearTimeout ( copyTimeoutId . current ) ;
69
+ return ( ) => clearTimeout ( copyTimeoutId ) ;
81
70
} , [ codeCopied ] ) ;
82
71
83
72
return (
@@ -116,23 +105,17 @@ export const Editor: FC<EditorProps> = ({ code, setCode }) => {
116
105
117
106
< DropdownMenuPortal >
118
107
< DropdownMenuContent align = "start" >
119
- < DropdownMenuItem onClick = { ( ) => onAddSnippet ( "input" ) } >
120
- < TextCursorInputIcon width = { 24 } height = { 24 } />
121
- Text input
122
- </ DropdownMenuItem >
123
- < DropdownMenuItem
124
- onClick = { ( ) => onAddSnippet ( "multi-select" ) }
125
- >
126
- < SquareMousePointerIcon width = { 24 } height = { 24 } />
127
- Multi-select
128
- </ DropdownMenuItem >
129
- < DropdownMenuItem onClick = { ( ) => onAddSnippet ( "radio" ) } >
130
- < RadioIcon width = { 24 } height = { 24 } />
131
- Radio
132
- </ DropdownMenuItem >
133
- < DropdownMenuItem onClick = { ( ) => onAddSnippet ( "switch" ) } >
134
- < ToggleLeftIcon width = { 24 } height = { 24 } /> Switches
135
- </ DropdownMenuItem >
108
+ { snippets . map (
109
+ ( { name, label, icon : Icon , snippet } , index ) => (
110
+ < DropdownMenuItem
111
+ key = { index }
112
+ onClick = { ( ) => onAddSnippet ( name , snippet ) }
113
+ >
114
+ < Icon size = { 24 } />
115
+ { label }
116
+ </ DropdownMenuItem >
117
+ ) ,
118
+ ) }
136
119
</ DropdownMenuContent >
137
120
</ DropdownMenuPortal >
138
121
</ DropdownMenu >
0 commit comments