UNPKG

@douyinfe/semi-ui

Version:

A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.

401 lines (343 loc) 11.8 kB
--- localeCode: zh-CN order: 92 category: 反馈类 title: Skeleton 骨架屏 icon: doc-skeleton brief: 在需要等待加载内容的位置提供的占位组件。 --- ## 概述 - `Avatar`:占位头像,默认为圆形,默认尺寸:Avatar medium: `width: 48px`,`height: 48px`。支持 Avatar 的 size、shape 属性 (v2.20后支持) - `Image`:占位图像,默认尺寸:`width: 100%`,`height: 100%`。 - `Title`:占位标题,默认尺寸:`width: 100%`, `height: 24px`。 - `Paragraph`:占位内容部分,默认尺寸:`width: 100%`,`height: 16px`,`margin-bottom: 10px`。 - `Button`:占位按钮,默认尺寸:`width: 115px`,`height: 32px`。 > 注意:默认样式均可通过 `className` 或 `style` 进行自定义。 ## 代码演示 ### 如何引入 ```jsx import import { Skeleton } from '@douyinfe/semi-ui'; ``` ### 基本使用 ```jsx live=true import React, { useState } from 'react'; import { Skeleton, Switch, Avatar, Button } from '@douyinfe/semi-ui'; () => { const [loading, setLoading] = useState(true); const showContent = () => { setLoading(!loading); }; return ( <> <span style={{ display: 'flex', alignItems: 'center' }}> <Switch onChange={() => showContent()} /> <span style={{ marginLeft: '10px' }}>显示加载内容</span> </span> <br /> <Skeleton placeholder={<Skeleton.Avatar />} loading={loading}> <Avatar color="blue" style={{ marginBottom: 10 }}> U </Avatar> </Skeleton> <br /> <Skeleton style={{ width: 200, height: 150 }} placeholder={<Skeleton.Image />} loading={loading}> <img src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dy.png" height="150" alt="avatar" /> </Skeleton> <br /> <Skeleton style={{ width: 80 }} placeholder={<Skeleton.Title style={{ marginBottom: 10 }} />} loading={loading} > <h4 style={{ marginBottom: 0 }}>Semi UI</h4> </Skeleton> <Skeleton style={{ width: 240 }} placeholder={<Skeleton.Paragraph rows={2} />} loading={loading}> <p style={{ width: 240 }}>精心打磨每一个组件的用户体验,从用户的角度考虑每个组件的使用场景。</p> </Skeleton> <br /> <Skeleton placeholder={<Skeleton.Button />} loading={loading}> <Button>Button</Button> </Skeleton> </> ); }; ``` ### 组合使用 图片和标题。 ```jsx live=true import React from 'react'; import { Skeleton } from '@douyinfe/semi-ui'; () => { const placeholder = ( <div> <Skeleton.Image style={{ width: 200, height: 150 }} /> <Skeleton.Title style={{ width: 120, marginTop: 10 }} /> </div> ); return ( <Skeleton placeholder={placeholder} loading={true}> <img src="https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/dy.png" height="150" alt="avatar" /> <h4>Semi UI</h4> </Skeleton> ); }; ``` 统计数字。 ```jsx live=true import React from 'react'; import { Skeleton, Descriptions } from '@douyinfe/semi-ui'; () => { const placeholder = ( <div> <Skeleton.Paragraph rows={1} style={{ width: 80, marginBottom: 10 }} /> <Skeleton.Title style={{ width: 120 }} /> </div> ); const data = [{ key: '实际用户数量', value: '1,480,000' }]; return ( <Skeleton placeholder={placeholder} loading={true}> <Descriptions data={data} row /> </Skeleton> ); }; ``` 头像和标题。 ```jsx live=true import React from 'react'; import { Skeleton, Avatar } from '@douyinfe/semi-ui'; () => { const placeholder = ( <div style={{ display: 'flex', alignItems: 'center' }}> <Skeleton.Avatar style={{ marginRight: 12 }} /> <Skeleton.Title style={{ width: 120 }} /> </div> ); return ( <Skeleton placeholder={placeholder} loading={true}> <Avatar color="blue" style={{ marginRight: 12 }}> UI </Avatar> <span>Semi UI</span> </Skeleton> ); }; ``` 居中段落和按钮。 ```jsx live=true import React from 'react'; import { Skeleton, Button } from '@douyinfe/semi-ui'; () => { const style = { display: 'flex', flexDirection: 'column', alignItems: 'center', width: '300px', marginBottom: '10px', }; const placeholder = ( <div style={style}> <Skeleton.Paragraph style={style} rows={3} /> <Skeleton.Button /> </div> ); return ( <Skeleton placeholder={placeholder} loading={true} style={{ textAlign: 'center' }}> <div style={{ textAlign: 'center' }}> <p>Hi, Bytedance dance dance.</p> <p>Hi, Bytedance dance dance.</p> <Button>Button</Button> </div> </Skeleton> ); }; ``` 头像、标题和段落。 ```jsx live=true import React from 'react'; import { Skeleton, Avatar } from '@douyinfe/semi-ui'; () => { const style = { display: 'flex', alignItems: 'flex-start', }; const placeholder = ( <div style={style}> <Skeleton.Avatar style={{ marginRight: 12 }} /> <div> <Skeleton.Title style={{ width: 120, marginBottom: 12, marginTop: 12 }} /> <Skeleton.Paragraph style={{ width: 240 }} rows={3} /> </div> </div> ); return ( <Skeleton placeholder={placeholder} loading={true}> <div style={style}> <Avatar color="blue" style={{ marginRight: 12 }}> UI </Avatar> <div> <h3>Semi UI</h3> <p>Hi, Bytedance dance dance.</p> <p>Hi, Bytedance dance dance.</p> <p>Hi, Bytedance dance dance.</p> </div> </div> </Skeleton> ); }; ``` 表格。 ```jsx live=true hideInDSM import React from 'react'; import { Skeleton, Table } from '@douyinfe/semi-ui'; () => { const data = { columns: [ { title: 'Name', dataIndex: 'name', }, { title: 'Age', dataIndex: 'age', }, { title: 'Address', dataIndex: 'address', }, ], content: [ { key: '1', name: 'John Brown', age: 32, address: 'New York No. 1 Lake Park, New York No. 1 Lake Park', }, { key: '2', name: 'Jim Green', age: 42, address: 'London No. 1 Lake Park', }, { key: '3', name: 'Joe Black', age: 32, address: 'Sidney No. 1 Lake Park', }, { key: '4', name: 'Disabled User', age: 99, address: 'Sidney No. 1 Lake Park', }, ], }; const skData = { columns: [1, 2, 3].map(key => { const item = {}; item.title = <Skeleton.Title style={{ width: '0' }} />; item.dataIndex = `${key}`; return item; }), dataSource: [1, 2, 3, 4].map(key => { const item = {}; item.key = key; [1, 2, 3].forEach(i => { const width = 50 * i; item[i] = <Skeleton.Paragraph style={{ width: width }} rows={1} />; }); return item; }), }; const placeholder = ( <div style={{ position: 'relative' }}> <Table style={{ backgroundColor: 'var(--semi-color-bg-1)' }} columns={skData.columns} dataSource={skData.dataSource} pagination={false} /> <div style={{ position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 }}></div> </div> ); return ( <Skeleton placeholder={placeholder} loading={true}> <div> <Table columns={data.columns} dataSource={data.content} pagination={false} /> </div> </Skeleton> ); }; ``` ### 加载动画 通过设置 `active` 属性可以展示动画效果。 ```jsx live=true hideInDSM import React from 'react'; import { Skeleton, Avatar } from '@douyinfe/semi-ui'; () => { const style = { display: 'flex', alignItems: 'flex-start', }; const placeholder = ( <div style={style}> <Skeleton.Avatar style={{ marginRight: 12 }} /> <div> <Skeleton.Title style={{ width: 120, marginBottom: 12, marginTop: 12 }} /> <Skeleton.Paragraph style={{ width: 240 }} rows={3} /> </div> </div> ); return ( <Skeleton placeholder={placeholder} loading={true} active> <div style={style}> <Avatar color="blue" style={{ marginRight: 12 }}> UI </Avatar> <div> <h3>Semi UI</h3> <p>Hi, Bytedance dance dance.</p> <p>Hi, Bytedance dance dance.</p> <p>Hi, Bytedance dance dance.</p> </div> </div> </Skeleton> ); }; ``` ## API 参考 ### Skeleton | 属性 | 说明 | 类型 | 默认值 | | ----------- | ------------------------------------------ | ------------- | ------ | | active | 是否展示动画效果 | boolean | false | | className | 类名 | string | - | | loading | 为 true 时,显示占位元素。反之则显示子组件 | boolean | true | | placeholder | 加载等待时的占位元素 | ReactNode | - | | style | 样式 | CSSProperties | - | ### Skeleton.Avatar > `Skeleton.Image`,`Skeleton.Title`,`Skeleton.Button` 大部分API 与 `Skeleton.Avatar` 相同。其中 shape 仅 `Skeleton.Avatar支持` | 属性 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | className | 类名 | string | - | | size | 设置头像的大小,支持 `extra-extra-small`, `extra-small`、`small`、`medium`、`large`、`extra-large` | string | `medium` | | style | 样式 | CSSProperties | - | | shape | 指定头像的形状,支持 `circle`、`square` | string | `circle` | ### Skeleton.Paragraph | 属性 | 说明 | 类型 | 默认值 | | --------- | -------------------- | ------------- | ------ | | className | 类名 | string | - | | rows | 设置段落占位图的行数 | number | 4 | | style | 样式 | CSSProperties | - | ## 文案规范 - 不变的固定内容直接展示固定内容,可变的内容使用骨架屏展示 ## 设计变量 <DesignToken/>