From d1448cb0ef10f358bb7bddb4e1ec268515e0b787 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 15 七月 2025 11:46:57 +0800
Subject: [PATCH] 项目初始化

---
 uni_modules/uview-ui/components/u-tooltip/u-tooltip.vue |  365 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 365 insertions(+), 0 deletions(-)

diff --git a/uni_modules/uview-ui/components/u-tooltip/u-tooltip.vue b/uni_modules/uview-ui/components/u-tooltip/u-tooltip.vue
new file mode 100644
index 0000000..986829c
--- /dev/null
+++ b/uni_modules/uview-ui/components/u-tooltip/u-tooltip.vue
@@ -0,0 +1,365 @@
+<template>
+	<view
+		class="u-tooltip"
+		:style="[$u.addStyle(customStyle)]"
+	>
+		<u-overlay
+			:show="showTooltip && tooltipTop !== -10000 && overlay"
+			customStyle="backgroundColor: rgba(0, 0, 0, 0)"
+			@click="overlayClickHandler"
+		></u-overlay>
+		<view class="u-tooltip__wrapper">
+			<text
+				class="u-tooltip__wrapper__text"
+				:id="textId"
+				:ref="textId"
+				:userSelect="false"
+				:selectable="false"
+				@longpress.stop="longpressHandler"
+				:style="{
+					backgroundColor: bgColor && showTooltip && tooltipTop !== -10000 ? bgColor : 'transparent'
+				}"
+			>{{ text }}</text>
+			<u-transition
+				mode="fade"
+				:show="showTooltip"
+				duration="300"
+				:customStyle="{
+					position: 'absolute', 
+					top: $u.addUnit(tooltipTop),
+					zIndex: zIndex,
+					...tooltipStyle
+				}"
+			>
+				<view
+					class="u-tooltip__wrapper__popup"
+					:id="tooltipId"
+					:ref="tooltipId"
+				>
+					<view
+						class="u-tooltip__wrapper__popup__indicator"
+						hover-class="u-tooltip__wrapper__popup__indicator--hover"
+						v-if="showCopy || buttons.length"
+						:style="[indicatorStyle, {
+							width: $u.addUnit(indicatorWidth),
+							height: $u.addUnit(indicatorWidth),
+						}]"
+					>
+						<!-- 鐢变簬nvue涓嶆敮鎸佷笁瑙掑舰缁樺埗锛岃繖閲屽氨鍋氫竴涓洓鏂瑰舰锛屽啀鏃嬭浆45deg锛屽緱鍒伴湶鍑虹殑涓�涓笁瑙� -->
+					</view>
+					<view class="u-tooltip__wrapper__popup__list">
+						<view
+							v-if="showCopy"
+							class="u-tooltip__wrapper__popup__list__btn"
+							hover-class="u-tooltip__wrapper__popup__list__btn--hover"
+							@tap="setClipboardData"
+						>
+							<text
+								class="u-tooltip__wrapper__popup__list__btn__text"
+							>澶嶅埗</text>
+						</view>
+						<u-line
+							direction="column"
+							color="#8d8e90"
+							v-if="showCopy && buttons.length > 0"
+							length="18"
+						></u-line>
+						<block v-for="(item , index) in buttons" :key="index">
+							<view
+								class="u-tooltip__wrapper__popup__list__btn"
+								hover-class="u-tooltip__wrapper__popup__list__btn--hover"
+							>
+								<text
+									class="u-tooltip__wrapper__popup__list__btn__text"
+									@tap="btnClickHandler(index)"
+								>{{ item }}</text>
+							</view>
+							<u-line
+								direction="column"
+								color="#8d8e90"
+								v-if="index < buttons.length - 1"
+								length="18"
+							></u-line>
+						</block>
+					</view>
+				</view>
+			</u-transition>
+		</view>
+	</view>
+</template>
+
+<script>
+	import props from './props.js';
+	// #ifdef APP-NVUE 
+	const dom = uni.requireNativePlugin('dom')
+	// #endif
+	// #ifdef H5
+	import ClipboardJS from "./clipboard.min.js"
+	// #endif
+	/**
+	 * Tooltip 
+	 * @description 
+	 * @tutorial https://www.uviewui.com/components/tooltip.html
+	 * @property {String | Number}	text		闇�瑕佹樉绀虹殑鎻愮ず鏂囧瓧
+	 * @property {String | Number}	copyText	鐐瑰嚮澶嶅埗鎸夐挳鏃讹紝澶嶅埗鐨勬枃鏈紝涓虹┖鍒欎娇鐢╰ext鍊�
+	 * @property {String | Number}	size		鏂囨湰澶у皬锛堥粯璁� 14 锛�
+	 * @property {String}			color		瀛椾綋棰滆壊锛堥粯璁� '#606266' 锛�
+	 * @property {String}			bgColor		寮瑰嚭鎻愮ず妗嗘椂锛屾枃鏈殑鑳屾櫙鑹诧紙榛樿 'transparent' 锛�
+	 * @property {String}			direction	寮瑰嚭鎻愮ず鐨勬柟鍚戯紝top-涓婃柟锛宐ottom-涓嬫柟锛堥粯璁� 'top' 锛�
+	 * @property {String | Number}	zIndex		寮瑰嚭鎻愮ず鐨剒-index锛宯vue鏃犳晥锛堥粯璁� 10071 锛�
+	 * @property {Boolean}			showCopy	鏄惁鏄剧ず澶嶅埗鎸夐挳锛堥粯璁� true 锛�
+	 * @property {Array}			buttons		鎵╁睍鐨勬寜閽粍
+	 * @property {Boolean}			overlay		鏄惁鏄剧ず閫忔槑閬僵浠ラ槻姝㈣Е鎽哥┛閫忥紙榛樿 true 锛�
+	 * @property {Object}			customStyle	瀹氫箟闇�瑕佺敤鍒扮殑澶栭儴鏍峰紡
+	 * 
+	 * @event {Function} 
+	 * @example 
+	 */
+	export default {
+		name: 'u-tooltip',
+		mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
+		data() {
+			return {
+				// 鏄惁灞曠ず姘旀场
+				showTooltip: true,
+				// 鐢熸垚鍞竴id锛岄槻姝竴涓〉闈㈠涓粍浠讹紝閫犳垚骞叉壈
+				textId: uni.$u.guid(),
+				tooltipId: uni.$u.guid(),
+				// 鍒濆鏃剁敋鑷充负寰堝ぇ鐨勫�硷紝璁╁叾绉诲埌灞忓箷澶栭潰锛屼负浜嗚绠楀厓绱犵殑灏哄
+				tooltipTop: -10000,
+				// 姘旀场鐨勪綅缃俊鎭�
+				tooltipInfo: {
+					width: 0,
+					left: 0
+				},
+				// 鏂囨湰鐨勪綅缃俊鎭�
+				textInfo: {
+					width: 0,
+					left: 0
+				},
+				// 涓夎褰㈡寚绀哄櫒鐨勬牱寮�
+				indicatorStyle: {},
+				// 姘旀场鍦ㄥ彲鑳借秴鍑哄睆骞曡竟娌胯寖鍥存椂锛岄噸鏂板畾浣嶅悗锛岃窛绂诲睆骞曡竟娌跨殑璺濈
+				screenGap: 12,
+				// 涓夎褰㈡寚绀哄櫒鐨勫楂橈紝鐢变簬瀵瑰厓绱犺繘琛屼簡瑙掑害鏃嬭浆锛岀簿纭绠楁寚绀哄櫒浣嶇疆鏃讹紝闇�瑕佺敤鍒板叾灏哄淇℃伅
+				indicatorWidth: 14,
+			}
+		},
+		watch: {
+			propsChange() {
+				this.getElRect()
+			}
+		},
+		computed: {
+			// 鐗瑰埆澶勭悊H5鐨勫鍒讹紝鍥犱负H5娴忚鍣ㄦ槸鑷甫绯荤粺澶嶅埗鍔熻兘鐨勶紝鍦℉5鐜
+			// 褰撲竴浜涗緷璧栧弬鏁板彉鍖栨椂锛岄渶瑕侀噸鏂拌绠楁皵娉″拰鎸囩ず鍣ㄧ殑浣嶇疆淇℃伅
+			propsChange() {
+				return [this.text, this.buttons]
+			},
+			// 璁$畻姘旀场鍜屾寚绀哄櫒鐨勪綅缃俊鎭�
+			tooltipStyle() {
+				const style = {
+						transform: `translateY(${this.direction === 'top' ? '-100%' : '100%'})`,
+					},
+					sys = uni.$u.sys(),
+					getPx = uni.$u.getPx,
+					addUnit = uni.$u.addUnit
+				if (this.tooltipInfo.width / 2 > this.textInfo.left + this.textInfo.width / 2 - this.screenGap) {
+					this.indicatorStyle = {}
+					style.left = `-${addUnit(this.textInfo.left - this.screenGap)}`
+					this.indicatorStyle.left = addUnit(this.textInfo.width / 2 - getPx(style.left) - this.indicatorWidth /
+						2)
+				} else if (this.tooltipInfo.width / 2 > sys.windowWidth - this.textInfo.right + this.textInfo.width / 2 -
+					this.screenGap) {
+					this.indicatorStyle = {}
+					style.right = `-${addUnit(sys.windowWidth - this.textInfo.right - this.screenGap)}`
+					this.indicatorStyle.right = addUnit(this.textInfo.width / 2 - getPx(style.right) - this
+						.indicatorWidth / 2)
+				} else {
+					const left = Math.abs(this.textInfo.width / 2 - this.tooltipInfo.width / 2)
+					style.left = this.textInfo.width > this.tooltipInfo.width ? addUnit(left) : -addUnit(left)
+					this.indicatorStyle = {}
+				}
+				if (this.direction === 'top') {
+					style.marginTop = '-10px'
+					this.indicatorStyle.bottom = '-4px'
+				} else {
+					style.marginBottom = '-10px'
+					this.indicatorStyle.top = '-4px'
+				}
+				return style
+			}
+		},
+		mounted() {
+			this.init()
+		},
+		methods: {
+			init() {
+				this.getElRect()
+			},
+			// 闀挎寜瑙﹀彂浜嬩欢
+			async longpressHandler() {
+				this.tooltipTop = 0
+				this.showTooltip = true
+			},
+			// 鐐瑰嚮閫忔槑閬僵
+			overlayClickHandler() {
+				this.showTooltip = false
+			},
+			// 鐐瑰嚮寮瑰嚭鎸夐挳
+			btnClickHandler(index) {
+				this.showTooltip = false
+				// 濡傛灉闇�瑕佸睍绀哄鍒舵寜閽紝姝ゅindex闇�瑕佸姞1锛屽洜涓哄鍒舵寜閽湪绗竴涓綅缃�
+				this.$emit('click', this.showCopy ? index + 1 : index)
+			},
+			// 鏌ヨ鍐呭楂樺害
+			queryRect(ref) {
+				// #ifndef APP-NVUE
+				// $uGetRect涓簎View鑷甫鐨勮妭鐐规煡璇㈢畝鍖栨柟娉曪紝璇﹁鏂囨。浠嬬粛锛歨ttps://www.uviewui.com/js/getRect.html
+				// 缁勪欢鍐呴儴涓�鑸敤this.$uGetRect锛屽澶栫殑涓簎ni.$u.getRect锛屼簩鑰呭姛鑳戒竴鑷达紝鍚嶇О涓嶅悓
+				return new Promise(resolve => {
+					this.$uGetRect(`#${ref}`).then(size => {
+						resolve(size)
+					})
+				})
+				// #endif
+
+				// #ifdef APP-NVUE
+				// nvue涓嬶紝浣跨敤dom妯″潡鏌ヨ鍏冪礌楂樺害
+				// 杩斿洖涓�涓猵romise锛岃璋冪敤姝ゆ柟娉曠殑涓讳綋鑳戒娇鐢╰hen鍥炶皟
+				return new Promise(resolve => {
+					dom.getComponentRect(this.$refs[ref], res => {
+						resolve(res.size)
+					})
+				})
+				// #endif
+			},
+			// 鍏冪礌灏哄
+			getElRect() {
+				// 璋冪敤涔嬪墠锛屽厛灏嗘寚绀哄櫒璋冩暣鍒板睆骞曞锛屾柟渚胯幏鍙栧昂瀵�
+				this.showTooltip = true
+				this.tooltipTop = -10000
+				uni.$u.sleep(500).then(() => {
+					this.queryRect(this.tooltipId).then(size => {
+						this.tooltipInfo = size
+						// 鑾峰彇姘旀场灏哄涔嬪悗锛屽皢鍏堕殣钘忥紝涓轰簡璁╀笅娆″垏鎹㈡皵娉℃樉绀轰笌闅愯棌鏃讹紝鏈夋贰鍏ユ贰鍑虹殑鏁堟灉
+						this.showTooltip = false
+					})
+					this.queryRect(this.textId).then(size => {
+						this.textInfo = size
+					})
+				})
+			},
+			// 澶嶅埗鏂囨湰鍒扮矘璐存澘
+			setClipboardData() {
+				// 鍏抽棴缁勪欢
+				this.showTooltip = false
+				this.$emit('click', 0)
+				// #ifndef H5
+				uni.setClipboardData({
+					// 浼樺厛浣跨敤copyText瀛楁锛屽鏋滄病鏈夛紝鍒欓粯璁や娇鐢╰ext瀛楁褰撳仛澶嶅埗鐨勫唴瀹�
+					data: this.copyText || this.text,
+					success: () => {
+						this.showToast && uni.$u.toast('澶嶅埗鎴愬姛')
+					},
+					fail: () => {
+						this.showToast && uni.$u.toast('澶嶅埗澶辫触')
+					},
+					complete: () => {
+						this.showTooltip = false
+					}
+				})
+				// #endif
+
+				// #ifdef H5
+				let event = window.event || e || {}
+				let clipboard = new ClipboardJS('', {
+					text: () => this.copyText || this.text
+				})
+				clipboard.on('success', (e) => {
+					this.showToast && uni.$u.toast('澶嶅埗鎴愬姛')
+					clipboard.off('success')
+					clipboard.off('error')
+					// 鍦ㄥ崟椤靛簲鐢ㄤ腑锛岄渶瑕侀攢姣丏OM鐨勭洃鍚�
+					clipboard.destroy()
+				})
+				clipboard.on('error', (e) => {
+					this.showToast && uni.$u.toast('澶嶅埗澶辫触')
+					clipboard.off('success')
+					clipboard.off('error')
+					// 鍦ㄥ崟椤靛簲鐢ㄤ腑锛岄渶瑕侀攢姣丏OM鐨勭洃鍚�
+					clipboard.destroy()
+				})
+				clipboard.onClick(event)
+				// #endif
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import "../../libs/css/components.scss";
+
+	.u-tooltip {
+		position: relative;
+		@include flex;
+
+		&__wrapper {
+			@include flex;
+			justify-content: center;
+			/* #ifndef APP-NVUE */
+			white-space: nowrap;
+			/* #endif */
+
+			&__text {
+				color: $u-content-color;
+				font-size: 14px;
+			}
+
+			&__popup {
+				@include flex;
+				justify-content: center;
+
+				&__list {
+					background-color: #060607;
+					position: relative;
+					flex: 1;
+					border-radius: 5px;
+					padding: 0px 0;
+					@include flex(row);
+					align-items: center;
+					overflow: hidden;
+
+					&__btn {
+						padding: 11px 13px;
+
+						&--hover {
+							background-color: #58595B;
+						}
+
+						&__text {
+							line-height: 12px;
+							font-size: 13px;
+							color: #FFFFFF;
+						}
+					}
+				}
+
+				&__indicator {
+					position: absolute;
+					background-color: #060607;
+					width: 14px;
+					height: 14px;
+					bottom: -4px;
+					transform: rotate(45deg);
+					border-radius: 2px;
+					z-index: -1;
+
+					&--hover {
+						background-color: #58595B;
+					}
+				}
+			}
+		}
+	}
+</style>

--
Gitblit v1.9.3