11import { useSnippngEditor } from "@/context/SnippngEditorContext" ;
22import { useToast } from "@/context/ToastContext" ;
33import { ColorPicker } from "@/lib/color-picker" ;
4- import { LANGUAGES , THEMES } from "@/lib/constants" ;
4+ import { DOWNLOAD_OPTIONS , LANGUAGES , THEMES } from "@/lib/constants" ;
5+ import { SelectOptionInterface } from "@/types" ;
56import { getEditorWrapperBg } from "@/utils" ;
67import { Menu , Transition } from "@headlessui/react" ;
78import {
@@ -20,8 +21,6 @@ import Range from "../form/Range";
2021import Select from "../form/Select" ;
2122
2223const SnippngControlHeader = ( ) => {
23- const [ downloadingSnippet , setDownloadingSnippet ] = useState ( false ) ;
24-
2524 const { editorConfig, handleConfigChange } = useSnippngEditor ( ) ;
2625 const { addToast } = useToast ( ) ;
2726
@@ -44,39 +43,48 @@ const SnippngControlHeader = () => {
4443 snippetsName,
4544 } = editorConfig ;
4645
47- const downloadImage = ( ) => {
46+ const downloadImage = ( type : SelectOptionInterface ) => {
4847 var node = document . getElementById ( "code-wrapper" ) ;
4948 if ( ! node ) return ;
50- setDownloadingSnippet ( true ) ;
51- htmlToImage
52- . toPng ( node )
49+ ( ( ) => {
50+ switch ( type . id ) {
51+ case "png" :
52+ return htmlToImage . toPng ( node ) ;
53+ case "jpeg" :
54+ return htmlToImage . toJpeg ( node ) ;
55+ case "svg" :
56+ return htmlToImage . toSvg ( node ) ;
57+ default :
58+ return htmlToImage . toPng ( node ) ;
59+ }
60+ } ) ( )
5361 . then ( ( dataUrl ) => {
5462 const a = document . createElement ( "a" ) ;
5563 a . href = dataUrl ;
5664 a . download = snippetsName
57- ? `${ snippetsName . split ( " " ) . join ( "_" ) . toLowerCase ( ) } .png`
58- : "snippng.png" ;
65+ ? `${ snippetsName . split ( " " ) . join ( "_" ) . toLowerCase ( ) } .${
66+ type . id || "png"
67+ } `
68+ : "snippng." + ( type . id || "png" ) ;
5969 a . click ( ) ;
6070 } )
6171 . catch ( ( error ) => {
6272 console . error ( "oops, something went wrong!" , error ) ;
63- } )
64- . finally ( ( ) => {
65- setDownloadingSnippet ( false ) ;
73+ addToast ( {
74+ message : "Error while downloading the image" ,
75+ type : "error" ,
76+ } ) ;
6677 } ) ;
6778 } ;
6879
6980 return (
7081 < div className = "mb-4 flex flex-wrap w-full justify-start items-center gap-2" >
71- < Button
72- className = "md:w-fit w-full"
73- data-testid = "download-cta"
74- disabled = { downloadingSnippet }
75- StartIcon = { CloudArrowDownIcon }
76- onClick = { downloadImage }
77- >
78- { downloadingSnippet ? "Downloading..." : "Download" }
79- </ Button >
82+ < Select
83+ Icon = { CloudArrowDownIcon }
84+ value = { { label : "Download" , id : "download" } }
85+ onChange = { downloadImage }
86+ options = { [ ...DOWNLOAD_OPTIONS ] }
87+ />
8088
8189 < Select
8290 Icon = { SparklesIcon }
@@ -98,7 +106,7 @@ const SnippngControlHeader = () => {
98106 />
99107 < div
100108 data-testid = "wrapper-color-picker"
101- className = "relative md :w-fit w-full"
109+ className = "relative lg :w-fit w-full flex lg:justify-start justify-end items-center gap-2 "
102110 >
103111 < ColorPicker
104112 color = { wrapperBg }
@@ -126,19 +134,20 @@ const SnippngControlHeader = () => {
126134 } }
127135 > </ button >
128136 </ ColorPicker >
129- </ div >
130- < Button
131- onClick = { ( ) => {
132- if ( ! navigator ) return ;
133- navigator . clipboard . writeText ( code ) . then ( ( ) => {
134- addToast ( {
135- message : "Code snippet copied!" ,
137+ < Button
138+ onClick = { ( ) => {
139+ if ( ! navigator ) return ;
140+ navigator . clipboard . writeText ( code ) . then ( ( ) => {
141+ addToast ( {
142+ message : "Code snippet copied!" ,
143+ } ) ;
136144 } ) ;
137- } ) ;
138- } }
139- >
140- < DocumentDuplicateIcon className = "h-5 w-5 dark:text-white text-zinc-900" />
141- </ Button >
145+ } }
146+ >
147+ < DocumentDuplicateIcon className = "h-5 w-5 dark:text-white text-zinc-900" />
148+ </ Button >
149+ </ div >
150+
142151 < div className = "ml-auto" >
143152 < Menu as = "div" className = "relative inline-block text-left" >
144153 < div >
0 commit comments