Merge pull request #128 in YR/star-web-components from container_exchange_strategy to master

* commit 'e07eb096920a6b4b822dc39c365eb0589e69054c':
  BUG: #145117 - (star-web-components)为当前页面无足够空间放置拖拽节点添加通知的功能
This commit is contained in:
汪昌棋 2022-11-10 09:11:46 +08:00
commit 672e419f4d
7 changed files with 312 additions and 76 deletions

View File

@ -1608,6 +1608,13 @@ export class GaiaContainer extends StarBaseElement {
composed: true,
})
)
} else if (this._dnd.isSpanning) {
this.dispatchEvent(
new CustomEvent('cross-field', {
detail: child,
composed: true,
})
)
}
}

View File

@ -19,6 +19,13 @@ type PlacedRecorder = {
* 7. 56
* 8.
* 9. TODO: 图标被小组件挤压后,
* 10. TODO: 被挤占位置时, ,
*
* :
* 1. TODO: 应尽量保证用户放置图标
* 2. ,
* 3. TODO: 非必要不应挪动其他与本次换位无关的元素的位置
* 4. , (, )
*/
enum Directions {

View File

@ -65,6 +65,8 @@ export default class GaiaContainerChild {
_order: number = -1
// 用于记录将会与其进行交换的占位DOM
_switch?: HTMLElement
// 越界标志
breakout: boolean = false
constructor(
element: HTMLElement = document.createElement('div'),
@ -453,7 +455,15 @@ export default class GaiaContainerChild {
this._lastElementHeight = this.element?.offsetHeight!
}
const crossResult = this.manager.exchangeStratege.handleCrossField(
this.curGridId,
this
)
this.breakout = crossResult.bottom || crossResult.right
!isActive &&
!this.breakout &&
!this.container.classList.contains('dragging') &&
(container.style.transform = 'translate(' + left + 'px, ' + top + 'px)')
return true

View File

@ -0,0 +1,92 @@
import {css} from 'lit'
export default css`
/** Host
---------------------------------------------------------*/
:host {
position: fixed;
left: 50%;
bottom: 13.33vh;
border-radius: var(--auto-20px);
max-width: 70%;
text-align: center;
z-index: 100;
color: var(--font-main-black, #262626);
overflow: hidden;
transform: translateX(-50%);
}
/** Inner
---------------------------------------------------------*/
.inner {
display: none;
}
.inner.visible {
display: block;
}
/**
---------------------------------------------------------*/
.bread {
max-width: 600px;
margin: 0 auto;
padding: var(--auto-24px) var(--auto-32px);
box-shadow: 0px 1px 0px 0px rgba(0, 0, 0, 0.15);
transform: translateY(100%);
font-size: var(--auto-26px);
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
color: var(--font-normal-color);
background: var(--base-normal-bgc);
transition: color 0.2s, background 0.2s;
}
.bread.animate-in {
animation-name: gaia-toast-enter;
animation-fill-mode: forwards;
animation-duration: 300ms;
}
.bread.animate-out {
animation-name: gaia-toast-leave;
animation-duration: 600ms;
transform: translateY(0%);
}
@keyframes gaia-toast-enter {
0% {
transform: translateY(100%);
opacity: 0;
}
40% {
opacity: 0;
}
100% {
transform: translateY(0%);
opacity: 1;
}
}
@keyframes gaia-toast-leave {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@media screen and (orientation: landscape) {
:host {
}
}
`

View File

@ -1,6 +1,9 @@
import {html, LitElement, CSSResultArray, TemplateResult} from 'lit'
import {html, CSSResultArray} from 'lit'
import {customElement, property, query, state} from 'lit/decorators.js'
import {sharedStyles} from './toast-styles.js'
import {autoPxStyle} from '../base/auto-px-style'
import {StarBaseElement} from '../base/star-base-element.js'
import style from './style'
export const toastVariants: ToastVariants[] = [
'negative',
@ -18,17 +21,110 @@ export type ToastVariants =
| 'warning'
| ''
enum Direction {
top,
bottom,
}
interface Options {
[prop: string]: string | boolean | undefined
direction?: keyof typeof Direction
icon?: boolean
close?: boolean
verline?: boolean
do?: boolean
information: string
}
// BUG: 该组件存在 UI 隐患, 因为弹出键盘时, 使用该组件的应用将会被键盘挤压窗口
// 导致该组件位置会被推至屏幕上方, 无法避免; 即便不被挤压(如Homescreen), 仍会
// 存在被键盘遮挡的情况, 依旧无法避免
@customElement('star-toast')
export class StarToast extends LitElement {
export class StarToast extends StarBaseElement {
public static override get styles(): CSSResultArray {
return [sharedStyles]
return [style, sharedStyles, autoPxStyle]
}
/* 暂时更改使用: start */
constructor(options: Options) {
super()
Object.assign(this, options)
document.body.appendChild(this)
this.appended = true
}
@property()
public direction: keyof typeof Direction = 'bottom'
@property({type: Number})
get timeout() {
return Number(this.getAttribute('timeout')) || 3000
}
set timeout(value) {
let current = Number(this.getAttribute('timeout'))
if (current == value) {
return
} else if (!value) {
this.removeAttribute('timeout')
} else {
this.setAttribute('timeout', String(value))
}
}
appended: boolean = false
onAnimateOutEnd = (_: any) => {}
hideTimeout?: number
@query('.inner') inner!: HTMLElement
@query('.bread') bread!: HTMLElement
show = () => {
if (!this.appended) {
document.body.appendChild(this)
this.appended = true
}
this.open = true
this.bread.removeEventListener('animationend', this.onAnimateOutEnd)
clearTimeout(this.hideTimeout)
this.inner.classList.add('visible')
this.bread.classList.remove('animate-out')
this.bread.classList.add('animate-in')
this.hideTimeout = window.setTimeout(this.hide.bind(this), this.timeout)
}
hide = () => {
clearTimeout(this.hideTimeout)
this.open = false
this.bread.classList.remove('animate-in')
this.bread.classList.add('animate-out')
this.bread.removeEventListener('animationend', this.onAnimateOutEnd)
this.onAnimateOutEnd = () => {
this.bread.removeEventListener('animationend', this.onAnimateOutEnd)
this.bread.classList.remove('animate-out')
this.inner.classList.remove('visible')
}
this.bread.addEventListener('animationend', this.onAnimateOutEnd)
}
render() {
return html`
<div class="inner">
<div class="bread">${this.information}</div>
</div>
`
}
/* 暂时更改使用: end */
@state()
public open: Boolean = false
@property({type: Number})
private timeout = 5000
// @property({type: Number})
// private timeout = 5000
@property({type: String})
public variant: ToastVariants = ''
@ -52,77 +148,77 @@ export class StarToast extends LitElement {
@property({type: String})
public buttonName = ''
private renderIcon(): TemplateResult {
switch (this.variant) {
case 'positive':
return html`
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 36 36"
role="img"
fill="white"
aria-hidden="false"
aria-label="Success"
>
<path
d="M18 2a16 16 0 1 0 16 16A16 16 0 0 0 18 2Zm10.666 9.08L16.018 27.341a1.208 1.208 0 0 1-.875.461c-.024.002-.05.002-.073.002a1.2 1.2 0 0 1-.85-.351l-7.784-7.795a1.2 1.2 0 0 1 0-1.698l1.326-1.325a1.201 1.201 0 0 1 1.695 0l5.346 5.347L25.314 8.473A1.203 1.203 0 0 1 27 8.263l1.455 1.133a1.205 1.205 0 0 1 .211 1.684Z"
></path>
</svg>
`
case 'warning':
case 'info':
return html`
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 36 36"
role="img"
fill="white"
aria-hidden="false"
aria-label="Information"
>
<path
d="M18 2a16 16 0 1 0 16 16A16 16 0 0 0 18 2Zm-.3 4.3a2.718 2.718 0 0 1 2.864 2.824 2.664 2.664 0 0 1-2.864 2.863 2.705 2.705 0 0 1-2.864-2.864A2.717 2.717 0 0 1 17.7 6.3ZM22 27a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-2a1 1 0 0 1 1-1h1v-6h-1a1 1 0 0 1-1-1v-2a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v9h1a1 1 0 0 1 1 1Z"
></path>
</svg>
`
case 'error':
case 'negative':
default:
return html`
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 36 36"
role="img"
fill="white"
aria-hidden="false"
aria-label="Error"
>
<path
d="M17.127 2.579.4 32.512A1 1 0 0 0 1.272 34h33.456a1 1 0 0 0 .872-1.488L18.873 2.579a1 1 0 0 0-1.746 0ZM20 29.5a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-3a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5Zm0-6a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-12a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5Z"
></path>
</svg>
`
}
}
// private renderIcon() {
// switch (this.variant) {
// case 'positive':
// return html`
// <svg
// xmlns="http://www.w3.org/2000/svg"
// viewBox="0 0 36 36"
// role="img"
// fill="white"
// aria-hidden="false"
// aria-label="Success"
// >
// <path
// d="M18 2a16 16 0 1 0 16 16A16 16 0 0 0 18 2Zm10.666 9.08L16.018 27.341a1.208 1.208 0 0 1-.875.461c-.024.002-.05.002-.073.002a1.2 1.2 0 0 1-.85-.351l-7.784-7.795a1.2 1.2 0 0 1 0-1.698l1.326-1.325a1.201 1.201 0 0 1 1.695 0l5.346 5.347L25.314 8.473A1.203 1.203 0 0 1 27 8.263l1.455 1.133a1.205 1.205 0 0 1 .211 1.684Z"
// ></path>
// </svg>
// `
// case 'warning':
// case 'info':
// return html`
// <svg
// xmlns="http://www.w3.org/2000/svg"
// viewBox="0 0 36 36"
// role="img"
// fill="white"
// aria-hidden="false"
// aria-label="Information"
// >
// <path
// d="M18 2a16 16 0 1 0 16 16A16 16 0 0 0 18 2Zm-.3 4.3a2.718 2.718 0 0 1 2.864 2.824 2.664 2.664 0 0 1-2.864 2.863 2.705 2.705 0 0 1-2.864-2.864A2.717 2.717 0 0 1 17.7 6.3ZM22 27a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-2a1 1 0 0 1 1-1h1v-6h-1a1 1 0 0 1-1-1v-2a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v9h1a1 1 0 0 1 1 1Z"
// ></path>
// </svg>
// `
// case 'error':
// case 'negative':
// default:
// return html`
// <svg
// xmlns="http://www.w3.org/2000/svg"
// viewBox="0 0 36 36"
// role="img"
// fill="white"
// aria-hidden="false"
// aria-label="Error"
// >
// <path
// d="M17.127 2.579.4 32.512A1 1 0 0 0 1.272 34h33.456a1 1 0 0 0 .872-1.488L18.873 2.579a1 1 0 0 0-1.746 0ZM20 29.5a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-3a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5Zm0-6a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-12a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5Z"
// ></path>
// </svg>
// `
// }
// }
protected override render(): TemplateResult {
return html`
<div open=${this.open} class="toast" id="toast" variant=${this.variant}>
<div>
<icon icon=${this.icon}>${this.renderIcon()}</icon>
</div>
<div>
<span class="text">${this.information}</span>
<do do=${this.do} wraping>Do Something</do>
</div>
<verline verline=${this.verline}></verline>
<close close=${this.close} @click=${this.closeToast}>X</close>
</div>
<div>
<do do="true" click @click=${this.toastChange}>${this.buttonName}</do>
</div>
`
}
// protected override render() {
// return html`
// <div open=${this.open} class="toast" id="toast" variant=${this.variant}>
// <div>
// <icon icon=${this.icon}>${this.renderIcon()}</icon>
// </div>
// <div>
// <span class="text">${this.information}</span>
// <do do=${this.do} wraping>Do Something</do>
// </div>
// <verline verline=${this.verline}></verline>
// <close close=${this.close} @click=${this.closeToast}>X</close>
// </div>
// <div>
// <do do="true" click @click=${this.toastChange}>${this.buttonName}</do>
// </div>
// `
// }
@query('#toast')
toast!: HTMLElement

View File

@ -4,5 +4,5 @@
"composite": true,
"rootDir": "../../"
},
"include": ["*.ts"]
"include": ["*.ts", "../base/*.ts"]
}

View File

@ -1,13 +1,37 @@
import {html, LitElement, CSSResultArray} from 'lit'
import {customElement} from 'lit/decorators.js'
import {sharedStyles} from '../../../components/toast/toast-styles'
import '../../../components/button'
import {StarToast} from '../../../components/toast'
@customElement('panel-toast')
export class PanelToast extends LitElement {
toast: StarToast = new StarToast({information: 'test'})
constructor() {
super()
}
public static override get styles(): CSSResultArray {
return [sharedStyles]
}
show() {
if (this.toast.open) {
this.toast.hide()
} else {
this.toast.show()
}
}
render() {
return html`
<star-button
type="normal"
class="$1"
@click=${this.show}
label="弹出通知"
></star-button>
`
}
render_bak() {
return html`
<div>
<h3></h3>