add contact-number
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
|
||||
html {
|
||||
cursor: var(--tui-cur-default);
|
||||
text-underline-offset: .16rem;
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -130,7 +131,7 @@ textarea {
|
||||
// 模糊玻璃效果:白色
|
||||
.glass-white {
|
||||
color: var(--eui-black, #000);
|
||||
background: rgba(255, 255, 255, .8);
|
||||
background: rgba(255, 255, 255, .6);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
@@ -138,7 +139,7 @@ textarea {
|
||||
// 模糊玻璃效果:黑色
|
||||
.glass-black {
|
||||
color: var(--eui-white, #FFF);
|
||||
background: rgba(0, 0, 0, .8);
|
||||
background: rgba(0, 0, 0, .6);
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import view from "./index.vue";
|
||||
import Toolkit from "../../utils/Toolkit";
|
||||
|
||||
export const ContactNumber = Toolkit.withInstall(view);
|
||||
export default ContactNumber;
|
||||
@@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<span class="tui-contact-number">
|
||||
<a v-if="value" :href="`tel:${dialValue}`">
|
||||
<span v-if="$slots.icon" class="icon">
|
||||
<slot name="icon"></slot>
|
||||
</span>
|
||||
<span :class="{ underline }" v-text="formattedValue"></span>
|
||||
</a>
|
||||
<span v-else>
|
||||
<span v-if="$slots.icon" class="icon">
|
||||
<slot name="icon"></slot>
|
||||
</span>
|
||||
<span :class="{ underline }" v-text="formattedValue"></span>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: "ContactNumber"
|
||||
});
|
||||
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
value?: string | number;
|
||||
underline?: boolean;
|
||||
separator?: " " | "-";
|
||||
}>(), {
|
||||
underline: false,
|
||||
separator: " "
|
||||
});
|
||||
|
||||
const { underline, separator } = toRefs(props);
|
||||
|
||||
/** 将号码按指定长度分组。 */
|
||||
function splitNumber(number: string, lengths: number[], separator: " " | "-"): string {
|
||||
let start = 0;
|
||||
const groups: string[] = [];
|
||||
for (const length of lengths) {
|
||||
groups.push(number.slice(start, start + length));
|
||||
start += length;
|
||||
}
|
||||
if (start < number.length) {
|
||||
groups.push(number.slice(start));
|
||||
}
|
||||
return groups.filter(Boolean).join(separator);
|
||||
}
|
||||
|
||||
/** 格式化号码展示文本,保留开头的国际区号。 */
|
||||
function formatNumber(number: string): string {
|
||||
const normalized = number.replace(/[^\d+]/g, "").replace(/(?!^)\+/g, "");
|
||||
const digits = normalized.replace(/\D/g, "");
|
||||
if (digits.length < 8) {
|
||||
return normalized;
|
||||
}
|
||||
if (normalized.startsWith("+")) {
|
||||
const countryCode = digits.slice(0, 2);
|
||||
const localNumber = digits.slice(2);
|
||||
|
||||
if (localNumber.length >= 11) {
|
||||
return `+${countryCode}${separator.value}${splitNumber(localNumber, [3, 4], separator.value)}`;
|
||||
}
|
||||
|
||||
return `+${countryCode}${separator.value}${splitNumber(localNumber, [4], separator.value)}`;
|
||||
}
|
||||
|
||||
if (digits.length === 11) {
|
||||
return splitNumber(digits, [3, 4], separator.value);
|
||||
}
|
||||
|
||||
return splitNumber(digits, [4], separator.value);
|
||||
}
|
||||
|
||||
const value = computed(() => props.value !== undefined && props.value !== null && String(props.value).trim() !== "");
|
||||
const dialValue = computed(() => String(props.value ?? "").replace(/[^\d+]/g, "").replace(/(?!^)\+/g, ""));
|
||||
const formattedValue = computed(() => formatNumber(String(props.value ?? "").trim()));
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.tui-contact-number {
|
||||
|
||||
.icon {
|
||||
display: inline-flex;
|
||||
margin-right: .25rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
|
||||
span {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -10,6 +10,7 @@ import MarkdownView from "./markdown-view";
|
||||
import BEFlowerFall from "./background-effect/flower-fall";
|
||||
import MarkdownEditor from "./markdown-editor";
|
||||
import PassTimeLabel from "./passtime-label";
|
||||
import ContactNumber from "./contact-number";
|
||||
|
||||
export default [
|
||||
Icon,
|
||||
@@ -22,7 +23,8 @@ export default [
|
||||
MarkdownView,
|
||||
BEFlowerFall,
|
||||
MarkdownEditor,
|
||||
PassTimeLabel
|
||||
PassTimeLabel,
|
||||
ContactNumber
|
||||
];
|
||||
|
||||
export {
|
||||
@@ -36,5 +38,6 @@ export {
|
||||
MarkdownView,
|
||||
BEFlowerFall,
|
||||
MarkdownEditor,
|
||||
PassTimeLabel
|
||||
PassTimeLabel,
|
||||
ContactNumber
|
||||
};
|
||||
|
||||
@@ -57,7 +57,6 @@ function toggle(): void {
|
||||
|
||||
&.underline {
|
||||
text-decoration: underline;
|
||||
text-underline-offset: .16rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user