# Arco Design Mobile Arco Design Mobile is a comprehensive React UI component library designed specifically for mobile H5 and WebView environments. Built on TypeScript and Less, it provides 50+ production-ready components that follow the Arco Design system principles with pixel-perfect restoration and optimized touch interactions. The library has been battle-tested in high-traffic online environments and offers features like server-side rendering, internationalization, on-demand imports, and theme customization. The library uses rem-based responsive design (base font size: 50px) and requires a flexible.js implementation or similar tool to dynamically set the root font size based on screen dimensions. Components are organized in a monorepo structure using Lerna, with the main package published as `@arco-design/mobile-react`. The architecture supports both ESM and CommonJS module formats, enabling flexible integration patterns including tree-shaking for optimal bundle sizes. ## Installation and Setup ### Installing the Package ```bash npm install @arco-design/mobile-react # or yarn add @arco-design/mobile-react ``` ### Configuring Responsive Scaling ```javascript import setRootPixel from '@arco-design/mobile-react/tools/flexible'; // Initialize with default settings (baseFontSize: 50, sketchWidth: 375, maxFontSize: 64) setRootPixel(); // Or customize settings const removeRootPixel = setRootPixel(37.5); // Custom base font size // Later, if needed, remove the listener removeRootPixel(); ``` ### Babel Plugin for Tree-Shaking (Webpack/Babel) ```javascript // .babelrc.js or babel.config.js module.exports = { plugins: [ ["import", { "libraryName": "@arco-design/mobile-react", "libraryDirectory": "esm", // Use "cjs" for SSR "style": (path) => `${path}/style` }, "@arco-design/mobile-react"], ["import", { "libraryName": "@arco-design/mobile-react/esm/icon", "libraryDirectory": "", "camel2DashComponentName": false }, "@arco-design/mobile-react/esm/icon"] ] }; ``` ### Vite Plugin for Tree-Shaking ```javascript // vite.config.ts import { defineConfig } from 'vite'; import usePluginImport from 'vite-plugin-importer'; export default defineConfig({ plugins: [ usePluginImport({ libraryName: "@arco-design/mobile-react", libraryDirectory: "esm", style: (path) => `${path}/style`, }), usePluginImport({ libraryName: "@arco-design/mobile-react/esm/icon", libraryDirectory: "", camel2DashComponentName: false, }) ] }); ``` ## Button Component ### Basic Button Usage ```typescript import React from 'react'; import ReactDOM from 'react-dom'; import Button from '@arco-design/mobile-react/esm/button'; import '@arco-design/mobile-react/esm/button/style'; function ButtonExample() { const handleClick = (e) => { console.log('Button clicked', e); }; const handleDisabledClick = (e) => { console.log('Disabled button clicked', e); }; return (
{/* Primary button */} {/* Default button */} {/* Ghost button */} {/* Loading state */} {/* Disabled button with callback */} {/* Custom size */} {/* Round shape with icon */} {/* Inline button */}
); } ReactDOM.render(, document.getElementById('root')); ``` ## Dialog Component ### Imperative Dialog Methods ```typescript import React, { useState } from 'react'; import Dialog from '@arco-design/mobile-react/esm/dialog'; import '@arco-design/mobile-react/esm/dialog/style'; function DialogExample() { // Alert dialog (single OK button) const showAlert = () => { const { close, update } = Dialog.alert({ title: 'Success', children: 'Your operation was completed successfully!', okText: 'Got it', onOk: (e) => { console.log('OK clicked'); // Return true to prevent auto-close return false; }, onClose: (scene) => { console.log('Dialog closed', scene); } }); // Update dialog after 2 seconds setTimeout(() => { update({ children: 'Updated content!' }); }, 2000); // Programmatically close // close(); }; // Confirm dialog (OK and Cancel buttons) const showConfirm = () => { Dialog.confirm({ title: 'Delete Confirmation', children: 'Are you sure you want to delete this item? This action cannot be undone.', okText: 'Delete', cancelText: 'Cancel', platform: 'ios', // or 'android' onOk: async (e) => { console.log('Deleting...'); // Simulate async operation await new Promise(resolve => setTimeout(resolve, 1000)); console.log('Deleted'); return false; // Allow close }, onCancel: (e) => { console.log('Cancelled'); } }); }; // Custom dialog const showCustomDialog = () => { Dialog.open({ title: 'Custom Dialog', children: (

This is a custom dialog with custom footer

), footer: [ { content: 'Action 1', onClick: (e) => { console.log('Action 1'); return true; // Prevent close } }, { content: 'Action 2', className: 'custom-button', onClick: (e) => { console.log('Action 2'); } }, { content: 'Close', onClick: (e) => { console.log('Close'); } } ], footerType: 'button', // 'grid' or 'button' maskClosable: true }); }; return (
); } export default DialogExample; ``` ### Controlled Dialog ```typescript import React, { useState } from 'react'; import Dialog from '@arco-design/mobile-react/esm/dialog'; import '@arco-design/mobile-react/esm/dialog/style'; function ControlledDialogExample() { const [visible, setVisible] = useState(false); const [content, setContent] = useState('Initial content'); return ( <> setVisible(false)} title="Controlled Dialog" footer={[ { content: 'Cancel', onClick: () => setVisible(false) }, { content: 'Confirm', onClick: () => { console.log('Confirmed'); setVisible(false); } } ]} maskClosable={true} onClose={(scene) => { console.log('Dialog closed:', scene); }} >
{content}
); } ``` ## Toast Component ### Toast Notifications ```typescript import React from 'react'; import Toast from '@arco-design/mobile-react/esm/toast'; import '@arco-design/mobile-react/esm/toast/style'; function ToastExample() { // Info toast (text only) const showInfo = () => { const { close, update } = Toast.info('This is an info message'); // Update after 1 second setTimeout(() => { update({ content: 'Updated message' }); }, 1000); }; // Success toast const showSuccess = () => { Toast.success({ content: 'Operation successful!', duration: 2000, // Auto close after 2s direction: 'center', // 'top' | 'center' | 'bottom' onClose: () => { console.log('Toast closed'); } }); }; // Error toast const showError = () => { Toast.error({ content: 'Something went wrong!', duration: 3000 }); }; // Loading toast const showLoading = () => { const { close } = Toast.loading({ content: 'Loading...', duration: 0, // Won't auto close disableBodyTouch: true // Disable background interaction }); // Simulate async operation setTimeout(() => { close(); Toast.success('Loaded successfully!'); }, 3000); }; // Warning toast const showWarning = () => { Toast.warn('This is a warning message'); }; // Custom layout const showCustomLayout = () => { Toast.info({ content: 'Horizontal layout message', layout: 'horizontal', // 'vertical' | 'horizontal' icon: 🎉, duration: 2000 }); }; // Toast at top const showTopToast = () => { Toast.info({ content: 'Top positioned toast', direction: 'top' }); }; return (
); } export default ToastExample; ``` ## Input Component ### Text Input with Validation ```typescript import React, { useState } from 'react'; import Input from '@arco-design/mobile-react/esm/input'; import '@arco-design/mobile-react/esm/input/style'; function InputExample() { const [value, setValue] = useState(''); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); return (
{/* Basic input */} setValue(val)} clearable={true} label="Name" border="bottom" /> {/* Email input with validation */} setEmail(val)} validator={/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/} label="Email" required={true} clearable={true} border="bottom" style={{ marginTop: '16px' }} /> {/* Password input */} setPassword(val)} maxLength={20} label="Password" required={true} clearable={true} clearShowType="always" border="bottom" style={{ marginTop: '16px' }} /> {/* Input with prefix and suffix */} $} suffix={USD} border="all" style={{ marginTop: '16px' }} /> {/* Input with prepend and append */} {/* Disabled input */} {/* Read-only input */}
Current values: {value} / {email} / {password}
); } export default InputExample; ``` ## Form Component ### Complete Form with Validation ```typescript import React, { useRef } from 'react'; import Form from '@arco-design/mobile-react/esm/form'; import Input from '@arco-design/mobile-react/esm/input'; import Textarea from '@arco-design/mobile-react/esm/textarea'; import Switch from '@arco-design/mobile-react/esm/switch'; import Button from '@arco-design/mobile-react/esm/button'; import Toast from '@arco-design/mobile-react/esm/toast'; import '@arco-design/mobile-react/esm/form/style'; import '@arco-design/mobile-react/esm/input/style'; import '@arco-design/mobile-react/esm/textarea/style'; import '@arco-design/mobile-react/esm/switch/style'; import '@arco-design/mobile-react/esm/button/style'; import '@arco-design/mobile-react/esm/toast/style'; function FormExample() { const [form] = Form.useForm(); const handleSubmit = (values, errors) => { if (errors && errors.length > 0) { Toast.error('Please fix form errors'); return; } console.log('Form submitted:', values); Toast.success('Form submitted successfully!'); }; const handleSubmitFailed = (values, errorInfo) => { console.log('Submit failed:', values, errorInfo); Toast.error('Form validation failed'); }; const handleReset = () => { form.resetFields(); Toast.info('Form reset'); }; return (
{ console.log('Form changed:', changedValues, allValues); }} >