-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
682 additions
and
0 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
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,87 @@ | ||
# Toast 轻提示 | ||
|
||
<code hidden="hidden" src="./demos/demo.tsx"></code> | ||
|
||
## 介绍 | ||
对操作结果的轻量级反馈,适用于页面内容的变化不能直接反应操作结果时使用。 | ||
|
||
## 使用 | ||
|
||
```tsx | ||
import { Toast } from 'aunt'; | ||
``` | ||
|
||
### 基本用法 | ||
通过调用`Toast` 方法进行展示提示。 | ||
<code src="./demos/demo-base.tsx"></code> | ||
|
||
### 自定义图标 | ||
可通过`icon` 传入相关内容在自定义图标,可传入图片。 | ||
<code src="./demos/demo-icon.tsx"></code> | ||
|
||
### 横向排布 | ||
通过`direction`属性设置展示的布局,可选`horizontal`进行横向排布。 | ||
<code src="./demos/demo-direction.tsx"></code> | ||
|
||
### 自定义位置 | ||
通过`position`属性设置展示的位置。 | ||
<code src="./demos/demo-position.tsx"></code> | ||
|
||
## 参数 | ||
| 参数 | 说明 | 类型 | 默认值 | | ||
| --------- | -------------- | ---------- | --------- | | ||
| type | 提示类型 | `'loading' \| 'success' \| 'fail' \| 'info'` | `info` | | ||
| message | 文本内容,支持通过\n换行 | `number \| string` | `-` | | ||
| duration | 展示时长(ms),值为 0 时,toast 不会消失 | `number` | `3000` | | ||
| icon | 自定义图标 | `React.ReactNode` | `-` | | ||
| iconSize | 展示时长(ms),值为 0 时,toast 不会消失 | `number \| string \| ((direction: ToastDirection) => number \| string)` | `-` | | ||
| loadingType | 展示时长(ms),值为 0 时,toast 不会消失 | `LoadingType` | `gap` | | ||
| direction | 图标和文字的排列方式 | `'vertical' \| 'horizontal'` | `vertical` | | ||
| forbidClick | 是否禁止背景点击 | `boolean` | `false` | | ||
| position | 位置,可选值为 top bottom | `'top' \| 'center' \| 'bottom'` | `center` | | ||
| teleport | 轻提示弹出时的的父容器 | `HTMLElement \| (() => HTMLElement)` | `body` | | ||
| onClose | 关闭时的回调函数 | `() => void` | `-` | | ||
| onOpened | 完全展示后的回调函数 | `() => void` | `-` | | ||
|
||
```tsx | ||
const iconSize = (direction: ToastDirection)=>{ | ||
if(direction === 'horizontal') return 20; | ||
return 34; | ||
} | ||
``` | ||
|
||
## 方法 | ||
| 方法名 | 说明 | 参数 | 返回值 | | ||
| --- | --- | --- | --- | | ||
| Toast | 展示提示 | `options \| message` | toast 实例 | | ||
| Toast.info | 展示文字提示 | `options \| message` | toast 实例 | | ||
| Toast.loading | 展示加载提示 | `options \| message` | toast 实例 | | ||
| Toast.success | 展示成功提示 | `options \| message` | toast 实例 | | ||
| Toast.fail | 展示失败提示 | `options \| message` | toast 实例 | | ||
| Toast.clear | 关闭提示 | `-` | `void` | | ||
| Toast.allowMultiple | 允许同时存在多个 Toast | `-` | `void` | | ||
| Toast.setDefaultOptions | 修改默认配置,对所有 Toast 生效。<br>传入 type 可以修改指定类型的默认配置 | `options` | `void` | | ||
| Toast.resetDefaultOptions | 重置默认配置,对所有 Toast 生效。<br>传入 type 可以重置指定类型的默认配置 | `-` | `void` | | ||
|
||
```tsx | ||
// toast 实例 | ||
export type ToastReturnType = { | ||
/** 动态更新方法 */ | ||
config: React.Dispatch<React.SetStateAction<ToastProps>> | ||
/** 清除单例toast */ | ||
clear: () => void | ||
} | ||
``` | ||
## 样式变量 | ||
| 属性名 | 说明 | 默认值 | | ||
| ---------------- | -------- | --------- | | ||
| --aunt-toast-z-index | 显示层级 | `var(--aunt-z-index-full-screen);` | | ||
| --aunt-toast-content-background-color | 背景颜色| `rgba(0,0,0,.8);` | | ||
| --aunt-toast-content-padding | 默认内边距| `var(--aunt-padding-base) var(--aunt-padding-s);` | | ||
| --aunt-toast-content-border-radius | 默认圆角| `var(--aunt-border-radius-md);` | | ||
| --aunt-toast-content-color | 默认字体颜色| `var(--aunt-white-color);` | | ||
| --aunt-toast-content-top | 默认Top高度| `20%;` | | ||
| --aunt-toast-content-bottom | 默认Bottom高度| `20%;` | | ||
| --aunt-toast-content-text-size | 文字大小| `var(--aunt-font-size-sm);` | | ||
| --aunt-toast-content-text-margin-left | 横行排布的文字左外边距 | `var(--aunt-padding-base);` | |
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,178 @@ | ||
import React, { useEffect, useState, useCallback } from 'react'; | ||
import type { ToastType, ToastOptions, ToastProps, ToastInstance, ToastReturnType } from './types'; | ||
import Transition from '../transition'; | ||
import { Toast as BaseToast } from './toast'; | ||
import { isObject } from '../../utils'; | ||
import { render, unmount } from '../../utils/dom/render'; | ||
import { resolveContainer } from '../../utils/dom/getContainer'; | ||
|
||
const currentOptions: { [key: string]: ToastOptions } = {}; | ||
|
||
function parseOptions(message: string | ToastOptions): ToastOptions { | ||
return isObject(message) ? message : { message }; | ||
} | ||
|
||
const toastArray: (() => void)[] = []; | ||
|
||
// 同步的销毁 | ||
function syncClear() { | ||
let fn = toastArray.pop(); | ||
while (fn) { | ||
fn(); | ||
fn = toastArray.pop(); | ||
} | ||
} | ||
|
||
// 针对 toast 还没弹出来就立刻销毁的情况,将销毁放到下一个 event loop 中,避免销毁失败。 | ||
function nextTickClear() { | ||
setTimeout(syncClear); | ||
} | ||
|
||
const show = (p: ToastProps | string) => { | ||
const props = parseOptions(p); | ||
const update: ToastReturnType = { | ||
config: () => {}, | ||
clear: () => null, | ||
}; | ||
// 创建父亲节点 | ||
const userContainer = resolveContainer(props.teleport); | ||
const container = document.createElement('div'); | ||
userContainer.appendChild(container); | ||
|
||
// 定时器 | ||
let timer = 0; | ||
|
||
const TempNotify = () => { | ||
const options = { | ||
...props, | ||
}; | ||
const [state, setState] = useState<ToastProps>({ ...options }); | ||
const [visible, setVisible] = useState(false); | ||
|
||
const destroy = useCallback(() => { | ||
setVisible(false); | ||
if (props.onClose) props.onClose(); | ||
}, []); | ||
|
||
const internalOnClosed = useCallback(() => { | ||
const unmountResult = unmount(container); | ||
if (unmountResult && container.parentNode) { | ||
container.parentNode.removeChild(container); | ||
} | ||
}, [container]); | ||
|
||
update.clear = internalOnClosed; | ||
|
||
update.config = useCallback( | ||
nextState => { | ||
setState(prev => | ||
typeof nextState === 'function' | ||
? { ...prev, ...nextState(prev) } | ||
: { ...prev, ...nextState } | ||
); | ||
}, | ||
[setState] | ||
); | ||
|
||
useEffect(() => { | ||
setVisible(true); | ||
syncClear(); | ||
toastArray.push(internalOnClosed); | ||
|
||
if (state.duration && +state.duration > 0) { | ||
timer = window.setTimeout(destroy, state.duration); | ||
} | ||
|
||
return () => { | ||
if (timer !== 0) { | ||
window.clearTimeout(timer); | ||
} | ||
}; | ||
}, []); | ||
|
||
return ( | ||
<Transition in={visible} onEntered={props.onOpened} onExited={props.onClose}> | ||
<BaseToast {...state} /> | ||
</Transition> | ||
); | ||
}; | ||
|
||
render(<TempNotify />, container); | ||
|
||
return update; | ||
}; | ||
|
||
const defaultOptions: ToastOptions = { | ||
message: '', | ||
duration: 3000, | ||
direction: 'vertical', | ||
loadingType: 'gap', | ||
position: 'center', | ||
}; | ||
|
||
['info', 'loading', 'success', 'fail'].forEach(method => { | ||
currentOptions[method] = defaultOptions; | ||
}); | ||
|
||
const setDefaultOptions = (type: ToastType, options: ToastOptions) => { | ||
currentOptions[type] = Object.assign(currentOptions[type], options); | ||
}; | ||
|
||
// 重置配置 | ||
const resetDefaultOptions = (type: ToastType) => { | ||
currentOptions[type] = { ...defaultOptions }; | ||
}; | ||
|
||
const clear = nextTickClear; | ||
|
||
const ToastDefault = (options: ToastProps | string) => { | ||
let type: ToastType = 'info'; | ||
if (typeof options !== 'string') { | ||
type = options.type || 'info'; | ||
} | ||
return show({ | ||
type: type, | ||
...currentOptions[type], | ||
...parseOptions(options), | ||
}); | ||
}; | ||
|
||
const info = (options: ToastOptions | string) => | ||
show({ | ||
...currentOptions['info'], | ||
...parseOptions(options), | ||
type: 'info', | ||
}); | ||
|
||
const fail = (options: ToastOptions | string) => | ||
show({ | ||
...currentOptions['fail'], | ||
...parseOptions(options), | ||
type: 'fail', | ||
}); | ||
|
||
const success = (options: ToastOptions | string) => | ||
show({ | ||
...currentOptions['success'], | ||
...parseOptions(options), | ||
type: 'success', | ||
}); | ||
|
||
const loading = (options: ToastOptions | string) => | ||
show({ | ||
...currentOptions['loading'], | ||
...parseOptions(options), | ||
type: 'loading', | ||
}); | ||
|
||
const ToastController: ToastInstance = Object.assign(ToastDefault, { | ||
setDefaultOptions, | ||
resetDefaultOptions, | ||
clear, | ||
info, | ||
fail, | ||
loading, | ||
success, | ||
}); | ||
|
||
export default ToastController; |
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,21 @@ | ||
import React from 'react'; | ||
import { Space, Button, Toast } from 'aunt'; | ||
|
||
export default () => { | ||
return ( | ||
<Space wrap direction='vertical' style={{ width: '100%' }}> | ||
<Button type='primary' block onClick={() => Toast('文字提示')}> | ||
文字提示 | ||
</Button> | ||
<Button type='success' block onClick={() => Toast.success('成功提示')}> | ||
成功提示 | ||
</Button> | ||
<Button type='danger' block onClick={() => Toast.fail('失败提示')}> | ||
失败提示 | ||
</Button> | ||
<Button type='warning' block onClick={() => Toast.loading('加载提示')}> | ||
加载提示 | ||
</Button> | ||
</Space> | ||
); | ||
}; |
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,45 @@ | ||
import React from 'react'; | ||
import { Space, Button, Toast } from 'aunt'; | ||
|
||
export default () => { | ||
return ( | ||
<Space wrap direction='vertical' style={{ width: '100%' }}> | ||
<Button | ||
type='success' | ||
block | ||
onClick={() => | ||
Toast.success({ | ||
message: '成功提示', | ||
direction: 'horizontal', | ||
}) | ||
} | ||
> | ||
成功提示 | ||
</Button> | ||
<Button | ||
type='danger' | ||
block | ||
onClick={() => | ||
Toast.fail({ | ||
message: '失败提示', | ||
direction: 'horizontal', | ||
}) | ||
} | ||
> | ||
失败提示 | ||
</Button> | ||
<Button | ||
type='warning' | ||
block | ||
onClick={() => | ||
Toast.loading({ | ||
message: '加载提示', | ||
direction: 'horizontal', | ||
}) | ||
} | ||
> | ||
加载提示 | ||
</Button> | ||
</Space> | ||
); | ||
}; |
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,48 @@ | ||
import React from 'react'; | ||
import { Space, Button, Toast, AuntIconCheckCircle, AuntIconXCircle } from 'aunt'; | ||
|
||
export default () => { | ||
return ( | ||
<Space wrap direction='vertical' style={{ width: '100%' }}> | ||
<Button | ||
type='success' | ||
block | ||
onClick={() => | ||
Toast.success({ | ||
message: '成功提示', | ||
icon: <AuntIconCheckCircle />, | ||
}) | ||
} | ||
> | ||
成功提示 | ||
</Button> | ||
<Button | ||
type='danger' | ||
block | ||
onClick={() => | ||
Toast.fail({ | ||
message: '失败提示', | ||
icon: <AuntIconXCircle />, | ||
}) | ||
} | ||
> | ||
失败提示 | ||
</Button> | ||
<Button | ||
type='warning' | ||
block | ||
onClick={() => | ||
Toast.loading({ | ||
message: '加载提示', | ||
loadingType: 'bars', | ||
}) | ||
} | ||
> | ||
加载提示 | ||
</Button> | ||
<Button type='primary' block onClick={() => Toast.loading({})}> | ||
单图标模式 | ||
</Button> | ||
</Space> | ||
); | ||
}; |
Oops, something went wrong.