Skip to content

Refactor progress #4358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 29 commits into from
Jul 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
203e423
fix: timepicker error border not show #4331
tangjinzhou Jul 6, 2021
9e0244d
fix(UploadDragger): fix UploadDrager no export (#4334)
fanhaoyuan Jul 7, 2021
427cf36
refactor(switch): support customize checked value #4329 (#4332)
John60676 Jul 7, 2021
ffb52a2
style: uncheckedValue to unCheckedValue
tangjinzhou Jul 7, 2021
292f5c9
test: update snap
tangjinzhou Jul 7, 2021
cf2ffa2
feat: udpate switch ts
tangjinzhou Jul 7, 2021
60aeec7
docs: remove ie11
tangjinzhou Jul 7, 2021
1152e8c
fix: tree-select throw error when use slot title
tangjinzhou Jul 8, 2021
fb94726
fix: TypeScript definition of Table interface for typescript 4.3.5 (#…
axetroy Jul 11, 2021
c20c1f2
fix: dropdown submenu style error #4351
tangjinzhou Jul 11, 2021
8ce46ab
fix(notification): 完善notification类型 (#4346)
zanllp Jul 11, 2021
2ba963b
refactor(progress): use composition API (#4355)
John60676 Jul 11, 2021
01fb7f1
refactor: progress
tangjinzhou Jul 12, 2021
2b6715a
refactor: progress
tangjinzhou Jul 12, 2021
a523c39
fix: timepicker error border not show #4331
tangjinzhou Jul 6, 2021
935ecf5
fix(UploadDragger): fix UploadDrager no export (#4334)
fanhaoyuan Jul 7, 2021
46c8609
refactor(switch): support customize checked value #4329 (#4332)
John60676 Jul 7, 2021
1f852e3
style: uncheckedValue to unCheckedValue
tangjinzhou Jul 7, 2021
baefc3f
test: update snap
tangjinzhou Jul 7, 2021
eed264b
feat: udpate switch ts
tangjinzhou Jul 7, 2021
185e51c
docs: remove ie11
tangjinzhou Jul 7, 2021
59e483b
fix: tree-select throw error when use slot title
tangjinzhou Jul 8, 2021
fc0d687
fix: TypeScript definition of Table interface for typescript 4.3.5 (#…
axetroy Jul 11, 2021
190d65f
fix: dropdown submenu style error #4351
tangjinzhou Jul 11, 2021
09eb976
fix(notification): 完善notification类型 (#4346)
zanllp Jul 11, 2021
05c0d2e
refactor(progress): use composition API (#4355)
John60676 Jul 11, 2021
a0d9372
refactor: progress
tangjinzhou Jul 12, 2021
25eea2a
refactor: progress
tangjinzhou Jul 12, 2021
b090d92
Merge branch 'refactor-progress' of github.com:vueComponent/ant-desig…
tangjinzhou Jul 12, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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