7
7
DropdownMenuTrigger ,
8
8
} from "@/components/DropdownMenu" ;
9
9
import { ResizablePanel } from "@/components/Resizable" ;
10
+ import * as Tabs from "@/components/Tabs" ;
10
11
import { Tooltip , TooltipContent , TooltipTrigger } from "@/components/Tooltip" ;
11
12
import { useStore } from "@/store" ;
12
13
import {
@@ -15,11 +16,11 @@ import {
15
16
ChevronDownIcon ,
16
17
CopyIcon ,
17
18
FileJsonIcon ,
18
- SettingsIcon ,
19
- ToggleLeftIcon ,
20
19
RadioIcon ,
20
+ SettingsIcon ,
21
21
SquareMousePointerIcon ,
22
22
TextCursorInputIcon ,
23
+ ToggleLeftIcon ,
23
24
} from "lucide-react" ;
24
25
import { type FC , useEffect , useRef , useState } from "react" ;
25
26
import CodeEditor from "react-simple-code-editor" ;
@@ -28,8 +29,8 @@ import CodeEditor from "react-simple-code-editor";
28
29
// @ts -expect-error TODO: create types for this
29
30
import { highlight , languages } from "prismjs/components/prism-core" ;
30
31
import "prismjs/components/prism-hcl" ;
31
- // @ts -expect-error TODO: create types for this
32
32
import "prismjs/themes/prism.css" ;
33
+ import { cn } from "@/utils/cn" ;
33
34
34
35
// Adds line numbers to the highlight.
35
36
const hightlightWithLineNumbers = ( input : string , language : unknown ) =>
@@ -50,6 +51,8 @@ export const Editor: FC = () => {
50
51
undefined ,
51
52
) ;
52
53
54
+ const [ tab , setTab ] = useState ( ( ) => "code" ) ;
55
+
53
56
const onCopy = ( ) => {
54
57
navigator . clipboard . writeText ( $code ) ;
55
58
setCodeCopied ( ( ) => true ) ;
@@ -70,81 +73,88 @@ export const Editor: FC = () => {
70
73
} , [ codeCopied ] ) ;
71
74
72
75
return (
73
- < ResizablePanel className = "relative flex flex-col items-start" >
74
- { /* EDITOR TOP BAR */ }
75
- < div className = "flex h-12 w-full items-center justify-between border-b border-b-surface-quaternary pr-3" >
76
- < div className = "flex" >
77
- < button className = "flex w-fit min-w-[120px] items-center gap-1 border-x bg-surface-secondary px-4 py-3 text-content-primary transition-colors hover:bg-surface-tertiary" >
78
- < FileJsonIcon className = "w-[18px] min-w-[18px]" />
79
- < span className = "w-full text-sm" > Code</ span >
80
- </ button >
81
-
82
- < Tooltip >
83
- < TooltipTrigger asChild = { true } >
84
- < button
85
- disabled = { true }
86
- className = "flex w-fit min-w-[120px] cursor-not-allowed items-center gap-1 px-4 py-3 text-content-secondary"
87
- >
88
- < SettingsIcon className = "w-[18px] min-w-[18px]" />
89
- < span className = "w-full text-sm" > Variables</ span >
90
- </ button >
91
- </ TooltipTrigger >
92
- < TooltipContent > Coming soon</ TooltipContent >
93
- </ Tooltip >
94
- </ div >
95
-
96
- < DropdownMenu >
97
- < DropdownMenuTrigger className = "flex w-fit min-w-[140px] cursor-pointer items-center justify-between rounded-md border bg-surface-primary px-2 py-1.5 text-content-secondary transition-colors hover:text-content-primary data-[state=open]:text-content-primary" >
98
- < div className = "flex items-center justify-center gap-2" >
99
- < BookIcon width = { 18 } height = { 18 } />
100
- < p className = "text-xs" > Examples</ p >
76
+ < Tabs . Root
77
+ asChild = { true }
78
+ value = { tab }
79
+ onValueChange = { ( tab ) => setTab ( ( ) => tab ) }
80
+ >
81
+ < ResizablePanel className = "relative flex flex-col items-start" >
82
+ { /* EDITOR TOP BAR */ }
83
+ < Tabs . List asChild = { true } >
84
+ < div className = "flex h-12 w-full items-center justify-between border-b border-b-surface-quaternary pr-3" >
85
+ < div className = "flex" >
86
+ < Tabs . Trigger icon = { FileJsonIcon } label = "Code" value = "code" />
87
+ < Tooltip >
88
+ < TooltipTrigger asChild = { true } >
89
+ < Tabs . Trigger
90
+ icon = { SettingsIcon }
91
+ label = "Variables"
92
+ value = "variables"
93
+ disabled = { true }
94
+ />
95
+ </ TooltipTrigger >
96
+ < TooltipContent > Coming soon</ TooltipContent >
97
+ </ Tooltip >
101
98
</ div >
102
- < ChevronDownIcon width = { 18 } height = { 18 } />
103
- </ DropdownMenuTrigger >
104
99
105
- < DropdownMenuPortal >
106
- < DropdownMenuContent align = "start" >
107
- < DropdownMenuItem >
108
- < TextCursorInputIcon width = { 24 } height = { 24 } />
109
- Text input
110
- </ DropdownMenuItem >
111
- < DropdownMenuItem >
112
- < SquareMousePointerIcon width = { 24 } height = { 24 } />
113
- Multi-select
114
- </ DropdownMenuItem >
115
- < DropdownMenuItem >
116
- < RadioIcon width = { 24 } height = { 24 } />
117
- Radio
118
- </ DropdownMenuItem >
119
- < DropdownMenuItem >
120
- < ToggleLeftIcon width = { 24 } height = { 24 } /> Switches
121
- </ DropdownMenuItem >
122
- </ DropdownMenuContent >
123
- </ DropdownMenuPortal >
124
- </ DropdownMenu >
125
- </ div >
100
+ < DropdownMenu >
101
+ < DropdownMenuTrigger className = "flex w-fit min-w-[140px] cursor-pointer items-center justify-between rounded-md border bg-surface-primary px-2 py-1.5 text-content-secondary transition-colors hover:text-content-primary data-[state=open]:text-content-primary" >
102
+ < div className = "flex items-center justify-center gap-2" >
103
+ < BookIcon width = { 18 } height = { 18 } />
104
+ < p className = "text-xs" > Examples</ p >
105
+ </ div >
106
+ < ChevronDownIcon width = { 18 } height = { 18 } />
107
+ </ DropdownMenuTrigger >
126
108
127
- { /* CODE EDITOR */ }
128
- < div className = "absolute mt-12 flex h-full w-full justify-end p-3" >
129
- < Button
130
- className = "z-10"
131
- variant = "subtle"
132
- size = "sm"
133
- onClick = { onCopy }
109
+ < DropdownMenuPortal >
110
+ < DropdownMenuContent align = "start" >
111
+ < DropdownMenuItem >
112
+ < TextCursorInputIcon width = { 24 } height = { 24 } />
113
+ Text input
114
+ </ DropdownMenuItem >
115
+ < DropdownMenuItem >
116
+ < SquareMousePointerIcon width = { 24 } height = { 24 } />
117
+ Multi-select
118
+ </ DropdownMenuItem >
119
+ < DropdownMenuItem >
120
+ < RadioIcon width = { 24 } height = { 24 } />
121
+ Radio
122
+ </ DropdownMenuItem >
123
+ < DropdownMenuItem >
124
+ < ToggleLeftIcon width = { 24 } height = { 24 } /> Switches
125
+ </ DropdownMenuItem >
126
+ </ DropdownMenuContent >
127
+ </ DropdownMenuPortal >
128
+ </ DropdownMenu >
129
+ </ div >
130
+ </ Tabs . List >
131
+
132
+ { /* CODE EDITOR */ }
133
+ < div
134
+ className = { cn (
135
+ "absolute mt-12 flex h-full w-full justify-end p-3" ,
136
+ tab !== "code" && "hidden" ,
137
+ ) }
134
138
>
135
- { codeCopied ? < CheckIcon /> : < CopyIcon /> } Copy
136
- </ Button >
137
- </ div >
139
+ < Button className = "z-10" variant = "subtle" size = "sm" onClick = { onCopy } >
140
+ { codeCopied ? < CheckIcon /> : < CopyIcon /> } Copy
141
+ </ Button >
142
+ </ div >
138
143
139
- < div className = "h-full w-full overflow-y-scroll bg-surface-secondary font-mono" >
140
- < CodeEditor
141
- value = { $code }
142
- onValueChange = { ( code ) => $setCode ( code ) }
143
- highlight = { ( code ) => hightlightWithLineNumbers ( code , languages . hcl ) }
144
- textareaId = "codeArea"
145
- className = "editor pt-3"
146
- />
147
- </ div >
148
- </ ResizablePanel >
144
+ < Tabs . Content value = "code" asChild = { true } >
145
+ < div className = "h-full w-full overflow-y-scroll bg-surface-secondary font-mono" >
146
+ < CodeEditor
147
+ value = { $code }
148
+ onValueChange = { ( code ) => $setCode ( code ) }
149
+ highlight = { ( code ) =>
150
+ hightlightWithLineNumbers ( code , languages . hcl )
151
+ }
152
+ textareaId = "codeArea"
153
+ className = "editor pt-3"
154
+ />
155
+ </ div >
156
+ </ Tabs . Content >
157
+ </ ResizablePanel >
158
+ </ Tabs . Root >
149
159
) ;
150
160
} ;
0 commit comments