Installation
npm Install
# npm
npm install svelte-mobile-ui
# cnpm(国内镜像)
cnpm install svelte-mobile-ui
# yarn
yarn add svelte-mobile-ui
# pnpm
pnpm add svelte-mobile-ui
Peer Dependencies
Make sure the following dependencies are installed:
npm install svelte
Full Import
// main.ts — 全量导入样式
import 'svelte-mobile-ui/dist/styles.css'
// 组件中使用
import { Button, Cell, Field, Dialog, Tabs } from 'svelte-mobile-ui'
On-demand Import
// 按需导入单个组件(推荐)
import Button from 'svelte-mobile-ui/components/Button/Button.svelte'
import Cell from 'svelte-mobile-ui/components/Cell/Cell.svelte'
// 按需导入样式
import 'svelte-mobile-ui/styles/var.scss'
import 'svelte-mobile-ui/styles/index.scss'
CDN Usage
You can also use it directly via CDN (for quick prototyping or online demos):
<!-- CSS -->
<link rel="stylesheet" href="https://unpkg.com/svelte-mobile-ui@1.2.0/dist/styles.css" />
<!-- JS (IIFE) -->
<script src="https://unpkg.com/svelte-mobile-ui@1.2.0/dist/svelte-mobile-ui.iife.js"></script>
CommonJS Require
const { Button, Cell, Field } = require('svelte-mobile-ui')
More Components
All components below are implemented. Import via import { Component } from 'svelte-mobile-ui' to use.
Calendar Calendar
Date selection supporting single, multiple, and range modes
View Code
<Calendar bind:show type="single"
title="选择日期" color="#1989fa"
minDate={new Date(2024, 0, 1)}
maxDate={new Date(2025, 11, 31)}
onConfirm={(date) => console.log(date)} />
Props
| Property | Description | Type | Default |
|---|
show | Whether to show calendar popup | boolean | false |
type | Selection type | 'single' | 'multiple' | 'range' | 'single' |
title | Calendar title | string | '日期选择' |
color | Theme color | string | '#1989fa' |
minDate | Minimum selectable date | Date | 当天 |
maxDate | Maximum selectable date | Date | 六个月后 |
defaultDate | Default selected date | Date | Date[] | null |
rowHeight | Row height of date | number | string | 64 |
poppable | Whether to show as popup | boolean | true |
showMark | Whether to show month watermark | boolean | true |
showTitle | Whether to show calendar title | boolean | true |
showSubtitle | Whether to show calendar subtitle | boolean | true |
showConfirm | Whether to show confirm button | boolean | true |
readonly | Whether readonly | boolean | false |
confirmText | Confirm button text | string | '确定' |
confirmDisabledText | Text when confirm button is disabled | string | '确定' |
firstDayOfWeek | First day of week (0-6) | number | 0 |
maxRange | Max days for range selection | number | string | - |
onConfirm | Confirm button callback | Function | - |
onclose | Close popup callback | Function | - |
Cascader Cascader
Multi-level data cascading selection
View Code
<Cascader bind:show title="请选择地区"
options={areaOptions}
fieldNames={{ text: 'name', value: 'code', children: 'items' }}
onFinish={(val) => console.log(val)}
onclose={() => (show = false)} />
Props
| Property | Description | Type | Default |
|---|
show | Whether to show | boolean | false |
title | Top title | string | '' |
value | Selected value | string | number | - |
options | Options data source | CascaderOption[] | [] |
placeholder | Placeholder text when not selected | string | '请选择' |
activeColor | Selected state color | string | '#1989fa' |
closeable | Whether to show close icon | boolean | true |
closeIcon | Close icon name | string | 'cross' |
fieldNames | Custom field name mapping | object | { text: 'text', value: 'value', children: 'children' } |
onFinish | All options selected callback | Function | - |
onclose | Close callback | Function | - |
onChange | Selection change callback | Function | - |
DatePicker DatePicker
Date picker with year/month/day control
View Code
<DatePicker bind:show title="选择日期"
columnsType={['year', 'month', 'day']}
minDate={new Date(2020, 0, 1)}
maxDate={new Date(2030, 11, 31)}
onConfirm={(val) => console.log(val)}
onCancel={() => (show = false)} />
Props
| Property | Description | Type | Default |
|---|
show | Whether to show | boolean | false |
columnsType | Columns type | string[] | ['year', 'month', 'day'] |
minDate | Minimum selectable date | Date | 十年前 |
maxDate | Maximum selectable date | Date | 十年后 |
title | Top title | string | '' |
loading | Whether to show loading | boolean | false |
readonly | Whether readonly | boolean | false |
filter | Options filter function | Function | - |
formatter | Options formatter function | Function | - |
confirmButtonText | Confirm button text | string | '确认' |
cancelButtonText | Cancel text | string | '取消' |
onConfirm | Confirm callback | Function | - |
onCancel | Cancel callback | Function | - |
onChange | Value change callback | Function | - |
TimePicker TimePicker
Time picker with hour/minute/second control
View Code
<TimePicker bind:show title="选择时间"
columnsType={['hour', 'minute']}
minHour={8} maxHour={22}
onConfirm={(val) => console.log(val)}
onCancel={() => (show = false)} />
Props
| Property | Description | Type | Default |
|---|
show | Whether to show | boolean | false |
columnsType | Columns type | string[] | ['hour', 'minute'] |
minHour | Minimum selectable hour | number | 0 |
maxHour | Maximum selectable hour | number | 23 |
minMinute | Minimum selectable minute | number | 0 |
maxMinute | Maximum selectable minute | number | 59 |
title | Top title | string | '' |
loading | Whether to show loading | boolean | false |
readonly | Whether readonly | boolean | false |
filter | Options filter function | Function | - |
formatter | Options formatter function | Function | - |
confirmButtonText | Confirm button text | string | '确认' |
cancelButtonText | Cancel text | string | '取消' |
onConfirm | Confirm callback | Function | - |
onCancel | Cancel callback | Function | - |
onChange | Value change callback | Function | - |
Picker Picker
General picker with multi-column linkage
View Code
<Picker bind:show title="选择城市"
columns={cityColumns}
confirmButtonText="确定"
cancelButtonText="取消"
onConfirm={(val) => console.log(val)}
onCancel={() => (show = false)}
onChange={(val) => console.log(val)} />
Props
| Property | Description | Type | Default |
|---|
show | Whether to show | boolean | false |
columns | Columns data | PickerColumn[] | [] |
title | Top title | string | '' |
confirmButtonText | Confirm button text | string | '确认' |
cancelButtonText | Cancel text | string | '取消' |
loading | Whether to show loading | boolean | false |
readonly | Whether readonly | boolean | false |
showToolbar | Whether to show toolbar | boolean | true |
defaultIndex | Default selected index | number | string | 0 |
itemHeight | Option height (px) | number | string | 44 |
visibleItemCount | Visible option count | number | string | 6 |
swipeDuration | Momentum duration on quick swipe (ms) | number | string | 1000 |
onConfirm | Confirm callback | Function | - |
onCancel | Cancel callback | Function | - |
onChange | Option change callback | Function | - |
PickerGroup PickerGroup
Combine multiple pickers with tab switching
View Code
<PickerGroup title="预约日期时间"
tabs={['选择日期', '选择时间']}
nextStepText="下一步"
bind:activeTab>
<DatePicker />
<TimePicker />
</PickerGroup>
Props
| Property | Description | Type | Default |
|---|
title | Top title | string | '' |
tabs | Tab list | string[] | [] |
activeTab | Current active tab index | number | 0 |
nextStepText | Next step button text | string | '下一步' |
NumberKeyboard NumberKeyboard
Virtual number keyboard with custom keys
View Code
<NumberKeyboard bind:show
theme="default"
title="输入金额"
extraKey="."
closeButtonText="完成"
randomKeyOrder={false}
onInput={(key) => console.log(key)}
onDelete={() => console.log('delete')}
onclose={() => console.log('close')} />
Props
| Property | Description | Type | Default |
|---|
show | Whether to show keyboard | boolean | false |
theme | Theme style | 'default' | 'custom' | 'default' |
title | Keyboard title | string | '' |
extraKey | Extra bottom key | string | string[] | '' |
closeButtonText | Done button text | string | '完成' |
closeButtonLoading | Whether done button is loading | boolean | false |
maxlength | Max input length | number | string | Infinity |
randomKeyOrder | Whether to randomize key order | boolean | false |
transition | Whether to enable transition | boolean | true |
blurOnClose | Whether to blur on close | boolean | true |
hideOnClickOutside | Whether to close on outside click | boolean | true |
safeAreaInsetBottom | Whether to adapt bottom safe area | boolean | true |
onInput | Key press callback | (key: string) => void | - |
onDelete | Delete key callback | () => void | - |
onclose | Close callback | () => void | - |
Uploader Uploader
File upload with camera and preview support
View Code
<Uploader bind:fileList
maxCount={5} accept="image/*"
maxSize={5 * 1024 * 1024}
multiple preview
deletable imageFit="cover"
afterRead={(file) => uploadFile(file)}
onOversize={(file) => toast('文件过大')}
onDelete={(file) => console.log(file)} />
Props
| Property | Description | Type | Default |
|---|
fileList | Uploaded file list | FileItem[] | [] |
accept | Accepted file types | string | 'image/*' |
maxCount | Max upload count | number | string | Infinity |
maxSize | File size limit (bytes) | number | string | Infinity |
multiple | Whether multiple selection | boolean | false |
disabled | Whether to disable upload | boolean | false |
readonly | Whether readonly | boolean | false |
preview | Whether to show preview after upload | boolean | true |
previewSize | Preview and upload area size | number | string | '80px' |
previewImage | Whether to preview full-screen on click | boolean | true |
previewFullImage | Whether to show full-screen preview | boolean | true |
deletable | Whether to show delete button | boolean | true |
imageFit | Preview image fit mode | string | 'cover' |
uploadIcon | Upload area icon name | string | 'photograph' |
uploadText | Upload area text hint | string | '' |
afterRead | After file read callback | Function | - |
beforeRead | Before file read callback | Function | - |
beforeDelete | Before delete callback | Function | - |
onOversize | Oversize callback | Function | - |
onDelete | Delete file callback | Function | - |
Circle Circle
Circular progress bar with gradient and custom content
View Code
<Circle currentRate={70} rate={100}
size="120px" color="#1989fa"
layerColor="#ebedf0" strokeWidth={4}
clockwise fill="none"
speed={50} text="70%" />
Props
| Property | Description | Type | Default |
|---|
currentRate | Current progress | number | 0 |
rate | Target progress | number | 100 |
size | Circle diameter | string | number | '100px' |
color | Progress bar color | string | object | '#1989fa' |
layerColor | Track color | string | '#fff' |
fill | Fill color | string | 'none' |
speed | Animation speed (rate/s) | number | string | 0 |
text | Text content | string | '' |
strokeWidth | Progress bar width | number | string | 40 |
strokeLinecap | Line cap style | 'round' | 'butt' | 'square' | 'round' |
clockwise | Whether clockwise | boolean | true |
startPosition | Progress start position | 'top' | 'bottom' | 'left' | 'right' | 'top' |
CountDown CountDown
Millisecond-level countdown timer
View Code
<CountDown time={30 * 60 * 60 * 1000}
format="HH:mm:ss"
autoStart millisecond={false}
onFinish={() => console.log('结束')}
onChange={(current) => console.log(current)} />
Props
| Property | Description | Type | Default |
|---|
time | Total duration (ms) | number | 0 |
format | Time format | string | 'HH:mm:ss' |
autoStart | Whether to auto start | boolean | true |
millisecond | Whether to enable ms rendering | boolean | false |
onFinish | Countdown finish callback | () => void | - |
onChange | Countdown change callback | (current: CurrentTime) => void | - |
Highlight Highlight
Highlight search keywords in text
View Code
<Highlight
source="慕课网是好的学习平台"
keywords={['学习', '平台']}
highlightClass="custom-highlight"
caseSensitive={false}
unhighlightClass="normal-text" />
Props
| Property | Description | Type | Default |
|---|
source | Source text content | string | '' |
keywords | Highlight keywords | string | string[] | '' |
highlightClass | Highlight class name | string | '' |
highlightTag | Highlight HTML tag | string | 'span' |
unhighlightClass | Unhighlight class name | string | '' |
unhighlightTag | Unhighlight HTML tag | string | 'span' |
caseSensitive | Whether case sensitive | boolean | false |
ImagePreview ImagePreview
Full-screen image preview with zoom support
View Code
<ImagePreview bind:show
images={['a.jpg', 'b.jpg', 'c.jpg']}
startPosition={0} closeable
showIndex closeOnClickOverlay
closeOnClickImage={false}
maxZoom={3} minZoom={1/3}
swipeDuration={300}
onClose={() => {}} onChange={(index) => {}} />
Props
| Property | Description | Type | Default |
|---|
show | Whether to show preview | boolean | false |
images | Image URLs to preview | string[] | [] |
startPosition | Initial preview position | number | string | 0 |
closeable | Whether to show close button | boolean | false |
showIndex | Whether to show page index | boolean | true |
showIndicators | Whether to show indicators | boolean | false |
closeOnClickOverlay | Whether to close on overlay click | boolean | true |
closeOnClickImage | Whether to close on image click | boolean | true |
closeIcon | Close icon name | string | 'clear' |
closeIconPosition | Close icon position | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-right' |
loop | Whether to enable loop | boolean | true |
maxZoom | Max zoom ratio | number | 3 |
minZoom | Min zoom ratio | number | 1/3 |
swipeDuration | Animation duration (ms) | number | string | 300 |
onClose | Close callback | Function | - |
onChange | Image change callback | (index: number) => void | - |
Skeleton Skeleton
Loading placeholder skeleton screen
View Code
<!-- 基础用法 -->
<Skeleton title row={3} avatar round
avatarSize="48px" avatarShape="round"
rowWidth={['60%', '100%', '80%']}
loading={isLoading}>
<p>实际内容在这里显示</p>
</Skeleton>
<!-- 组合用法 -->
<SkeletonTitle />
<SkeletonAvatar />
<SkeletonParagraph row={4} rowWidth="100%" round />
<SkeletonImage />
Props
| Property | Description | Type | Default |
|---|
loading | Whether to show skeleton | boolean | true |
row | Paragraph row count | number | string | 0 |
rowWidth | Paragraph row width | string | string[] | '100%' |
title | Whether to show title placeholder | boolean | false |
titleWidth | Title placeholder width | string | number | '40%' |
avatar | Whether to show avatar placeholder | boolean | false |
avatarSize | Avatar placeholder size | string | number | '32px' |
avatarShape | Avatar placeholder shape | 'round' | 'square' | 'round' |
round | Whether to round placeholders | boolean | false |
animate | Whether to enable animation | boolean | true |
Steps Steps
Guide multi-step process
View Code
<Steps active={1} direction="horizontal"
activeColor="#1989fa" inactiveColor="#969799"
activeIcon="success" inactiveIcon="">
<Step title="买家下单" description="描述信息" />
<Step title="商家接单" />
<Step title="买家提货" />
</Steps>
Props
| Property | Description | Type | Default |
|---|
active | Current step index | number | string | 0 |
direction | Steps direction | 'horizontal' | 'vertical' | 'horizontal' |
activeColor | Active state color | string | '#1989fa' |
inactiveColor | Inactive state color | string | '#969799' |
activeIcon | Active icon | string | 'checked' |
inactiveIcon | Inactive icon | string | '' |
finishIcon | Finished step icon | string | '' |
iconPrefix | Icon class prefix | string | 'smu-icon' |
Swipe Swipe
Carousel with gesture swipe support
View Code
<Swipe autoplay={3000} duration={500}
loop showIndicators
initialSwipe={0}
touchable vertical={false}
width="100%" height="200px"
indicatorColor="#1989fa"
onChange={(index) => console.log(index)}>
<SwipeItem>1</SwipeItem>
<SwipeItem>2</SwipeItem>
<SwipeItem>3</SwipeItem>
</Swipe>
Props
| Property | Description | Type | Default |
|---|
autoplay | Autoplay interval (ms), 0 to disable | number | string | 0 |
duration | Animation duration (ms) | number | string | 500 |
loop | Whether to enable loop | boolean | true |
showIndicators | Whether to show indicators | boolean | true |
initialSwipe | Initial position index | number | string | 0 |
touchable | Whether touchable to swipe | boolean | true |
vertical | Whether vertical scroll | boolean | false |
width | Slide width | number | string | 'auto' |
height | Slide height | number | string | 'auto' |
indicatorColor | Indicator color | string | '#1989fa' |
stopPropagation | Whether to prevent swipe propagation | boolean | true |
onChange | Swipe page change callback | (index: number) => void | - |
TextEllipsis TextEllipsis
Multi-line text ellipsis with expand/collapse
View Code
<TextEllipsis content={longText}
rows={3}
expandText="展开"
collapseText="收起"
dots="..."
onClickAction={(expanded) => console.log(expanded)} />
Props
| Property | Description | Type | Default |
|---|
content | Text to display | string | '' |
rows | Display rows | number | string | 1 |
expandText | Expand action text | string | '' |
collapseText | Collapse action text | string | '' |
dots | Ellipsis text | string | '...' |
onClickAction | Expand/collapse callback | (expanded: boolean) => void | - |
Watermark Watermark
Add global watermark to page
View Code
<Watermark content="机密文档"
image="" rotate={-22}
width={100} height={100}
gapX={100} gapY={100}
opacity={0.15}
fullPage zIndex={100}>
<div>页面内容</div>
</Watermark>
Props
| Property | Description | Type | Default |
|---|
content | Watermark text content | string | '' |
image | Watermark image URL (higher priority than text) | string | '' |
width | Watermark width | number | 100 |
height | Watermark height | number | 100 |
rotate | Watermark rotation angle | number | string | -22 |
gapX | Horizontal gap between watermarks | number | 100 |
gapY | Vertical gap between watermarks | number | 100 |
opacity | Watermark opacity | number | string | 1 |
fullPage | Whether to cover full page | boolean | true |
zIndex | Watermark z-index | number | string | 100 |
textColor | Text color | string | '#dcdee0' |
fontSize | Text size | number | string | 14 |
fontWeight | Font weight | string | 'normal' |
fontFamily | Font family | string | - |
Barrage Barrage
Scrollable barrage component
View Code
<Barrage bind:modelValue={barrages}
autoPlay rows={4}
duration={4000} delay={300}
top={10} bottom={10}>
<video src="video.mp4" />
</Barrage>
Props
| Property | Description | Type | Default |
|---|
modelValue | Barrage data | BarrageItem[] | [] |
autoPlay | Whether to auto play barrage | boolean | true |
rows | Barrage rows | number | string | 4 |
duration | Barrage scroll duration (ms) | number | 4000 |
delay | Barrage animation delay (ms) | number | 300 |
top | Barrage area top distance (px) | number | string | 10 |
bottom | Barrage area bottom distance (px) | number | string | 10 |
RollingText RollingText
Number rolling animation effect
View Code
<RollingText startNum={0}
targetNum={9999}
duration={2} autoStart
direction="down"
height={40}
stopOrder={[]}
textList={[]} />
Props
| Property | Description | Type | Default |
|---|
startNum | Start value | number | 0 |
targetNum | Target value | number | 0 |
duration | Animation duration (s) | number | 2 |
autoStart | Whether to auto start animation | boolean | true |
direction | Rolling direction | 'up' | 'down' | 'down' |
height | Number height (px) | number | 40 |
stopOrder | Stop order for each digit | number[] | [] |
textList | Custom text array | string[] | [] |
List List
Auto load more on scroll bottom
View Code
<List loading={isLoading} finished={isFinished}
offset={300} direction="down"
immediateCheck={true}
loadingText="加载中..."
finishedText="没有更多了"
errorText="加载失败"
onLoad={loadMore}>
{#each list as item}
<Cell title={item.title} />
{/each}
</List>
Props
| Property | Description | Type | Default |
|---|
loading | Whether loading | boolean | false |
finished | Whether all data loaded | boolean | false |
error | Whether load failed | boolean | false |
offset | Distance threshold to trigger load (px) | number | string | 300 |
direction | Scroll trigger direction | 'up' | 'down' | 'down' |
immediateCheck | Whether to check immediately | boolean | true |
loadingText | Loading text | string | '加载中...' |
finishedText | Finished text | string | '' |
errorText | Error text | string | '' |
onLoad | Trigger when scroll distance to bottom < offset | () => void | - |
Notify Notify
Top notification bar
View Code
<Notify bind:show type="success"
message="操作成功"
duration={2000}
color="#fff"
background="#1989fa"
lockScroll={false}
onclick={() => {}} />
Props
| Property | Description | Type | Default |
|---|
show | Whether to show notification | boolean | false |
type | Type | 'primary' | 'success' | 'warning' | 'danger' | 'danger' |
message | Display message | string | '' |
duration | Duration (ms), 0 for persistent | number | string | 3000 |
color | Font color | string | '' |
background | Background color | string | '' |
className | Custom class name | string | '' |
lockScroll | Whether to lock background scroll | boolean | false |
onclick | Click callback | () => void | - |
onclose | Close callback | () => void | - |
onOpened | Fully displayed callback | () => void | - |
Popover Popover
Popover menu/tooltip
View Code
<Popover bind:show placement="bottom-start"
theme="light" trigger="click"
actions={[
{ text: '选项一', icon: 'add-o' },
{ text: '选项二', icon: 'music-o' },
{ text: '选项三', disabled: true },
]}
closeOnClickAction
closeOnClickOutside
onSelect={(action) => console.log(action)} />
Props
| Property | Description | Type | Default |
|---|
show | Whether to show popover | boolean | false |
actions | Options list | PopoverAction[] | [] |
actionsDirection | Options direction | 'vertical' | 'horizontal' | 'vertical' |
placement | Popup position | string | 'bottom' |
theme | Theme style | 'light' | 'dark' | 'light' |
trigger | Trigger method | 'click' | 'manual' | 'click' |
offset | Position offset | [number, number] | [0, 8] |
overlay | Whether to show overlay | boolean | false |
showArrow | Whether to show arrow | boolean | true |
closeOnClickAction | Whether to close on select | boolean | true |
closeOnClickOutside | Whether to close on outside click | boolean | true |
closeOnClickOverlay | Whether to close on overlay click | boolean | true |
duration | Animation duration (s) | number | string | 0.3 |
onSelect | Option select callback | (action: PopoverAction) => void | - |
onOpen | Open callback | () => void | - |
onClose | Close callback | () => void | - |
PullRefresh PullRefresh
Pull-to-refresh container
View Code
<PullRefresh bind:loading
successText="刷新成功"
pullingText="下拉即可刷新..."
loosingText="释放即可刷新..."
loadingText="加载中..."
successDuration={500}
headHeight={50}
onRefresh={onRefresh}>
<p>内容区域</p>
</PullRefresh>
Props
| Property | Description | Type | Default |
|---|
loading | Whether loading | boolean | false |
pullingText | Pulling text | string | '下拉即可刷新...' |
loosingText | Loosing text | string | '释放即可刷新...' |
loadingText | Loading text | string | '加载中...' |
successText | Success text | string | '' |
successDuration | Success duration (ms) | number | string | 500 |
animationDuration | Animation duration (ms) | number | string | 300 |
headHeight | Head height (px) | number | string | 50 |
pullDistance | Pull distance threshold | number | string | 与 headHeight 一致 |
disabled | Whether to disable pull refresh | boolean | false |
onRefresh | Refresh callback | () => void | - |
ShareSheet ShareSheet
Bottom share options panel
View Code
<ShareSheet bind:show
title="立即分享给好友"
description="描述信息"
cancelText="取消"
options={[
[
{ name: '微信', icon: 'wechat' },
{ name: '朋友圈', icon: 'wechat-moments' },
],
[
{ name: '复制链接', icon: 'link' },
{ name: '二维码', icon: 'qrcode' },
],
]}
onSelect={(option, index) => console.log(option)}
onCancel={() => (show = false)} />
Props
| Property | Description | Type | Default |
|---|
show | Whether to show share sheet | boolean | false |
options | Share options | ShareOption[] | ShareOption[][] | [] |
title | Top title | string | '' |
description | Description below title | string | '' |
cancelText | Cancel text | string | '取消' |
closeable | Whether to show close icon | boolean | true |
closeOnClickOverlay | Whether to close on overlay click | boolean | true |
closeOnPopstate | Whether to close on page back | boolean | true |
duration | Animation duration (s) | number | string | 0.3 |
safeAreaInsetBottom | Whether to adapt bottom safe area | boolean | true |
onSelect | Share option select callback | (option, index) => void | - |
onCancel | Cancel button click callback | () => void | - |
onclose | Close callback | () => void | - |
SwipeCell SwipeCell
Left/right swipe actions
View Code
<SwipeCell disabled={false}
stopPropagation
beforeClose={onBeforeClose}>
{#snippet left()}<Button square type="primary" text="选择" />{/snippet}
<Cell title="单元格" value="内容" />
{#snippet right()}<Button square type="danger" text="删除" />{/snippet}
</SwipeCell>
Props
| Property | Description | Type | Default |
|---|
disabled | Whether to disable swipe | boolean | false |
name | Identifier | string | number | '' |
stopPropagation | Whether to prevent swipe propagation | boolean | false |
beforeClose | Before close callback | Function | - |
onOpen | Open callback | (params: { name, position }) => void | - |
onClose | Close callback | (params: { name, position }) => void | - |
onclick | Click callback | (position: string) => void | - |
FloatingPanel FloatingPanel
Draggable bottom floating panel
View Code
<FloatingPanel
anchors={[100, 300, window.innerHeight * 0.6]}
height={0} minHeight={100}
contentDraggable lockScroll={false}
safeAreaInsetBottom
onHeightChange={({ height }) => console.log(height)}>
<p>面板内容</p>
</FloatingPanel>
Props
| Property | Description | Type | Default |
|---|
anchors | Set custom anchors (height array) | number[] | [100, 窗口60%] |
height | Current panel height | number | 0 |
minHeight | Min height | number | 100 |
maxHeight | Max height | number | 0 |
contentDraggable | Whether to allow content drag | boolean | true |
lockScroll | Whether to lock background scroll | boolean | false |
safeAreaInsetBottom | Whether to adapt bottom safe area | boolean | true |
duration | Animation duration (s) | number | string | 0.3 |
onHeightChange | Height change callback | (params: { height }) => void | - |
FloatingBubble FloatingBubble
Draggable floating bubble button
View Code
<FloatingBubble icon="chat"
offset={{ x: -60, y: -60 }}
gap={24} magnetic="x"
axis="xy"
onclick={() => console.log('click')} />
Props
| Property | Description | Type | Default |
|---|
icon | Icon name or image URL | string | '' |
offset | Control bubble initial position | { x: number, y: number } | { x: -30, y: -30 } |
gap | Min gap from window edges (px) | number | 24 |
magnetic | Auto magnetic direction | 'x' | 'y' | '' | '' |
axis | Drag direction | 'x' | 'y' | 'xy' | 'lock' | 'y' |
onclick | Bubble click callback | () => void | - |
onOffsetChange | Position change callback | (offset: { x, y }) => void | - |
Grid Grid
Grid layout for content entries
View Code
<Grid columnNum={4} border center
square={false} gutter={0}
iconSize="28px" clickable
direction="vertical" reverse={false}>
<GridItem icon="photo" text="文字" dot />
<GridItem icon="photo" text="文字" badge="99+" />
<GridItem icon="photo" text="文字" url="/detail" />
</Grid>
Props
| Property | Description | Type | Default |
|---|
columnNum | Column count | number | string | 4 |
iconSize | Icon size | string | number | '28px' |
gutter | Cell gap (px) | number | string | 0 |
border | Whether to show border | boolean | true |
center | Whether to center cell content | boolean | true |
square | Whether to fix cells as square | boolean | false |
clickable | Whether to enable cell click feedback | boolean | false |
direction | Cell content direction | 'vertical' | 'horizontal' | 'vertical' |
reverse | Whether to reverse icon and text | boolean | false |
text | Text (GridItem) | string | '' |
icon | Icon name (GridItem) | string | '' |
iconColor | Icon color (GridItem) | string | '' |
dot | Whether to show dot (GridItem) | boolean | false |
badge | Badge content (GridItem) | string | number | '' |
url | Click link (GridItem) | string | '' |
IndexBar IndexBar
Alphabetical index list navigation
View Code
<IndexBar indexList={['A','B','C','D']}
sticky stickyOffsetTop={0}
highlightColor="#1989fa"
onSelect={(index) => console.log(index)}
onChange={(index) => console.log(index)}>
<IndexAnchor index="A" />
<Cell title="Aaron" />
<Cell title="Alex" />
<IndexAnchor index="B" />
<Cell title="Bob" />
</IndexBar>
Props
| Property | Description | Type | Default |
|---|
indexList | Index character list | string[] | number[] | A-Z |
sticky | Whether to enable sticky index | boolean | true |
stickyOffsetTop | Sticky anchor top offset (px) | number | 0 |
highlightColor | Index highlight color | string | '#1989fa' |
zIndex | Z-index when sticky | number | string | 1 |
teleport | Sidebar mount container | string | Element | - |
onSelect | Index select callback | (index: string | number) => void | - |
onChange | Active index change callback | (index: string | number) => void | - |
index | Index character (IndexAnchor) | string | number | '' |
Sticky Sticky
Sticky positioning effect similar to CSS position: sticky
View Code
<Sticky offsetTop={50} zIndex={99}
position="top" container={container}
onChange={(isFixed) => console.log(isFixed)}
onScroll={({ scrollTop, isFixed }) => {}}>
<Button type="primary">吸顶按钮</Button>
</Sticky>
Props
| Property | Description | Type | Default |
|---|
offsetTop | Top offset when sticky (px) | number | string | 0 |
offsetBottom | Bottom offset when sticky (px) | number | string | 0 |
zIndex | Z-index when sticky | number | string | 99 |
position | Sticky position | 'top' | 'bottom' | 'top' |
container | Container HTML element | HTMLElement | - |
onChange | Sticky state change callback | (isFixed: boolean) => void | - |
onScroll | Scroll callback | (params: { scrollTop, isFixed }) => void | - |
BackTop BackTop
Back to top button
View Code
<BackTop target=".scroll-container"
visibilityHeight={200}
right={30} bottom={60}
zIndex={100}
onclick={() => console.log('top')} />
Props
| Property | Description | Type | Default |
|---|
target | Target element selector for scroll | string | HTMLElement | - |
visibilityHeight | Show when scroll height reaches this value (px) | number | string | 200 |
right | Right offset from page (px) | number | string | 30 |
bottom | Bottom offset from page (px) | number | string | 40 |
zIndex | Z-index | number | string | 100 |
teleport | Mount container | string | Element | 'body' |
onclick | Click callback | () => void | - |
TreeSelect TreeSelect
Left category + right content list
View Code
<TreeSelect items={treeItems}
bind:activeId bind:mainActiveIndex
height="300px" max={Infinity}
selectedIcon="success"
onClickNav={(index) => console.log(index)}
onClickItem={(item) => console.log(item)} />
Props
| Property | Description | Type | Default |
|---|
items | Category display data | TreeSelectItem[] | [] |
activeId | Right side active item id | number | string | (number | string)[] | 0 |
mainActiveIndex | Left side active index | number | string | 0 |
height | Height | number | string | 300 |
max | Max selectable on right side | number | string | Infinity |
selectedIcon | Selected item icon | string | 'success' |
onClickNav | Left nav click callback | (index: number) => void | - |
onClickItem | Right item click callback | (item: TreeSelectChild) => void | - |
ActionBar ActionBar
Bottom action bar for product detail page
View Code
<ActionBar>
<ActionBarIcon icon="chat-o" text="客服"
dot color="" badge="" url="" />
<ActionBarIcon icon="cart-o" text="购物车"
badge="5" url="" />
<ActionBarIcon icon="shop-o" text="店铺" />
<ActionBarButton type="warning" text="加入购物车"
color="" loading={false} disabled={false} />
<ActionBarButton type="danger" text="立即购买" />
</ActionBar>
Props
| Property | Description | Type | Default |
|---|
icon | Icon name (ActionBarIcon) | string | '' |
text | Button text | string | '' |
color | Icon color (ActionBarIcon) | string | '' |
dot | Whether to show dot (ActionBarIcon) | boolean | false |
badge | Badge content (ActionBarIcon) | string | number | '' |
url | Click link (ActionBarIcon) | string | '' |
onclick | Click callback (ActionBarIcon) | Function | - |
type | Button type (ActionBarButton) | string | 'danger' |
color | Button color (ActionBarButton) | string | '' |
icon | Button icon (ActionBarButton) | string | '' |
loading | Whether loading (ActionBarButton) | boolean | false |
disabled | Whether disabled (ActionBarButton) | boolean | false |
Row / Col 栅格
24-column grid layout system
View Code
<Row gutter={20} justify="center" align="top"
wrap tag="div">
<Col span={8} offset={0}>span: 8</Col>
<Col span={8}>span: 8</Col>
<Col span={8}>span: 8</Col>
</Row>
Props
| Property | Description | Type | Default |
|---|
gutter | Column gap (px) | number | string | 0 |
justify | Main axis alignment | 'start' | 'end' | 'center' | 'space-around' | 'space-between' | 'start' |
align | Cross axis alignment | 'top' | 'center' | 'bottom' | 'top' |
wrap | Whether to wrap | boolean | true |
tag | Custom root element tag | string | 'div' |
span | Column width (Col, 1-24) | number | string | - |
offset | Column offset (Col) | number | string | 0 |
tag | Custom tag (Col) | string | 'div' |
Space Space
Set gap between elements
View Code
<Space direction="horizontal" fill={false}
wrap="nowrap" align="start">
<Button type="primary">按钮 1</Button>
<Button type="primary">按钮 2</Button>
<Button type="primary">按钮 3</Button>
</Space>
Props
| Property | Description | Type | Default |
|---|
direction | Gap direction | 'horizontal' | 'vertical' | 'horizontal' |
fill | Whether to fill entire row | boolean | false |
wrap | Whether to wrap | 'nowrap' | 'wrap' | 'nowrap' |
align | Cross axis alignment | 'start' | 'center' | 'end' | 'baseline' | 'start' |
AddressEdit AddressEdit
Shipping address form editing
View Code
<AddressEdit addressInfo={addressInfo}
areaList={areaData}
showPostal showSetDefault
showSearchResult={false}
isEdit={false}
showDelete={false}
showArea saveButtonText="保存"
deleteButtonText="删除"
areaColumnsPlaceholder={['请选择', '请选择', '请选择']}
telValidator={(tel) => /^1[3-9]d{9}$/.test(tel)}
onSave={(info) => saveAddress(info)}
onDelete={(info) => deleteAddress(info)}
onChange={(info) => console.log(info)}
onChangeDetail={(val) => {}} />
Props
| Property | Description | Type | Default |
|---|
addressInfo | Recipient info object | AddressInfo | {} |
areaList | Area data | object | {} |
showPostal | Whether to show postal code | boolean | false |
showSetDefault | Whether to show default address bar | boolean | false |
showSearchResult | Whether to show search result | boolean | false |
showArea | Whether to show area | boolean | true |
showDelete | Whether to show delete button | boolean | false |
isEdit | Whether edit mode | boolean | false |
saveButtonText | Save button text | string | '保存' |
deleteButtonText | Delete button text | string | '删除' |
areaColumnsPlaceholder | Area column placeholder | string[] | [] |
telValidator | Phone validator function | (tel: string) => boolean | - |
onSave | Save callback | (info: AddressInfo) => void | - |
onDelete | Delete callback | (info: AddressInfo) => void | - |
onChange | Form change callback | (info: AddressInfo) => void | - |
onChangeDetail | Detail change callback | (val: string) => void | - |
AddressList AddressList
Display/switch address list
View Code
<AddressList list={addresses}
chosenId={selectedId}
addButtonText="新增地址"
defaultTagText="默认"
disabledText="以下地址超出配送范围"
disabledList={disabledAddresses}
switchable
onAdd={() => addNew()}
onSelect={(item, index) => select(item)}
onEdit={(item, index) => edit(item)}
onClickItem={(item, index) => {}} />
Props
| Property | Description | Type | Default |
|---|
list | AddressList | AddressItem[] | [] |
disabledList | Non-deliverable address list | AddressItem[] | [] |
chosenId | Current selected address id | string | number | '' |
addButtonText | Bottom add button text | string | '新增地址' |
defaultTagText | Default address tag text | string | '' |
disabledText | Non-deliverable area hint | string | '' |
switchable | Whether to allow address switching | boolean | true |
onAdd | Add button click callback | () => void | - |
onSelect | Switch selected address callback | (item, index) => void | - |
onEdit | Edit button click callback | (item, index) => void | - |
onClickItem | Address item click callback | (item, index) => void | - |
Area Area
Province/city/district cascading select
View Code
<Area bind:show title="选择地区"
areaList={areaData}
value="110101"
columnsNum={3}
columnsPlaceholder={['请选择', '请选择', '请选择']}
onConfirm={(val) => console.log(val)}
onCancel={() => (show = false)}
onChange={(val) => console.log(val)} />
Props
| Property | Description | Type | Default |
|---|
show | Whether to show | boolean | false |
value | Current selected area code | string | '' |
title | Toolbar title | string | '' |
areaList | Area data | object | {} |
columnsNum | Columns count (1-3) | number | string | 3 |
columnsPlaceholder | Column placeholder text | string[] | [] |
loading | Whether to show loading | boolean | false |
readonly | Whether readonly | boolean | false |
confirmButtonText | Confirm button text | string | '确认' |
cancelButtonText | Cancel text | string | '取消' |
onConfirm | Confirm callback | Function | - |
onCancel | Cancel callback | Function | - |
onChange | Option change callback | Function | - |
Card Card
Product card for displaying image, price, etc.
View Code
<Card title="商品名称"
price="2.00" originPrice="10.00"
desc="描述信息" num={2}
thumb="https://img.example.com/thumb.jpg"
tag="标签" currency="¥"
centered lazyLoad
thumbLink="" />
Props
| Property | Description | Type | Default |
|---|
title | Product title | string | '' |
price | Product price | string | number | '' |
originPrice | Original price (strikethrough) | string | number | '' |
desc | Product description | string | '' |
num | Product quantity | string | number | '' |
thumb | Left image URL | string | '' |
tag | Tag content | string | '' |
currency | Currency symbol | string | '¥' |
centered | Whether to center content vertically | boolean | false |
lazyLoad | Whether to lazy load image | boolean | false |
thumbLink | Image click link | string | '' |
Coupon / CouponList 优惠券
Coupon display and selection
View Code
<CouponList
coupons={availableCoupons}
disabledCoupons={usedCoupons}
bind:chosenCoupon
bind:code
enabledTitle="可用优惠券"
disabledTitle="不可用优惠券"
exchangeButtonText="兑换"
showExchangeBar showCloseButton
showCount currency="¥"
closeButtonText="不使用优惠"
inputPlaceholder="请输入优惠码"
onchange={(index) => selectCoupon(index)}
onexchange={(code) => exchangeCoupon(code)} />
Props
| Property | Description | Type | Default |
|---|
coupons | Available coupons | CouponInfo[] | [] |
disabledCoupons | Disabled coupons | CouponInfo[] | [] |
chosenCoupon | Current selected coupon index | number | -1 |
code | Exchange code | string | '' |
enabledTitle | Available coupons title | string | '可用优惠券' |
disabledTitle | Disabled coupons title | string | '不可用优惠券' |
exchangeButtonText | Exchange button text | string | '兑换' |
exchangeButtonLoading | Whether exchange button loading | boolean | false |
exchangeButtonDisabled | Whether exchange button disabled | boolean | false |
showExchangeBar | Whether to show exchange bar | boolean | true |
showCloseButton | Whether to show close button | boolean | true |
showCount | Whether to show counts | boolean | true |
closeButtonText | List bottom button text | string | '不使用优惠' |
inputPlaceholder | Input placeholder text | string | '请输入优惠码' |
currency | Currency symbol | string | '¥' |
emptyImage | Empty list placeholder image | string | '' |
onchange | Coupon change callback | (index: number) => void | - |
onexchange | Exchange callback | (code: string) => void | - |
Signature Signature
Handwriting signature pad
View Code
<Signature type="png"
penColor="#000" lineWidth={3}
backgroundColor=""
clearButtonText="清空"
confirmButtonText="确认"
onclear={() => console.log('cleared')}
onconfirm={({ image, canvas }) => saveSignature(image)}
onstart={() => console.log('start')}
onsigning={() => {}}
onend={() => console.log('end')} />
Props
| Property | Description | Type | Default |
|---|
type | Export image type | string | 'png' |
penColor | Stroke color | string | '#000' |
lineWidth | Line width | number | 3 |
backgroundColor | Canvas background color | string | '' |
clearButtonText | Clear button text | string | '清空' |
confirmButtonText | Confirm button text | string | '确认' |
onclear | Clear callback | () => void | - |
onconfirm | Confirm button click callback | (data: { image, canvas }) => void | - |
onstart | Signing start callback | () => void | - |
onsigning | Signing callback | () => void | - |
onend | Signing end callback | () => void | - |
SubmitBar SubmitBar
Bottom submit bar for cart/checkout page
View Code
<SubmitBar price={3050}
buttonText="提交订单"
disabled={!hasChecked}
loading={submitting}
currency="¥" decimalLength={2}
suffixLabel=""
textAlign="right"
buttonType="danger"
tipText="提示信息"
tipIcon="info-o"
safeAreaInsetBottom
placeholder
onSubmit={() => submitOrder()} />
Props
| Property | Description | Type | Default |
|---|
price | Amount (in cents) | number | 0 |
buttonText | Button text | string | '' |
buttonType | Button type | string | 'danger' |
buttonColor | Button color | string | '' |
loading | Whether to show loading button | boolean | false |
disabled | Whether to disable button | boolean | false |
tipText | Tip text | string | '' |
tipIcon | Tip icon | string | '' |
currency | Currency symbol | string | '¥' |
decimalLength | Price decimal places | number | string | 2 |
suffixLabel | Text after price | string | '' |
textAlign | Price text alignment | 'left' | 'right' | 'right' |
label | Text before price | string | '合计:' |
safeAreaInsetBottom | Whether to adapt bottom safe area | boolean | true |
placeholder | Whether to generate placeholder above | boolean | false |
onSubmit | Button click callback | () => void | - |
ConfigProvider ConfigProvider
Global theme config, CSS variable injection
View Code
<ConfigProvider theme="dark"
themeVars={{
primaryColor: '#07c160',
successColor: '#67c23a',
buttonPrimaryBackground: '#07c160',
}}
tag="div"
iconPrefix="smu-icon">
<App />
</ConfigProvider>
Props
| Property | Description | Type | Default |
|---|
theme | Theme mode | 'light' | 'dark' | 'light' |
themeVars | Custom theme CSS variables | object | {} |
themeVarsDark | Dark mode CSS variables | object | {} |
themeVarsLight | Light mode CSS variables | object | {} |
tag | Root HTML tag name | string | 'div' |
zIndex | Set z-index for all popup components | number | 2000 |
iconPrefix | Icon class prefix for all icons | string | 'smu-icon' |