refactor: avatar
parent
0984951845
commit
4a5c4cdeb7
|
@ -1,8 +1,26 @@
|
||||||
import { computed, inject } from 'vue';
|
import { computed, ComputedRef, inject, UnwrapRef } from 'vue';
|
||||||
import { defaultConfigProvider } from '../../config-provider';
|
import {
|
||||||
|
ConfigProviderProps,
|
||||||
|
defaultConfigProvider,
|
||||||
|
Direction,
|
||||||
|
SizeType,
|
||||||
|
} from '../../config-provider';
|
||||||
|
|
||||||
export default (name: string, props: Record<any, any>) => {
|
export default (
|
||||||
const configProvider = inject('configProvider', defaultConfigProvider);
|
name: string,
|
||||||
|
props: Record<any, any>,
|
||||||
|
): {
|
||||||
|
configProvider: UnwrapRef<ConfigProviderProps>;
|
||||||
|
prefixCls: ComputedRef<string>;
|
||||||
|
direction: ComputedRef<Direction>;
|
||||||
|
size: ComputedRef<SizeType>;
|
||||||
|
} => {
|
||||||
|
const configProvider = inject<UnwrapRef<ConfigProviderProps>>(
|
||||||
|
'configProvider',
|
||||||
|
defaultConfigProvider,
|
||||||
|
);
|
||||||
const prefixCls = computed(() => configProvider.getPrefixCls(name, props.prefixCls));
|
const prefixCls = computed(() => configProvider.getPrefixCls(name, props.prefixCls));
|
||||||
return { configProvider, prefixCls };
|
const direction = computed(() => configProvider.direction);
|
||||||
|
const size = computed(() => props.size || configProvider.componentSize);
|
||||||
|
return { configProvider, prefixCls, direction, size };
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { computed, ComputedRef, inject } from 'vue';
|
||||||
|
import { defaultConfigProvider } from '../../config-provider';
|
||||||
|
|
||||||
|
export default (name: string, props: Record<any, any>): ComputedRef<string> => {
|
||||||
|
const configProvider = inject('configProvider', defaultConfigProvider);
|
||||||
|
const prefixCls = computed(() => configProvider.getPrefixCls(name, props.prefixCls));
|
||||||
|
return prefixCls;
|
||||||
|
};
|
|
@ -1,5 +1,5 @@
|
||||||
export type Breakpoint = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs';
|
export type Breakpoint = 'xxl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs';
|
||||||
export type BreakpointMap = Partial<Record<Breakpoint, string>>;
|
export type BreakpointMap = Record<Breakpoint, string>;
|
||||||
export type ScreenMap = Partial<Record<Breakpoint, boolean>>;
|
export type ScreenMap = Partial<Record<Breakpoint, boolean>>;
|
||||||
export type ScreenSizeMap = Partial<Record<Breakpoint, number>>;
|
export type ScreenSizeMap = Partial<Record<Breakpoint, number>>;
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ const responsiveObserve = {
|
||||||
},
|
},
|
||||||
unregister() {
|
unregister() {
|
||||||
Object.keys(responsiveMap).forEach((screen: string) => {
|
Object.keys(responsiveMap).forEach((screen: string) => {
|
||||||
const matchMediaQuery = responsiveMap[screen]!;
|
const matchMediaQuery = responsiveMap[screen];
|
||||||
const handler = this.matchHandlers[matchMediaQuery];
|
const handler = this.matchHandlers[matchMediaQuery];
|
||||||
handler?.mql.removeListener(handler?.listener);
|
handler?.mql.removeListener(handler?.listener);
|
||||||
});
|
});
|
||||||
|
@ -52,7 +52,7 @@ const responsiveObserve = {
|
||||||
},
|
},
|
||||||
register() {
|
register() {
|
||||||
Object.keys(responsiveMap).forEach((screen: string) => {
|
Object.keys(responsiveMap).forEach((screen: string) => {
|
||||||
const matchMediaQuery = responsiveMap[screen]!;
|
const matchMediaQuery = responsiveMap[screen];
|
||||||
const listener = ({ matches }: { matches: boolean }) => {
|
const listener = ({ matches }: { matches: boolean }) => {
|
||||||
this.dispatch({
|
this.dispatch({
|
||||||
...screens,
|
...screens,
|
||||||
|
|
|
@ -22,7 +22,7 @@ export type AvatarSize = 'large' | 'small' | 'default' | number | ScreenSizeMap;
|
||||||
|
|
||||||
export const avatarProps = {
|
export const avatarProps = {
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
shape: PropTypes.oneOf(tuple('circle', 'square')),
|
shape: PropTypes.oneOf(tuple('circle', 'square')).def('circle'),
|
||||||
size: {
|
size: {
|
||||||
type: [Number, String, Object] as PropType<AvatarSize>,
|
type: [Number, String, Object] as PropType<AvatarSize>,
|
||||||
default: (): AvatarSize => 'default',
|
default: (): AvatarSize => 'default',
|
||||||
|
|
|
@ -1,20 +1,11 @@
|
||||||
import toArray from 'lodash/toArray';
|
|
||||||
import { cloneElement } from '../_util/vnode';
|
import { cloneElement } from '../_util/vnode';
|
||||||
import { defaultConfigProvider } from '../config-provider';
|
import Avatar, { avatarProps, AvatarSize } from './Avatar';
|
||||||
import Avatar, { avatarProps } from './Avatar';
|
|
||||||
import Popover from '../popover';
|
import Popover from '../popover';
|
||||||
import {
|
import { defineComponent, provide, PropType, ExtractPropTypes, CSSProperties } from 'vue';
|
||||||
computed,
|
|
||||||
defineComponent,
|
|
||||||
inject,
|
|
||||||
provide,
|
|
||||||
PropType,
|
|
||||||
ExtractPropTypes,
|
|
||||||
CSSProperties,
|
|
||||||
} from 'vue';
|
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import { getPropsSlot } from '../_util/props-util';
|
import { flattenChildren, getPropsSlot } from '../_util/props-util';
|
||||||
import { tuple } from '../_util/type';
|
import { tuple } from '../_util/type';
|
||||||
|
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||||
|
|
||||||
const groupProps = {
|
const groupProps = {
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
|
@ -31,39 +22,30 @@ const groupProps = {
|
||||||
size: avatarProps.size,
|
size: avatarProps.size,
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AvatarGroupProps = Partial<ExtractPropTypes<typeof groupProps>>;
|
export type AvatarGroupProps = Partial<ExtractPropTypes<typeof groupProps>> & {
|
||||||
|
size?: AvatarSize;
|
||||||
|
};
|
||||||
|
|
||||||
const Group = defineComponent({
|
const Group = defineComponent({
|
||||||
name: 'AAvatarGroup',
|
name: 'AAvatarGroup',
|
||||||
props: groupProps,
|
props: groupProps,
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup(props, { slots, attrs }) {
|
setup(props, { slots, attrs }) {
|
||||||
const configProvider = inject('configProvider', defaultConfigProvider);
|
const { prefixCls, direction, size } = useConfigInject('avatar-group', props);
|
||||||
|
|
||||||
provide(
|
provide('SizeProvider', size);
|
||||||
'SizeProvider',
|
|
||||||
computed(() => props.size || configProvider.componentSize),
|
|
||||||
);
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
const {
|
const { maxPopoverPlacement = 'top', maxCount, maxStyle } = props;
|
||||||
prefixCls: customizePrefixCls,
|
|
||||||
maxPopoverPlacement = 'top',
|
|
||||||
maxCount,
|
|
||||||
maxStyle,
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const { getPrefixCls } = configProvider;
|
|
||||||
const prefixCls = getPrefixCls('avatar-group', customizePrefixCls);
|
|
||||||
const className = attrs.class as string;
|
|
||||||
|
|
||||||
const cls = {
|
const cls = {
|
||||||
[prefixCls]: true,
|
[prefixCls.value]: true,
|
||||||
[className]: className !== undefined,
|
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
|
||||||
|
[`${attrs.class}`]: !!attrs.class,
|
||||||
};
|
};
|
||||||
|
|
||||||
const children = getPropsSlot(slots, props);
|
const children = getPropsSlot(slots, props);
|
||||||
const childrenWithProps = toArray(children).map((child, index) =>
|
const childrenWithProps = flattenChildren(children).map((child, index) =>
|
||||||
cloneElement(child, {
|
cloneElement(child, {
|
||||||
key: `avatar-key-${index}`,
|
key: `avatar-key-${index}`,
|
||||||
}),
|
}),
|
||||||
|
@ -80,20 +62,20 @@ const Group = defineComponent({
|
||||||
content={childrenHidden}
|
content={childrenHidden}
|
||||||
trigger="hover"
|
trigger="hover"
|
||||||
placement={maxPopoverPlacement}
|
placement={maxPopoverPlacement}
|
||||||
overlayClassName={`${prefixCls}-popover`}
|
overlayClassName={`${prefixCls.value}-popover`}
|
||||||
>
|
>
|
||||||
<Avatar style={maxStyle}>{`+${numOfChildren - maxCount}`}</Avatar>
|
<Avatar style={maxStyle}>{`+${numOfChildren - maxCount}`}</Avatar>
|
||||||
</Popover>,
|
</Popover>,
|
||||||
);
|
);
|
||||||
return (
|
return (
|
||||||
<div class={cls} style={attrs.style}>
|
<div {...attrs} class={cls} style={attrs.style}>
|
||||||
{childrenShow}
|
{childrenShow}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={cls} style={attrs.style}>
|
<div {...attrs} class={cls} style={attrs.style}>
|
||||||
{childrenWithProps}
|
{childrenWithProps}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.@{ant-prefix}-image-img {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
.avatar-size(@avatar-size-base, @avatar-font-size-base);
|
.avatar-size(@avatar-size-base, @avatar-font-size-base);
|
||||||
|
|
||||||
&-lg {
|
&-lg {
|
||||||
|
@ -55,7 +59,12 @@
|
||||||
|
|
||||||
&.@{avatar-prefix-cls}-icon {
|
&.@{avatar-prefix-cls}-icon {
|
||||||
font-size: @font-size;
|
font-size: @font-size;
|
||||||
|
|
||||||
|
> .@{iconfont-css-prefix} {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@import './group';
|
@import './group';
|
||||||
|
@import './rtl';
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
.@{avatar-prefix-cls}-group {
|
||||||
|
&-rtl {
|
||||||
|
.@{avatar-prefix-cls}:not(:first-child) {
|
||||||
|
margin-right: @avatar-group-overlapping;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-popover.@{ant-prefix}-popover-rtl {
|
||||||
|
.@{ant-prefix}-avatar + .@{ant-prefix}-avatar {
|
||||||
|
margin-right: @avatar-group-space;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,12 @@
|
||||||
import { reactive, provide, PropType, defineComponent, watch, ExtractPropTypes } from 'vue';
|
import {
|
||||||
|
reactive,
|
||||||
|
provide,
|
||||||
|
PropType,
|
||||||
|
defineComponent,
|
||||||
|
watch,
|
||||||
|
ExtractPropTypes,
|
||||||
|
UnwrapRef,
|
||||||
|
} from 'vue';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import defaultRenderEmpty, { RenderEmptyHandler } from './renderEmpty';
|
import defaultRenderEmpty, { RenderEmptyHandler } from './renderEmpty';
|
||||||
import LocaleProvider, { Locale, ANT_MARK } from '../locale-provider';
|
import LocaleProvider, { Locale, ANT_MARK } from '../locale-provider';
|
||||||
|
@ -14,6 +22,8 @@ export interface CSPConfig {
|
||||||
|
|
||||||
export { RenderEmptyHandler };
|
export { RenderEmptyHandler };
|
||||||
|
|
||||||
|
export type Direction = 'ltr' | 'rtl';
|
||||||
|
|
||||||
export interface ConfigConsumerProps {
|
export interface ConfigConsumerProps {
|
||||||
getTargetContainer?: () => HTMLElement;
|
getTargetContainer?: () => HTMLElement;
|
||||||
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
|
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
|
||||||
|
@ -146,13 +156,13 @@ const ConfigProvider = defineComponent({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const defaultConfigProvider: ConfigProviderProps = {
|
export const defaultConfigProvider: UnwrapRef<ConfigProviderProps> = reactive({
|
||||||
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => {
|
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => {
|
||||||
if (customizePrefixCls) return customizePrefixCls;
|
if (customizePrefixCls) return customizePrefixCls;
|
||||||
return `ant-${suffixCls}`;
|
return `ant-${suffixCls}`;
|
||||||
},
|
},
|
||||||
renderEmpty: defaultRenderEmpty,
|
renderEmpty: defaultRenderEmpty,
|
||||||
direction: 'ltr',
|
direction: 'ltr',
|
||||||
};
|
});
|
||||||
|
|
||||||
export default withInstall(ConfigProvider);
|
export default withInstall(ConfigProvider);
|
||||||
|
|
Loading…
Reference in New Issue