UNPKG

7.73 kBTypeScriptView Raw
1import { ComponentType } from 'react'
2import { StandardProps, CommonEventFunction } from './common'
3interface ShareElementProps extends StandardProps {
4 /** 映射标记
5 * @supported weapp
6 */
7 key?: string
8
9 /** 映射标记
10 * @supported alipay
11 */
12 name?: string
13
14 /** 是否进行动画
15 * @default false
16 * @supported weapp, alipay
17 */
18 transform?: boolean
19
20 /** 动画时长,单位毫秒
21 * @default 300
22 * @supported weapp, alipay
23 */
24 duration?: number
25
26 /** css缓动函数
27 * @default ease-out
28 * @supported weapp, alipay
29 */
30 easingFunction?: string
31}
32
33/** 共享元素
34 *
35 * 共享元素是一种动画形式,类似于 [`flutter Hero`](https://flutterchina.club/animations/hero-animations/) 动画,表现为元素像是在页面间穿越一样。该组件需与 [`PageContainer`](/docs/components/viewContainer/page-container) 组件结合使用。
36 * 使用时需在当前页放置 `ShareElement` 组件,同时在 `PageContainer` 容器中放置对应的 `ShareElement` 组件,对应关系通过属性值 key 映射。当设置 `PageContainer` `显示时,transform` 属性为 `true` 的共享元素会产生动画。当前页面容器退出时,会产生返回动画。
37 * @classification viewContainer
38 * @supported weapp, alipay
39 * @example_react
40 * ```tsx
41 * // index.js
42 * import { useState, useCallback } from 'react'
43 * import { View, Button, PageContainer, ShareElement } from '@tarojs/components'
44 *
45 * import './index.scss'
46 *
47 * const contacts = [
48 * { id: 1, name: 'Frank', img: 'frank.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
49 * { id: 2, name: 'Susan', img: 'susan.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
50 * { id: 3, name: 'Emma', img: 'emma.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
51 * { id: 4, name: 'Scott', img: 'scott.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
52 * { id: 5, name: 'Bob', img: 'bob.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
53 * { id: 6, name: 'Olivia', img: 'olivia.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
54 * { id: 7, name: 'Anne', img: 'anne.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
55 * { id: 8, name: 'sunny', img: 'olivia.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' }
56 * ]
57 *
58 * export default function () {
59 * const [show, setShow] = useState(false)
60 * const [contact, setContact] = useState(contacts[0])
61 * const [transformIdx, setTransformIdx] = useState(0)
62 *
63 * const onBeforeEnter = useCallback((res) => {
64 * console.log('onBeforeEnter: ', res)
65 * }, [])
66 * const onEnter = useCallback((res) => {
67 * console.log('onEnter: ', res)
68 * }, [])
69 * const onAfterEnter = useCallback((res) => {
70 * console.log('onAfterEnter: ', res)
71 * }, [])
72 * const onBeforeLeave = useCallback((res) => {
73 * console.log('onBeforeLeave: ', res)
74 * }, [])
75 * const onLeave = useCallback((res) => {
76 * console.log('onLeave: ', res)
77 * }, [])
78 * const onAfterLeave = useCallback((res) => {
79 * console.log('onAfterLeave: ', res)
80 * }, [])
81 *
82 * const showNext = (e, index) => {
83 * setShow(true)
84 * setContact(contacts[index])
85 * setTransformIdx(index)
86 * }
87 *
88 * const showPrev = useCallback(() => {
89 * setShow(false)
90 * }, [])
91 *
92 * return (
93 * <View>
94 * <View className="screen screen1">
95 * {
96 * contacts.map((item, index) => (
97 * <View key={item.id} className="contact" onClick={e => showNext(e, index)}>
98 * <ShareElement duration={300} className="name" mapkey="name" transform={transformIdx === index}>
99 * {item.name}
100 * </ShareElement>
101 * <View className="list">
102 * <View>Phone: {item.phone}</View>
103 * <View>Mobile: {item.mobile}</View>
104 * <View>Email: {item.email}</View>
105 * </View>
106 * </View>
107 * ))
108 * }
109 * </View>
110 * <PageContainer
111 * show={show}
112 * overlay={false}
113 * closeOnSlideDown
114 * duration={300}
115 * position='center'
116 * onBeforeEnter={onBeforeEnter}
117 * onEnter={onEnter}
118 * onAfterEnter={onAfterEnter}
119 * onBeforeLeave={onBeforeLeave}
120 * onLeave={onLeave}
121 * onAfterLeave={onAfterLeave}
122 * >
123 * <View className="screen screen2">
124 * <View className="contact">
125 * <ShareElement className="name" mapkey="name" duration={300} transform>
126 * {contact.name}
127 * </ShareElement>
128 * <View className={`paragraph ${show ? 'enter' : ''}`}>
129 * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus nisl enim, sodales non augue efficitur, sagittis
130 * varius neque. Fusce dolor turpis, maximus eu volutpat quis, pellentesque et ligula. Ut vehicula metus in nibh
131 * mollis ornare. Etiam aliquam lacinia malesuada. Vestibulum dignissim mollis quam a tristique. Maecenas neque
132 * mauris, malesuada vitae magna eu, congue consectetur risus. Etiam vitae pulvinar ex. Maecenas suscipit mi ac
133 * imperdiet pretium. Aliquam velit mauris, euismod quis elementum sed, malesuada non dui. Nunc rutrum sagittis
134 * ligula in dapibus. Cras suscipit ut augue eget mollis. Donec auctor feugiat ipsum id viverra. Vestibulum eu nisi
135 * risus. Vestibulum eleifend dignissim.
136 *
137 * </View>
138 * <Button className="screen2-button" onClick={showPrev} hidden={!show} hoverClass="none">Click Me</Button>
139 * </View>
140 * </View>
141 * </PageContainer>
142 * </View>
143 * )
144 * }
145 * ```
146 * ```scss
147 * \/** index.scss *\/
148 * page {
149 * color: #333;
150 * background-color: #ddd;
151 * overflow: hidden;
152 * }
153 *
154 * button {
155 * border: 0 solid #0010ae;
156 * background-color: #1f2afe;
157 * color: #fff;
158 * font-size: 120%;
159 * padding: 8px 16px;
160 * outline-width: 0;
161 * -webkit-appearance: none;
162 * box-shadow: 0 8px 17px rgba(0, 0, 0, 0.2);
163 * }
164 *
165 * .screen {
166 * position: absolute;
167 * top: 0;
168 * bottom: 0;
169 * left: 0;
170 * right: 0;
171 * padding: 16px;
172 * -webkit-overflow-scrolling: touch;
173 * }
174 *
175 * .contact {
176 * position: relative;
177 * padding: 16px;
178 * background-color: #fff;
179 * width: 100%;
180 * height: 100%;
181 * box-sizing: border-box;
182 * }
183 *
184 * .avatar {
185 * position: absolute;
186 * top: 16px;
187 * left: 16px;
188 * font-size: 0;
189 * }
190 *
191 * .name {
192 * height: 65px;
193 * font-size: 2em;
194 * font-weight: bold;
195 * text-align: center;
196 * margin: 10px 0;
197 * }
198 *
199 * .list {
200 * padding-top: 8px;
201 * padding-left: 32px;
202 * }
203 *
204 * .screen1 {
205 * overflow-y: scroll;
206 * padding: 0;
207 * }
208 *
209 * .screen1 .contact {
210 * margin: 16px;
211 * height: auto;
212 * width: auto;
213 * box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.2);
214 * }
215 *
216 * .screen2-button {
217 * display: block;
218 * margin: 24px auto;
219 * }
220 *
221 * .paragraph {
222 * -webkit-transition: transform ease-in-out 300ms;
223 * transition: transform ease-in-out 300ms;
224 * -webkit-transform: scale(0.6);
225 * transform: scale(0.6);
226 * }
227 *
228 * .enter.paragraph {
229 * transform: none;
230 * }
231 * ```
232 * @see https://developers.weixin.qq.com/miniprogram/dev/component/share-element.html
233 */
234declare const ShareElement: ComponentType<ShareElementProps>
235export { ShareElement, ShareElementProps }