feat: add skeleton button & input

feat-css-var
tangjinzhou 2022-03-06 21:25:21 +08:00
parent 741ec4c835
commit 2bd5fc15ff
19 changed files with 296 additions and 50 deletions

View File

@ -150,13 +150,21 @@ export { default as Row } from './row';
export type { SelectProps } from './select'; export type { SelectProps } from './select';
export { default as Select, SelectOptGroup, SelectOption } from './select'; export { default as Select, SelectOptGroup, SelectOption } from './select';
export type { SkeletonProps } from './skeleton'; export type {
SkeletonProps,
SkeletonButtonProps,
SkeletonInputProps,
SkeletonImageProps,
SkeletonAvatarProps,
SkeletonTitleProps,
} from './skeleton';
export { export {
default as Skeleton, default as Skeleton,
SkeletonButton, SkeletonButton,
SkeletonAvatar, SkeletonAvatar,
SkeletonInput, SkeletonInput,
SkeletonImage, SkeletonImage,
SkeletonTitle,
} from './skeleton'; } from './skeleton';
export type { SliderProps } from './slider'; export type { SliderProps } from './slider';

View File

@ -1,26 +1,25 @@
import type { ExtractPropTypes, PropType } from 'vue';
import { computed, defineComponent } from 'vue'; import { computed, defineComponent } from 'vue';
import classNames from '../_util/classNames'; import classNames from '../_util/classNames';
import PropTypes from '../_util/vue-types';
import { tuple } from '../_util/type';
import initDefaultProps from '../_util/props-util/initDefaultProps'; import initDefaultProps from '../_util/props-util/initDefaultProps';
import useConfigInject from '../_util/hooks/useConfigInject'; import useConfigInject from '../_util/hooks/useConfigInject';
import type { SkeletonElementProps } from './Element';
import Element, { skeletonElementProps } from './Element'; import Element, { skeletonElementProps } from './Element';
export interface AvatarProps extends Omit<SkeletonElementProps, 'shape'> { export const avatarProps = () => {
shape?: 'circle' | 'square'; return {
} ...skeletonElementProps(),
shape: String as PropType<'circle' | 'square'>,
};
};
export const avatarProps = initDefaultProps( export type SkeletonAvatarProps = Partial<ExtractPropTypes<ReturnType<typeof avatarProps>>>;
{ ...skeletonElementProps(), shape: PropTypes.oneOf(tuple('circle', 'square')) },
{
size: 'large',
},
);
const SkeletonAvatar = defineComponent({ const SkeletonAvatar = defineComponent({
name: 'ASkeletonAvatar', name: 'ASkeletonAvatar',
props: avatarProps, props: initDefaultProps(avatarProps(), {
size: 'default',
shape: 'circle',
}),
setup(props) { setup(props) {
const { prefixCls } = useConfigInject('skeleton', props); const { prefixCls } = useConfigInject('skeleton', props);
const cls = computed(() => const cls = computed(() =>

View File

@ -1,23 +1,31 @@
import type { ExtractPropTypes, PropType } from 'vue';
import { computed, defineComponent } from 'vue'; import { computed, defineComponent } from 'vue';
import classNames from '../_util/classNames'; import classNames from '../_util/classNames';
import PropTypes from '../_util/vue-types';
import { tuple } from '../_util/type';
import useConfigInject from '../_util/hooks/useConfigInject'; import useConfigInject from '../_util/hooks/useConfigInject';
import type { SkeletonElementProps } from './Element'; import { initDefaultProps } from '../_util/props-util';
import Element, { skeletonElementProps } from './Element'; import Element, { skeletonElementProps } from './Element';
export interface SkeletonButtonProps extends Omit<SkeletonElementProps, 'size'> { export const skeletonButtonProps = () => {
size?: 'large' | 'small' | 'default'; return {
} ...skeletonElementProps(),
size: String as PropType<'large' | 'small' | 'default'>,
block: Boolean,
};
};
export type SkeletonButtonProps = Partial<ExtractPropTypes<ReturnType<typeof skeletonButtonProps>>>;
const SkeletonButton = defineComponent({ const SkeletonButton = defineComponent({
name: 'ASkeletonButton', name: 'ASkeletonButton',
props: { ...skeletonElementProps(), size: PropTypes.oneOf(tuple('large', 'small', 'default')) }, props: initDefaultProps(skeletonButtonProps(), {
size: 'default',
}),
setup(props) { setup(props) {
const { prefixCls } = useConfigInject('skeleton', props); const { prefixCls } = useConfigInject('skeleton', props);
const cls = computed(() => const cls = computed(() =>
classNames(prefixCls.value, `${prefixCls.value}-element`, { classNames(prefixCls.value, `${prefixCls.value}-element`, {
[`${prefixCls.value}-active`]: props.active, [`${prefixCls.value}-active`]: props.active,
[`${prefixCls.value}-block`]: props.block,
}), }),
); );
return () => { return () => {

View File

@ -1,16 +1,11 @@
import type { CSSProperties, ExtractPropTypes, FunctionalComponent } from 'vue'; import type { CSSProperties, ExtractPropTypes, FunctionalComponent, PropType } from 'vue';
import classNames from '../_util/classNames'; import classNames from '../_util/classNames';
import { tuple } from '../_util/type';
import PropTypes from '../_util/vue-types';
export const skeletonElementProps = () => ({ export const skeletonElementProps = () => ({
prefixCls: PropTypes.string, prefixCls: String,
size: PropTypes.oneOfType([ size: [String, Number] as PropType<'large' | 'small' | 'default' | number>,
PropTypes.oneOf(tuple('large', 'small', 'default')), shape: String as PropType<'circle' | 'square' | 'round' | 'default'>,
PropTypes.number, active: { type: Boolean, default: undefined },
]),
shape: PropTypes.oneOf(tuple('circle', 'square', 'round')),
active: PropTypes.looseBool,
}); });
export type SkeletonElementProps = Partial< export type SkeletonElementProps = Partial<

View File

@ -1,6 +1,7 @@
import { computed, defineComponent } from 'vue'; import { computed, defineComponent } from 'vue';
import classNames from '../_util/classNames'; import classNames from '../_util/classNames';
import useConfigInject from '../_util/hooks/useConfigInject'; import useConfigInject from '../_util/hooks/useConfigInject';
import omit from '../_util/omit';
import type { SkeletonElementProps } from './Element'; import type { SkeletonElementProps } from './Element';
import { skeletonElementProps } from './Element'; import { skeletonElementProps } from './Element';
@ -11,7 +12,7 @@ const path =
const SkeletonImage = defineComponent({ const SkeletonImage = defineComponent({
name: 'ASkeletonImage', name: 'ASkeletonImage',
props: skeletonElementProps(), props: omit(skeletonElementProps(), ['size', 'shape', 'active']),
setup(props) { setup(props) {
const { prefixCls } = useConfigInject('skeleton', props); const { prefixCls } = useConfigInject('skeleton', props);
const cls = computed(() => classNames(prefixCls.value, `${prefixCls.value}-element`)); const cls = computed(() => classNames(prefixCls.value, `${prefixCls.value}-element`));

View File

@ -1,7 +1,6 @@
import type { PropType } from 'vue';
import { computed, defineComponent } from 'vue'; import { computed, defineComponent } from 'vue';
import classNames from '../_util/classNames'; import classNames from '../_util/classNames';
import PropTypes from '../_util/vue-types';
import { tuple } from '../_util/type';
import useConfigInject from '../_util/hooks/useConfigInject'; import useConfigInject from '../_util/hooks/useConfigInject';
import type { SkeletonElementProps } from './Element'; import type { SkeletonElementProps } from './Element';
import Element, { skeletonElementProps } from './Element'; import Element, { skeletonElementProps } from './Element';
@ -15,7 +14,7 @@ const SkeletonInput = defineComponent({
name: 'ASkeletonInput', name: 'ASkeletonInput',
props: { props: {
...omit(skeletonElementProps(), ['shape']), ...omit(skeletonElementProps(), ['shape']),
size: PropTypes.oneOf(tuple('large', 'small', 'default')), size: String as PropType<'large' | 'small' | 'default'>,
}, },
setup(props) { setup(props) {
const { prefixCls } = useConfigInject('skeleton', props); const { prefixCls } = useConfigInject('skeleton', props);

View File

@ -2,17 +2,19 @@ import type { ExtractPropTypes, PropType } from 'vue';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
type widthUnit = number | string; type widthUnit = number | string;
export const skeletonParagraphProps = { export const skeletonParagraphProps = () => ({
prefixCls: String, prefixCls: String,
width: { type: [Number, String, Array] as PropType<widthUnit[] | widthUnit> }, width: { type: [Number, String, Array] as PropType<widthUnit[] | widthUnit> },
rows: Number, rows: Number,
}; });
export type SkeletonParagraphProps = Partial<ExtractPropTypes<typeof skeletonParagraphProps>>; export type SkeletonParagraphProps = Partial<
ExtractPropTypes<ReturnType<typeof skeletonParagraphProps>>
>;
const SkeletonParagraph = defineComponent({ const SkeletonParagraph = defineComponent({
name: 'SkeletonParagraph', name: 'SkeletonParagraph',
props: skeletonParagraphProps, props: skeletonParagraphProps(),
setup(props) { setup(props) {
const getWidth = (index: number) => { const getWidth = (index: number) => {
const { width, rows = 2 } = props; const { width, rows = 2 } = props;

View File

@ -2,7 +2,7 @@ import type { ExtractPropTypes, PropType } from 'vue';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import classNames from '../_util/classNames'; import classNames from '../_util/classNames';
import { initDefaultProps } from '../_util/props-util'; import { initDefaultProps } from '../_util/props-util';
import type { AvatarProps } from './Avatar'; import type { SkeletonAvatarProps as AvatarProps } from './Avatar';
import type { SkeletonTitleProps } from './Title'; import type { SkeletonTitleProps } from './Title';
import Title from './Title'; import Title from './Title';
import type { SkeletonParagraphProps } from './Paragraph'; import type { SkeletonParagraphProps } from './Paragraph';
@ -13,7 +13,7 @@ import Element from './Element';
/* This only for skeleton internal. */ /* This only for skeleton internal. */
type SkeletonAvatarProps = Omit<AvatarProps, 'active'>; type SkeletonAvatarProps = Omit<AvatarProps, 'active'>;
export const skeletonProps = { export const skeletonProps = () => ({
active: { type: Boolean, default: undefined }, active: { type: Boolean, default: undefined },
loading: { type: Boolean, default: undefined }, loading: { type: Boolean, default: undefined },
prefixCls: String, prefixCls: String,
@ -30,9 +30,9 @@ export const skeletonProps = {
default: undefined as SkeletonParagraphProps | boolean, default: undefined as SkeletonParagraphProps | boolean,
}, },
round: { type: Boolean, default: undefined }, round: { type: Boolean, default: undefined },
}; });
export type SkeletonProps = Partial<ExtractPropTypes<typeof skeletonProps>>; export type SkeletonProps = Partial<ExtractPropTypes<ReturnType<typeof skeletonProps>>>;
function getComponentProps<T>(prop: T | boolean | undefined): T | {} { function getComponentProps<T>(prop: T | boolean | undefined): T | {} {
if (prop && typeof prop === 'object') { if (prop && typeof prop === 'object') {
@ -81,7 +81,7 @@ function getParagraphBasicProps(hasAvatar: boolean, hasTitle: boolean): Skeleton
const Skeleton = defineComponent({ const Skeleton = defineComponent({
name: 'ASkeleton', name: 'ASkeleton',
props: initDefaultProps(skeletonProps, { props: initDefaultProps(skeletonProps(), {
avatar: false, avatar: false,
title: true, title: true,
paragraph: true, paragraph: true,

View File

@ -1,16 +1,16 @@
import type { ExtractPropTypes, PropType } from 'vue'; import type { ExtractPropTypes, PropType } from 'vue';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export const skeletonTitleProps = { export const skeletonTitleProps = () => ({
prefixCls: String, prefixCls: String,
width: { type: [Number, String] as PropType<string | number> }, width: { type: [Number, String] as PropType<string | number> },
}; });
export type SkeletonTitleProps = Partial<ExtractPropTypes<typeof skeletonTitleProps>>; export type SkeletonTitleProps = Partial<ExtractPropTypes<ReturnType<typeof skeletonTitleProps>>>;
const SkeletonTitle = defineComponent({ const SkeletonTitle = defineComponent({
name: 'SkeletonTitle', name: 'SkeletonTitle',
props: skeletonTitleProps, props: skeletonTitleProps(),
setup(props) { setup(props) {
return () => { return () => {
const { prefixCls, width } = props; const { prefixCls, width } = props;

View File

@ -54,6 +54,109 @@ exports[`renders ./components/skeleton/demo/complex.vue correctly 1`] = `
</div> </div>
`; `;
exports[`renders ./components/skeleton/demo/element.vue correctly 1`] = `
<div class="ant-space ant-space-horizontal ant-space-align-center">
<div class="ant-space-item" style="margin-right: 8px;">
<div class="ant-skeleton ant-skeleton-element"><span class="ant-skeleton-button"></span></div>
</div>
<!---->
<div class="ant-space-item" style="margin-right: 8px;">
<div class="ant-skeleton ant-skeleton-element"><span class="ant-skeleton-avatar ant-skeleton-avatar-circle"></span></div>
</div>
<!---->
<div class="ant-space-item">
<div class="ant-skeleton ant-skeleton-element" style="width: 200px;"><span class="ant-skeleton-input"></span></div>
</div>
<!---->
</div><br><br>
<div class="ant-skeleton ant-skeleton-element"><span class="ant-skeleton-button"></span></div><br><br>
<div class="ant-skeleton ant-skeleton-element">
<div class="ant-skeleton-image"><svg viewBox="0 0 1098 1024" xmlns="http://www.w3.org/2000/svg" class="ant-skeleton-image-svg">
<path d="M365.714286 329.142857q0 45.714286-32.036571 77.677714t-77.677714 32.036571-77.677714-32.036571-32.036571-77.677714 32.036571-77.677714 77.677714-32.036571 77.677714 32.036571 32.036571 77.677714zM950.857143 548.571429l0 256-804.571429 0 0-109.714286 182.857143-182.857143 91.428571 91.428571 292.571429-292.571429zM1005.714286 146.285714l-914.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 694.857143q0 7.460571 5.412571 12.873143t12.873143 5.412571l914.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143l0-694.857143q0-7.460571-5.412571-12.873143t-12.873143-5.412571zM1097.142857 164.571429l0 694.857143q0 37.741714-26.843429 64.585143t-64.585143 26.843429l-914.285714 0q-37.741714 0-64.585143-26.843429t-26.843429-64.585143l0-694.857143q0-37.741714 26.843429-64.585143t64.585143-26.843429l914.285714 0q37.741714 0 64.585143 26.843429t26.843429 64.585143z" class="ant-skeleton-image-path"></path>
</svg></div>
</div>
<div class="ant-divider ant-divider-horizontal" role="separator">
<!---->
</div>
<form style="margin: 16px 0px;" class="ant-form ant-form-inline">
<div class="ant-row ant-form-item">
<div class="ant-col ant-form-item-label"><label class="" title="Active">Active
<!---->
</label></div>
<div class="ant-col ant-form-item-control">
<div class="ant-form-item-control-input">
<div class="ant-form-item-control-input-content"><button type="button" role="switch" aria-checked="false" class="ant-switch">
<!----><span class="ant-switch-inner"><!----></span>
</button></div>
<!---->
</div>
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-form-item-label"><label class="" title="Button Block">Button Block
<!---->
</label></div>
<div class="ant-col ant-form-item-control">
<div class="ant-form-item-control-input">
<div class="ant-form-item-control-input-content"><button type="button" role="switch" aria-checked="false" class="ant-switch">
<!----><span class="ant-switch-inner"><!----></span>
</button></div>
<!---->
</div>
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-form-item-label"><label class="" title="Size">Size
<!---->
</label></div>
<div class="ant-col ant-form-item-control">
<div class="ant-form-item-control-input">
<div class="ant-form-item-control-input-content">
<div class="ant-radio-group ant-radio-group-outline ant-radio-group-default"><label class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"><span class="ant-radio-button ant-radio-button-checked"><input type="radio" class="ant-radio-button-input" value="default"><span class="ant-radio-button-inner"></span></span><span>Default</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="large"><span class="ant-radio-button-inner"></span></span><span>Large</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="small"><span class="ant-radio-button-inner"></span></span><span>Small</span></label></div>
</div>
<!---->
</div>
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-form-item-label"><label class="" title="Button Shape">Button Shape
<!---->
</label></div>
<div class="ant-col ant-form-item-control">
<div class="ant-form-item-control-input">
<div class="ant-form-item-control-input-content">
<div class="ant-radio-group ant-radio-group-outline ant-radio-group-default"><label class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"><span class="ant-radio-button ant-radio-button-checked"><input type="radio" class="ant-radio-button-input" value="default"><span class="ant-radio-button-inner"></span></span><span>Default</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="round"><span class="ant-radio-button-inner"></span></span><span>Round</span></label><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="circle"><span class="ant-radio-button-inner"></span></span><span>Circle</span></label></div>
</div>
<!---->
</div>
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
<div class="ant-row ant-form-item">
<div class="ant-col ant-form-item-label"><label class="" title="Avatar Shape">Avatar Shape
<!---->
</label></div>
<div class="ant-col ant-form-item-control">
<div class="ant-form-item-control-input">
<div class="ant-form-item-control-input-content">
<div class="ant-radio-group ant-radio-group-outline ant-radio-group-default"><label class="ant-radio-button-wrapper"><span class="ant-radio-button"><input type="radio" class="ant-radio-button-input" value="square"><span class="ant-radio-button-inner"></span></span><span>Square</span></label><label class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"><span class="ant-radio-button ant-radio-button-checked"><input type="radio" class="ant-radio-button-input" value="circle"><span class="ant-radio-button-inner"></span></span><span>Circle</span></label></div>
</div>
<!---->
</div>
<div class="ant-form-item-explain ant-form-item-explain-connected"></div>
<!---->
</div>
</div>
</form>
`;
exports[`renders ./components/skeleton/demo/list.vue correctly 1`] = ` exports[`renders ./components/skeleton/demo/list.vue correctly 1`] = `
<div><button type="button" role="switch" aria-checked="false" class="ant-switch"> <div><button type="button" role="switch" aria-checked="false" class="ant-switch">
<!----><span class="ant-switch-inner"><!----></span> <!----><span class="ant-switch-inner"><!----></span>

View File

@ -0,0 +1,75 @@
<docs>
---
order: 2.1
title:
zh-CN: 按钮/头像/输入框/图像
en-US: Button/Avatar/Input/Image
---
## zh-CN
骨架按钮头像输入框和图像
## en-US
Skeleton Button, Avatar, Input and Image.
</docs>
<template>
<a-space>
<a-skeleton-button :active="active" :size="size" :shape="buttonShape" :block="block" />
<a-skeleton-avatar :active="active" :size="size" :shape="avatarShape" />
<a-skeleton-input style="width: 200px" :active="active" :size="size" />
</a-space>
<br />
<br />
<a-skeleton-button :active="active" :size="size" :shape="buttonShape" :block="block" />
<br />
<br />
<a-skeleton-image />
<a-divider />
<a-form layout="inline" style="margin: 16px 0">
<a-form-item label="Active">
<a-switch v-model:checked="active" />
</a-form-item>
<a-form-item label="Button Block">
<a-switch v-model:checked="block" />
</a-form-item>
<a-form-item label="Size">
<a-radio-group v-model:value="size">
<a-radio-button value="default">Default</a-radio-button>
<a-radio-button value="large">Large</a-radio-button>
<a-radio-button value="small">Small</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item label="Button Shape">
<a-radio-group v-model:value="buttonShape">
<a-radio-button value="default">Default</a-radio-button>
<a-radio-button value="round">Round</a-radio-button>
<a-radio-button value="circle">Circle</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item label="Avatar Shape">
<a-radio-group v-model:value="avatarShape">
<a-radio-button value="square">Square</a-radio-button>
<a-radio-button value="circle">Circle</a-radio-button>
</a-radio-group>
</a-form-item>
</a-form>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import type { SkeletonButtonProps, SkeletonAvatarProps } from 'ant-design-vue';
export default defineComponent({
setup() {
return {
active: ref(false),
block: ref(false),
size: ref<SkeletonButtonProps['size']>('default'),
buttonShape: ref<SkeletonButtonProps['shape']>('default'),
avatarShape: ref<SkeletonAvatarProps['shape']>('circle'),
};
},
});
</script>

View File

@ -4,6 +4,7 @@
<active /> <active />
<children /> <children />
<list /> <list />
<elementVue />
</template> </template>
<script lang="ts"> <script lang="ts">
import Basic from './basic.vue'; import Basic from './basic.vue';
@ -11,6 +12,7 @@ import Complex from './complex.vue';
import Active from './active.vue'; import Active from './active.vue';
import Children from './children.vue'; import Children from './children.vue';
import List from './list.vue'; import List from './list.vue';
import elementVue from './element.vue';
import CN from '../index.zh-CN.md'; import CN from '../index.zh-CN.md';
import US from '../index.en-US.md'; import US from '../index.en-US.md';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
@ -24,6 +26,7 @@ export default defineComponent({
Active, Active,
List, List,
Children, Children,
elementVue,
}, },
setup() { setup() {
return {}; return {};

View File

@ -45,3 +45,19 @@ Provide a placeholder while you wait for content to load, or to visualise conten
| --- | --- | --- | --- | | --- | --- | --- | --- |
| rows | Set the row count of paragraph | number | - | | rows | Set the row count of paragraph | number | - |
| width | Set the width of paragraph. When width is an Array, it can set the width of each row. Otherwise only set the last row width | number \| string \| Array<number \| string> | - | | width | Set the width of paragraph. When width is an Array, it can set the width of each row. Otherwise only set the last row width | number \| string \| Array<number \| string> | - |
### SkeletonButtonProps (3.0+)
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| active | Show animation effect | boolean | false | |
| block | Option to fit button width to its parent width | boolean | false | |
| shape | Set the shape of button | `circle` \| `round` \| `default` | - | |
| size | Set the size of button | `large` \| `small` \| `default` | - | |
### SkeletonInputProps (3.0+)
| Property | Description | Type | Default |
| -------- | --------------------- | ------------------------------- | ------- |
| active | Show animation effect | boolean | false |
| size | Set the size of input | `large` \| `small` \| `default` | - |

View File

@ -4,6 +4,12 @@ import SkeletonButton from './Button';
import SkeletonInput from './Input'; import SkeletonInput from './Input';
import SkeletonImage from './Image'; import SkeletonImage from './Image';
import SkeletonAvatar from './Avatar'; import SkeletonAvatar from './Avatar';
import SkeletonTitle from './Title';
export type { SkeletonButtonProps } from './Button';
export type { SkeletonInputProps } from './Input';
export type { SkeletonImageProps } from './Image';
export type { SkeletonAvatarProps } from './Avatar';
export type { SkeletonTitleProps } from './Title';
export type { SkeletonProps } from './Skeleton'; export type { SkeletonProps } from './Skeleton';
export { skeletonProps } from './Skeleton'; export { skeletonProps } from './Skeleton';
@ -12,6 +18,7 @@ Skeleton.Button = SkeletonButton;
Skeleton.Avatar = SkeletonAvatar; Skeleton.Avatar = SkeletonAvatar;
Skeleton.Input = SkeletonInput; Skeleton.Input = SkeletonInput;
Skeleton.Image = SkeletonImage; Skeleton.Image = SkeletonImage;
Skeleton.Title = SkeletonTitle;
/* istanbul ignore next */ /* istanbul ignore next */
Skeleton.install = function (app: App) { Skeleton.install = function (app: App) {
@ -20,9 +27,10 @@ Skeleton.install = function (app: App) {
app.component(Skeleton.Avatar.name, SkeletonAvatar); app.component(Skeleton.Avatar.name, SkeletonAvatar);
app.component(Skeleton.Input.name, SkeletonInput); app.component(Skeleton.Input.name, SkeletonInput);
app.component(Skeleton.Image.name, SkeletonImage); app.component(Skeleton.Image.name, SkeletonImage);
app.component(Skeleton.Title.name, SkeletonTitle);
return app; return app;
}; };
export { SkeletonButton, SkeletonAvatar, SkeletonInput, SkeletonImage }; export { SkeletonButton, SkeletonAvatar, SkeletonInput, SkeletonImage, SkeletonTitle };
export default Skeleton as typeof Skeleton & export default Skeleton as typeof Skeleton &
Plugin & { Plugin & {
readonly Button: typeof SkeletonButton; readonly Button: typeof SkeletonButton;

View File

@ -46,3 +46,19 @@ cover: https://gw.alipayobjects.com/zos/alicdn/KpcciCJgv/Skeleton.svg
| --- | --- | --- | --- | | --- | --- | --- | --- |
| rows | 设置段落占位图的行数 | number | - | | rows | 设置段落占位图的行数 | number | - |
| width | 设置段落占位图的宽度,若为数组时则为对应的每行宽度,反之则是最后一行的宽度 | number \| string \| Array<number \| string> | - | | width | 设置段落占位图的宽度,若为数组时则为对应的每行宽度,反之则是最后一行的宽度 | number \| string \| Array<number \| string> | - |
### SkeletonButtonProps (3.0+)
| 属性 | 说明 | 类型 | 默认值 | 版本 |
| ------ | ------------------------------ | -------------------------------- | ------ | ---- |
| active | 是否展示动画效果 | boolean | false | |
| block | 将按钮宽度调整为其父宽度的选项 | boolean | false | |
| shape | 指定按钮的形状 | `circle` \| `round` \| `default` | - | |
| size | 设置按钮的大小 | `large` \| `small` \| `default` | - | |
### SkeletonInputProps (3.0+)
| 属性 | 说明 | 类型 | 默认值 |
| ------ | ---------------- | ------------------------------- | ------ |
| active | 是否展示动画效果 | boolean | false |
| size | 设置输入框的大小 | `large` \| `small` \| `default` | - |

View File

@ -109,6 +109,15 @@
} }
} }
// Skeleton Block Button
&.@{skeleton-prefix-cls}-block {
width: 100%;
.@{skeleton-button-prefix-cls} {
width: 100%;
}
}
// Skeleton element // Skeleton element
&-element { &-element {
display: inline-block; display: inline-block;
@ -214,10 +223,12 @@
.skeleton-element-button-size(@size) { .skeleton-element-button-size(@size) {
width: @size * 2; width: @size * 2;
min-width: @size * 2;
.skeleton-element-common-size(@size); .skeleton-element-common-size(@size);
&.@{skeleton-button-prefix-cls}-circle { &.@{skeleton-button-prefix-cls}-circle {
width: @size; width: @size;
min-width: @size;
border-radius: 50%; border-radius: 50%;
} }
@ -260,6 +271,7 @@
0% { 0% {
background-position: 100% 50%; background-position: 100% 50%;
} }
100% { 100% {
background-position: 0 50%; background-position: 0 50%;
} }

View File

@ -41,6 +41,7 @@
0% { 0% {
background-position: 0% 50%; background-position: 0% 50%;
} }
100% { 100% {
background-position: 100% 50%; background-position: 100% 50%;
} }

View File

@ -1,5 +1,5 @@
// debugger tsx // debugger tsx
import Demo from '../../components/upload/demo/defaultFileList.vue'; import Demo from '../../components/select/demo/field-names.vue';
// import Demo from './demo/demo.vue'; // import Demo from './demo/demo.vue';
export default { export default {