Merge pull request #36 in YR/star-web-components from feature-notification to master

* commit '31b747cd19e847fcacff177b53a156e1dd56e7a1':
  添加配置文件
  添加测试文件
  添加消息组组件,下拉通知栏组件
  TASK: #109658 添加消息通知组件
This commit is contained in:
汪昌棋 2022-09-24 13:51:31 +08:00
commit fec8a1bc70
13 changed files with 1228 additions and 0 deletions

View File

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

View File

@ -0,0 +1,194 @@
import {html, css, LitElement, HTMLTemplateResult} from 'lit'
import {
customElement,
property,
eventOptions,
queryAssignedElements,
} from 'lit/decorators.js'
import {StarNotification} from '../notification/notification.js'
@customElement('star-notification-group')
export class StarNotificationGroup extends LitElement {
@property({type: Number}) count = 0
@queryAssignedElements({flatten: true}) slotElements!:
| HTMLSlotElement[]
| StarNotification[]
connectedCallback() {
super.connectedCallback()
window.addEventListener('notification-delete', this)
}
firstUpdated() {
this.setAttribute('show', 'false')
this.count = this.slotElements.length
if (this.count > 1) {
let firstChild = this.slotElements[0] as StarNotification
let lastChild = this.slotElements[this.count - 1] as StarNotification
if (this.getAttribute('show') == 'true') {
// 展开
// 以下是为防止未在html或js创建单条通知类型时定义
firstChild.withArrowUp = true
firstChild.notificationType = 'more-notifiactions'
} else {
// 折叠
// 以下是为防止未在html或js创建单条通知类型时定义
firstChild.withArrowUp = false
firstChild.notificationType = 'more-notifiactions-first'
firstChild.radiusType = 'top-border-radius'
}
// 以下是为防止未在html或js创建单条通知类型时定义
let otherChild = Array.from(
this.slotElements as StarNotification[]
).filter((child) => {
return child !== firstChild && child !== lastChild
})
otherChild.forEach((child) => {
;(child as StarNotification).notificationType = 'more-notifiactions'
})
lastChild.notificationType = 'more-notifiactions'
// 以下是为防止在html或js创建首条条通知时未定义副标题、副内容
let secondChild = this.slotElements[1] as StarNotification
firstChild.secondTitle = secondChild.title
firstChild.secondText = secondChild.text
}
}
@eventOptions({passive: false})
handleEvent(event: Event) {
switch (event.type) {
case 'slotchange':
this.handleSlotchange(event)
break
case 'notification-delete':
let id = (event as any).detail.id
;(this.slotElements as StarNotification[]).forEach(
(el: StarNotification) => {
if (this.getAttribute('show') == 'false') {
let self = this
if (el.id == id) {
// 删除某个notification-group
this.dispatchEvent(
new CustomEvent('notification-group-delete', {
detail: {
group: self,
},
bubbles: true,
composed: true,
})
)
}
} else {
if (el.id == id) {
// 删除单条notification
this.removeChild(el)
}
}
}
)
break
}
}
render(): HTMLTemplateResult {
return html`
<slot @slotchange=${this}></slot>
`
}
handleSlotchange(event: Event) {
console.log('ddf slotchange!!')
let slotElements = (event.target as HTMLSlotElement).assignedElements()
let slotLen = slotElements.length
let allNotificationshown = this.allNotificationshown.bind(this)
if (slotLen) {
let firstChild = slotElements[0] as StarNotification
firstChild.count = slotLen
if (slotLen == 1) {
// group中只有一条消息应该转为'one-notification'类型,并折叠
firstChild.notificationType = 'one-notification'
this.setAttribute('show', 'false')
firstChild.withArrowUp = false
firstChild.removeEventListener('click', allNotificationshown)
} else if (slotLen > 1) {
let lastChild = slotElements[slotLen - 1] as StarNotification
if (this.getAttribute('show') == 'true') {
// 展开
firstChild.radiusType = 'top-border-radius'
} else {
// 折叠
firstChild.radiusType = 'border-radius'
}
// 仅对一条以上的进行监听处理
firstChild.addEventListener('click', allNotificationshown, false)
// 处理group中最后一条notification
lastChild.radiusType = 'bottom-border-radius'
// 首条通知的副标题、副内容通过第二条通知获取
let secondChild = slotElements[1] as StarNotification
firstChild.secondTitle = secondChild.title
firstChild.secondText = secondChild.text
}
}
}
allNotificationshown(event: Event) {
// 解决响应多次的问题
event.stopImmediatePropagation()
if (this.slotElements.length == 1) {
return
}
let firstChild = this.slotElements[0] as StarNotification
let type = firstChild.notificationType
if (type == 'more-notifiactions-first') {
firstChild.notificationType = 'more-notifiactions'
} else {
firstChild.notificationType = 'more-notifiactions-first'
}
let isShow = this.getAttribute('show') == 'true'
if (isShow) {
// 当前是展开状态,点击需折叠
this.setAttribute('show', 'false')
firstChild.radiusType = 'border-radius'
firstChild.withArrowUp = false
} else {
this.setAttribute('show', 'true')
firstChild.radiusType = 'top-border-radius'
firstChild.withArrowUp = true
}
}
static styles = css`
:host {
width: 860px;
display: block;
margin: 16px 170px 0;
border-radius: 20px;
}
:host([show='false']) ::slotted(*) {
display: none;
}
:host([show='false']) ::slotted(:first-child) {
display: block;
}
:host([show='true']) ::slotted(*) {
display: block;
}
`
}
declare global {
interface HTMLElementTagNameMap {
'star-notification-group': StarNotificationGroup
}
}

