11import { useSnippngEditor } from "@/context/SnippngEditorContext" ;
22import { useToast } from "@/context/ToastContext" ;
33import { ColorPicker } from "@/lib/color-picker" ;
4- import { DOWNLOAD_OPTIONS , LANGUAGES , THEMES } from "@/lib/constants" ;
4+ import {
5+ defaultEditorConfig ,
6+ DOWNLOAD_OPTIONS ,
7+ LANGUAGES ,
8+ THEMES ,
9+ } from "@/lib/constants" ;
10+ import { ImagePicker } from "@/lib/image-picker" ;
511import { SelectOptionInterface } from "@/types" ;
612import { getEditorWrapperBg } from "@/utils" ;
713import { Menu , Transition } from "@headlessui/react" ;
@@ -11,16 +17,19 @@ import {
1117 Cog6ToothIcon ,
1218 CommandLineIcon ,
1319 DocumentDuplicateIcon ,
20+ PhotoIcon ,
1421 SparklesIcon ,
1522} from "@heroicons/react/24/outline" ;
1623import * as htmlToImage from "html-to-image" ;
17- import { Fragment } from "react" ;
24+ import { Fragment , RefObject } from "react" ;
1825import Button from "../form/Button" ;
1926import Checkbox from "../form/Checkbox" ;
2027import Range from "../form/Range" ;
2128import Select from "../form/Select" ;
2229
23- const SnippngControlHeader = ( ) => {
30+ const SnippngControlHeader : React . FC < {
31+ wrapperRef : RefObject < HTMLDivElement > ;
32+ } > = ( { wrapperRef } ) => {
2433 const { editorConfig, handleConfigChange } = useSnippngEditor ( ) ;
2534 const { addToast } = useToast ( ) ;
2635
@@ -41,6 +50,8 @@ const SnippngControlHeader = () => {
4150 gradients,
4251 gradientAngle,
4352 snippetsName,
53+ bgBlur = 0 ,
54+ bgImageVisiblePatch,
4455 } = editorConfig ;
4556
4657 const downloadImage = ( type : SelectOptionInterface ) => {
@@ -108,6 +119,22 @@ const SnippngControlHeader = () => {
108119 data-testid = "wrapper-color-picker"
109120 className = "relative lg:w-fit w-full flex lg:justify-start justify-end items-center gap-2"
110121 >
122+ < Button
123+ onClick = { ( ) => {
124+ if ( ! navigator ?. clipboard )
125+ return addToast ( {
126+ message : "navigator unavailable" ,
127+ type : "error" ,
128+ } ) ;
129+ navigator . clipboard ?. writeText ( code ) . then ( ( ) => {
130+ addToast ( {
131+ message : "Code snippet copied!" ,
132+ } ) ;
133+ } ) ;
134+ } }
135+ >
136+ < DocumentDuplicateIcon className = "h-5 w-5 dark:text-white text-zinc-900" />
137+ </ Button >
111138 < ColorPicker
112139 color = { wrapperBg }
113140 gradientColors = { gradients }
@@ -134,22 +161,18 @@ const SnippngControlHeader = () => {
134161 } }
135162 > </ button >
136163 </ ColorPicker >
137- < Button
138- onClick = { ( ) => {
139- if ( ! navigator ?. clipboard )
140- return addToast ( {
141- message : "navigator unavailable" ,
142- type : "error" ,
143- } ) ;
144- navigator . clipboard ?. writeText ( code ) . then ( ( ) => {
145- addToast ( {
146- message : "Code snippet copied!" ,
147- } ) ;
148- } ) ;
149- } }
164+ < ImagePicker
165+ aspect = {
166+ wrapperRef ?. current
167+ ? wrapperRef . current . clientWidth / wrapperRef . current . clientHeight
168+ : 1
169+ }
170+ onChange = { ( src ) => handleConfigChange ( "bgImageVisiblePatch" ) ( src ) }
150171 >
151- < DocumentDuplicateIcon className = "h-5 w-5 dark:text-white text-zinc-900" />
152- </ Button >
172+ < button className = "h-8 cursor-pointer rounded-sm outline justify-center items-center outline-1 dark:outline-white outline-zinc-400 flex aspect-square " >
173+ < PhotoIcon className = "h-4 w-4 mx-auto dark:text-white text-zinc-900" />
174+ </ button >
175+ </ ImagePicker >
153176 </ div >
154177
155178 < div className = "ml-auto" >
@@ -222,6 +245,51 @@ const SnippngControlHeader = () => {
222245 } }
223246 />
224247 </ div >
248+ < div className = "py-1 px-2" >
249+ < Checkbox
250+ label = "Remove background"
251+ id = "remove-bg"
252+ data-testid = "remove-bg"
253+ checked = {
254+ wrapperBg === "transparent" &&
255+ ! gradients . length &&
256+ ! bgBlur &&
257+ ! bgImageVisiblePatch
258+ }
259+ onChange = { ( e ) => {
260+ if ( ! e . target . checked ) {
261+ handleConfigChange ( "bgImageVisiblePatch" ) (
262+ defaultEditorConfig . bgImageVisiblePatch
263+ ) ;
264+ handleConfigChange ( "bgBlur" ) ( defaultEditorConfig . bgBlur ) ;
265+ handleConfigChange ( "gradients" ) (
266+ defaultEditorConfig . gradients
267+ ) ;
268+ handleConfigChange ( "wrapperBg" ) (
269+ defaultEditorConfig . wrapperBg
270+ ) ;
271+ } else {
272+ handleConfigChange ( "bgImageVisiblePatch" ) ( null ) ;
273+ handleConfigChange ( "bgBlur" ) ( 0 ) ;
274+ handleConfigChange ( "gradients" ) ( [ ] ) ;
275+ handleConfigChange ( "wrapperBg" ) ( "transparent" ) ;
276+ }
277+ } }
278+ />
279+ </ div >
280+ < div className = "py-1 px-2 z-30" >
281+ < Range
282+ label = { `Bg blur (${ bgBlur } px)` }
283+ value = { bgBlur }
284+ max = { 20 }
285+ min = { 0 }
286+ rangeMax = "20"
287+ rangeMin = "0"
288+ onChange = { ( e ) => {
289+ handleConfigChange ( "bgBlur" ) ( + e . target . value ) ;
290+ } }
291+ />
292+ </ div >
225293 < div className = "py-1 px-2 z-30" >
226294 < Range
227295 label = { `Font size (${ editorFontSize } px)` }
0 commit comments