feat: remove backtop
							parent
							
								
									118ae9a50b
								
							
						
					
					
						commit
						de00607dc7
					
				|  | @ -1,20 +0,0 @@ | |||
| // Jest Snapshot v1, https://goo.gl/fbAQLP | ||||
| 
 | ||||
| exports[`renders ./components/back-top/demo/basic.vue correctly 1`] = ` | ||||
| <div class="ant-back-top fade-enter fade-enter-prepare" style="display: none;"> | ||||
|   <div class="ant-back-top-content"> | ||||
|     <div class="ant-back-top-icon"><span role="img" aria-label="vertical-align-top" class="anticon anticon-vertical-align-top"><svg focusable="false" class="" data-icon="vertical-align-top" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M859.9 168H164.1c-4.5 0-8.1 3.6-8.1 8v60c0 4.4 3.6 8 8.1 8h695.8c4.5 0 8.1-3.6 8.1-8v-60c0-4.4-3.6-8-8.1-8zM518.3 355a8 8 0 00-12.6 0l-112 141.7a7.98 7.98 0 006.3 12.9h73.9V848c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V509.7H624c6.7 0 10.4-7.7 6.3-12.9L518.3 355z"></path></svg></span></div> | ||||
|   </div> | ||||
| </div> | ||||
| Scroll down to see the bottom-right | ||||
| <strong style="color: rgba(64, 64, 64, 0.6);">gray</strong> | ||||
| button. | ||||
| `; | ||||
| 
 | ||||
| exports[`renders ./components/back-top/demo/custom.vue correctly 1`] = ` | ||||
| <div id="components-back-top-demo-custom"> | ||||
|   <div class="ant-back-top fade-enter fade-enter-prepare" style="display: none;"> | ||||
|     <div class="ant-back-top-inner">UP</div> | ||||
|   </div> Scroll down to see the bottom-right <strong style="color: rgb(16, 136, 233);">blue</strong> button. | ||||
| </div> | ||||
| `; | ||||
|  | @ -1,3 +0,0 @@ | |||
| import demoTest from '../../../tests/shared/demoTest'; | ||||
| 
 | ||||
| demoTest('back-top'); | ||||
|  | @ -1,46 +0,0 @@ | |||
| import { mount } from '@vue/test-utils'; | ||||
| import BackTop from '..'; | ||||
| import { sleep } from '../../../tests/utils'; | ||||
| 
 | ||||
| describe('BackTop', () => { | ||||
|   it('should scroll to top after click it', async () => { | ||||
|     const wrapper = mount(BackTop, { | ||||
|       props: { | ||||
|         visibilityHeight: -1, | ||||
|       }, | ||||
|       attachTo: 'body', | ||||
|     }); | ||||
|     const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => { | ||||
|       window.scrollY = y; | ||||
|       window.pageYOffset = y; | ||||
|       document.documentElement.scrollTop = y; | ||||
|     }); | ||||
|     window.scrollTo(0, 400); | ||||
|     expect(document.documentElement.scrollTop).toBe(400); | ||||
|     await sleep(100); | ||||
|     wrapper.find('.ant-back-top').trigger('click'); | ||||
|     await sleep(500); | ||||
|     expect(document.documentElement.scrollTop).toBe(0); | ||||
|     scrollToSpy.mockRestore(); | ||||
|   }); | ||||
|   it('support onClick', async () => { | ||||
|     const onClick = jest.fn(); | ||||
|     const wrapper = mount(BackTop, { | ||||
|       props: { | ||||
|         visibilityHeight: -1, | ||||
|         onClick, | ||||
|       }, | ||||
|       attachTo: 'body', | ||||
|     }); | ||||
|     const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((x, y) => { | ||||
|       window.scrollY = y; | ||||
|       window.pageYOffset = y; | ||||
|     }); | ||||
|     document.dispatchEvent(new Event('scroll')); | ||||
|     window.scrollTo(0, 400); | ||||
|     await sleep(10); | ||||
|     wrapper.find('.ant-back-top').trigger('click'); | ||||
|     expect(onClick).toHaveBeenCalled(); | ||||
|     scrollToSpy.mockRestore(); | ||||
|   }); | ||||
| }); | ||||
|  | @ -1,23 +0,0 @@ | |||
| <docs> | ||||
| --- | ||||
| order: 0 | ||||
| title: | ||||
|   zh-CN: 基本使用 | ||||
|   en-US: Basic Usage | ||||
| --- | ||||
| 
 | ||||
| ## zh-CN | ||||
| 
 | ||||
