Connor Fogarty commited on
Commit
38e6a79
·
unverified ·
1 Parent(s): 9aca292

feat: add ability to change preview URL (#26)

Browse files
packages/bolt/app/components/workbench/Preview.tsx CHANGED
@@ -1,10 +1,11 @@
1
  import { useStore } from '@nanostores/react';
2
- import { memo, useEffect, useRef, useState } from 'react';
3
  import { IconButton } from '~/components/ui/IconButton';
4
  import { workbenchStore } from '~/lib/stores/workbench';
5
 
6
  export const Preview = memo(() => {
7
  const iframeRef = useRef<HTMLIFrameElement>(null);
 
8
  const [activePreviewIndex] = useState(0);
9
  const previews = useStore(workbenchStore.previews);
10
  const activePreview = previews[activePreviewIndex];
@@ -28,6 +29,25 @@ export const Preview = memo(() => {
28
  }
29
  }, [activePreview, iframeUrl]);
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  const reloadPreview = () => {
32
  if (iframeRef.current) {
33
  iframeRef.current.src = iframeRef.current.src;
@@ -43,12 +63,22 @@ export const Preview = memo(() => {
43
  <div className="i-ph:info-bold text-lg" />
44
  </div>
45
  <input
 
46
  className="w-full bg-transparent outline-none"
47
  type="text"
48
  value={url}
49
  onChange={(event) => {
50
  setUrl(event.target.value);
51
  }}
 
 
 
 
 
 
 
 
 
52
  />
53
  </div>
54
  </div>
 
1
  import { useStore } from '@nanostores/react';
2
+ import { memo, useCallback, useEffect, useRef, useState } from 'react';
3
  import { IconButton } from '~/components/ui/IconButton';
4
  import { workbenchStore } from '~/lib/stores/workbench';
5
 
6
  export const Preview = memo(() => {
7
  const iframeRef = useRef<HTMLIFrameElement>(null);
8
+ const inputRef = useRef<HTMLInputElement>(null);
9
  const [activePreviewIndex] = useState(0);
10
  const previews = useStore(workbenchStore.previews);
11
  const activePreview = previews[activePreviewIndex];
 
29
  }
30
  }, [activePreview, iframeUrl]);
31
 
32
+ const validateUrl = useCallback(
33
+ (value: string) => {
34
+ if (!activePreview) {
35
+ return false;
36
+ }
37
+
38
+ const { baseUrl } = activePreview;
39
+
40
+ if (value === baseUrl) {
41
+ return true;
42
+ } else if (value.startsWith(baseUrl)) {
43
+ return ['/', '?', '#'].includes(value.charAt(baseUrl.length));
44
+ }
45
+
46
+ return false;
47
+ },
48
+ [activePreview],
49
+ );
50
+
51
  const reloadPreview = () => {
52
  if (iframeRef.current) {
53
  iframeRef.current.src = iframeRef.current.src;
 
63
  <div className="i-ph:info-bold text-lg" />
64
  </div>
65
  <input
66
+ ref={inputRef}
67
  className="w-full bg-transparent outline-none"
68
  type="text"
69
  value={url}
70
  onChange={(event) => {
71
  setUrl(event.target.value);
72
  }}
73
+ onKeyDown={(event) => {
74
+ if (event.key === 'Enter' && validateUrl(url)) {
75
+ setIframeUrl(url);
76
+
77
+ if (inputRef.current) {
78
+ inputRef.current.blur();
79
+ }
80
+ }
81
+ }}
82
  />
83
  </div>
84
  </div>