Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Theme
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Create API Key
Add Docs
Arco Design Mobile
https://github.com/arco-design/arco-design-mobile
Admin
A comprehensive React UI components library based on the Arco Design system, offering over 50
...
Tokens:
231,469
Snippets:
1,219
Trust Score:
8.8
Update:
1 week ago
Context
Skills
Chat
Benchmark
80.3
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Arco Design Mobile Arco Design Mobile is a comprehensive React UI component library designed for mobile H5 and WebView environments. Built on TypeScript, it provides 50+ highly customizable components with pixel-perfect design, optimized touch interactions, and support for server-side rendering, internationalization, on-demand imports, and theme configuration. The library is battle-tested in high-traffic production environments. The component library follows a clean, minimalist design philosophy with fine-grained property configuration. It supports both iOS and Android platform-specific styles, dark mode, RTL layouts, and accessibility features. Components are designed with mobile-first interactions including gesture support, pull-to-refresh, and smooth animations. ## Installation ```bash # with npm npm install @arco-design/mobile-react # with yarn yarn add @arco-design/mobile-react ``` --- ## Button A versatile button component for triggering immediate actions, supporting multiple types, sizes, shapes, loading states, and custom colors. ```tsx import React, { useState } from 'react'; import Button from '@arco-design/mobile-react/esm/button'; import '@arco-design/mobile-react/esm/button/style'; function ButtonExample() { const [loading, setLoading] = useState(false); const handleClick = async () => { setLoading(true); await new Promise(resolve => setTimeout(resolve, 2000)); setLoading(false); }; return ( <div> {/* Primary button */} <Button type="primary" onClick={handleClick}> Primary Button </Button> {/* Ghost button with custom colors */} <Button type="ghost" color="#1890ff" borderColor="#1890ff" > Ghost Button </Button> {/* Loading state with disabled interaction */} <Button type="primary" loading={loading} disableWhenLoading={true} onClick={handleClick} > Submit </Button> {/* Different sizes and shapes */} <Button size="small" shape="round">Small Round</Button> <Button size="large" shape="square">Large Square</Button> {/* Inline button */} <Button inline disabled>Disabled Inline</Button> </div> ); } ``` --- ## Dialog A modal dialog component displayed in a floating layer for user confirmations and alerts. Includes built-in alert and confirm methods with anti-scroll penetration. ```tsx import React, { useState } from 'react'; import Dialog from '@arco-design/mobile-react/esm/dialog'; import Button from '@arco-design/mobile-react/esm/button'; import '@arco-design/mobile-react/esm/dialog/style'; function DialogExample() { const [visible, setVisible] = useState(false); // Imperative alert method const showAlert = () => { Dialog.alert({ title: 'Alert Title', children: 'This is an alert message', okText: 'Got it', onOk: () => console.log('Alert confirmed'), }); }; // Imperative confirm method const showConfirm = () => { const { close, update } = Dialog.confirm({ title: 'Confirm Action', children: 'Are you sure you want to proceed?', okText: 'Confirm', cancelText: 'Cancel', onOk: async () => { // Return true to prevent closing update({ children: 'Processing...' }); await new Promise(r => setTimeout(r, 1000)); return false; // Allow close }, onCancel: () => console.log('Cancelled'), }); }; // Declarative dialog with custom footer return ( <div> <Button onClick={showAlert}>Show Alert</Button> <Button onClick={showConfirm}>Show Confirm</Button> <Button onClick={() => setVisible(true)}>Custom Dialog</Button> <Dialog visible={visible} close={() => setVisible(false)} title="Custom Dialog" platform="ios" footer={[ { content: 'Cancel', onClick: () => setVisible(false) }, { content: 'OK', className: 'primary-btn', onClick: async () => { // Async operation, return true to prevent close return false; } }, ]} > <p>Custom dialog content with two buttons</p> </Dialog> </div> ); } ``` --- ## Toast A lightweight toast notification component supporting various display types including success, error, warning, and loading states. ```tsx import React from 'react'; import Toast from '@arco-design/mobile-react/esm/toast'; import Button from '@arco-design/mobile-react/esm/button'; import '@arco-design/mobile-react/esm/toast/style'; function ToastExample() { // Basic toast const showToast = () => { Toast.toast('This is a simple message'); }; // Success toast with auto-close const showSuccess = () => { Toast.success({ content: 'Operation successful!', duration: 2000, onClose: () => console.log('Toast closed'), }); }; // Error toast const showError = () => { Toast.error('Something went wrong'); }; // Warning toast const showWarn = () => { Toast.warn('Please check your input'); }; // Loading toast with manual close const showLoading = async () => { const { close, update } = Toast.loading({ content: 'Loading...', duration: 0, // Won't auto close disableBodyTouch: true, // Block interactions }); // Simulate async operation await new Promise(r => setTimeout(r, 2000)); // Update content before closing update({ content: 'Almost done...' }); await new Promise(r => setTimeout(r, 1000)); close(); Toast.success('Completed!'); }; return ( <div> <Button onClick={showToast}>Basic Toast</Button> <Button onClick={showSuccess}>Success</Button> <Button onClick={showError}>Error</Button> <Button onClick={showWarn}>Warning</Button> <Button onClick={showLoading}>Loading</Button> </div> ); } ``` --- ## Input A text input component supporting prefixes, suffixes, clearable functionality, and validation. ```tsx import React, { useState, useRef } 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 inputRef = useRef(null); return ( <div> {/* Basic input with label */} <Input label="Username" placeholder="Enter username" value={value} onChange={(e, val) => setValue(val)} clearable onClear={() => setValue('')} /> {/* Password input */} <Input label="Password" type="password" placeholder="Enter password" border="all" /> {/* Input with validation */} <Input label="Phone" type="tel" placeholder="Enter phone number" maxLength={11} validator={/^\d*$/} border="bottom" /> {/* Input with prefix and suffix */} <Input prefix={<span>$</span>} suffix={<span>.00</span>} placeholder="Enter amount" type="number" /> {/* Disabled and readonly states */} <Input label="Disabled" value="Cannot edit" disabled /> {/* Input with ref access */} <Input ref={inputRef} placeholder="Click button to focus" onPressEnter={(e) => console.log('Enter pressed')} /> <button onClick={() => inputRef.current?.input?.focus()}> Focus Input </button> </div> ); } ``` --- ## Tabs A tab switching component for navigating between different views, supporting swipe gestures and scroll listening modes. ```tsx import React, { useState, useRef } from 'react'; import Tabs from '@arco-design/mobile-react/esm/tabs'; import '@arco-design/mobile-react/esm/tabs/style'; function TabsExample() { const [activeTab, setActiveTab] = useState(0); const tabsRef = useRef(null); const tabs = [ { title: 'Home' }, { title: 'Products' }, { title: 'Services' }, { title: 'About' }, { title: 'Contact' }, ]; return ( <div> {/* Basic swipe tabs */} <Tabs tabs={tabs} defaultActiveTab={0} onChange={(tab, index) => console.log('Changed to:', index)} onAfterChange={(tab, index) => { // Fetch data after animation completes console.log('Animation complete, fetch data for:', index); }} > <div>Home Content</div> <div>Products Content</div> <div>Services Content</div> <div>About Content</div> <div>Contact Content</div> </Tabs> {/* Controlled tabs with different styles */} <Tabs ref={tabsRef} tabs={tabs} activeTab={activeTab} type="card" tabBarPosition="bottom" useCaterpillar onChange={(tab, index) => setActiveTab(index)} > {tabs.map((tab, i) => ( <div key={i}>{tab.title} Panel</div> ))} </Tabs> {/* Scroll mode tabs */} <Tabs tabs={tabs} mode="scroll" scrollThrottle={200} getScrollContainer={() => document.querySelector('.scroll-container')} > {tabs.map((tab, i) => ( <div key={i} style={{ height: 500 }}>{tab.title} Section</div> ))} </Tabs> {/* Manual tab change */} <button onClick={() => tabsRef.current?.changeIndex(2)}> Go to Services </button> </div> ); } ``` --- ## Form A form component for data collection with built-in validation, supporting various form controls. ```tsx import React, { useRef } from 'react'; import Form from '@arco-design/mobile-react/esm/form'; import Input from '@arco-design/mobile-react/esm/input'; import Switch from '@arco-design/mobile-react/esm/switch'; import Checkbox from '@arco-design/mobile-react/esm/checkbox'; import Button from '@arco-design/mobile-react/esm/button'; import '@arco-design/mobile-react/esm/form/style'; function FormExample() { const formRef = useRef(null); const handleSubmit = (values, errors) => { if (errors?.length) { console.log('Validation failed:', errors); return; } console.log('Form values:', values); }; const handleSubmitFailed = (values, errorInfo) => { console.log('Submit failed:', errorInfo); // Scroll to first error field errorInfo[0]?.dom?.scrollIntoView({ behavior: 'smooth' }); }; return ( <Form ref={formRef} layout="horizontal" initialValues={{ username: '', email: '', subscribe: true, }} onSubmit={handleSubmit} onSubmitFailed={handleSubmitFailed} onValuesChange={(changed, all) => console.log('Changed:', changed)} > <Form.Item label="Username" field="username" required rules={[ { required: true, message: 'Username is required' }, { minLength: 3, message: 'At least 3 characters' }, ]} > <Input placeholder="Enter username" /> </Form.Item> <Form.Item label="Email" field="email" rules={[ { required: true, message: 'Email is required' }, { type: 'email', message: 'Invalid email format' }, ]} > <Input type="email" placeholder="Enter email" /> </Form.Item> <Form.Item label="Subscribe" field="subscribe" > <Switch /> </Form.Item> <Form.Item label="Agreement" field="agreement" rules={[ { validator: (val) => val === true, message: 'You must agree to terms', }, ]} > <Checkbox value={true} label="I agree to terms" /> </Form.Item> <Button type="primary" onClick={() => formRef.current?.form?.submit()}> Submit </Button> <Button onClick={() => formRef.current?.form?.resetFields()}> Reset </Button> </Form> ); } ``` --- ## Popup A full-screen popup component with slide animations from any direction, featuring anti-scroll penetration. ```tsx import React, { useState } from 'react'; import Popup from '@arco-design/mobile-react/esm/popup'; import Button from '@arco-design/mobile-react/esm/button'; import '@arco-design/mobile-react/esm/popup/style'; function PopupExample() { const [visible, setVisible] = useState(false); const [direction, setDirection] = useState('bottom'); // Imperative open method const openPopup = () => { const { close, update } = Popup.open({ direction: 'right', children: ( <div style={{ width: 300, padding: 20 }}> <h3>Sidebar Menu</h3> <p>Click mask to close</p> <Button onClick={close}>Close</Button> </div> ), onClose: (scene) => console.log('Closed by:', scene), }); }; return ( <div> <Button onClick={() => { setDirection('bottom'); setVisible(true); }}> From Bottom </Button> <Button onClick={() => { setDirection('top'); setVisible(true); }}> From Top </Button> <Button onClick={() => { setDirection('left'); setVisible(true); }}> From Left </Button> <Button onClick={openPopup}>Open Right Sidebar</Button> <Popup visible={visible} close={() => setVisible(false)} direction={direction} needBottomOffset={direction === 'bottom'} maskClosable onOpen={() => console.log('Popup opened')} onClose={(scene) => console.log('Closed:', scene)} > <div style={{ padding: 20, minHeight: 200 }}> <h3>Popup Content</h3> <p>Sliding from {direction}</p> <Button onClick={() => setVisible(false)}>Close</Button> </div> </Popup> </div> ); } ``` --- ## Picker A selector component with cascading support, displayed in a popup layer. ```tsx import React, { useState } from 'react'; import Picker from '@arco-design/mobile-react/esm/picker'; import Button from '@arco-design/mobile-react/esm/button'; import '@arco-design/mobile-react/esm/picker/style'; function PickerExample() { const [visible, setVisible] = useState(false); const [value, setValue] = useState([]); // Simple non-cascading data const simpleData = [ [ { label: 'January', value: 1 }, { label: 'February', value: 2 }, { label: 'March', value: 3 }, ], [ { label: '2023', value: 2023 }, { label: '2024', value: 2024 }, { label: '2025', value: 2025 }, ], ]; // Cascading data (province -> city) const cascadeData = [ { label: 'California', value: 'CA', children: [ { label: 'Los Angeles', value: 'LA' }, { label: 'San Francisco', value: 'SF' }, { label: 'San Diego', value: 'SD' }, ], }, { label: 'New York', value: 'NY', children: [ { label: 'New York City', value: 'NYC' }, { label: 'Buffalo', value: 'BUF' }, ], }, ]; return ( <div> {/* Non-cascading picker */} <Picker visible={visible} close={() => setVisible(false)} data={simpleData} cascade={false} value={value} title="Select Date" onOk={(val, data) => { setValue(val); console.log('Selected:', val, data); }} onDismiss={() => console.log('Dismissed')} /> <Button onClick={() => setVisible(true)}> Select Month/Year: {value.join('/')} </Button> {/* Cascading picker with linked container */} <Picker data={cascadeData} cascade={true} cols={2} title="Select Location" renderLinkedContainer={(val, data) => ( <div className="picker-trigger"> {data.map(d => d?.label).join(' - ') || 'Select location'} </div> )} onOk={(val, data) => console.log('Location:', val)} /> </div> ); } ``` --- ## Carousel A carousel/slider component supporting autoplay, loop, custom indicators, and various transition effects. ```tsx import React, { useRef } from 'react'; import Carousel from '@arco-design/mobile-react/esm/carousel'; import '@arco-design/mobile-react/esm/carousel/style'; function CarouselExample() { const carouselRef = useRef(null); const images = [ { src: 'https://example.com/image1.jpg', text: 'Slide 1' }, { src: 'https://example.com/image2.jpg', text: 'Slide 2' }, { src: 'https://example.com/image3.jpg', text: 'Slide 3' }, ]; return ( <div> {/* Basic autoplay carousel */} <Carousel list={images} autoPlay loop stayDuration={3000} indicatorType="circle" onChange={(index) => console.log('Current:', index)} /> {/* Custom children carousel with ref control */} <Carousel ref={carouselRef} autoPlay={false} loop={false} showIndicator indicatorPos="end" percentToChange={0.3} onAfterChange={(index, oldIndex) => { console.log(`Changed from ${oldIndex} to ${index}`); }} > <div style={{ background: '#1890ff', height: 200 }}>Panel 1</div> <div style={{ background: '#52c41a', height: 200 }}>Panel 2</div> <div style={{ background: '#faad14', height: 200 }}>Panel 3</div> </Carousel> {/* Navigation controls */} <button onClick={() => carouselRef.current?.changeIndex(0)}>First</button> <button onClick={() => carouselRef.current?.changeIndex(2, true)}>Jump to Last</button> {/* Vertical carousel */} <Carousel vertical boxHeight={300} autoPlay loop > <div>Vertical Slide 1</div> <div>Vertical Slide 2</div> <div>Vertical Slide 3</div> </Carousel> </div> ); } ``` --- ## Image An enhanced image component with loading states, error handling, and various fill modes. ```tsx import React from 'react'; import Image from '@arco-design/mobile-react/esm/image'; import '@arco-design/mobile-react/esm/image/style'; function ImageExample() { return ( <div> {/* Basic image with cover fit */} <Image src="https://example.com/photo.jpg" width={200} height={150} fit="cover" radius={8} showLoading showError onLoad={(e, img) => console.log('Image loaded:', img.naturalWidth)} onError={(e) => console.log('Load failed')} /> {/* Image with auto retry */} <Image src="https://example.com/unstable.jpg" width="100%" height={200} fit="contain" retryTime={3} onAutoRetry={(e) => console.log('Retrying...')} /> {/* Custom loading and error areas */} <Image src="https://example.com/image.jpg" width={150} height={150} loadingArea={<div>Loading...</div>} errorArea={<div>Failed to load</div>} /> {/* Static image (direct img tag) */} <Image src="https://example.com/static.jpg" width={200} staticLabel alt="Static image" /> {/* Image with overlay content */} <Image src="https://example.com/product.jpg" width={200} height={200} fit="cover" topOverlap={<span className="badge">New</span>} bottomOverlap={<span className="price">$99.00</span>} /> </div> ); } ``` --- ## PullRefresh A pull-to-refresh component for refreshing list data with customizable states and animations. ```tsx import React, { useState } from 'react'; import PullRefresh from '@arco-design/mobile-react/esm/pull-refresh'; import '@arco-design/mobile-react/esm/pull-refresh/style'; function PullRefreshExample() { const [list, setList] = useState(['Item 1', 'Item 2', 'Item 3']); const handleRefresh = async () => { // Simulate API call await new Promise(resolve => setTimeout(resolve, 1500)); setList(prev => [`New Item ${Date.now()}`, ...prev]); }; return ( <PullRefresh onRefresh={handleRefresh} pullingText="Pull down to refresh" loosingText="Release to refresh" loadingText="Refreshing..." finishText="Refresh complete" finishDelay={500} > <div className="list-container"> {list.map((item, index) => ( <div key={index} className="list-item"> {item} </div> ))} </div> </PullRefresh> ); } ``` --- ## LoadMore A load-more component for infinite scrolling and pagination, supporting scroll and click triggers. ```tsx import React, { useState, useRef } from 'react'; import LoadMore from '@arco-design/mobile-react/esm/load-more'; import '@arco-design/mobile-react/esm/load-more/style'; function LoadMoreExample() { const [list, setList] = useState(Array.from({ length: 10 }, (_, i) => `Item ${i + 1}`)); const [page, setPage] = useState(1); const loadMoreRef = useRef(null); const fetchData = (callback) => { // Simulate API call setTimeout(() => { if (page >= 5) { callback('nomore'); // No more data return; } const newItems = Array.from( { length: 10 }, (_, i) => `Item ${page * 10 + i + 1}` ); setList(prev => [...prev, ...newItems]); setPage(prev => prev + 1); callback('prepare'); // Ready for next load }, 1000); }; return ( <div className="scroll-container" style={{ height: 500, overflow: 'auto' }}> {list.map((item, index) => ( <div key={index} className="list-item">{item}</div> ))} <LoadMore ref={loadMoreRef} trigger="scroll" threshold={100} getData={fetchData} getScrollContainer={() => document.querySelector('.scroll-container')} loadingArea="Loading more..." noMoreArea="No more items" retryArea="Load failed, tap to retry" prepareArea="Pull up to load more" onStatusChange={(status, scene) => console.log('Status:', status)} /> </div> ); } ``` --- ## ContextProvider A global configuration component for theme customization, internationalization, dark mode, and RTL support. ```tsx import React from 'react'; import { ContextProvider } from '@arco-design/mobile-react/esm/context-provider'; import Button from '@arco-design/mobile-react/esm/button'; import Dialog from '@arco-design/mobile-react/esm/dialog'; // Custom locale const customLocale = { locale: 'en-US', Dialog: { okText: 'Confirm', cancelText: 'Cancel', }, LoadMore: { loadMoreText: 'Load more', loadingText: 'Loading...', noDataText: 'No more data', failLoadText: 'Load failed', prepareScrollText: 'Pull up to load more', prepareClickText: 'Click to load more', }, // ... other component locales }; function App() { return ( <ContextProvider // Theme customization theme={{ '--primary-color': '#1890ff', '--button-primary-bg': '#1890ff', }} // Internationalization locale={customLocale} // Dark mode useDarkMode={true} isDarkMode={false} darkModeSelector="arco-theme-dark" onDarkModeChange={(isDark) => console.log('Dark mode:', isDark)} // RTL support useRtl={false} // System detection (for SSR) system="ios" // React 19 support // createRoot={createRoot} > <Button type="primary">Themed Button</Button> <Button onClick={() => Dialog.alert({ title: 'Localized Dialog' })}> Show Dialog </Button> </ContextProvider> ); } ``` --- ## Switch A toggle switch component supporting both tap and slide interactions with platform-specific styling. ```tsx import React, { useState } from 'react'; import Switch from '@arco-design/mobile-react/esm/switch'; import '@arco-design/mobile-react/esm/switch/style'; function SwitchExample() { const [checked, setChecked] = useState(false); return ( <div> {/* Basic switch */} <Switch checked={checked} onChange={(val) => setChecked(val)} /> {/* Switch with text labels */} <Switch defaultChecked text={{ on: 'ON', off: 'OFF' }} /> {/* Disabled switch */} <Switch disabled checked /> {/* Platform-specific styling */} <Switch platform="ios" defaultChecked /> <Switch platform="android" defaultChecked /> {/* Semi-rounded shape */} <Switch shape="semi" defaultChecked /> </div> ); } ``` --- ## Checkbox A checkbox component with support for single selection, groups, and custom icons. ```tsx import React, { useState } from 'react'; import Checkbox from '@arco-design/mobile-react/esm/checkbox'; import '@arco-design/mobile-react/esm/checkbox/style'; function CheckboxExample() { const [selected, setSelected] = useState(['apple']); const options = [ { label: 'Apple', value: 'apple' }, { label: 'Orange', value: 'orange' }, { label: 'Banana', value: 'banana' }, { label: 'Grape', value: 'grape', disabled: true }, ]; return ( <div> {/* Single checkbox */} <Checkbox value="agree" label="I agree to the terms" onChange={(checked, value) => console.log(checked, value)} /> {/* Checkbox group */} <Checkbox.Group options={options} value={selected} onChange={(values) => setSelected(values)} layout="block" shape="square" min={1} max={3} /> {/* Custom children */} <Checkbox.Group value={selected} onChange={setSelected} layout="inline" > <Checkbox value="apple"> <span className="custom-label">Apple</span> </Checkbox> <Checkbox value="orange"> <span className="custom-label">Orange</span> </Checkbox> </Checkbox.Group> {/* Justified layout */} <Checkbox value="notification" label="Enable notifications" layout="justify" /> </div> ); } ``` --- ## Summary Arco Design Mobile provides a comprehensive toolkit for building mobile-first React applications. The library excels in scenarios requiring rich user interactions such as e-commerce apps, social platforms, content-driven applications, and enterprise mobile dashboards. Key integration patterns include using ContextProvider at the app root for global theming and i18n, combining PullRefresh with LoadMore for infinite scroll lists, and leveraging imperative methods (Dialog.alert, Toast.loading, Popup.open) for programmatic UI control. For optimal performance, use on-demand imports (`@arco-design/mobile-react/esm/component-name`) with corresponding style imports. The library integrates seamlessly with build tools like Webpack and Vite, supports tree-shaking, and works well with state management solutions like Redux or Zustand. For SSR applications (Next.js, Remix), specify the `system` prop in ContextProvider to avoid hydration mismatches. The component library is actively maintained with regular updates, comprehensive TypeScript support, and detailed documentation for each component.