| 最简单的用法。 | ||||
| 
 | ||||
| ## en-US | ||||
| 
 | ||||
| The simplest usage. | ||||
| </docs> | ||||
| 
 | ||||
| <template> | ||||
|   <a-back-top /> | ||||
|   Scroll down to see the bottom-right | ||||
|   <strong style="color: rgba(64, 64, 64, 0.6)">gray</strong> | ||||
|   button. | ||||
| </template> | ||||
|  | @ -1,48 +0,0 @@ | |||
| <docs> | ||||
| --- | ||||
| order: 1 | ||||
| title: | ||||
|   zh-CN: 自定义样式 | ||||
|   en-US: Custom style | ||||
| --- | ||||
| 
 | ||||
| ## zh-CN | ||||
| 
 | ||||
| 可以自定义回到顶部按钮的样式,限制宽高:`40px * 40px`。 | ||||
| 
 | ||||
| ## en-US | ||||
| 
 | ||||
| You can customize the style of the button, just note the size limit: no more than `40px * 40px`. | ||||
| </docs> | ||||
| 
 | ||||
| <template> | ||||
|   <div id="components-back-top-demo-custom"> | ||||
|     <a-back-top @click="handleClick"> | ||||
|       <div class="ant-back-top-inner">UP</div> | ||||
|     </a-back-top> | ||||
|     Scroll down to see the bottom-right | ||||
|     <strong style="color: #1088e9">blue</strong> | ||||
|     button. | ||||
|   </div> | ||||
| </template> | ||||
| <script setup> | ||||
| const handleClick = () => { | ||||
|   console.log('click'); | ||||
| }; | ||||
| </script> | ||||
| 
 | ||||
| <style scoped> | ||||
| :deep(#components-back-top-demo-custom) .ant-back-top { | ||||
|   inset-block-end: 100px; | ||||
| } | ||||
| #components-back-top-demo-custom .ant-back-top-inner { | ||||
|   height: 40px; | ||||
|   width: 40px; | ||||
|   line-height: 40px; | ||||
|   border-radius: 4px; | ||||
|   background-color: #1088e9; | ||||
|   color: #fff; | ||||
|   text-align: center; | ||||
|   font-size: 20px; | ||||
| } | ||||
| </style> | ||||
|  | @ -1,27 +0,0 @@ | |||
| <template> | ||||
|   <demo-sort> | ||||
|     <basic /> | ||||
|     <custom /> | ||||
|   </demo-sort> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import Basic from './basic.vue'; | ||||
| import Custom from './custom.vue'; | ||||
| 
 | ||||
| import CN from '../index.zh-CN.md'; | ||||
| import US from '../index.en-US.md'; | ||||
| import { defineComponent } from 'vue'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
|   CN, | ||||
|   US, | ||||
|   components: { | ||||
|     Basic, | ||||
|     Custom, | ||||
|   }, | ||||
|   setup() { | ||||
|     return {}; | ||||
|   }, | ||||
| }); | ||||
| </script> | ||||
|  | @ -1,30 +0,0 @@ | |||
| --- | ||||
| category: Components | ||||
| type: Other | ||||
| title: BackTop | ||||
| cover: https://gw.alipayobjects.com/zos/alicdn/tJZ5jbTwX/BackTop.svg | ||||
| --- | ||||
| 
 | ||||
| `BackTop` makes it easy to go back to the top of the page. | ||||
| 
 | ||||
| ## When To Use | ||||
| 
 | ||||
| - When the page content is very long. | ||||
| - When you need to go back to the top very frequently in order to view the contents. | ||||
| 
 | ||||
| ## API | ||||
| 
 | ||||
| > The distance to the bottom is set to `50px` by default, which is overridable. | ||||
| > | ||||
| > If you decide to use custom styles, please note the size limit: no more than `40px * 40px`. | ||||
| 
 | ||||
| | Property | Description | Type | Default | Version | | ||||
| | --- | --- | --- | --- | --- | | ||||
| | target | specifies the scrollable area dom node | () => HTMLElement | () => window |  | | ||||
| | visibilityHeight | the `BackTop` button will not show until the scroll height reaches this value | number | 400 |  | | ||||
| 
 | ||||
| ### events | ||||
| 
 | ||||
