feat(skeleton-item): add skeleton-item component (#11173)

* feat(skeleton-item): add skeleton-item component

* docs(Skeleton): update docs

* feat(Skeleton): add skeleton title avatar paragraph image componets

* chore: add uncommit files

* test(Skeleton): fix skeleton test case failed

* feat(Skeleton-Image): add skeleton-image style

* test(Skeleton): fix failed test case

* docs(Skeleton): update skeleton docs

* fix(Skeleton): add skeleton image theme vars

* perf(Skeleton): use Icon componet in Skeleton image to reduce bundle size

* docs(Skeleton): update skeleton docs

* docs(Skeleton): fix wrong component name
This commit is contained in:
哭你几哇 2022-11-05 21:17:23 +08:00 committed by GitHub
parent 3991f27a02
commit 19cd0667e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 542 additions and 81 deletions

View File

@ -0,0 +1,35 @@
import { defineComponent, ExtractPropTypes } from 'vue';
// Utils
import {
numericProp,
getSizeStyle,
makeStringProp,
createNamespace,
} from '../utils';
const [name, bem] = createNamespace('skeleton-avatar');
export type SkeletonAvatarShape = 'square' | 'round';
export const skeletonAvatarProps = {
avatarSize: numericProp,
avatarShape: makeStringProp<SkeletonAvatarShape>('round'),
};
export type SkeletonAvatarProps = ExtractPropTypes<typeof skeletonAvatarProps>;
export default defineComponent({
name,
props: skeletonAvatarProps,
setup(props) {
return () => (
<div
class={bem([props.avatarShape])}
style={getSizeStyle(props.avatarSize)}
/>
);
},
});

View File

@ -0,0 +1,38 @@
import { defineComponent, type ExtractPropTypes } from 'vue';
import {
numericProp,
getSizeStyle,
makeStringProp,
createNamespace,
} from '../utils';
import { Icon } from '../icon';
const [name, bem] = createNamespace('skeleton-image');
export type SkeletonImageShape = 'square' | 'round';
export const skeletonImageProps = {
imageSize: numericProp,
imageShape: makeStringProp<SkeletonImageShape>('square'),
};
export type SkeletonImageProps = ExtractPropTypes<typeof skeletonImageProps>;
export default defineComponent({
name,
props: skeletonImageProps,
setup(props) {
return () => (
<div
class={bem([props.imageShape])}
style={getSizeStyle(props.imageSize)}
>
<Icon name={'photo'} class={bem('icon')} />
</div>
);
},
});

View File

@ -0,0 +1,34 @@
import { defineComponent, ExtractPropTypes } from 'vue';
import { createNamespace, numericProp } from '../utils';
export const DEFAULT_ROW_WIDTH = '100%';
export const skeletonParagraphProps = {
round: Boolean,
rowWidth: {
type: numericProp,
default: DEFAULT_ROW_WIDTH,
},
};
export type SkeletonParagraphProps = ExtractPropTypes<
typeof skeletonParagraphProps
>;
const [name, bem] = createNamespace('skeleton-paragraph');
export default defineComponent({
name,
props: skeletonParagraphProps,
setup(props) {
return () => (
<div
class={bem([{ round: props.round }])}
style={{ width: props.rowWidth }}
/>
);
},
});

View File

@ -10,10 +10,20 @@ Register component globally via `app.use`, refer to [Component Registration](#/e
```js
import { createApp } from 'vue';
import { Skeleton } from 'vant';
import {
Skeleton,
VanSkeletonTitle,
VanSkeletonImage,
VanSkeletonAvatar,
VanSkeletonParagraph,
} from 'vant';
const app = createApp();
app.use(Skeleton);
app.use(VanSkeletonTitle);
app.use(VanSkeletonImage);
app.use(VanSkeletonAvatar);
app.use(VanSkeletonParagraph);
```
## Usage
@ -56,9 +66,29 @@ export default {
};
```
### Custom Content
Using `template` slots to display custom content.
```html
<van-skeleton>
<template #template>
<div class="template-slot">
<van-skeleton-image />
<div :style="{ flex: 1 }">
<van-skeleton-paragraph row-width="60%" />
<van-skeleton-paragraph />
<van-skeleton-paragraph />
<van-skeleton-paragraph />
</div>
</div>
</template>
</van-skeleton>
```
## API
### Props
### Skeleton Props
| Attribute | Description | Type | Default |
| --- | --- | --- | --- |
@ -68,17 +98,58 @@ export default {
| avatar | Whether to show avatar placeholder | _boolean_ | `false` |
| loading | Whether to show skeleton, pass `false` to show child component | _boolean_ | `true` |
| animate | Whether to enable animation | _boolean_ | `true` |
| round | Whether to show round title and row | _boolean_ | `false` |
| round | Whether to show round title and paragraph | _boolean_ | `false` |
| title-width | Title width | _number \| string_ | `40%` |
| avatar-size | Size of avatar placeholder | _number \| string_ | `32px` |
| avatar-shape | Shape of avatar placeholder, can be set to `square` | _string_ | `round` |
### SkeletonParagraph Props
| Attribute | Description | Type | Default |
| --------- | ------------------------------- | --------- | ------- |
| round | Whether to show round paragraph | _boolean_ | `false` |
| row-width | Paragraph width | _string_ | `100%` |
### SkeletonTitle Props
| Attribute | Description | Type | Default |
| ----------- | --------------------------- | ------------------ | ------- |
| round | Whether to show round title | _boolean_ | `false` |
| title-width | Title width | _number \| string_ | `40%` |
### SkeletonAvatar Props
| Attribute | Description | Type | Default |
| --- | --- | --- | --- |
| avatar-size | Size of avatar placeholder | _number \| string_ | `32px` |
| avatar-shape | Shape of avatar placeholder, can be set to `square` | _string_ | `round` |
### SkeletonImage Props
| Attribute | Description | Type | Default |
| --- | --- | --- | --- |
| image-size | Size of image placeholder | _number \| string_ | `32px` |
| image-shape | Shape of image placeholder, can be set to `square` | _string_ | `round` |
### Skeleton Slots
| Name | Description |
| -------- | -------------- |
| default | Default slot |
| template | Custom content |
### Types
The component exports the following type definitions:
```ts
import type { SkeletonProps, SkeletonAvatarShape } from 'vant';
import type {
SkeletonProps,
SkeletonImageProps,
SkeletonTitleProps,
SkeletonAvatarShape,
SkeletonParagraphProps,
} from 'vant';
```
## Theming
@ -96,3 +167,5 @@ The component provides the following CSS variables, which can be used to customi
| --van-skeleton-avatar-size | _32px_ | - |
| --van-skeleton-avatar-background | _var(--van-active-color)_ | - |
| --van-skeleton-duration | _1.2s_ | - |
| --van-skeleton-image-size | _96px_ |
| --van-skeleton-image-radius | _24px_ | - |

View File

@ -10,10 +10,20 @@
```js
import { createApp } from 'vue';
import { Skeleton } from 'vant';
import {
Skeleton,
VanSkeletonTitle,
VanSkeletonImage,
VanSkeletonAvatar,
VanSkeletonParagraph,
} from 'vant';
const app = createApp();
app.use(Skeleton);
app.use(VanSkeletonTitle);
app.use(VanSkeletonImage);
app.use(VanSkeletonAvatar);
app.use(VanSkeletonParagraph);
```
## 代码演示
@ -62,9 +72,29 @@ export default {
};
```
### 自定义展示内容
通过 `template` 插槽完成自定义内容的展示。
```html
<van-skeleton>
<template #template>
<div class="template-slot">
<van-skeleton-image />
<div :style="{ flex: 1 }">
<van-skeleton-paragraph row-width="60%" />
<van-skeleton-paragraph />
<van-skeleton-paragraph />
<van-skeleton-paragraph />
</div>
</div>
</template>
</van-skeleton>
```
## API
### Props
### Skeleton Props
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
@ -79,12 +109,53 @@ export default {
| avatar-size | 头像占位图大小 | _number \| string_ | `32px` |
| avatar-shape | 头像占位图形状,可选值为 `square` | _string_ | `round` |
### SkeletonParagraph Props
| 参数 | 说明 | 类型 | 默认值 |
| --------- | ------------------------ | --------- | ------- |
| round | 是否将段落显示为圆角风格 | _boolean_ | `false` |
| row-width | 段落占位图宽度 | _string_ | `100%` |
### SkeletonTitle Props
| 参数 | 说明 | 类型 | 默认值 |
| ----------- | ------------------------ | ------------------ | ------- |
| round | 是否将标题显示为圆角风格 | _boolean_ | `false` |
| title-width | 标题占位图宽度 | _number \| string_ | `40%` |
### SkeletonAvatar Props
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| avatar-size | 头像占位图大小 | _number \| string_ | `32px` |
| avatar-shape | 头像占位图形状,可选值为 `square` | _string_ | `round` |
### SkeletonImage Props
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| image-size | 图片占位图大小 | _number \| string_ | `32px` |
| image-shape | 图片占位图形状,可选值为 `square` | _string_ | `round` |
### Skeleton Slots
| 名称 | 说明 |
| -------- | ---------- |
| default | 骨架屏内容 |
| template | 自定义内容 |
### 类型定义
组件导出以下类型定义:
```ts
import type { SkeletonProps, SkeletonAvatarShape } from 'vant';
import type {
SkeletonProps,
SkeletonImageProps,
SkeletonTitleProps,
SkeletonAvatarShape,
SkeletonParagraphProps,
} from 'vant';
```
## 主题定制
@ -93,12 +164,14 @@ import type { SkeletonProps, SkeletonAvatarShape } from 'vant';
组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 [ConfigProvider 组件](#/zh-CN/config-provider)。
| 名称 | 默认值 | 描述 |
| -------------------------------- | ------------------------- | ---- |
| --van-skeleton-row-height | _16px_ | - |
| --van-skeleton-row-background | _var(--van-active-color)_ | - |
| --van-skeleton-row-margin-top | _var(--van-padding-sm)_ | - |
| --van-skeleton-title-width | _40%_ | - |
| --van-skeleton-avatar-size | _32px_ | - |
| --van-skeleton-avatar-background | _var(--van-active-color)_ | - |
| --van-skeleton-duration | _1.2s_ | - |
| 名称 | 默认值 | 描述 |
| ----------------------------------- | ------------------------- | ---- |
| --van-skeleton-paragraph-height | _16px_ | - |
| --van-skeleton-paragraph-background | _var(--van-active-color)_ | - |
| --van-skeleton-paragraph-margin-top | _var(--van-padding-sm)_ | - |
| --van-skeleton-title-width | _40%_ | - |
| --van-skeleton-avatar-size | _32px_ | - |
| --van-skeleton-avatar-background | _var(--van-active-color)_ | - |
| --van-skeleton-duration | _1.2s_ | - |
| --van-skeleton-image-size | _96px_ |
| --van-skeleton-image-radius | _24px_ | - |

View File

@ -1,31 +1,34 @@
import { defineComponent, type PropType, type ExtractPropTypes } from 'vue';
// Utils
import {
addUnit,
truthProp,
numericProp,
getSizeStyle,
makeStringProp,
makeNumericProp,
createNamespace,
type Numeric,
} from '../utils';
const [name, bem] = createNamespace('skeleton');
const DEFAULT_ROW_WIDTH = '100%';
const DEFAULT_LAST_ROW_WIDTH = '60%';
// Components
import SkeletonTitle from './Title';
import SkeletonAvatar, { type SkeletonAvatarShape } from './Avatar';
import SkeletonParagraph, { DEFAULT_ROW_WIDTH } from './Paragraph';
export type SkeletonAvatarShape = 'square' | 'round';
const [name, bem] = createNamespace('skeleton');
const DEFAULT_LAST_ROW_WIDTH = '60%';
export const skeletonProps = {
row: makeNumericProp(0),
title: Boolean,
round: Boolean,
title: Boolean,
titleWidth: numericProp,
avatar: Boolean,
avatarSize: numericProp,
avatarShape: makeStringProp<SkeletonAvatarShape>('round'),
loading: truthProp,
animate: truthProp,
avatarSize: numericProp,
titleWidth: numericProp,
avatarShape: makeStringProp<SkeletonAvatarShape>('round'),
rowWidth: {
type: [Number, String, Array] as PropType<Numeric | Numeric[]>,
default: DEFAULT_ROW_WIDTH,
@ -45,9 +48,9 @@ export default defineComponent({
const renderAvatar = () => {
if (props.avatar) {
return (
<div
class={bem('avatar', props.avatarShape)}
style={getSizeStyle(props.avatarSize)}
<SkeletonAvatar
avatarShape={props.avatarShape}
avatarSize={props.avatarSize}
/>
);
}
@ -56,10 +59,7 @@ export default defineComponent({
const renderTitle = () => {
if (props.title) {
return (
<h3
class={bem('title')}
style={{ width: addUnit(props.titleWidth) }}
/>
<SkeletonTitle round={props.round} titleWidth={props.titleWidth} />
);
}
};
@ -82,9 +82,29 @@ export default defineComponent({
Array(+props.row)
.fill('')
.map((_, i) => (
<div class={bem('row')} style={{ width: addUnit(getRowWidth(i)) }} />
<SkeletonParagraph
key={i}
round={props.round}
rowWidth={addUnit(getRowWidth(i))}
/>
));
const renderContents = () => {
if (slots.template) {
return slots.template();
}
return (
<>
{renderAvatar()}
<div class={bem('content')}>
{renderTitle()}
{renderRows()}
</div>
</>
);
};
return () => {
if (!props.loading) {
return slots.default?.();
@ -95,11 +115,7 @@ export default defineComponent({
class={bem({ animate: props.animate, round: props.round })}
{...attrs}
>
{renderAvatar()}
<div class={bem('content')}>
{renderTitle()}
{renderRows()}
</div>
{renderContents()}
</div>
);
};

View File

@ -0,0 +1,27 @@
import { defineComponent, type ExtractPropTypes } from 'vue';
import { createNamespace, numericProp, addUnit } from '../utils';
const [name, bem] = createNamespace('skeleton-title');
export const skeletonTitleProps = {
round: Boolean,
titleWidth: numericProp,
};
export type SkeletonTitleProps = ExtractPropTypes<typeof skeletonTitleProps>;
export default defineComponent({
name,
props: skeletonTitleProps,
setup(props) {
return () => (
<h3
class={bem([{ round: props.round }])}
style={{ width: addUnit(props.titleWidth) }}
/>
);
},
});

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import VanSkeleton from '..';
import VanSkeleton, { VanSkeletonParagraph, VanSkeletonImage } from '..';
import VanSwitch from '../../switch';
import { ref } from 'vue';
import { cdnURL, useTranslate } from '../../../docs/site';
@ -10,12 +10,14 @@ const t = useTranslate({
showChildren: '显示子组件',
title: '关于 Vant',
desc: 'Vant 是一套轻量、可靠的移动端 Vue 组件库,提供了丰富的基础组件和业务组件,帮助开发者快速搭建移动应用。',
customContent: '自定义展示内容',
},
'en-US': {
showAvatar: 'Show Avatar',
showChildren: 'Show Children',
title: 'About Vant',
desc: 'Vant is a set of Mobile UI Components built on Vue.',
customContent: 'Custom Content',
},
});
@ -43,6 +45,22 @@ const show = ref(false);
</div>
</van-skeleton>
</demo-block>
<demo-block :title="t('customContent')">
<van-skeleton>
<template #template>
<div class="template-slot">
<van-skeleton-image />
<div :style="{ flex: 1 }">
<van-skeleton-paragraph row-width="60%" />
<van-skeleton-paragraph />
<van-skeleton-paragraph />
<van-skeleton-paragraph />
</div>
</div>
</template>
</van-skeleton>
</demo-block>
</template>
<style lang="less">
@ -80,5 +98,14 @@ const show = ref(false);
margin-right: var(--van-padding-md);
}
}
.template-slot {
display: flex;
width: 100%;
.van-skeleton-image {
margin-right: var(--van-padding-md);
}
}
}
</style>

View File

@ -1,10 +1,12 @@
:root {
--van-skeleton-row-height: 16px;
--van-skeleton-row-background: var(--van-active-color);
--van-skeleton-row-margin-top: var(--van-padding-sm);
--van-skeleton-paragraph-height: 16px;
--van-skeleton-paragraph-background: var(--van-active-color);
--van-skeleton-paragraph-margin-top: var(--van-padding-sm);
--van-skeleton-title-width: 40%;
--van-skeleton-avatar-size: 32px;
--van-skeleton-avatar-background: var(--van-active-color);
--van-skeleton-image-size: 96px;
--van-skeleton-image-radius: 24px;
--van-skeleton-duration: 1.2s;
}
@ -12,7 +14,7 @@
display: flex;
padding: 0 var(--van-padding-md);
&__avatar {
&-avatar {
flex-shrink: 0;
width: var(--van-skeleton-avatar-size);
height: var(--van-skeleton-avatar-size);
@ -28,28 +30,28 @@
width: 100%;
}
&__avatar + &__content {
&-avatar + &__content {
padding-top: var(--van-padding-xs);
}
&__row,
&__title {
height: var(--van-skeleton-row-height);
background: var(--van-skeleton-row-background);
&-paragraph,
&-title {
height: var(--van-skeleton-paragraph-height);
background: var(--van-skeleton-paragraph-background);
}
&__title {
&-title {
width: var(--van-skeleton-title-width);
margin: 0;
}
&__row {
&-paragraph {
&:not(:first-child) {
margin-top: var(--van-skeleton-row-margin-top);
margin-top: var(--van-skeleton-paragraph-margin-top);
}
}
&__title + &__row {
&-title + &-paragraph {
margin-top: 20px;
}
@ -59,11 +61,31 @@
}
&--round {
.van-skeleton__row,
.van-skeleton__title {
.van-skeleton-paragraph,
.van-skeleton-title {
border-radius: var(--van-radius-max);
}
}
&-image {
display: flex;
width: var(--van-skeleton-image-size);
height: var(--van-skeleton-image-size);
align-items: center;
justify-content: center;
background: var(--van-active-color);
&--round {
border-radius: var(--van-skeleton-image-radius);
}
&__icon {
width: calc(var(--van-skeleton-image-size) / 2);
height: calc(var(--van-skeleton-image-size) / 2);
font-size: calc(var(--van-skeleton-image-size) / 2);
color: var(--van-gray-5);
}
}
}
@keyframes van-skeleton-blink {

View File

@ -1,14 +1,47 @@
import { withInstall } from '../utils';
import _Skeleton from './Skeleton';
import _SkeletonImage from './Image';
import _SkeletonTitle from './Title';
import _SkeletonAvatar from './Avatar';
import _SkeletonParagraph from './Paragraph';
import { withInstall } from '../utils';
export const VanSkeletonImage = withInstall(_SkeletonImage);
export const VanSkeletonTitle = withInstall(_SkeletonTitle);
export const VanSkeletonAvatar = withInstall(_SkeletonAvatar);
export const VanSkeletonParagraph = withInstall(_SkeletonParagraph);
export const Skeleton = withInstall(_Skeleton);
export default Skeleton;
// Skeleton
export { skeletonProps } from './Skeleton';
export type { SkeletonProps, SkeletonAvatarShape } from './Skeleton';
export type { SkeletonProps } from './Skeleton';
// SkeletonImage
export { skeletonImageProps } from './Image';
export type { SkeletonImageProps, SkeletonImageShape } from './Image';
// SkeletonAvatar
export { skeletonAvatarProps } from './Avatar';
export type { SkeletonAvatarProps, SkeletonAvatarShape } from './Avatar';
// SkeletonParagraph
export { skeletonParagraphProps } from './Paragraph';
export type { SkeletonParagraphProps } from './Paragraph';
// SkeletonTitle
export { skeletonTitleProps } from './Title';
export type { SkeletonTitleProps } from './Title';
export type { SkeletonThemeVars } from './types';
declare module 'vue' {
export interface GlobalComponents {
VanSkeleton: typeof Skeleton;
VanSkeletonImage: typeof VanSkeletonImage;
VanSkeletonTitle: typeof VanSkeletonTitle;
VanSkeletonAvatar: typeof VanSkeletonAvatar;
VanSkeletonParagraph: typeof VanSkeletonParagraph;
}
}

View File

@ -4,17 +4,17 @@ exports[`should render demo and match snapshot 1`] = `
<div>
<div class="van-skeleton van-skeleton--animate">
<div class="van-skeleton__content">
<h3 class="van-skeleton__title">
<h3 class="van-skeleton-title">
</h3>
<div class="van-skeleton__row"
<div class="van-skeleton-paragraph"
style="width: 100%;"
>
</div>
<div class="van-skeleton__row"
<div class="van-skeleton-paragraph"
style="width: 100%;"
>
</div>
<div class="van-skeleton__row"
<div class="van-skeleton-paragraph"
style="width: 60%;"
>
</div>
@ -23,20 +23,20 @@ exports[`should render demo and match snapshot 1`] = `
</div>
<div>
<div class="van-skeleton van-skeleton--animate">
<div class="van-skeleton__avatar van-skeleton__avatar--round">
<div class="van-skeleton-avatar van-skeleton-avatar--round">
</div>
<div class="van-skeleton__content">
<h3 class="van-skeleton__title">
<h3 class="van-skeleton-title">
</h3>
<div class="van-skeleton__row"
<div class="van-skeleton-paragraph"
style="width: 100%;"
>
</div>
<div class="van-skeleton__row"
<div class="van-skeleton-paragraph"
style="width: 100%;"
>
</div>
<div class="van-skeleton__row"
<div class="van-skeleton-paragraph"
style="width: 60%;"
>
</div>
@ -53,24 +53,52 @@ exports[`should render demo and match snapshot 1`] = `
</div>
</div>
<div class="van-skeleton van-skeleton--animate">
<div class="van-skeleton__avatar van-skeleton__avatar--round">
<div class="van-skeleton-avatar van-skeleton-avatar--round">
</div>
<div class="van-skeleton__content">
<h3 class="van-skeleton__title">
<h3 class="van-skeleton-title">
</h3>
<div class="van-skeleton__row"
<div class="van-skeleton-paragraph"
style="width: 100%;"
>
</div>
<div class="van-skeleton__row"
<div class="van-skeleton-paragraph"
style="width: 100%;"
>
</div>
<div class="van-skeleton__row"
<div class="van-skeleton-paragraph"
style="width: 60%;"
>
</div>
</div>
</div>
</div>
<div>
<div class="van-skeleton van-skeleton--animate">
<div class="template-slot">
<div class="van-skeleton-image van-skeleton-image--square">
<i class="van-badge__wrapper van-icon van-icon-photo van-skeleton-image__icon">
</i>
</div>
<div style="flex: 1;">
<div class="van-skeleton-paragraph"
style="width: 60%;"
>
</div>
<div class="van-skeleton-paragraph"
style="width: 100%;"
>
</div>
<div class="van-skeleton-paragraph"
style="width: 100%;"
>
</div>
<div class="van-skeleton-paragraph"
style="width: 100%;"
>
</div>
</div>
</div>
</div>
</div>
`;

View File

@ -1,7 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should Skeleton works with template slots 1`] = `
<div class="van-skeleton van-skeleton--animate">
custom content
</div>
`;
exports[`should change avatar shape when using avatar-shape prop 1`] = `
<div class="van-skeleton__avatar van-skeleton__avatar--square">
<div class="van-skeleton-avatar van-skeleton-avatar--square">
</div>
`;
@ -18,20 +24,29 @@ exports[`should render default slot when loading is false 1`] = `
exports[`should render with row width array correctly 1`] = `
<div class="van-skeleton van-skeleton--animate">
<div class="van-skeleton__content">
<div class="van-skeleton__row"
<div class="van-skeleton-paragraph"
style="width: 100%;"
>
</div>
<div class="van-skeleton__row"
<div class="van-skeleton-paragraph"
style="width: 30px;"
>
</div>
<div class="van-skeleton__row"
<div class="van-skeleton-paragraph"
style="width: 5rem;"
>
</div>
<div class="van-skeleton__row">
<div class="van-skeleton-paragraph"
style="width: 100%;"
>
</div>
</div>
</div>
`;
exports[`should skeleton image render correctly 1`] = `
<div class="van-skeleton-image van-skeleton-image--square">
<i class="van-badge__wrapper van-icon van-icon-photo van-skeleton-image__icon">
</i>
</div>
`;

View File

@ -1,5 +1,5 @@
import { mount } from '../../../test';
import { Skeleton } from '..';
import { Skeleton, VanSkeletonImage } from '..';
test('should render with row width array correctly', () => {
const wrapper = mount(Skeleton, {
@ -30,7 +30,7 @@ test('should change avatar size when using avatar-size prop', () => {
},
});
const avatar = wrapper.find('.van-skeleton__avatar');
const avatar = wrapper.find('.van-skeleton-avatar');
expect(avatar.style.width).toMatchSnapshot('20rem');
expect(avatar.style.height).toMatchSnapshot('20ren');
});
@ -42,7 +42,7 @@ test('should change avatar shape when using avatar-shape prop', () => {
avatarShape: 'square',
},
});
expect(wrapper.find('.van-skeleton__avatar').html()).toMatchSnapshot();
expect(wrapper.find('.van-skeleton-avatar').html()).toMatchSnapshot();
});
test('should be round when using round prop', () => {
@ -56,6 +56,16 @@ test('should be round when using round prop', () => {
expect(wrapper.find('.van-skeleton--round').exists()).toBeTruthy();
});
test('should Skeleton works with template slots', () => {
const wrapper = mount(Skeleton, {
slots: {
template: () => 'custom content',
},
});
expect(wrapper.html()).toMatchSnapshot();
});
test('should allow to disable animation', async () => {
const wrapper = mount(Skeleton, {
props: {
@ -68,3 +78,31 @@ test('should allow to disable animation', async () => {
await wrapper.setProps({ animate: false });
expect(wrapper.find('.van-skeleton--animate').exists()).toBeFalsy();
});
test('should skeleton image render correctly', () => {
const wrapper = mount(VanSkeletonImage);
expect(wrapper.html()).toMatchSnapshot();
});
test('should skeleton image works with imageSize prop', () => {
const wrapper = mount(VanSkeletonImage, {
props: {
imageSize: '20rem',
},
});
const dom = wrapper.find('.van-skeleton-image');
expect(dom.style.width).toBe('20rem');
expect(dom.style.height).toBe('20rem');
});
test('should skeleton image worsk with imageShape prop', () => {
const wrapper = mount(VanSkeletonImage, {
props: {
imageShape: 'round',
},
});
expect(wrapper.find('.van-skeleton-image--round')).toBeTruthy();
});

View File

@ -1,9 +1,11 @@
export type SkeletonThemeVars = {
skeletonRowHeight?: string;
skeletonRowBackground?: string;
skeletonRowMarginTop?: string;
skeletonParagraphHeight?: string;
skeletonParagraphBackground?: string;
skeletonParagraphMarginTop?: string;
skeletonTitleWidth?: string;
skeletonAvatarSize?: string;
skeletonAvatarBackground?: string;
SkeletonImageSize?: string;
SkeletonImageRadius?: string;
skeletonDuration?: string;
};