1
- import { FrameTheme , FrameState } from "./types.js" ;
2
- import React , { ImgHTMLAttributes , useEffect } from "react" ;
3
- import { FrameButton } from "frames.js" ;
1
+ import type { ImgHTMLAttributes } from "react" ;
2
+ import React , { useEffect , useState } from "react" ;
3
+ import type { FrameButton } from "frames.js" ;
4
+ import type { FrameTheme , FrameState } from "./types" ;
4
5
5
6
export const defaultTheme : Required < FrameTheme > = {
6
7
buttonBg : "#fff" ,
@@ -11,7 +12,7 @@ export const defaultTheme: Required<FrameTheme> = {
11
12
bg : "#efefef" ,
12
13
} ;
13
14
14
- const getThemeWithDefaults = ( theme : FrameTheme ) => {
15
+ const getThemeWithDefaults = ( theme : FrameTheme ) : FrameTheme => {
15
16
return {
16
17
...defaultTheme ,
17
18
...theme ,
@@ -25,8 +26,12 @@ export type FrameUIProps = {
25
26
} ;
26
27
27
28
/** A UI component only, that should be easy for any app to integrate */
28
- export function FrameUI ( { frameState, theme, FrameImage } : FrameUIProps ) {
29
- const [ isImageLoading , setIsImageLoading ] = React . useState ( true ) ;
29
+ export function FrameUI ( {
30
+ frameState,
31
+ theme,
32
+ FrameImage,
33
+ } : FrameUIProps ) : React . JSX . Element | null {
34
+ const [ isImageLoading , setIsImageLoading ] = useState ( true ) ;
30
35
31
36
const isLoading = ! ! frameState . isLoading || isImageLoading ;
32
37
@@ -53,7 +58,7 @@ export function FrameUI({ frameState, theme, FrameImage }: FrameUIProps) {
53
58
< ImageEl
54
59
src = { frameState . frame . image }
55
60
alt = "Frame image"
56
- width = { "100%" }
61
+ width = "100%"
57
62
style = { {
58
63
filter : isLoading ? "blur(4px)" : undefined ,
59
64
borderTopLeftRadius : `${ resolvedTheme . buttonRadius } px` ,
@@ -69,9 +74,11 @@ export function FrameUI({ frameState, theme, FrameImage }: FrameUIProps) {
69
74
onLoad = { ( ) => {
70
75
setIsImageLoading ( false ) ;
71
76
} }
72
- onError = { ( ) => setIsImageLoading ( false ) }
77
+ onError = { ( ) => {
78
+ setIsImageLoading ( false ) ;
79
+ } }
73
80
/>
74
- { frameState . frame . inputText && (
81
+ { frameState . frame . inputText ? (
75
82
< input
76
83
className = "p-[6px] mx-2 border box-border"
77
84
style = { {
@@ -81,9 +88,11 @@ export function FrameUI({ frameState, theme, FrameImage }: FrameUIProps) {
81
88
value = { frameState . inputText }
82
89
type = "text"
83
90
placeholder = { frameState . frame . inputText }
84
- onChange = { ( e ) => frameState . setInputText ( e . target . value ) }
91
+ onChange = { ( e ) => {
92
+ frameState . setInputText ( e . target . value ) ;
93
+ } }
85
94
/>
86
- ) }
95
+ ) : null }
87
96
< div
88
97
style = { {
89
98
display : "flex" ,
@@ -108,7 +117,13 @@ export function FrameUI({ frameState, theme, FrameImage }: FrameUIProps) {
108
117
color : resolvedTheme . buttonColor ,
109
118
cursor : isLoading ? undefined : "pointer" ,
110
119
} }
111
- onClick = { ( ) => frameState . onButtonPress ( frameButton , index ) }
120
+ onClick = { ( ) => {
121
+ Promise . resolve ( frameState . onButtonPress ( frameButton , index ) ) . catch ( ( e : unknown ) => {
122
+ // eslint-disable-next-line no-console -- provide feedback to the user
123
+ console . error ( e ) ;
124
+ } ) ;
125
+ } }
126
+ // eslint-disable-next-line react/no-array-index-key -- this is fine
112
127
key = { index }
113
128
>
114
129
{ frameButton . action === "mint" ? `⬗ ` : "" }
@@ -124,7 +139,7 @@ export function FrameUI({ frameState, theme, FrameImage }: FrameUIProps) {
124
139
height = "12"
125
140
fill = "currentColor"
126
141
>
127
- < path d = "M9.504.43a1.516 1.516 0 0 1 2.437 1.713L10.415 5.5h2.123c1.57 0 2.346 1.909 1.22 3.004l-7.34 7.142a1.249 1.249 0 0 1-.871.354h-.302a1.25 1.25 0 0 1-1.157-1.723L5.633 10.5H3.462c-1.57 0-2.346-1.909-1.22-3.004L9.503.429Zm1.047 1.074L3.286 8.571A.25.25 0 0 0 3.462 9H6.75a.75.75 0 0 1 .694 1.034l-1.713 4.188 6.982-6.793A.25.25 0 0 0 12.538 7H9.25a.75.75 0 0 1-.683-1.06l2.008-4.418.003-.006a.036.036 0 0 0-.004-.009l-.006-.006-.008-.001c-.003 0-.006.002-.009.004Z" > </ path >
142
+ < path d = "M9.504.43a1.516 1.516 0 0 1 2.437 1.713L10.415 5.5h2.123c1.57 0 2.346 1.909 1.22 3.004l-7.34 7.142a1.249 1.249 0 0 1-.871.354h-.302a1.25 1.25 0 0 1-1.157-1.723L5.633 10.5H3.462c-1.57 0-2.346-1.909-1.22-3.004L9.503.429Zm1.047 1.074L3.286 8.571A.25.25 0 0 0 3.462 9H6.75a.75.75 0 0 1 .694 1.034l-1.713 4.188 6.982-6.793A.25.25 0 0 0 12.538 7H9.25a.75.75 0 0 1-.683-1.06l2.008-4.418.003-.006a.036.036 0 0 0-.004-.009l-.006-.006-.008-.001c-.003 0-.006.002-.009.004Z" / >
128
143
</ svg >
129
144
) : (
130
145
""
0 commit comments