View File

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

View File

@ -0,0 +1,8 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"composite": true,
"rootDir": "../../"
},
"include": ["*.ts", "../notification/notification.js"]
}

View File

@ -0,0 +1,211 @@
## 通知栏
### StarNotification
用于定义通知组件。
#### 通知 UI 类型
有三种类型,类型说明如下:
```ts
enum NotificationType {
ONE = 'one-notification',
MORE = 'more-notifiactions',
MORE_FIRST = 'more-notifiactions-first',
}
```
`ONE` 单条通知,notification-group 展开时第一条 notification 类型
`MORE` notification-group 中除第一条以外的 notification 类型(区别于`ONE`的是,该种类型展开时有向上箭头)
`MORE_FIRST`: notification-group 折叠时第一条 notification 类型(包括主标题、主内容、副标题、副内容、通知数量)
#### 通知圆角样式
notification-group 中通知圆角类型,说明如下:
```ts
enum RadiusType {
TOP_BORDER_RADIUS = 'top-border-radius',
BOTTOM_BORDER_RADIUS = 'bottom-border-radius',
BORDER_RADIUS = 'border-radius',
}
```
`TOP_BORDER_RADIUS`: 对应 notification-group 展开时第一条通知,仅上边有圆角
`BOTTOM_BORDER_RADIUS`: 对应 notification-group 展开时最后一条通知,仅下边有圆角
`BORDER_RADIUS`: 对应 notification-group 折叠时 notification, 上下边都有圆角
#### 属性参数说明
1. 公共属性
`notificationType`: 定义单条通知时须定义,若使用 notification-group,可以不用定义(已在组件中定义)
`radiusType`: notification-group 中通知圆角样式,组件内部参数
`withArrowUp`: 向上箭头是否显示,组件内部参数
`id`: 须定义,通知删除时与 id 紧密绑定,由系统通知对象给定
`timestamp`: 通知时间戳,由系统通知对象给定
`title`: 须定义,通知标题,由系统通知对象给定
`text`: 须定义,通知内容,由系统通知对象给定
`src`: 须定义,通知图标 src由系统通知对象给定
`type`: 通知类型,由系统通知对象给定
`manifesturl` 通知来源,由系统通知对象给定
`noclear`: 通知是否可清除,由系统通知对象给定
`count`: 通知数量,由组件自动计算,不需赋值,用于组件判断向上箭头是否显示的根据
2. `more-notifiactions-first`仅有属性
`secondTitle`: notification-group 中首条通知的副标题,第二条通知的标题,由组件自动获取
`secondText`: notification-group 中首条通知的副内容,第二条通知的内容, 由组件自动获取
#### 功能说明
1. 通知删除功能
通知自右向左滑动会出现删除按钮,点击图标,可进行单条通知的删除。
2. 跳转至设置
通知自右向左滑动会出现设置按钮,点击图标,可跳转至设置应用。
说明:
a. 目前每条通知都有以上两种功能,后续考虑是否每条通知都要具备这两种功能。
b. 目前未添加复杂的动作进行删除,后续需添加。
#### 使用示例
```html
<star-notification
id="002001"
notificationType="${NotificationType.ONE}"
title="唐山被打女生律师在发声透露近况!"
text='"唐山打人事件"已过去一个月除了6月21日河北公安厅...'
timestamp="2分钟"
src="../../Gallery.png"
type="desktop-notification"
manifesturl="http://system.localhost/manifest.webmanifest"
noclear="false"
></star-notification>
```
### StarNotificationGroup
是对同一应用产生的多条通知进行的封装组件。
#### 功能说明
1. 单条通知删除
展开通知组,对某一通知自右向左滑动,点击删除按钮,可进行单条通知的删除。
2. 通知组删除
通知组折叠,对通知组自右向左滑动,点击删除按钮,可对通知组进行整个删除。
3. 通知展开与折叠
点击通知组首条通知,可对通知组进行展开与折叠。
#### 使用示例
```html
<star-notification-group>
<star-notification
id="0111"
title="开福区高温橙色预警"
text="点击查看详情"
secondTitle="开福区暴雨蓝色预警"
secondText="点击查看详情"
timestamp="2分钟"
src="../../Gallery.png"
type="desktop-notification"
manifesturl="http://system.localhost/manifest.webmanifest"
noclear="false"
></star-notification>
<star-notification
id="011"
title="开福区暴雨蓝色预警"
text="点击查看详情"
timestamp="5天"
src="../../Gallery.png"
type="desktop-notification"
manifesturl="http://system.localhost/manifest.webmanifest"
noclear="false"
></star-notification>
</star-notification-group>
```
### NotificationCenterBar
是对整个下拉通知栏的封装组件。UI 包括日期时间栏、快捷设置按钮、通知部分。
#### 功能说明
1. 通知全部清除功能
点击面板最下方的删除按钮,可清除整个面板的通知。
#### 使用示例
```html
<notification-center-bar>
<star-notification-group>
<star-notification
id="0"
title="你的关注"
text="星光麒麟新系统桌面,爱了爱了!"
timestamp="2分钟"
src="../../Gallery.png"
type="desktop-notification"
manifesturl="http://system.localhost/manifest.webmanifest"
noclear="false"
></star-notification>
<star-notification
id="01"
title="#研究生录取通知书"
text="没别的意思,就想让你们夸夸我"
timestamp="5小时前"
src="../../Gallery.png"
type="desktop-notification"
manifesturl="http://system.localhost/manifest.webmanifest"
noclear="false"
></star-notification>
<star-notification
id="02"
title="#研究生录取通知书"
text="没别的意思,就想让你们夸夸我"
timestamp="1天"
src="../../Gallery.png"
type="desktop-notification"
manifesturl="http://system.localhost/manifest.webmanifest"
noclear="false"
></star-notification>
<star-notification
id="03"
title="#研究生录取通知书"
text="没别的意思,就想让你们夸夸我"
timestamp="5天"
src="../../Gallery.png"
type="desktop-notification"
manifesturl="http://system.localhost/manifest.webmanifest"
noclear="false"
></star-notification>
</star-notification-group>
<star-notification
id="7"
title="开福区高温橙色预警"
text="点击查看详情"
secondTitle="开福区暴雨蓝色预警"
secondText="点击查看详情"
timestamp="2分钟"
src="../../Gallery.png"
type="desktop-notification"
manifesturl="http://system.localhost/manifest.webmanifest"
noclear="false"
></star-notification>
</notification-center-bar>
```
### 说明
未使用`notification-center-bar`标签包裹`star-notification`、`star-notification-group`,需要对应监听"notification-delete"、"notification-group-delete"事件进行处理以删除通知。
```ts
window.addEventListener('notification-delete', (evt) => {
let notification = (evt as any).detail.notification
this.outer.removeChild(notification)
})
window.addEventListener('notification-group-delete', (evt) => {
let group = (evt as any).detail.group
this.outer.removeChild(group)
})
```

