-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added backtop component (#138)
* feat: added backtop component * docs: added backtop component document * docs: added backtop component unit test * test: added backtop component unit test * update: update unit test * test: updated backtop component unit test
- Loading branch information
1 parent
7e828b5
commit c6d2bba
Showing
19 changed files
with
476 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { afterEach, expect, test, describe, beforeEach, vi } from 'vitest'; | ||
import KBacktop from '../src'; | ||
import KBacktopSlot from './backtop.test.svelte'; | ||
import { tick } from 'svelte'; | ||
|
||
const initHost = () => { | ||
document.body.style.height = '100px'; | ||
document.body.style.overflow = 'auto'; | ||
}; | ||
beforeEach(() => { | ||
initHost(); | ||
}); | ||
afterEach(() => { | ||
document.body.innerHTML = ''; | ||
}); | ||
|
||
describe('Test: KBacktop', () => { | ||
vi.mock('svelte', async () => { | ||
const actual = (await vi.importActual('svelte')) as object; | ||
return { | ||
...actual, | ||
// @ts-ignore | ||
onMount: (await import('svelte/internal')).onMount | ||
}; | ||
}); | ||
|
||
test('props: showHeight & right & bottom', async () => { | ||
new KBacktop({ | ||
target: document.body, | ||
props: { | ||
right: 66, | ||
bottom: 66, | ||
showHeight: 100 | ||
} | ||
}); | ||
|
||
await tick(); | ||
expect(document.documentElement.innerHTML.includes('k-backtop')).not.toBeTruthy(); | ||
|
||
document.documentElement.scrollTop = 50; | ||
document.documentElement.dispatchEvent(new Event('scroll', { bubbles: true })); | ||
await tick(); | ||
expect(document.body.innerHTML.includes('k-backtop')).not.toBeTruthy(); | ||
|
||
document.documentElement.scrollTop = 110; | ||
document.documentElement.dispatchEvent(new Event('scroll', { bubbles: true })); | ||
await tick(); | ||
expect(document.documentElement.innerHTML.includes('k-backtop')).toBeTruthy(); | ||
expect(document.documentElement.innerHTML.includes('right: 66px; bottom: 66px;')).toBeTruthy(); | ||
}); | ||
|
||
test('events: click', async () => { | ||
const mockFn = vi.fn(); | ||
const instance = new KBacktop({ | ||
target: document.body | ||
}); | ||
await tick(); | ||
instance.$on('click', mockFn); | ||
expect(document.documentElement.innerHTML.includes('k-backtop')).not.toBeTruthy(); | ||
|
||
document.documentElement.scrollTop = 210; | ||
document.documentElement.dispatchEvent(new Event('scroll', { bubbles: true })); | ||
await tick(); | ||
expect(document.documentElement.innerHTML.includes('k-backtop')).toBeTruthy(); | ||
const triggerEl = document.body.children[0]; | ||
triggerEl.dispatchEvent(new Event('click', { bubbles: true })); | ||
await tick(); | ||
expect(mockFn).toBeCalled(); | ||
}); | ||
|
||
test('slot: custom render', async () => { | ||
new KBacktopSlot({ | ||
target: document.body | ||
}); | ||
|
||
await tick(); | ||
expect(document.documentElement.innerHTML.includes('k-backtop')).not.toBeTruthy(); | ||
document.documentElement.scrollTop = 50; | ||
document.documentElement.dispatchEvent(new Event('scroll', { bubbles: true })); | ||
await tick(); | ||
expect(document.documentElement.innerHTML.includes('k-backtop')).toBeTruthy(); | ||
expect(document.documentElement.innerHTML.includes('__BACKTO_TEST')).toBeTruthy(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<script> | ||
import { KBacktop } from "../src"; | ||
</script> | ||
<KBacktop showHeight="{10}"> | ||
<div id="__BACKTO_TEST"></div> | ||
</KBacktop> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
{ | ||
"name": "@ikun-ui/backtop", | ||
"version": "0.0.9-beta.2", | ||
"type": "module", | ||
"main": "dist/index.js", | ||
"module": "dist/index.js", | ||
"svelte": "dist/index.js", | ||
"types": "src/index.ts", | ||
"keywords": [ | ||
"svelte", | ||
"svelte3", | ||
"web component", | ||
"component", | ||
"react", | ||
"vue", | ||
"svelte-kit", | ||
"dx" | ||
], | ||
"scripts": { | ||
"build": "npm run build:js && npm run build:svelte", | ||
"build:js": "tsc -p . --outDir dist/ --rootDir src/", | ||
"build:svelte": "svelte-strip strip src/ dist", | ||
"publish:npm": "pnpm publish --no-git-checks --access public" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"dependencies": { | ||
"@ikun-ui/icon": "workspace:*", | ||
"@ikun-ui/utils": "workspace:*", | ||
"baiwusanyu-utils": "^1.0.14", | ||
"smoke-distance": "^1.0.3" | ||
}, | ||
"devDependencies": { | ||
"@tsconfig/svelte": "^5.0.0", | ||
"svelte-strip": "^2.0.0", | ||
"tslib": "^2.6.1", | ||
"typescript": "^5.1.6" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
<script lang="ts"> | ||
import { getPrefixCls, createCls } from '@ikun-ui/utils'; | ||
import { KIcon } from '@ikun-ui/icon'; | ||
import { SmokeDistance } from 'smoke-distance' | ||
import type { easingType } from 'smoke-distance' | ||
import {createEventDispatcher, onDestroy, onMount} from "svelte"; | ||
export let cls: string = ''; | ||
export let attrs: Record<string, string> = {}; | ||
export let right: number = 40 | ||
export let bottom: number = 40 | ||
export let showHeight: number = 200 | ||
export let target: string = '' | ||
export let easing: string = 'quartOut' | ||
export let duration: number = 500 | ||
let show = false | ||
let targetEl:undefined | HTMLElement = undefined | ||
let container: undefined | Document | HTMLElement = undefined | ||
$: backTopStyle = { | ||
right: `${right}px`, | ||
bottom: `${bottom}px`, | ||
} | ||
const scrollToTop = () => { | ||
if (!targetEl) return | ||
const { scrollTop } = targetEl | ||
const smoke = new SmokeDistance({ | ||
from: { scrollTop }, | ||
to: { scrollTop: 0 }, | ||
easing: easing as easingType, | ||
duration: duration, | ||
onUpdate: (keys: any) => { | ||
if (targetEl) | ||
targetEl.scrollTop = keys.scrollTop | ||
}, | ||
}) | ||
smoke.start() | ||
} | ||
const dispatch = createEventDispatcher(); | ||
const handleClick = (event: MouseEvent) => { | ||
scrollToTop() | ||
dispatch('click', event) | ||
} | ||
const setContainer = () => { | ||
container = document | ||
targetEl = document.documentElement | ||
if (target) { | ||
targetEl = document.querySelector<HTMLElement>(target) ?? undefined | ||
if (!targetEl){ | ||
console.error(`[ikun-ui]: backtop component - ${target} does not exist`) | ||
targetEl = document.body | ||
} | ||
container = targetEl | ||
} | ||
} | ||
const handleScroll = () => { | ||
if (targetEl) { | ||
const { scrollTop } = targetEl | ||
show = scrollTop >= showHeight | ||
} | ||
} | ||
handleScroll() | ||
onMount(() => { | ||
setContainer() | ||
container && container.addEventListener('scroll', handleScroll) | ||
}) | ||
onDestroy(() => { | ||
container && container.removeEventListener('scroll', handleScroll) | ||
}) | ||
const prefixCls = getPrefixCls('backtop'); | ||
$: cnames = createCls(prefixCls, { | ||
[`${prefixCls}--base`]: true, | ||
[`${prefixCls}__dark`]: true | ||
}, cls); | ||
</script> | ||
|
||
{#if show} | ||
<div class={cnames} | ||
style:right={backTopStyle.right} | ||
style:bottom={backTopStyle.bottom} | ||
aria-hidden="true" | ||
on:click|stopPropagation={handleClick} | ||
{...$$restProps} | ||
{...attrs}> | ||
<slot> | ||
<KIcon icon="i-carbon-arrow-up"/> | ||
</slot> | ||
</div> | ||
{/if} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/// <reference types="./types" /> | ||
import Backtop from './index.svelte'; | ||
export { Backtop as KBacktop }; | ||
|
||
export default Backtop; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/// <reference types="svelte" /> | ||
export type KBacktopProps = { | ||
cls: string; | ||
attrs: Record<string, string>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"extends": "@tsconfig/svelte/tsconfig.json", | ||
|
||
"compilerOptions": { | ||
"noImplicitAny": true, | ||
"strict": true, | ||
"declaration": true | ||
}, | ||
"include": ["src/**/*.ts", "src/**/*.svelte"], | ||
"exclude": ["node_modules/*", "**/*.spec.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
--- | ||
title: KBacktop | ||
lang: en-US | ||
--- | ||
|
||
# KBacktop | ||
|
||
A button to back to top. | ||
|
||
## Install | ||
|
||
::: code-group | ||
|
||
```bash [pnpm] | ||
pnpm add @ikun-ui/backtop | ||
``` | ||
|
||
```bash [yarn] | ||
yarn add @ikun-ui/backtop | ||
``` | ||
|
||
```bash [npm] | ||
npm install @ikun-ui/backtop | ||
``` | ||
|
||
::: | ||
|
||
## Basic usage | ||
|
||
Scroll down to see the bottom-right button. | ||
|
||
<demo src="../../../../example/backtop/basic.svelte" github='Backtop'></demo> | ||
|
||
## Slot Render | ||
|
||
Render custom content via slots. | ||
|
||
<demo src="../../../../example/backtop/custom.svelte" github='Backtop'></demo> | ||
|
||
## Backtop Props | ||
|
||
| Name | Type | Default | Description | | ||
| ---------- | -------- | ---------- | ---------------------------------------------------- | | ||
| right | `number` | `40` | Distance from the right side of the screen. | | ||
| bottom | `number` | `40` | Distance from the bottom of the screen. | | ||
| showHeight | `number` | `200` | Scroll to this height to show the Backtop component. | | ||
| target | `string` | `-` | Scroll target element `id` | | ||
| easing | `string` | `quartOut` | Animation during back to top(TODO) | | ||
| duration | `number` | `500` | Time spent back to top. | | ||
| cls | `string` | `''` | Additional class for | | ||
| attrs | `any` | `{}` | Additional attributes | | ||
|
||
## Backtop Events | ||
|
||
| Name | Description | Type | | ||
| ----- | --------------------------- | ---------------------------- | | ||
| click | trigger when backtop click. | `(event: MouseEvent)=> void` | | ||
|
||
## Backtop Slots | ||
|
||
| Name | Description | | ||
| ------- | ------------------------- | | ||
| default | Customize default content | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<script> | ||
import { KBacktop } from '@ikun-ui/backtop'; | ||
</script> | ||
|
||
<p> | ||
attention to the right _(:з」∠)_ | ||
</p> | ||
<KBacktop bottom="100" right="100" showHeight="100"/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<script> | ||
import { KBacktop } from '@ikun-ui/backtop'; | ||
import IKun from './ikun.svelte'; | ||
</script> | ||
|
||
<p> | ||
attention to the right _(:з」∠)_ | ||
</p> | ||
<KBacktop | ||
bottom="{20}" | ||
right="{100}" | ||
showHeight="{600}"> | ||
<IKun/> | ||
</KBacktop> |
Oops, something went wrong.