diff --git a/example/src/index.tsx b/example/src/index.tsx
index c4e39df2..5f2de44d 100644
--- a/example/src/index.tsx
+++ b/example/src/index.tsx
@@ -48,7 +48,32 @@ app.frame('/', (context) => {
,
,
,
- status === 'response' && ,
+ status === 'response' && Reset,
+ ],
+ }
+})
+
+app.frame('/buttons', ({ buttonValue }) => {
+ return {
+ image: (
+
+ {buttonValue ?? ''}
+
+ ),
+ intents: [
+ ,
+ Google,
+
+ Mint
+ ,
+ Reset,
],
}
})
diff --git a/src/index.tsx b/src/index.tsx
index 8950df58..3f8d1c71 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -11,6 +11,7 @@ import { type Context, Hono } from 'hono'
import { ImageResponse } from 'hono-og'
import { type JSXNode } from 'hono/jsx'
import { jsxRenderer } from 'hono/jsx-renderer'
+import type { HtmlEscapedString } from 'hono/utils/html'
import { Preview, previewStyles } from './preview.js'
import {
@@ -263,23 +264,84 @@ export class Farc extends Hono {
export type ButtonProps = {
children: string
index?: number | undefined
- type?: 'reset'
+}
+
+export type ButtonRootProps = ButtonProps & {
+ action?: 'post' | 'post_redirect'
value?: string | undefined
}
// TODO: `fc:frame:button:$idx:action` and `fc:frame:button:$idx:target`
-Button.__type = 'button'
-export function Button({ children, index = 0, type, value }: ButtonProps) {
- return (
+ButtonRoot.__type = 'button'
+export function ButtonRoot({
+ action = 'post',
+ children,
+ index = 0,
+ value,
+}: ButtonRootProps) {
+ return [
,
+ ,
+ ] as unknown as HtmlEscapedString
+}
+
+export type ButtonLinkProps = ButtonProps & {
+ href: string
+}
+
+ButtonLink.__type = 'button'
+export function ButtonLink({ children, index = 0, href }: ButtonLinkProps) {
+ return [
+ ,
+ ,
+ ,
+ ] as unknown as HtmlEscapedString
+}
+
+export type ButtonMintProps = ButtonProps & {
+ target: string
+}
+
+ButtonMint.__type = 'button'
+export function ButtonMint({ children, index = 0, target }: ButtonMintProps) {
+ return [
+ ,
+ ,
+ ,
+ ] as unknown as HtmlEscapedString
+}
+
+export type ButtonResetProps = ButtonProps
+
+ButtonReset.__type = 'button'
+export function ButtonReset({ children, index = 0 }: ButtonResetProps) {
+ return (
+
)
}
+export const Button = Object.assign(ButtonRoot, {
+ Link: ButtonLink,
+ Mint: ButtonMint,
+ Reset: ButtonReset,
+})
+
export type TextInputProps = {
placeholder?: string | undefined
}
@@ -302,7 +364,7 @@ function getIntentState(
if (!intents) return state
if (buttonIndex) {
const buttonIntents = intents.filter((intent) =>
- intent?.props.property.includes('fc:frame:button'),
+ intent?.props.property.match(/fc:frame:button:\d$/),
)
const intent = buttonIntents[buttonIndex - 1]
state.buttonValue = intent.props['data-value']
@@ -360,7 +422,7 @@ function parseIntents(intents_: Intents) {
return parseIntent(nodes, counter)
})()
- return Array.isArray(intents) ? intents : [intents]
+ return (Array.isArray(intents) ? intents : [intents]).flat()
}
function parseIntent(node_: JSXNode, counter: Counter) {