View File

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

View File

@ -0,0 +1,9 @@
export interface WebActivity {
start(): Promise<any>
cancel(): void
}
export var WebActivity: {
prototype: WebActivity
new (name: string, data?: any): WebActivity
}

View File

@ -0,0 +1,605 @@
import {html, css, LitElement, HTMLTemplateResult, nothing} from 'lit'
import {
customElement,
property,
eventOptions,
query,
state,
} from 'lit/decorators.js'
import {WebActivity} from './interface.js'
// ONE 单条通知notification-group展开时第一条notification类型
// MORE notification-group中除第一条以外的notification类型
// MORE_FIRST: notification-group折叠时第一条notification类型
export enum NotificationType {
ONE = 'one-notification',
MORE = 'more-notifiactions',
MORE_FIRST = 'more-notifiactions-first',
}
// TOP_BORDER_RADIUS 对应notification-group展开时第一条notification仅上边有圆角
// BOTTOM_BORDER_RADIUS 对应notification-group展开时最后一条notification仅下边有圆角
// BORDER_RADIUS 对应notification-group折叠时notification,上下边都有圆角
export enum RadiusType {
TOP_BORDER_RADIUS = 'top-border-radius',
BOTTOM_BORDER_RADIUS = 'bottom-border-radius',
BORDER_RADIUS = 'border-radius',
}
@customElement('star-notification')
export class StarNotification extends LitElement {
// 公共属性
@property({type: String}) id = ''
@property({type: String}) timestamp = ''
@property({type: String}) src = ''
@property({type: String}) type = ''
@property({type: NotificationType}) notificationType = 'one-notification'
@property({type: String}) manifesturl = ''
@property({type: Boolean}) noclear = false
@property({type: Number}) count = 1
@property({type: RadiusType}) radiusType = ''
@property({type: Boolean}) withArrowUp = false
@property({type: String}) title = ''
@property({type: String}) text = ''
// 仅more-notifiactions-first有
@property({type: String}) secondTitle = ''
@property({type: String}) secondText = ''
@query('.notification') notification!: HTMLDivElement
@query('.btn-tool') btnTool!: HTMLDivElement
@query('.arrow-up') arrowUp!: HTMLDivElement
@state() touchAction = {
// 触摸开始落点
start: {
pageX: 0,
pageY: 0,
clientX: 0,
clientY: 0,
},
// 触摸结束落点
last: {
pageX: 0,
pageY: 0,
clientX: 0,
clientY: 0,
},
}
render(): HTMLTemplateResult | typeof nothing {
switch (this.notificationType) {
case NotificationType.ONE:
case NotificationType.MORE:
return this.getone()
case NotificationType.MORE_FIRST:
return this.getmorefirst()
default:
console.error('unhandled 【star-notification】 type')
return nothing
}
}
getone(): HTMLTemplateResult | typeof nothing {
if (!this.title) {
console.error('【star-notification】缺少 title 参数')
return nothing
}
if (!this.text) {
console.error('【star-notification】缺少 text 参数')
return nothing
}
// if (!this.timestamp) {
// console.error('【star-notification】缺少 timestamp 参数')
// return nothing
// }
this.timestamp ? new Date(this.timestamp) : new Date()
if (!this.manifesturl) {
console.error('【star-notification】缺少 manifesturl 参数')
return nothing
}
const arrowShow =
this.count > 1 && this.withArrowUp
? html`
<style>
.arrow-up {
display: block !important;
}
</style>
`
: nothing
// "more-notifiactions"用于notification-group中的第二条及以后的notification,
// 中间位置notification没有圆角(radiusType为"")最底部的radiusType为bottom-border-radius.
const otherClass =
this.notificationType == 'more-notifiactions'
? this.radiusType
: 'border-radius'
return html`
<div class="one">
<div
class="notification ${otherClass}"
role="link"
tabindex="0"
data-notification-id=${this.id}
data-no-clear=${this.noclear}
data-obsolete-a-p-i="false"
data-type=${this.type}
data-manifest-u-r-l=${this.manifesturl}
@touchstart=${this}
@touchmove=${this}
@touchend=${this}
>
<img src=${this.src} role="presentation" />
<div class="title-container">
<div class="title" dir="auto">${this.title}</div>
<span class="timestamp" data-timestamp=${this.timestamp}>
${this.timestamp}
</span>
</div>
<div class="detail">
<div class="detail-content" dir="auto">${this.text}</div>
<span class="arrow-up" data-icon="o"></span>
${arrowShow}
</div>
</div>
<div class="btn-tool">
<div data-icon="delete" @click=${this}></div>
<div data-icon="settings" @click=${this}></div>
</div>
</div>
`
}
getmorefirst(): HTMLTemplateResult | typeof nothing {
if (!this.title) {
console.error(
'【star-notification】【more-notification-first】缺少 title 参数'
)
return nothing
}
if (!this.text) {
console.error(
'【star-notification】【more-notification-first】缺少 text 参数'
)
return nothing
}
if (!this.secondTitle) {
console.error(
'【star-notification】【more-notification-first】缺少 secondTitle 参数'
)
return nothing
}
if (!this.secondText) {
console.error(
'【star-notification】【more-notification-first】缺少 secondText 参数'
)
return nothing
}
if (!this.radiusType) {
console.error(
'【star-notification】【more-notification-first】缺少 radiusType 参数'
)
return nothing
}
this.timestamp ? new Date(this.timestamp) : new Date()
return html`
<div class="more">
<div
class="notification ${this.radiusType}"
role="link"
tabindex="0"
data-notification-id=${this.id}
data-no-clear=${this.noclear}
data-obsolete-a-p-i="false"
data-type=${this.type}
data-manifest-u-r-l=${this.manifesturl}
@touchstart=${this}
@touchmove=${this}
@touchend=${this}
>
<img src=${this.src} role="presentation" />
<div class="container one-container">
<div class="title" dir="auto">${this.title}</div>
<div class="detail-content" dir="auto">${this.text}</div>
<span class="timestamp" data-timestamp=${this.timestamp}>
${this.timestamp}
</span>
</div>
<div class="container another-container">
<div class="title" dir="auto">${this.secondTitle}</div>
<div class="detail-content" dir="auto">${this.secondText}</div>
<span class="notificaiton-counts">${this.count}</span>
</div>
</div>
<div class="btn-tool">
<div data-icon="delete" @click=${this}></div>
<div data-icon="settings" @click=${this}></div>
</div>
</div>
`
}
@eventOptions({passive: false})
handleEvent(event: TouchEvent) {
switch (event.type) {
case 'touchstart':
this.touchAction.start.clientX = event.touches[0].clientX
this.btnTool.style.visibility = 'visiable'
break
case 'touchmove':
this.touchAction.last.clientX = event.touches[0].clientX
let touchPosX =
this.touchAction.last.clientX - this.touchAction.start.clientX
// if (Math.abs(touchPosX) > 266) {
// touchPosX = 266;
// }
// this.notification.style.transform = 'translateX(' + touchPosX + 'px)';
if (touchPosX < 0) {
// if (Math.abs(touchPosX) > 18) {
// (this.btnTool.children[1] as HTMLElement).style.visibility = "visible";
// }
// if (Math.abs(touchPosX) > 142) {
// (this.btnTool.children[0] as HTMLElement).style.visibility = "visible";
// }
// if (Math.abs(touchPosX) > 222) {
// (this.btnTool.children[1] as HTMLElement).style.opacity = "1";
// (this.btnTool.children[0] as HTMLElement).style.opacity = "1";
// }
;(this.btnTool.children[0] as HTMLElement).style.visibility =
'visible'
;(this.btnTool.children[1] as HTMLElement).style.visibility =
'visible'
;(this.btnTool.children[0] as HTMLElement).style.opacity = '1'
;(this.btnTool.children[1] as HTMLElement).style.opacity = '1'
this.notification.style.transform = 'translateX(-' + 266 + 'px)'
} else {
// if (touchPosX > 44) {
// (this.btnTool.children[0] as any).style.opacity = 0.6;
// }
// if (touchPosX > 124) {
// (this.btnTool.children[0] as any).style.visibility = "hidden";
// }
// if (touchPosX > 168) {
// (this.btnTool.children[1] as any).style.opacity = 0.6;
// }
// if (touchPosX > 248) {
// (this.btnTool.children[1] as any).style.visibility = "hidden";
// }
;(this.btnTool.children[0] as any).style.visibility = 'hidden'
;(this.btnTool.children[1] as any).style.visibility = 'hidden'
this.notification.style.transform = 'translateX(' + 0 + 'px)'
}
break
case 'touchend':
break
case 'click':
event.stopPropagation()
switch ((event.target as HTMLElement).dataset.icon) {
case 'delete':
// console.log("fg45 handle delete!!");
let self = this
this.dispatchEvent(
new CustomEvent('notification-delete', {
detail: {
id: this.id,
notification: self,
},
bubbles: true,
composed: true,
})
)
break
case 'settings':
let activity = new WebActivity('configure', {})
activity.start().then(
() => {},
() => {}
)
break
}
break
}
}
static styles = css`
:host {
--notification-background-lm: rgba(255, 255, 255, 0.55);
--notification-background-dm: rgba(0, 0, 0, 0.25);
--border-lm: rgba(0, 0, 0, 0.09);
--border-dm: rgba(0, 0, 0, 0.09);
--button-background-color-lm: rgba(255, 255, 255, 0.68);
--button-background-color-dm: rgba(0, 0, 0, 0.3);
left: 0px;
top: 0px;
position: relative;
display: block;
// width: 860px;
}
:host([notificationType='one-notification']) {
margin: 16px 0 0 0;
}
.notification {
height: 152px;
width: 860px;
background: var(--notification-background-lm);
}
.top-border-radius {
border-top-left-radius: 20px;
border-top-right-radius: 20px;
}
.bottom-border-radius {
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
}
.border-radius {
border-radius: 20px;
}
.notification > img {
width: 48px;
height: 48px;
pointer-events: none;
margin: 26px 10px 78px 26px;
}
.notification > div.title-container {
display: flex;
width: calc(100% - 84px);
position: absolute;
left: 84px;
top: 36px;
}
.notification > div.title-container .title {
height: 28px;
line-height: 28px;
white-space: nowrap;
text-overflow: ellipsis;
flex: none;
order: 0;
flex-grow: 0;
font-size: 28px;
color: #404040;
}
.notification > div.title-container .timestamp {
flex: initial;
position: absolute;
height: 32px;
right: 32px;
// top: 32px;
top: -4px;
font-size: 24px;
line-height: 32px;
text-align: right;
mix-blend-mode: normal;
opacity: 0.65;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.notification div {
pointer-events: none;
}
.notification > div.detail {
display: flex;
position: absolute;
width: calc(100% - 84px);
left: 84px;
top: 84px;
}
.notification > div.detail .detail-content {
// flex: 1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: 740px;
height: 34px;
font-family: 'OPPOSans';
font-style: normal;
font-weight: 400;
font-size: 26px;
line-height: 34px;
color: #404040;
mix-blend-mode: normal;
opacity: 0.65;
}
.notification > div.detail .arrow-up {
position: absolute;
width: 56px;
height: 34px;
right: 26px;
bottom: 30px;
top: 0px;
text-align: center;
vertical-align: middle;
line-height: 34px;
display: none;
background: rgba(0, 0, 0, 0.06);
border-radius: 189px;
}
.notification > div.detail .arrow-up::after {
font-size: 35px;
font-family: 'gaia-icons';
content: attr(data-icon);
font-style: normal;
text-rendering: optimizeLegibility;
font-weight: 500;
}
.one,
.more {
display: flex;
justify-content: space-between;
width: 100%;
height: 100%;
// overflow-x: hidden;
overflow: hidden;
}
.btn-tool {
display: flex;
align-items: center;
right: 18px;
position: absolute;
height: inherit;
visibility: hidden;
}
.btn-tool > div:first-child {
margin-right: 44px;
visibility: hidden;
}
.btn-tool > div:last-child {
visibility: hidden;
}
.btn-tool > div {
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
background: var(--button-background-color-lm);
border-radius: 50%;
opacity: 0.6;
}
.btn-tool > div::after {
width: 32px;
height: 32px;
line-height: 32px;
text-align: center;
vertical-align: middle;
content: attr(data-icon);
font-size: 32px;
font-family: gaia-icons;
font-style: normal;
text-rendering: optimizelegibility;
font-weight: 500;
}
.container {
display: flex;
width: calc(100% - 84px);
position: absolute;
left: 84px;
font-family: 'OPPOSans';
font-style: normal;
font-weight: 400;
}
.one-container {
top: 36px;
}
.another-container {
top: 89px;
}
.container .title {
height: 28px;
line-height: 28px;
font-size: 28px;
color: #404040;
flex: none;
order: 0;
flex-grow: 0;
}
.container .detail-content {
height: 34px;
line-height: 34px;
position: relative;
left: 24px;
top: -3px;
font-size: 26px;
color: #404040;
mix-blend-mode: normal;
opacity: 0.65;
flex: none;
order: 1;
flex-grow: 0;
}
.one-container .timestamp {
height: 34px;
position: absolute;
right: 34px;
top: -4px;
font-size: 24px;
line-height: 32px;
text-align: right;
color: #404040;
mix-blend-mode: normal;
opacity: 0.65;
}
.another-container .notificaiton-counts {
position: absolute;
width: 56px;
height: 34px;
right: 26px;
bottom: 30px;
top: -1px;
line-height: 34px;
text-align: center;
vertical-align: middle;
font-size: 20px;
color: #000000;
background: rgba(0, 0, 0, 0.06);
border-radius: 189px;
}
:host([dark-mode]) .notification {
height: 152px;
// width: 100%;
width: 860px;
background: var(--notification-background-dm);
}
:host([dark-mode]) .btn-tool > div {
width: 80px;
height: 80px;
display: flex;
align-items: center;
justify-content: center;
background: var(--button-background-color-dm);
border-radius: 50%;
opacity: 0.6;
}
`
}
declare global {
interface HTMLElementTagNameMap {
'star-notification': StarNotification
}
}

