Skip to content

Commit

Permalink
Refactor progress (#4358)
Browse files Browse the repository at this point in the history
* fix: timepicker error border not show #4331

* fix(UploadDragger): fix UploadDrager no export (#4334)

* refactor(switch): support customize checked value #4329 (#4332)

* refactor(switch): support customize checked value #4329

* test: add test case

* refactor: update props name

* refactor: update ts

* refactor: optimize

* style: uncheckedValue to unCheckedValue

* test: update snap

* feat: udpate switch ts

* docs: remove ie11

* fix: tree-select throw error when use slot title

* fix: TypeScript definition of Table interface for typescript 4.3.5 (#4353)

* fix type for typescript 4.3.5

* Update interface.ts

close #4296

* fix: dropdown submenu style error #4351
close #4351

* fix(notification): 完善notification类型 (#4346)

* refactor(progress): use composition API (#4355)

* refactor(progress): use composition API

* refactor(vc-progress): update

* refactor: progress

* refactor: progress

* fix: timepicker error border not show #4331

* fix(UploadDragger): fix UploadDrager no export (#4334)

* refactor(switch): support customize checked value #4329 (#4332)

* refactor(switch): support customize checked value #4329

* test: add test case

* refactor: update props name

* refactor: update ts

* refactor: optimize

* style: uncheckedValue to unCheckedValue

* test: update snap

* feat: udpate switch ts

* docs: remove ie11

* fix: tree-select throw error when use slot title

* fix: TypeScript definition of Table interface for typescript 4.3.5 (#4353)

* fix type for typescript 4.3.5

* Update interface.ts

close #4296

* fix: dropdown submenu style error #4351
close #4351

* fix(notification): 完善notification类型 (#4346)

* refactor(progress): use composition API (#4355)

* refactor(progress): use composition API

* refactor(vc-progress): update

* refactor: progress

* refactor: progress

Co-authored-by: Jarvis <35361626+fanhaoyuan@users.noreply.github.com>
Co-authored-by: John <John60676@qq.com>
Co-authored-by: 艾斯特洛 <axetroy.dev@gmail.com>
Co-authored-by: zanllp <qc@zanllp.cn>
  • Loading branch information
5 people authored Jul 12, 2021
1 parent f7b39e2 commit a770eb3
Show file tree
Hide file tree
Showing 50 changed files with 1,399 additions and 794 deletions.
1 change: 0 additions & 1 deletion CHANGELOG.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,6 @@

### Compatibility adjustment

- The minimum supported version of IE is IE 11.
- The minimum supported version of Vue is Vue 3.0.

#### Adjusted API
Expand Down
1 change: 0 additions & 1 deletion CHANGELOG.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,6 @@

### 兼容性调整

- IE 最低支持版本为 IE 11。
- Vue 最低支持版本为 Vue 3.0。

#### 调整的 API
Expand Down
2 changes: 1 addition & 1 deletion README-zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ An enterprise-class UI components based on Ant Design and Vue 3.

## 支持环境

- 现代浏览器和 IE11 及以上。1.x 版本支持 IE 9+(需要 [polyfills](https://www.antdv.com/docs/vue/getting-started-cn/#兼容性)
- 现代浏览器。1.x 版本支持 IE 9+(需要 [polyfills](https://www.antdv.com/docs/vue/getting-started-cn/#兼容性)
- 支持服务端渲染。
- [Electron](https://electronjs.org/)
- 支持 Vue 2 和 Vue 3
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ English | [简体中文](./README-zh_CN.md)

## Environment Support

- Modern browsers and Internet Explorer 11+. v1.x support Internet Explorer 9+ (with [polyfills](https://www.antdv.com/docs/vue/getting-started/#Compatibility))
- Modern browsers. v1.x support Internet Explorer 9+ (with [polyfills](https://www.antdv.com/docs/vue/getting-started/#Compatibility))
- Server-side Rendering
- Support Vue 2 & Vue 3
- [Electron](https://electronjs.org/)
Expand Down
6 changes: 4 additions & 2 deletions components/_util/hooks/useRef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import type { Ref } from 'vue';
import { onBeforeUpdate, ref } from 'vue';

export type UseRef = [(el: any, key: string | number) => void, Ref<any>];

export type Refs = Record<string | number, any>;
export const useRef = (): UseRef => {
const refs = ref<any>({});
const refs = ref<Refs>({});
const setRef = (el: any, key: string | number) => {
refs.value[key] = el;
};
Expand All @@ -13,3 +13,5 @@ export const useRef = (): UseRef => {
});
return [setRef, refs];
};

export default useRef;
2 changes: 1 addition & 1 deletion components/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,6 @@ export {

export type { UploadProps } from './upload';

export { default as Upload } from './upload';
export { default as Upload, UploadDragger } from './upload';

export { default as LocaleProvider } from './locale-provider';
2 changes: 1 addition & 1 deletion components/dropdown/dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const Dropdown = defineComponent({
// menu should be focusable in dropdown defaultly
const overlayProps = overlayNode && getPropsData(overlayNode);
const { selectable = false, focusable = true } = (overlayProps || {}) as any;
const expandIcon = (
const expandIcon = () => (
<span class={`${prefixCls}-menu-submenu-arrow`}>
<RightOutlined class={`${prefixCls}-menu-submenu-arrow-icon`} />
</span>
Expand Down
4 changes: 3 additions & 1 deletion components/dropdown/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@
&-submenu-popup {
position: absolute;
z-index: @zindex-dropdown;
background: transparent;
box-shadow: none;
transform-origin: 0 0;

> .@{dropdown-prefix-cls}-menu {
transform-origin: 0 0;
Expand All @@ -81,7 +84,6 @@
ul {
margin-right: 0.3em;
margin-left: 0.3em;
padding: 0;
}
}

Expand Down
102 changes: 51 additions & 51 deletions components/locale-provider/__tests__/__snapshots__/index.test.js.snap

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions components/menu/src/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ export const menuProps = {
triggerSubMenuAction: { type: String as PropType<TriggerSubMenuAction>, default: 'hover' },

getPopupContainer: Function as PropType<(node: HTMLElement) => HTMLElement>,

expandIcon: Function as PropType<(p?: { isOpen: boolean; [key: string]: any }) => any>,
};

export type MenuProps = Partial<ExtractPropTypes<typeof menuProps>>;
Expand All @@ -66,6 +68,7 @@ export default defineComponent({
'click',
'update:activeKey',
],
slots: ['expandIcon'],
setup(props, { slots, emit }) {
const { prefixCls, direction } = useConfigInject('menu', props);
const store = ref<Record<string, StoreMenuInfo>>({});
Expand Down Expand Up @@ -371,6 +374,7 @@ export default defineComponent({
unRegisterMenuInfo,
selectedSubMenuEventKeys,
isRootMenu: true,
expandIcon: props.expandIcon || slots.expandIcon,
});
return () => {
const childList = flattenChildren(slots.default?.());
Expand Down
9 changes: 6 additions & 3 deletions components/menu/src/SubMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const subMenuProps = {
popupOffset: Array as PropType<number[]>,
internalPopupClose: Boolean,
eventKey: String,
expandIcon: Function as PropType<(p?: { isOpen: boolean; [key: string]: any }) => any>,
};

export type SubMenuProps = Partial<ExtractPropTypes<typeof subMenuProps>>;
Expand All @@ -32,7 +33,7 @@ export default defineComponent({
name: 'ASubMenu',
inheritAttrs: false,
props: subMenuProps,
slots: ['icon', 'title'],
slots: ['icon', 'title', 'expandIcon'],
emits: ['titleClick', 'mouseenter', 'mouseleave'],
setup(props, { slots, attrs, emit }) {
useProvideFirstLevel(false);
Expand Down Expand Up @@ -84,6 +85,7 @@ export default defineComponent({
selectedSubMenuEventKeys,
motion,
defaultMotions,
expandIcon: menuExpandIcon,
} = useInjectMenu();

registerMenuInfo(eventKey, menuInfo);
Expand Down Expand Up @@ -226,6 +228,7 @@ export default defineComponent({
const icon = getPropsSlot(slots, props, 'icon');
const title = renderTitle(getPropsSlot(slots, props, 'title'), icon);
const subMenuPrefixClsValue = subMenuPrefixCls.value;
const expandIcon = props.expandIcon || slots.expandIcon || menuExpandIcon;
let titleNode = (
<div
style={directionStyle.value}
Expand All @@ -244,8 +247,8 @@ export default defineComponent({
{title}

{/* Only non-horizontal mode shows the icon */}
{mode.value !== 'horizontal' && slots.expandIcon ? (
slots.expandIcon({ ...props, isOpen: open.value })
{mode.value !== 'horizontal' && expandIcon ? (
expandIcon({ ...props, isOpen: open.value })
) : (
<i class={`${subMenuPrefixClsValue}-arrow`} />
)}
Expand Down
2 changes: 1 addition & 1 deletion components/menu/src/hooks/useMenuContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export interface MenuContextProps {

// // Icon
// itemIcon?: RenderIconType;
// expandIcon?: RenderIconType;
expandIcon?: (p?: { isOpen: boolean; [key: string]: any }) => any;

// // Function
onItemClick: MenuClickEventHandler;
Expand Down
8 changes: 6 additions & 2 deletions components/notification/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ function notice(args: NotificationArgsProps) {
);
}

const api: any = {
const apiBase = {
open: notice,
close(key: string) {
Object.keys(notificationInstance).forEach(cacheKey =>
Expand All @@ -228,7 +228,11 @@ const api: any = {
},
};

['success', 'info', 'warning', 'error'].forEach(type => {
type NotificationApi = typeof apiBase &
Record<IconType | 'warn', (args: Omit<NotificationArgsProps, 'type'>) => void>;
const api = apiBase as any as NotificationApi;
const iconTypes: IconType[] = ['success', 'info', 'warning', 'error'];
iconTypes.forEach(type => {
api[type] = args =>
api.open({
...args,
Expand Down
74 changes: 74 additions & 0 deletions components/progress/Circle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import type { CSSProperties } from 'vue';
import { computed, defineComponent } from 'vue';
import { presetPrimaryColors } from '@ant-design/colors';
import { Circle as VCCircle } from '../vc-progress';
import { getSuccessPercent, validProgress } from './utils';
import type { ProgressProps } from './props';
import { progressProps } from './props';

export type CircleProps = ProgressProps;

function getPercentage({ percent, success, successPercent }: CircleProps) {
const realSuccessPercent = validProgress(getSuccessPercent({ success, successPercent }));
return [realSuccessPercent, validProgress(validProgress(percent) - realSuccessPercent)];
}

export default defineComponent({
inheritAttrs: false,
props: progressProps(),
setup(props, { slots }) {
const gapDeg = computed(() => {
// Support gapDeg = 0 when type = 'dashboard'
if (props.gapDegree || props.gapDegree === 0) {
return props.gapDegree;
}
if (props.type === 'dashboard') {
return 75;
}
return undefined;
});

const circleStyle = computed<CSSProperties>(() => {
const circleSize = props.width || 120;
return {
width: typeof circleSize === 'number' ? `${circleSize}px` : circleSize,
height: typeof circleSize === 'number' ? `${circleSize}px` : circleSize,
fontSize: `${circleSize * 0.15 + 6}px`,
};
});

const circleWidth = computed(() => props.strokeWidth || 6);
const gapPos = computed(
() => props.gapPosition || (props.type === 'dashboard' && 'bottom') || 'top',
);

// using className to style stroke color
const strokeColor = computed(() => [presetPrimaryColors.green, props.strokeColor || null]);
const percent = computed(() => getPercentage(props));
const isGradient = computed(
() => Object.prototype.toString.call(props.strokeColor) === '[object Object]',
);

const wrapperClassName = computed(() => ({
[`${props.prefixCls}-inner`]: true,
[`${props.prefixCls}-circle-gradient`]: isGradient.value,
}));

return () => (
<div class={wrapperClassName.value} style={circleStyle.value}>
<VCCircle
percent={percent.value}
strokeWidth={circleWidth.value}
trailWidth={circleWidth.value}
strokeColor={strokeColor.value}
strokeLinecap={props.strokeLinecap}
trailColor={props.trailColor}
prefixCls={props.prefixCls}
gapDegree={gapDeg.value}
gapPosition={gapPos.value}
/>
{slots.default?.()}
</div>
);
},
});
128 changes: 128 additions & 0 deletions components/progress/Line.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import type { CSSProperties, ExtractPropTypes, PropType } from 'vue';
import { computed, defineComponent } from 'vue';
import type { Direction } from '../config-provider';
import PropTypes from '../_util/vue-types';
import type { StringGradients, ProgressGradient } from './props';
import { progressProps } from './props';
import { getSuccessPercent, validProgress } from './utils';

const lineProps = {
...progressProps(),
prefixCls: PropTypes.string,
direction: {
type: String as PropType<Direction>,
},
};

export type LineProps = Partial<ExtractPropTypes<typeof lineProps>>;

/**
* {
* '0%': '#afc163',
* '75%': '#009900',
* '50%': 'green', ====> '#afc163 0%, #66FF00 25%, #00CC00 50%, #009900 75%, #ffffff 100%'
* '25%': '#66FF00',
* '100%': '#ffffff'
* }
*/
export const sortGradient = (gradients: StringGradients) => {
let tempArr = [];
Object.keys(gradients).forEach(key => {
const formattedKey = parseFloat(key.replace(/%/g, ''));
if (!isNaN(formattedKey)) {
tempArr.push({
key: formattedKey,
value: gradients[key],
});
}
});
tempArr = tempArr.sort((a, b) => a.key - b.key);
return tempArr.map(({ key, value }) => `${value} ${key}%`).join(', ');
};

/**
* Then this man came to realize the truth: Besides six pence, there is the moon. Besides bread and
* butter, there is the bug. And... Besides women, there is the code.
*
* @example
* {
* "0%": "#afc163",
* "25%": "#66FF00",
* "50%": "#00CC00", // ====> linear-gradient(to right, #afc163 0%, #66FF00 25%,
* "75%": "#009900", // #00CC00 50%, #009900 75%, #ffffff 100%)
* "100%": "#ffffff"
* }
*/
export const handleGradient = (strokeColor: ProgressGradient, directionConfig: Direction) => {
const {
from = '#1890ff',
to = '#1890ff',
direction = directionConfig === 'rtl' ? 'to left' : 'to right',
...rest
} = strokeColor;
if (Object.keys(rest).length !== 0) {
const sortedGradients = sortGradient(rest as StringGradients);
return { backgroundImage: `linear-gradient(${direction}, ${sortedGradients})` };
}
return { backgroundImage: `linear-gradient(${direction}, ${from}, ${to})` };
};

export default defineComponent({
name: 'Line',
props: lineProps,
setup(props, { slots }) {
const backgroundProps = computed(() => {
const { strokeColor, direction } = props;
return strokeColor && typeof strokeColor !== 'string'
? handleGradient(strokeColor, direction)
: {
background: strokeColor,
};
});

const trailStyle = computed(() =>
props.trailColor
? {
backgroundColor: props.trailColor,
}
: undefined,
);

const percentStyle = computed<CSSProperties>(() => {
const { percent, strokeWidth, strokeLinecap, size } = props;
return {
width: `${validProgress(percent)}%`,
height: `${strokeWidth || (size === 'small' ? 6 : 8)}px`,
borderRadius: strokeLinecap === 'square' ? 0 : '',
...(backgroundProps.value as any),
};
});

const successPercent = computed(() => {
return getSuccessPercent(props);
});
const successPercentStyle = computed<CSSProperties>(() => {
const { strokeWidth, size, strokeLinecap, success } = props;
return {
width: `${validProgress(successPercent.value)}%`,
height: `${strokeWidth || (size === 'small' ? 6 : 8)}px`,
borderRadius: strokeLinecap === 'square' ? 0 : '',
backgroundColor: success?.strokeColor,
};
});

return () => (
<>
<div class={`${props.prefixCls}-outer`}>
<div class={`${props.prefixCls}-inner`} style={trailStyle.value}>
<div class={`${props.prefixCls}-bg`} style={percentStyle.value} />
{successPercent.value !== undefined ? (
<div class={`${props.prefixCls}-success-bg`} style={successPercentStyle.value} />
) : null}
</div>
</div>
{slots.default?.()}
</>
);
},
});
Loading

0 comments on commit a770eb3

Please sign in to comment.