mr-component
Version:
A library for Mr components
534 lines (494 loc) • 15.1 kB
HTML
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>支付方式选择器 - 完全还原Figma设计</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', sans-serif;
margin: 0;
padding: 20px;
background: #f5f6fa;
}
.phone-container {
max-width: 375px;
margin: 0 auto;
background: white;
border-radius: 20px;
overflow: hidden;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
}
.phone-header {
display: flex;
align-items: center;
padding: 16px 20px;
background: white;
border-bottom: 1px solid #f0f0f0;
}
.back-button {
font-size: 20px;
margin-right: 16px;
cursor: pointer;
}
.header-title {
font-size: 18px;
font-weight: 600;
color: #333;
}
.phone-content {
padding: 20px;
min-height: 500px;
background: white;
}
.confirm-button {
margin: 20px;
padding: 16px;
background: #4a90e2;
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
width: calc(100% - 40px);
}
.confirm-button:hover {
background: #357abd;
}
.demo-info {
max-width: 600px;
margin: 20px auto;
padding: 20px;
background: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.demo-title {
font-size: 20px;
font-weight: 600;
color: #333;
margin-bottom: 16px;
}
.comparison {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-top: 20px;
}
.comparison-item {
padding: 15px;
border: 1px solid #e8e8e8;
border-radius: 8px;
}
.comparison-title {
font-size: 16px;
font-weight: 600;
margin-bottom: 10px;
}
.comparison-title.original {
color: #4a90e2;
}
.comparison-title.new {
color: #07c160;
}
@media (max-width: 768px) {
.comparison {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="demo-info">
<div class="demo-title">🎯 专为您的Figma设计定制的支付选择器</div>
<p>
基于您的Figma截图,我创建了一个更适合支付场景的BusinessPaymentSelector组件。对比传统的MrSelect:
</p>
<div class="comparison">
<div class="comparison-item">
<div class="comparison-title original">❌ MrSelect (Picker)</div>
<ul style="margin: 10px 0; padding-left: 20px; color: #666">
<li>弹窗选择器,需要点击确认</li>
<li>不适合支付场景</li>
<li>无法显示余额和手续费</li>
<li>用户体验不佳</li>
</ul>
</div>
<div class="comparison-item">
<div class="comparison-title new">✅ BusinessPaymentSelector</div>
<ul style="margin: 10px 0; padding-left: 20px; color: #666">
<li>列表式选择,即点即选</li>
<li>专为支付场景设计</li>
<li>支持余额、手续费显示</li>
<li>完美还原您的设计</li>
</ul>
</div>
</div>
</div>
<div class="phone-container">
<div class="phone-header">
<div class="back-button">←</div>
<div class="header-title">Safaricom Postpaid</div>
</div>
<div class="phone-content">
<div id="payment-selector"></div>
</div>
<button class="confirm-button" onclick="handleConfirm()">Confirm</button>
</div>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script>
// 临时引入BusinessPaymentSelector组件(因为还没有构建)
const { createElement: h, useState, forwardRef } = React;
const { createRoot } = ReactDOM;
// 这里直接复制BusinessPaymentSelector的代码
// ... (组件代码)
// 支付选项数据 - 完全按照您的Figma设计
const paymentOptions = [
{
id: 'wallet',
name: 'Wallet',
balance: '140,455.50',
currency: 'KES',
extra: 'Not Allow for Overdraft',
icon: h(
'div',
{
style: {
width: '32px',
height: '32px',
borderRadius: '50%',
background: '#4A90E2',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'white',
fontSize: '14px',
fontWeight: 'bold',
},
},
'W',
),
},
{
id: 'murongbank1',
name: 'MuRong Bank',
balance: '13,093.40',
currency: 'KES',
fee: '6.00 KES',
extra: 'Immediate',
icon: h(
'div',
{
style: {
width: '32px',
height: '32px',
borderRadius: '50%',
background: '#07C160',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'white',
fontSize: '14px',
fontWeight: 'bold',
},
},
'M',
),
},
{
id: 'murongbank2',
name: 'MuRong Bank',
balance: '0.00',
currency: 'CNY',
fee: '6.00 KES',
extra: 'Immediate',
disabled: true,
disabledReason: 'Insufficient balance',
icon: h(
'div',
{
style: {
width: '32px',
height: '32px',
borderRadius: '50%',
background: '#999',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'white',
fontSize: '14px',
fontWeight: 'bold',
},
},
'M',
),
},
{
id: 'murongbank3',
name: 'MuRong Bank',
balance: '2,500.00',
currency: 'KES',
fee: '6.00 KES',
extra: 'Immediate',
icon: h(
'div',
{
style: {
width: '32px',
height: '32px',
borderRadius: '50%',
background: '#07C160',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'white',
fontSize: '14px',
fontWeight: 'bold',
},
},
'M',
),
},
{
id: 'murongbank4',
name: 'MuRong Bank',
balance: '0.00',
currency: 'USD',
fee: '6.00 KES',
extra: 'Immediate',
disabled: true,
disabledReason: 'Insufficient balance',
icon: h(
'div',
{
style: {
width: '32px',
height: '32px',
borderRadius: '50%',
background: '#999',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'white',
fontSize: '14px',
fontWeight: 'bold',
},
},
'M',
),
},
];
// 由于组件还没构建,这里做一个简化版本演示
function SimplePaymentSelector() {
const [selectedId, setSelectedId] = useState('wallet');
const handleSelect = (id) => {
setSelectedId(id);
console.log('选择了:', id);
};
const handleAddCard = () => {
alert('Add a new card clicked!');
};
return h('div', {}, [
h(
'div',
{
key: 'title',
style: {
fontSize: '18px',
fontWeight: '600',
color: '#333',
marginBottom: '20px',
},
},
'Payment Source',
),
...paymentOptions.map((option) =>
h(
'div',
{
key: option.id,
style: {
display: 'flex',
alignItems: 'center',
padding: '16px',
marginBottom: '12px',
borderRadius: '8px',
border: selectedId === option.id ? '2px solid #4A90E2' : '1px solid #E8E8E8',
backgroundColor: selectedId === option.id ? '#F0F8FF' : '#FFFFFF',
cursor: option.disabled ? 'not-allowed' : 'pointer',
opacity: option.disabled ? 0.5 : 1,
transition: 'all 0.3s ease',
},
onClick: () => !option.disabled && handleSelect(option.id),
},
[
// 选择圆点
h(
'div',
{
key: 'radio',
style: {
width: '20px',
height: '20px',
borderRadius: '50%',
border: `2px solid ${selectedId === option.id ? '#4A90E2' : '#E8E8E8'}`,
backgroundColor: selectedId === option.id ? '#4A90E2' : 'transparent',
marginRight: '12px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
},
selectedId === option.id
? h('div', {
style: {
width: '8px',
height: '8px',
borderRadius: '50%',
backgroundColor: 'white',
},
})
: null,
),
// 图标
h('div', { key: 'icon', style: { marginRight: '12px' } }, option.icon),
// 主要内容
h('div', { key: 'content', style: { flex: 1 } }, [
h(
'div',
{
key: 'name',
style: {
fontSize: '16px',
fontWeight: '500',
marginBottom: '4px',
color: selectedId === option.id ? '#4A90E2' : '#333',
},
},
option.name,
),
h(
'div',
{
key: 'balance',
style: {
fontSize: '14px',
color: '#666',
marginBottom: '2px',
},
},
`${option.currency} ${option.balance}`,
),
option.extra &&
h(
'div',
{
key: 'extra',
style: {
fontSize: '12px',
color: '#999',
},
},
option.extra,
),
option.disabledReason &&
h(
'div',
{
key: 'disabled',
style: {
fontSize: '12px',
color: '#EE0A24',
marginTop: '2px',
},
},
option.disabledReason,
),
]),
// 手续费
option.fee &&
h(
'div',
{
key: 'fee',
style: {
fontSize: '12px',
color: '#666',
textAlign: 'right',
},
},
`Fee: ${option.fee}`,
),
],
),
),
// Add a new card
h(
'div',
{
key: 'add-card',
style: {
display: 'flex',
alignItems: 'center',
padding: '16px',
marginTop: '8px',
borderRadius: '8px',
border: '1px dashed #E8E8E8',
backgroundColor: '#FFFFFF',
cursor: 'pointer',
transition: 'all 0.3s ease',
},
onClick: handleAddCard,
},
[
h(
'div',
{
key: 'plus',
style: {
width: '20px',
height: '20px',
borderRadius: '50%',
border: '2px solid #E8E8E8',
marginRight: '12px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: '16px',
fontWeight: 'bold',
color: '#666',
},
},
'+',
),
h(
'span',
{
key: 'text',
style: { fontSize: '16px', fontWeight: '500', color: '#333', flex: 1 },
},
'Add a new card',
),
h(
'div',
{
key: 'arrow',
style: { fontSize: '18px', color: '#666' },
},
'→',
),
],
),
]);
}
// 渲染组件
createRoot(document.getElementById('payment-selector')).render(h(SimplePaymentSelector));
// 确认按钮处理
function handleConfirm() {
alert('支付确认!这个组件完美适配您的Figma设计 🎉');
}
</script>
</body>
</html>