| | Events Name | Description | Arguments | Version | | ||||
| | --- | --- | --- | --- | | ||||
| | click | a callback function, which can be executed when you click the button | Function |  | | ||||
|  | @ -1,144 +0,0 @@ | |||
| import type { ExtractPropTypes, PropType } from 'vue'; | ||||
| import { | ||||
|   defineComponent, | ||||
|   nextTick, | ||||
|   onActivated, | ||||
|   onBeforeUnmount, | ||||
|   onMounted, | ||||
|   reactive, | ||||
|   ref, | ||||
|   watch, | ||||
|   onDeactivated, | ||||
| } from 'vue'; | ||||
| import VerticalAlignTopOutlined from '@ant-design/icons-vue/VerticalAlignTopOutlined'; | ||||
| import getScroll from '../_util/getScroll'; | ||||
| import { getTransitionProps, Transition } from '../_util/transition'; | ||||
| import scrollTo from '../_util/scrollTo'; | ||||
| import { withInstall, eventType } from '../_util/type'; | ||||
| import throttleByAnimationFrame from '../_util/throttleByAnimationFrame'; | ||||
| import useConfigInject from '../config-provider/hooks/useConfigInject'; | ||||
| import type { MouseEventHandler } from '../_util/EventInterface'; | ||||
| import useStyle from './style'; | ||||
| 
 | ||||
| export const backTopProps = () => ({ | ||||
|   visibilityHeight: { type: Number, default: 400 }, | ||||
|   duration: { type: Number, default: 450 }, | ||||
|   target: Function as PropType<() => HTMLElement | Window | Document>, | ||||
|   prefixCls: String, | ||||
|   onClick: eventType<MouseEventHandler>(), | ||||
|   // visible: { type: Boolean, default: undefined }, // Only for test. Don't use it. | ||||
| }); | ||||
| 
 | ||||
| export type BackTopProps = Partial<ExtractPropTypes<typeof backTopProps>>; | ||||
| 
 | ||||
