UNPKG

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