Merge pull request #174 in YR/star-web-components from loading to master

* commit '8fcc32289b60c95868034744805cee4ff0ea3d20':
  添加loading组件
This commit is contained in:
汪昌棋 2022-11-24 16:32:52 +08:00
commit 85acd240e6
7 changed files with 332 additions and 1 deletions

View File

@ -385,7 +385,7 @@ const baseStyle = css`
`
const baseDarkStyle = css`
@media (prefers-color-scheme: light) {
@media (prefers-color-scheme: dark) {
:root {
/****************************文字颜色*************************************/
--font-normal-color: var(--font-secondary-white);

View File

@ -0,0 +1 @@
export * from './loading.js'

View File

@ -0,0 +1,34 @@
import {css} from 'lit'
export default css`
:host {
position: fixed;
top: 0;
height: 100vh;
width: 100vw;
transition: opacity 0.2s;
pointer-events: all;
display: flex;
justify-content: center;
align-items: center;
}
#container {
display: flex;
align-items: center;
background-color: var(--base-normal-bgc);
box-shadow: var(--business-light-shaded);
border-radius: var(--auto-20px);
padding: var(--auto-4px) var(--auto-20px) var(--auto-4px) var(--auto-10px);
}
#loading {
margin-right: var(--auto-10px);
}
#notice {
color: var(--font-normal-color);
font-size: var(--auto-16px);
}
`

View File

@ -0,0 +1,177 @@
import {
customElement,
html,
property,
StarBaseElement,
state,
} from '@star-web-components/base'
import {
loading_lm_1x,
loading_lm_2x,
loading_dm_1x,
loading_dm_2x,
} from '@star-web-components/asset'
import loadingStyles from './loading.css.js'
const assets = {
lm1x: loading_lm_1x,
lm2x: loading_lm_2x,
dm1x: loading_dm_1x,
dm2x: loading_dm_2x,
}
interface Options {
notice?: string // 提示语
size?: 'large' | 'small' // 大小
mode?: 'light' | 'dark' // 模式
canCancel?: boolean // 是否能取消
cancelCallback?: (value: any) => any // 取消回调
showUntil?: Promise<any> | Promise<any>[] // 关闭条件,无论成功与否 settled 即关闭
successfulCallback?: (value: any) => any // 成功回调
failedCallback?: (value: any) => any // 失败回调
settledCallback?: Function // 结束回调
timeout?: number // 最长显示时长, 超时时无超时回调则默认为失败, 小于等于0意为无时限
timeoutCallback?: Function // 超时回调
}
/**
* TODO:
* 1. Overlay , 使
* 2. ,
*/
@customElement('star-loading')
export class StarLoading extends StarBaseElement {
@property() notice: string = ''
// loading 状态是否能取消
@property() canCancel: boolean = false
// 取消回调
cancelCallback?: Function
cancel = () => {
if (!this.canCancel) return
this.cancelCallback?.()
this.clearAndRemove()
}
// 图标大小
@property() size: 'large' | 'small' = 'small'
@state() mode: 'light' | 'dark' = 'light'
timeout?: number
timeoutCallback?: Function
successfulCallback?: Function
failedCallback?: Function
settledCallback?: Function
constructor(opts: Options) {
super()
if (opts.notice !== undefined) {
this.notice = opts.notice
}
if (opts.mode) {
this.mode = opts.mode
} else {
this.addColorSchemeListener()
}
this.canCancel = !!opts.canCancel
this.cancelCallback = opts.cancelCallback
this.observeStatus(opts)
this.timeout = opts.timeout
this.timeoutCallback = opts.timeoutCallback
}
blankCallback = () => {}
clearAndRemove = () => {
this.cancelCallback = undefined
this.successfulCallback = undefined
this.failedCallback = undefined
this.settledCallback = undefined
this.timeoutCallback = undefined
this.remove()
}
observeStatus = ({
showUntil,
successfulCallback = this.blankCallback,
failedCallback = this.blankCallback,
settledCallback = this.blankCallback,
}: Options) => {
if (!showUntil) return
let until!: Promise<any>
if (showUntil instanceof Array) {
until = Promise.all(showUntil)
} else {
until = showUntil
}
this.successfulCallback = successfulCallback
this.failedCallback = failedCallback
this.settledCallback = settledCallback
until
.then((value) => {
this.successfulCallback?.(value)
})
.catch((value) => {
this.failedCallback?.(value)
})
.finally(() => {
this.settledCallback?.()
this.clearAndRemove()
})
}
listener?: EventListener
addColorSchemeListener = () => {
const media = window.matchMedia('(prefers-color-scheme: dark)')
if (media.matches) {
this.mode = 'dark'
}
this.listener = (evt: any) => {
this.mode = evt.matches ? 'dark' : 'light'
}
media.addEventListener('change', this.listener)
}
disconnectedCallback() {
this.listener &&
window
.matchMedia('(prefers-color-scheme: dark)')
.removeEventListener('change', this.listener)
}
firstUpdated() {
if (this.timeout) {
setTimeout(() => {
this.timeoutCallback?.()
this.clearAndRemove()
}, this.timeout)
}
}
render() {
let img = this.mode == 'dark' ? 'dm' : 'lm'
img += this.size == 'large' ? '2x' : '1x'
return html`
<div id="container">
<img id="loading" src=${assets[img as keyof typeof assets]} />
<span id="notice">${this.notice}</span>
</div>
`
}
static override get styles() {
return [loadingStyles]
}
}
declare global {
interface HTMLElementTagNameMap {
'star-loading': StarLoading
}
}

View File

@ -0,0 +1,22 @@
{
"name": "@star-web-components/loading",
"version": "0.0.1",
"description": "",
"type": "module",
"main": "./index.js",
"module": "./index.js",
"exports": {
".": {
"default": "./index.js"
},
"./index": {
"default": "./index.js"
},
"./li.js": {
"default": "./loading.js"
},
"./package.json": "./package.json"
},
"author": "",
"license": "ISC"
}

View File

@ -0,0 +1,94 @@
import {html, customElement, LitElement} from '@star-web-components/base'
import {StarLoading} from '@star-web-components/loading'
import '@star-web-components/li'
import '@star-web-components/button'
@customElement('panel-loading')
export class PanelLoading extends LitElement {
createClick() {
const loading = new StarLoading({
notice: 'loading...',
canCancel: true,
cancelCallback: () => {
console.log('cancel')
},
})
loading.onclick = loading.cancel
document.body.appendChild(loading)
}
createTimeout() {
const loading = new StarLoading({
notice: 'loading...',
timeout: 3000,
timeoutCallback: () => console.log('loadend'),
})
document.body.appendChild(loading)
}
createAsync() {
const p1 = new Promise((res, rej) => {
setTimeout(() => {
const num = Math.random()
num > 0.5 ? res(num) : rej(num)
}, 1000)
})
const p2 = new Promise((res, rej) => {
setTimeout(() => {
const num = Math.random()
num < 0.5 ? res(num) : rej(num)
}, 2000)
})
const loading = new StarLoading({
notice: 'loading...',
showUntil: [p1, p2],
successfulCallback: (value) => {
console.log('success number:', value)
},
failedCallback: (value) => {
console.log('fail number:', value)
},
settledCallback: () => {
console.log('settled')
},
})
document.body.appendChild(loading)
}
render() {
return html`
<star-button
type="normal"
variant="primary"
size="small"
label="点击消失"
@click=${this.createClick}
></star-button>
<br />
<star-button
type="normal"
variant="primary"
size="small"
label="3s后消失并打印"
@click=${this.createTimeout}
></star-button>
<br />
<star-button
type="normal"
variant="primary"
size="small"
label="模拟异步事件"
@click=${this.createAsync}
></star-button>
`
}
}
declare global {
interface HTMLElementTagNameMap {
'panel-loading': PanelLoading
}
}

View File

@ -44,6 +44,7 @@ import './switch/switch'
import './toast/toast'
import './weather/weather'
import './swiper/swiper'
import './loading/loading'
import './animation/animation'
type SEID = string
@ -128,6 +129,8 @@ export class PanelRoot extends LitElement {
<hr />
<star-li label="AllConfirm" icon="messages" href="#confirm"></star-li>
<hr />
<star-li label="loading状态" icon="play-circle" href="#loading"></star-li>
<hr />
</star-ul>
<star-ul type=${UlType.BASE}>