| const BackTop = defineComponent({ | ||||
|   compatConfig: { MODE: 3 }, | ||||
|   name: 'ABackTopLegacy', | ||||
|   inheritAttrs: false, | ||||
|   props: backTopProps(), | ||||
|   // emits: ['click'], | ||||
|   setup(props, { slots, attrs, emit }) { | ||||
|     const { prefixCls, direction } = useConfigInject('back-top', props); | ||||
|     const [wrapSSR, hashId] = useStyle(prefixCls); | ||||
|     const domRef = ref(); | ||||
|     const state = reactive({ | ||||
|       visible: false, | ||||
|       scrollEvent: null, | ||||
|     }); | ||||
| 
 | ||||
|     const getDefaultTarget = () => | ||||
|       domRef.value && domRef.value.ownerDocument ? domRef.value.ownerDocument : window; | ||||
| 
 | ||||
|     const scrollToTop = (e: Event) => { | ||||
|       const { target = getDefaultTarget, duration } = props; | ||||
|       scrollTo(0, { | ||||
|         getContainer: target, | ||||
|         duration, | ||||
|       }); | ||||
|       emit('click', e); | ||||
|     }; | ||||
| 
 | ||||
|     const handleScroll = throttleByAnimationFrame((e: Event | { target: any }) => { | ||||
|       const { visibilityHeight } = props; | ||||
|       const scrollTop = getScroll(e.target, true); | ||||
|       state.visible = scrollTop >= visibilityHeight; | ||||
|     }); | ||||
| 
 | ||||
|     const bindScrollEvent = () => { | ||||
|       const { target } = props; | ||||
|       const getTarget = target || getDefaultTarget; | ||||
|       const container = getTarget(); | ||||
|       handleScroll({ target: container }); | ||||
|       container?.addEventListener('scroll', handleScroll); | ||||
|     }; | ||||
| 
 | ||||
|     const scrollRemove = () => { | ||||
|       const { target } = props; | ||||
|       const getTarget = target || getDefaultTarget; | ||||
|       const container = getTarget(); | ||||
|       handleScroll.cancel(); | ||||
|       container?.removeEventListener('scroll', handleScroll); | ||||
|     }; | ||||
| 
 | ||||
|     watch( | ||||
|       () => props.target, | ||||
|       () => { | ||||
|         scrollRemove(); | ||||
|         nextTick(() => { | ||||
|           bindScrollEvent(); | ||||
|         }); | ||||
|       }, | ||||
|     ); | ||||
| 
 | ||||
|     onMounted(() => { | ||||
|       nextTick(() => { | ||||
|         bindScrollEvent(); | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
|     onActivated(() => { | ||||
|       nextTick(() => { | ||||
|         bindScrollEvent(); | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
|     onDeactivated(() => { | ||||
|       scrollRemove(); | ||||
|     }); | ||||
| 
 | ||||
|     onBeforeUnmount(() => { | ||||
|       scrollRemove(); | ||||
|     }); | ||||
| 
 | ||||
|     return () => { | ||||
|       const defaultElement = ( | ||||
|         <div class={`${prefixCls.value}-content`}> | ||||
|           <div class={`${prefixCls.value}-icon`}> | ||||
|             <VerticalAlignTopOutlined /> | ||||
|           </div> | ||||
|         </div> | ||||
|       ); | ||||
|       const divProps = { | ||||
|         ...attrs, | ||||
|         onClick: scrollToTop, | ||||
|         class: { | ||||
|           [hashId.value]: true, | ||||
|           [`${prefixCls.value}`]: true, | ||||
|           [`${attrs.class}`]: attrs.class, | ||||
|           [`${prefixCls.value}-rtl`]: direction.value === 'rtl', | ||||
|         }, | ||||
|       }; | ||||
| 
 | ||||
|       const transitionProps = getTransitionProps('fade'); | ||||
|       return wrapSSR( | ||||
|         <Transition {...transitionProps}> | ||||
|           <div v-show={state.visible} {...divProps} ref={domRef}> | ||||
|             {slots.default?.() || defaultElement} | ||||
|           </div> | ||||
|         </Transition>, | ||||
|       ); | ||||
|     }; | ||||
|   }, | ||||
| }); | ||||
| 
 | ||||
| export default withInstall(BackTop); | ||||
|  | @ -1,31 +0,0 @@ | |||
| --- | ||||
| category: Components | ||||
| type: 其他 | ||||
| subtitle: 回到顶部 | ||||
| title: BackTop | ||||
| cover: https://gw.alipayobjects.com/zos/alicdn/tJZ5jbTwX/BackTop.svg | ||||
| --- | ||||
| 
 | ||||
| 返回页面顶部的操作按钮。 | ||||
| 
 | ||||
| ## 何时使用 | ||||
| 
 | ||||
| - 当页面内容区域比较长时; | ||||
| - 当用户需要频繁返回顶部查看相关内容时。 | ||||
| 
 | ||||
| ## API | ||||
| 
 | ||||
| > 有默认样式,距离底部 `50px`,可覆盖。 | ||||
| > | ||||
| > 自定义样式宽高不大于 40px \* 40px。 | ||||
| 
 | ||||
| | 参数 | 说明 | 类型 | 默认值 | 版本 | | ||||
| | --- | --- | --- | --- | --- | | ||||
| | target | 设置需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | Function | () => window |  | | ||||
| | visibilityHeight | 滚动高度达到此参数值才出现 `BackTop` | number | 400 |  | | ||||
| 
 | ||||
| ### 事件 | ||||
| 
 | ||||
| | 事件名称 | 说明               | 回调参数 | 版本 | | ||||
| | -------- | ------------------ | -------- | ---- | | ||||
| | click    | 点击按钮的回调函数 | Function |      | | ||||
|  | @ -1,118 +0,0 @@ | |||
| import type { CSSObject } from '../../_util/cssinjs'; | ||||
| import type { FullToken, GenerateStyle } from '../../theme/internal'; | ||||
| import { genComponentStyleHook, mergeToken } from '../../theme/internal'; | ||||
| import { resetComponent } from '../../style'; | ||||
| 
 | ||||
| /** Component only token. Which will handle additional calculation of alias token */ | ||||
| export interface ComponentToken { | ||||
|   zIndexPopup: number; | ||||
| } | ||||
| 
 | ||||
| type BackTopToken = FullToken<'BackTop'> & { | ||||
|   backTopBackground: string; | ||||
|   backTopColor: string; | ||||
|   backTopHoverBackground: string; | ||||
|   backTopFontSize: number; | ||||
|   backTopSize: number; | ||||
| 
 | ||||
|   // Position
 | ||||
|   backTopBlockEnd: number; | ||||
|   backTopInlineEnd: number; | ||||
|   backTopInlineEndMD: number; | ||||
|   backTopInlineEndXS: number; | ||||
| }; | ||||
| 
 | ||||
| // ============================== Shared ==============================
 | ||||
| const genSharedBackTopStyle: GenerateStyle<BackTopToken, CSSObject> = (token): CSSObject => { | ||||
|   const { componentCls, backTopFontSize, backTopSize, zIndexPopup } = token; | ||||
| 
 | ||||
|   return { | ||||
|     [componentCls]: { | ||||
|       ...resetComponent(token), | ||||
| 
 | ||||
|       position: 'fixed', | ||||
|       insetInlineEnd: token.backTopInlineEnd, | ||||
|       insetBlockEnd: token.backTopBlockEnd, | ||||
|       zIndex: zIndexPopup, | ||||
|       width: 40, | ||||
|       height: 40, | ||||
|       cursor: 'pointer', | ||||
| 
 | ||||
|       '&:empty': { | ||||
|         display: 'none', | ||||
|       }, | ||||
| 
 | ||||
|       [`${componentCls}-content`]: { | ||||
|         width: backTopSize, | ||||
|         height: backTopSize, | ||||
|         overflow: 'hidden', | ||||
|         color: token.backTopColor, | ||||
|         textAlign: 'center', | ||||
|         backgroundColor: token.backTopBackground, | ||||
|         borderRadius: backTopSize, | ||||
|         transition: `all ${token.motionDurationMid}`, | ||||
| 
 | ||||
|         '&:hover': { | ||||
|           backgroundColor: token.backTopHoverBackground, | ||||
|           transition: `all ${token.motionDurationMid}`, | ||||
|         }, | ||||
|       }, | ||||
| 
 | ||||
|       // change to .backtop .backtop-icon
 | ||||
|       [`${componentCls}-icon`]: { | ||||
|         fontSize: backTopFontSize, | ||||
|         lineHeight: `${backTopSize}px`, | ||||
|       }, | ||||
|     }, | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| const genMediaBackTopStyle: GenerateStyle<BackTopToken> = (token): CSSObject => { | ||||
|   const { componentCls } = token; | ||||
| 
 | ||||
|   return { | ||||
|     [`@media (max-width: ${token.screenMD}px)`]: { | ||||
|       [componentCls]: { | ||||
|         insetInlineEnd: token.backTopInlineEndMD, | ||||
|       }, | ||||
|     }, | ||||
| 
 | ||||
|     [`@media (max-width: ${token.screenXS}px)`]: { | ||||
|       [componentCls]: { | ||||
|         insetInlineEnd: token.backTopInlineEndXS, | ||||
|       }, | ||||
|     }, | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| // ============================== Export ==============================
 | ||||
| export default genComponentStyleHook<'BackTop'>( | ||||
|   'BackTop', | ||||
| 
 | ||||
|   token => { | ||||
|     const { | ||||
|       fontSizeHeading3, | ||||
|       colorTextDescription, | ||||
|       colorTextLightSolid, | ||||
|       colorText, | ||||
|       controlHeightLG, | ||||
|     } = token; | ||||
| 
 | ||||
|     const backTopToken = mergeToken<BackTopToken>(token, { | ||||
|       backTopBackground: colorTextDescription, | ||||
|       backTopColor: colorTextLightSolid, | ||||
|       backTopHoverBackground: colorText, | ||||
|       backTopFontSize: fontSizeHeading3, | ||||
|       backTopSize: controlHeightLG, | ||||
| 
 | ||||
|       backTopBlockEnd: controlHeightLG * 1.25, | ||||
|       backTopInlineEnd: controlHeightLG * 2.5, | ||||
|       backTopInlineEndMD: controlHeightLG * 1.5, | ||||
|       backTopInlineEndXS: controlHeightLG * 0.5, | ||||
|     }); | ||||
|     return [genSharedBackTopStyle(backTopToken), genMediaBackTopStyle(backTopToken)]; | ||||
|   }, | ||||
|   token => ({ | ||||
|     zIndexPopup: token.zIndexBase + 10, | ||||
|   }), | ||||
| ); | ||||
|  | @ -1,7 +1,6 @@ | |||
| import type { ComponentToken as AlertComponentToken } from '../../alert/style'; | ||||
| import type { ComponentToken as AnchorComponentToken } from '../../anchor/style'; | ||||
| import type { ComponentToken as AvatarComponentToken } from '../../avatar/style'; | ||||
| import type { ComponentToken as BackTopComponentToken } from '../../back-top/style'; | ||||
| import type { ComponentToken as ButtonComponentToken } from '../../button/style'; | ||||
| import type { ComponentToken as FloatButtonComponentToken } from '../../float-button/style'; | ||||
| import type { ComponentToken as CalendarComponentToken } from '../../calendar/style'; | ||||
|  | @ -55,7 +54,6 @@ export interface ComponentTokenMap { | |||
|   Alert?: AlertComponentToken; | ||||
|   Anchor?: AnchorComponentToken; | ||||
|   Avatar?: AvatarComponentToken; | ||||
|   BackTop?: BackTopComponentToken; | ||||
|   Badge?: {}; | ||||
|   Button?: ButtonComponentToken; | ||||
|   Breadcrumb?: {}; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 tangjinzhou
						tangjinzhou