View File

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

View File

@ -0,0 +1,8 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"composite": true,
"rootDir": "../../"
},
"include": ["*.ts", "./interface.js"]
}

View File

@ -16,6 +16,7 @@ import './components/toast/toast'
import './components/picker/picker'
import './components/overflowmenu/overflowmenu'
import './components/slider/slider'
import './components/notification/notification'
import './components/prompt/prompt'
import './components/digicipher/digicipher'
// import './components/pattern-view/pattern-view'

View File

@ -0,0 +1,136 @@
import {html, css, LitElement} from 'lit'
import {customElement, query} from 'lit/decorators.js'
// import { NotificationType, RadiusType } from '../../../components/notification/notification';
import {NotificationType} from '../../../components/notification/notification'
import '../../../components/notification/notification'
import '../../../components/notification-group/notification-group'
@customElement('panel-notification')
export class PanelNotifiaciton extends LitElement {
@query('.outer') outer!: HTMLDivElement
// render() {
// return html`
// <notification-center-bar>
// <star-notification-group>
// <star-notification id="0" notificationType=${NotificationType.MORE_FIRST} radiusType=${RadiusType.TOP_BORDER_RADIUS} title="你的关注" text="星光麒麟新系统桌面,爱了爱了!" secondTitle="#研究生录取通知书" secondText="没别的意思,就想让你们夸夸我" timestamp="2分钟" src="../../Gallery.png" type="desktop-notification" manifesturl="http://system.localhost/manifest.webmanifest" noclear=false>
// </star-notification>
// <star-notification id="01" notificationType=${NotificationType.MORE} title="#研究生录取通知书" text="没别的意思,就想让你们夸夸我" timestamp="5天" src="../../Gallery.png" type="desktop-notification" manifesturl="http://system.localhost/manifest.webmanifest" noclear=false>
// </star-notification>
// <star-notification id="02" notificationType=${NotificationType.MORE} title="屏幕" text="-01-19-25-52.png" timestamp="5天" src="../../Gallery.png" type="desktop-notification" manifesturl="http://system.localhost/manifest.webmanifest" noclear=false>
// </star-notification>
// <star-notification id="03" notificationType=${NotificationType.MORE} radiusType= ${RadiusType.BOTTOM_BORDER_RADIUS} title="截图" text="-01-19-25-52.png" timestamp="5小时前" src="../../Gallery.png" type="desktop-notification" manifesturl="http://system.localhost/manifest.webmanifest" noclear=false>
// </star-notification>
// </star-notification-group>
// <star-notification-group>
// <star-notification id="10" notificationType=${NotificationType.ONE} title="1" text="1.png" timestamp="2分钟" src="../../Gallery.png" type="desktop-notification" manifesturl="http://system.localhost/manifest.webmanifest" noclear=false>
// </star-notification>
// </star-notification-group>
// <star-notification-group>
// <star-notification id="0111" title="开福区高温橙色预警" text="点击查看详情" secondTitle="开福区暴雨蓝色预警" secondText="点击查看详情" timestamp="2分钟" src="../../Gallery.png" type="desktop-notification" manifesturl="http://system.localhost/manifest.webmanifest" noclear=false>
// </star-notification>
// <star-notification id="011" title="开福区暴雨蓝色预警" text="点击查看详情" timestamp="5天" src="../../Gallery.png" type="desktop-notification" manifesturl="http://system.localhost/manifest.webmanifest" noclear=false>
// </star-notification>
// </star-notification-group>
// <star-notification id="002001" notificationType=${NotificationType.ONE} title="唐山被打女生律师在发声透露近况!" text='"唐山打人事件"已过去一个月除了6月21日河北公安厅...' timestamp="2分钟" src="../../Gallery.png" type="desktop-notification" manifesturl="http://system.localhost/manifest.webmanifest" noclear=false>
// </star-notification>
// <star-notification-group>
// <star-notification id="01211" title="开福区高温橙色预警" text="点击查看详情" timestamp="2分钟" src="../../Gallery.png" type="desktop-notification" manifesturl="http://system.localhost/manifest.webmanifest" noclear=false>
// </star-notification>
// <star-notification id="0121" title="开福区暴雨蓝色预警" text="点击查看详情" timestamp="5天" src="../../Gallery.png" type="desktop-notification" manifesturl="http://system.localhost/manifest.webmanifest" noclear=false>
// </star-notification>
// <star-notification id="01201" title="开福区闪电红色预警" text="点击查看详情" timestamp="7天" src="../../Gallery.png" type="desktop-notification" manifesturl="http://system.localhost/manifest.webmanifest" noclear=false>
// </star-notification>
// </star-notification-group>
// </notification-center-bar>
// `
// }
render() {
return html`
<div class="outer">
<star-notification
id="0020017"
notificationType=${NotificationType.ONE}
title="唐山被打女生律师在发声透露近况!"
text='"唐山打人事件"已过去一个月除了6月21日河北公安厅...'
timestamp="2分钟"
src="../../Gallery.png"
type="desktop-notification"
manifesturl="http://system.localhost/manifest.webmanifest"
noclear="false"
></star-notification>
<star-notification-group>
<star-notification
id="012117"
title="开福区高温橙色预警"
text="点击查看详情"
timestamp="2分钟"
src="../../Gallery.png"
type="desktop-notification"
manifesturl="http://system.localhost/manifest.webmanifest"
noclear="false"
></star-notification>
<star-notification
id="01217"
title="开福区暴雨蓝色预警"
text="点击查看详情"
timestamp="5天"
src="../../Gallery.png"
type="desktop-notification"
manifesturl="http://system.localhost/manifest.webmanifest"
noclear="false"
></star-notification>
<star-notification
id="012017"
title="开福区闪电红色预警"
text="点击查看详情"
timestamp="7天"
src="../../Gallery.png"
type="desktop-notification"
manifesturl="http://system.localhost/manifest.webmanifest"
noclear="false"
></star-notification>
</star-notification-group>
</div>
`
}
static styles = css`
notification-center-bar {
width: 1200px;
height: 1920px;
}
.outer {
width: 100%;
height: 700px;
margin-top: 10px;
display: flex;
flex-direction: column;
align-items: center;
}
`
firstUpdated() {
window.addEventListener('notification-delete', (evt) => {
let notification = (evt as any).detail.notification
this.outer.removeChild(notification)
})
window.addEventListener('notification-group-delete', (evt) => {
let group = (evt as any).detail.group
this.outer.removeChild(group)
})
}
}
declare global {
interface HTMLElementTagNameMap {
'panel-notification': PanelNotifiaciton
}
}

View File

@ -27,6 +27,8 @@ import './digicipher/digicipher'
import './container/homescreen-container'
import './toast/toast'
import './picker/picker'
import './notification/notification'
import './switch/switch'
import './activeoverlay/activeoverlay'
@ -190,6 +192,14 @@ export class PanelRoot extends LitElement {
href="#overflowmenu"
></star-li>
<hr />
<star-li
type=${LiType.ICON_LABEL}
label="notification"
icon="play-circle"
iconcolor="blue"
href="#notification"
></star-li>
<hr />
<star-li
type=${LiType.ICON_LABEL}
label="overlay"