Skip to content

Commit

Permalink
Merge pull request #863 from Tencent/refactor/toast/dom
Browse files Browse the repository at this point in the history
refactor(toast): using transition mixin and refactor dom
  • Loading branch information
LeeJim authored Sep 14, 2022
2 parents aceb986 + 626dc86 commit ce07d58
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 121 deletions.
2 changes: 1 addition & 1 deletion src/toast/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ spline: message
isComponent: true
---

<span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20lines-65%25-red" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20functions-55%25-red" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20statements-63%25-red" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20branches-28%25-red" /></span>
<span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20lines-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20functions-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20statements-100%25-blue" /></span><span class="coverages-badge" style="margin-right: 10px"><img src="https://img.shields.io/badge/coverages%3A%20branches-83%25-blue" /></span>
## 引入

全局引入,在 miniprogram 根目录下的`app.json`中配置,局部引入,在需要引入的页面或组件的`index.json`中配置。
Expand Down
53 changes: 53 additions & 0 deletions src/toast/__test__/index.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import simulate from 'miniprogram-simulate';
import path from 'path';

import { showToast, hideToast } from '../index';
import * as Util from '../../common/utils';

describe('toast', () => {
const toast = simulate.load(path.resolve(__dirname, `../toast`), 't-toast', {
less: true,
Expand Down Expand Up @@ -41,4 +44,54 @@ describe('toast', () => {

expect(destory).toHaveBeenCalledTimes(1);
});

it(':duration', async () => {
const id = simulate.load({
template: `<t-toast id="toast"></t-toast>`,
usingComponents: {
't-toast': toast,
},
});
const comp = simulate.render(id);
comp.attach(document.createElement('parent-wrapper'));

const $toast = comp.querySelector('#toast');

$toast.instance.show({ message: 'test', duration: 0 });

await simulate.sleep(2000);

expect($toast.data.visible).toBeTruthy();
});

it(':instance', async () => {
const handleClose = jest.fn();
const id = simulate.load({
template: `<t-toast id="toast" bind:close="handleClose"></t-toast>`,
methods: {
handleClose,
},
usingComponents: {
't-toast': toast,
},
});
const comp = simulate.render(id);
comp.attach(document.createElement('parent-wrapper'));

const $toast = comp.querySelector('#toast');
const mock = jest.spyOn(Util, 'getInstance');
mock.mockImplementation(() => $toast.instance);

showToast();
expect($toast.data.visible).toBeTruthy();

showToast();
expect(handleClose).toHaveBeenCalledTimes(0);

await simulate.sleep(2000);
expect(handleClose).toHaveBeenCalledTimes(1);

hideToast();
expect($toast.data.visible).toBeFalsy();
});
});
24 changes: 6 additions & 18 deletions src/toast/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { getInstance } from '../common/utils';

type Context = WechatMiniprogram.Page.TrivialInstance | WechatMiniprogram.Component.TrivialInstance;

type ToastType = 'loading' | 'success' | 'fail';
Expand All @@ -17,22 +19,8 @@ export type ToastOptionsType = {
close?: <T = any>() => T;
};

const getInstance = (context?: Context, selector = '#t-toast') => {
if (!context) {
const pages = getCurrentPages();
const page = pages[pages.length - 1];
context = page.$$basePage || page;
}
const instance = context?.selectComponent(selector);
if (!instance) {
console.warn('未找到toast组件,请检查selector是否正确');
return null;
}
return instance;
};

function Toast(options: ToastOptionsType) {
const { context, selector, ...Options } = options;
const { context, selector = '#t-toast', ...Options } = options;
const instance = getInstance(context, selector);
if (instance) {
instance.show({
Expand All @@ -42,12 +30,12 @@ function Toast(options: ToastOptionsType) {
}
}

function showToast(options: ToastOptionsType) {
function showToast(options: ToastOptionsType = {}) {
Toast(options);
}

function hideToast(options: ToastOptionsType) {
const { context, selector } = options;
function hideToast(options: ToastOptionsType = {}) {
const { context, selector = '#t-toast' } = options;
const instance = getInstance(context, selector);
if (instance) {
instance.hide();
Expand Down
103 changes: 41 additions & 62 deletions src/toast/toast.less
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
@import '../common/style/index.less';

.@{prefix}-toast {
position: fixed;
right: -50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 12001;
opacity: 1;
transition: opacity 300ms ease;
background-color: rgba(0, 0, 0, 0.6);
border-radius: 8rpx;
font-size: 28rpx;
color: white;
max-width: 374rpx;
width: fit-content;
box-sizing: border-box;

&--column {
padding: 48rpx;
min-width: 272rpx;
min-height: 260rpx;
border-radius: 16rpx;
}

&__content {
position: fixed;
right: -50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0, 0, 0, 0.6);
align-items: center;
border-radius: 8rpx;
font-size: 28rpx;
color: white;
max-width: 374rpx;
width: fit-content;
line-height: 44rpx;
box-sizing: border-box;
z-index: 12001;
}

&__row {
display: flex;
text-align: left;
padding: 28rpx 44rpx;

&-text {
margin-left: 12rpx;
&--row {
display: flex;
text-align: left;
padding: 28rpx 44rpx;
}

&-icon {
&--column {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
}

&__column {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 48rpx;
min-width: 260rpx;
min-height: 260rpx;
border-radius: 16rpx;

&-text {
margin-top: 24rpx;
&__icon {
&--row {
display: flex;
}
}

Expand All @@ -53,39 +53,18 @@
-webkit-line-clamp: 3;
display: -webkit-box;
-webkit-box-orient: vertical;
}

&--enter {
animation: fade-enter 0.5s;
}

&--leave {
animation: fade-leave 0.5s;
}
}

@keyframes fade-enter {
from {
opacity: 0;
}
}

@keyframes fade-leave {
to {
opacity: 0;
}
}
&--column {
margin-top: 24rpx;
}

@keyframes scale-enter {
from {
opacity: 0;
transform: translate3d(-50%, -50%, 0) scale(0.9);
&--row {
margin-left: 12rpx;
}
}
}

@keyframes scale-leave {
to {
&.@{prefix}-fade-enter,
&.@{prefix}-fade-leave-to {
opacity: 0;
transform: translate3d(-50%, -50%, 0) scale(0.9);
}
}
35 changes: 11 additions & 24 deletions src/toast/toast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { SuperComponent, wxComponent } from '../common/src/index';
import config from '../common/config';
import props from './props';
import { ToastOptionsType } from './index';
import transition from '../mixins/transition';

const { prefix } = config;
const name = `${prefix}-toast`;
Expand All @@ -10,19 +11,18 @@ type Timer = NodeJS.Timeout | null;

@wxComponent()
export default class Toast extends SuperComponent {
externalClasses = ['t-class'];
externalClasses = [`${prefix}-class`];

options = {
multipleSlots: true, // 在组件定义时的选项中启用多slot支持
};

hideTimer: Timer = null;
behaviors = [transition()];

removeTimer: Timer = null;
hideTimer: Timer = null;

data = {
inserted: false,
show: false,
prefix,
classPrefix: name,
typeMapIcon: '',
};
Expand All @@ -36,7 +36,6 @@ export default class Toast extends SuperComponent {
methods = {
show(options: ToastOptionsType) {
if (this.hideTimer) clearTimeout(this.hideTimer);
if (this.removeTimer) clearTimeout(this.removeTimer);
const iconMap = {
loading: 'loading',
success: 'check-circle',
Expand All @@ -56,38 +55,26 @@ export default class Toast extends SuperComponent {
const data = {
...defaultOptions,
...options,
show: true,
visible: true,
typeMapIcon,
inserted: true,
};
const { duration } = data;
this.setData(data);

if (duration > 0) {
this.hideTimer = setTimeout(() => {
this.clear();
this.hide();
}, duration);
}
},

hide() {
this.clear();
},
clear() {
this.setData({ show: false });
this.removeTimer = setTimeout(() => {
this.setData({
inserted: false,
});
this.data?.close?.();
this.triggerEvent('close');
}, 300);
this.setData({ visible: false });
this.data?.close?.();
this.triggerEvent('close');
},

destroyed() {
if (this.removeTimer) {
clearTimeout(this.removeTimer);
this.removeTimer = null;
}
if (this.hideTimer) {
clearTimeout(this.hideTimer);
this.hideTimer = null;
Expand Down
33 changes: 17 additions & 16 deletions src/toast/toast.wxml
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
<block>
<view
wx:if="{{inserted}}"
class="{{classPrefix}}__content t-class {{classPrefix + '__' + direction}} {{classPrefix + '--' + show ? 'enter' : 'leave'}}"
style="top: {{placement === 'top' ? '25%' : placement === 'bottom' ? '75%': '45%'}}"
>
<view
wx:if="{{realVisible}}"
class="{{classPrefix}} {{prefix}}-class {{transitionClass}} {{classPrefix}}--{{direction}}"
style="top: {{placement === 'top' ? '25%' : placement === 'bottom' ? '75%': '45%'}}"
bind:transitionend="onTransitionEnd"
>
<view class="{{classPrefix}}__content {{classPrefix}}__content--{{direction}}">
<t-icon
wx:if="{{typeMapIcon!=='loading' || icon}}"
name="{{typeMapIcon || icon}}"
class="{{classPrefix + '__' + direction}}-icon"
color="#ffffff"
class="{{classPrefix}}__icon {{classPrefix}}__icon--{{direction}}"
color="#fff"
size="{{direction === 'row' ? '42rpx' : '96rpx'}}"
/>
<t-loading
Expand All @@ -21,15 +22,15 @@
layout="vertical"
/>
<slot name="icon" />
<view class="{{classPrefix}}__text {{typeMapIcon || icon ? classPrefix + '__' + direction + '-text' : ''}}"
<view class="{{classPrefix}}__text {{typeMapIcon || icon ? classPrefix + '__text--' + direction : ''}}"
>{{message}}</view
>
<slot name="message" />
</view>
<t-overlay
visible="{{inserted && (showOverlay || preventScrollThrough)}}"
z-index="{{overlayProps.zIndex}}"
backgroundColor="{{preventScrollThrough ? 'transparent' : overlayProps.backgroundColor}}"
preventScrollThrough="{{preventScrollThrough || overlayProps.preventScrollThrough}}"
/>
</block>
</view>
<t-overlay
visible="{{realVisible && (showOverlay || preventScrollThrough)}}"
z-index="{{overlayProps.zIndex}}"
backgroundColor="{{preventScrollThrough ? 'transparent' : overlayProps.backgroundColor}}"
preventScrollThrough="{{preventScrollThrough || overlayProps.preventScrollThrough}}"
/>

0 comments on commit ce07d58

Please sign in to comment.