Skip to content

TelegramMainButton

控制 Telegram 底部的主操作按钮。这是一个无渲染组件,通过 Telegram WebApp API 控制原生主按钮。

导入

tsx
import { TelegramMainButton } from '@xcloud/ui-telegram'

示例

基础使用

最简单的使用方式:

tsx
import { TelegramMainButton } from '@xcloud/ui-telegram'

function CheckoutPage() {
  const handleCheckout = () => {
    // 处理结账逻辑
    console.log('Checkout clicked')
  }

  return (
    <>
      <TelegramMainButton text="结账" onClick={handleCheckout} />
      <div>Order summary...</div>
    </>
  )
}

加载状态

显示加载状态,适用于异步操作:

tsx
import { TelegramMainButton } from '@xcloud/ui-telegram'
import { useState } from 'react'

function FormPage() {
  const [loading, setLoading] = useState(false)

  const handleSubmit = async () => {
    setLoading(true)
    try {
      await submitForm()
      alert('提交成功!')
    } finally {
      setLoading(false)
    }
  }

  return (
    <>
      <TelegramMainButton
        text="提交"
        onClick={handleSubmit}
        loading={loading}
        disabled={loading}
      />
      <form>{/* Form fields */}</form>
    </>
  )
}

条件启用

根据表单验证结果启用/禁用按钮:

tsx
import { TelegramMainButton } from '@xcloud/ui-telegram'
import { useState } from 'react'

function RegistrationForm() {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')

  const isValid = email && password.length >= 8

  return (
    <>
      <TelegramMainButton
        text="注册"
        onClick={handleRegister}
        disabled={!isValid}
      />
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
      />
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
      />
    </>
  )
}

自定义颜色

自定义按钮的背景色和文字颜色:

tsx
import { TelegramMainButton } from '@xcloud/ui-telegram'

function DangerAction() {
  return (
    <TelegramMainButton
      text="删除账户"
      onClick={handleDelete}
      color="#ef4444"
      textColor="#ffffff"
    />
  )
}

function SuccessAction() {
  return (
    <TelegramMainButton
      text="确认订单"
      onClick={handleConfirm}
      color="#10b981"
      textColor="#ffffff"
    />
  )
}

动态文本

根据状态改变按钮文本:

tsx
import { TelegramMainButton } from '@xcloud/ui-telegram'
import { useState } from 'react'

function SubscriptionPage() {
  const [isSubscribed, setIsSubscribed] = useState(false)

  const handleToggle = () => {
    setIsSubscribed(!isSubscribed)
  }

  return (
    <TelegramMainButton
      text={isSubscribed ? '取消订阅' : '订阅'}
      onClick={handleToggle}
      color={isSubscribed ? '#ef4444' : '#3b82f6'}
    />
  )
}

组件 API

TelegramMainButton Props

属性类型默认值描述
textstring必需按钮文本
onClick() => void-点击按钮的回调函数
visiblebooleantrue是否显示按钮
disabledbooleanfalse是否禁用按钮
loadingbooleanfalse是否显示加载状态
colorstring-按钮背景颜色 (hex 格式,如 #3b82f6)
textColorstring-按钮文字颜色 (hex 格式,如 #ffffff)

行为说明

  1. 无渲染: 组件本身不渲染任何 DOM 元素,返回 null
  2. 原生控制: 通过 Telegram WebApp API 的 mainButton 对象控制原生按钮
  3. 自动挂载: 组件挂载时自动初始化主按钮
  4. 自动清理: 组件卸载时自动隐藏主按钮
  5. 状态同步: 所有属性变化时实时更新按钮状态
  6. 事件绑定: onClick 回调变化时自动更新事件监听器

状态组合

不同状态可以组合使用:

visibledisabledloading效果
truefalsefalse正常显示,可点击
truetruefalse显示但禁用,不可点击
truefalsetrue显示加载动画,可点击
truetruetrue显示加载动画,禁用 (推荐)
false--隐藏按钮

注意事项

  1. 必须在 TelegramProvider 中使用: 确保应用被 TelegramProvider 包裹
  2. 只在 Telegram 环境有效: 在非 Telegram 环境中组件不会有任何效果
  3. 避免多次使用: 同一时间只应该有一个 TelegramMainButton 组件
  4. 颜色格式: colortextColor 必须是 hex 格式 (如 #3b82f6)
  5. 加载时禁用: 通常在 loading 时同时设置 disabled

最佳实践

表单提交

tsx
function FormSubmit() {
  const [loading, setLoading] = useState(false)
  const [isValid, setIsValid] = useState(false)

  const handleSubmit = async () => {
    setLoading(true)
    try {
      await api.submit()
    } finally {
      setLoading(false)
    }
  }

  return (
    <TelegramMainButton
      text={loading ? '提交中...' : '提交'}
      onClick={handleSubmit}
      disabled={!isValid || loading}
      loading={loading}
    />
  )
}

支付流程

tsx
function PaymentButton() {
  const [loading, setLoading] = useState(false)
  const amount = 99.99

  const handlePay = async () => {
    setLoading(true)
    try {
      await processPayment(amount)
    } finally {
      setLoading(false)
    }
  }

  return (
    <TelegramMainButton
      text={`支付 ¥${amount}`}
      onClick={handlePay}
      loading={loading}
      disabled={loading}
      color="#10b981"
      textColor="#ffffff"
    />
  )
}

多步骤流程

tsx
function MultiStepForm() {
  const [step, setStep] = useState(1)
  const totalSteps = 3

  const buttonText = step === totalSteps ? '完成' : '下一步'

  const handleNext = () => {
    if (step < totalSteps) {
      setStep(step + 1)
    } else {
      handleComplete()
    }
  }

  return (
    <TelegramMainButton
      text={buttonText}
      onClick={handleNext}
      disabled={!isStepValid(step)}
    />
  )
}

相关链接

基于 MIT 许可发布