This commit is contained in:
Ling53666
2025-08-18 09:11:51 +08:00
commit 02554225da
2516 changed files with 133155 additions and 0 deletions

View File

@ -0,0 +1,5 @@
import { IPinYinMapItem } from './props';
/**
* 拼音键盘按钮
*/
export declare const PINYIN_MAP: IPinYinMapItem[][];

View File

@ -0,0 +1,40 @@
/**
* 拼音键盘按钮
*/
export var PINYIN_MAP = [
// 第一行
[
{ label: 'Q', value: 'Q' },
{ label: 'W', value: 'W' },
{ label: 'E', value: 'E' },
{ label: 'R', value: 'R' },
{ label: 'T', value: 'T' },
{ label: 'Y', value: 'Y' },
{ label: 'U', value: 'U' },
{ label: 'I', value: 'I' },
{ label: 'O', value: 'O' },
{ label: 'P', value: 'P' },
],
// 第二行
[
{ label: 'A', value: 'A' },
{ label: 'S', value: 'S' },
{ label: 'D', value: 'D' },
{ label: 'F', value: 'F' },
{ label: 'G', value: 'G' },
{ label: 'H', value: 'H' },
{ label: 'J', value: 'J' },
{ label: 'K', value: 'K' },
{ label: 'L', value: 'L' },
],
// 第三行
[
{ label: 'Z', value: 'Z' },
{ label: 'X', value: 'X' },
{ label: 'C', value: 'C' },
{ label: 'V', value: 'V' },
{ label: 'B', value: 'B' },
{ label: 'N', value: 'N' },
{ label: 'M', value: 'M' },
],
];

View File

@ -0,0 +1,153 @@
<view
key="ant-rare-words-input-{{$id}}"
style="{{style}}"
class="ant-rare-words-keyboard {{className || ''}}"
>
<view
a:if="{{visible}}"
class="ant-rare-words-keyboard-modal {{showMask ? '' : 'hide'}}"
onTap="handleHide"
onAppear="catchAppearModal"
></view>
<view class="ant-rare-words-keyboard-kb {{visible ? '' : 'hide'}}">
<view class="ant-rare-words-keyboard-header">
<view
a:if="{{type !== 'handwriting'}}"
class="ant-rare-words-keyboard-input_value {{displayStr.length > 0 && visible ? '' : 'hide'}}"
>
{{displayStr}}
</view>
<view class="ant-rare-words-keyboard-match_words_wrap">
<view class="ant-rare-words-keyboard-match_words {{showMoreWords ? 'absolute' : ''}}">
<view class="ant-rare-words-keyboard-match_words_inner {{showMoreWords ? 'all' : ''}}">
<view
a:if="{{matchWordsList.length === 0}}"
class="ant-rare-words-keyboard-match_words_hidden"
>
</view>
<block
a:for="{{matchWordsList}}"
a:for-index="index"
a:for-item="item"
>
<view
class="ant-rare-words-keyboard-match_words_item {{showMoreWords ? 'all' : ''}}"
data-value="{{item.unicodeChar}}"
onTap="handleWordClick"
>
<view class="ant-rare-words-keyboard-match_words_item_text">
{{item.unicodeChar}}
</view>
</view>
</block>
<view
a:if="{{loading}}"
class="ant-rare-words-keyboard-match_words_item_tips loading"
>
<loading
className="ant-rare-words-keyboard-loading"
type="mini"
size="small"
color="#666666"
></loading>
<!--display: inline-->
<text>加载中</text>
</view>
<view
a:else
class="ant-rare-words-keyboard-match_words_item_tips"
>
<!--display: inline-->
<text a:if="{{!!(displayStr === '' && matchWordsList.length === 0)}}">请输入生僻字对应的拼音</text>
<!--display: inline-->
<text a:if="{{!!(displayStr !== '' && matchWordsList.length === 0)}}">更多生僻字完善中,敬请期待</text>
</view>
</view>
<view
class="ant-rare-words-keyboard-match_words_right {{showMoreWords ? 'sticky' : ''}} {{matchWordsList.length > maxDisplayNum && !showMoreWords ? 'overflow' : ''}}"
onTap="hanleLookMore"
>
<icon
className="ant-rare-words-keyboard_down"
type="DownOutline"
></icon>
</view>
</view>
</view>
<view class="ant-rare-words-keyboard_main">
<view a:if="{{showErrorPage}}">
<slot name="resultError">
<view class="ant-rare-words-keyboard_error">
<result
className="ant-rare-words-keyboard_error-result"
image="https://mdn.alipayobjects.com/huamei_2fq7mt/afts/img/A*VtvFS4EJl0cAAAAAAAAAAAAADh58AQ/original"
message="页面遇到一些小问题"
>
<view
slot="extra"
class="ant-rare-words-keyboard_error-btns"
>
<button
type="primary"
size="small"
inline
onTap="handleRetry"
>
重试
</button>
</view>
</result>
</view>
</slot>
</view>
<view
a:else
class="ant-rare-words-keyboard_pinyin"
>
<block
a:for="{{pinyinMaps}}"
a:for-index="mapIndex"
a:for-item="mapItem"
key="{{mapIndex}}"
>
<view class="ant-rare-words-keyboard_pinyin_row">
<block
a:for="{{mapItem}}"
a:for-index="index"
a:for-item="item"
key="{{item.value}}"
>
<view
data-value="{{item.value}}"
class="ant-rare-words-keyboard_pinyin_key {{showMoreWords ? 'all' : ''}}"
onTap="handleKeyClick"
>
<view class="ant-rare-words-keyboard_pinyin_key_text">
{{item.label}}
</view>
</view>
</block>
<view
a:if="{{mapIndex === pinyinMaps.length - 1}}"
class="ant-rare-words-keyboard_pinyin_key delete"
onTap="handleDelete"
>
<view class="ant-rare-words-keyboard_pinyin_key_text">
<icon
className="ant-rare-words-keyboard_delete"
type="TextDeletionOutline"
></icon>
</view>
</view>
</view>
</block>
</view>
</view>
</view>
<view
a:if="{{safeArea}}"
class="ant-rare-words-keyboard-kb_iphonex-safe"
></view>
</view>
</view>

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,136 @@
import { __assign, __awaiter, __generator, __spreadArray } from "tslib";
import { Component, triggerEvent, triggerEventOnly } from '../_util/simply';
import { PINYIN_MAP } from './constants';
import { RareWordsKeyboardProps } from './props';
import { formatZDatas, loadFontFace, matchWordsRecommend } from './utils';
import { ZDATAS } from './zdatas';
import { getInstanceBoundingClientRect } from '../_util/jsapi/get-instance-bounding-client-rect';
var wordsData = formatZDatas(ZDATAS.datas);
Component(RareWordsKeyboardProps, {
getInstance: function () {
if (this.$id) {
return my;
}
return this;
},
getBoundingClientRect: function (query) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, getInstanceBoundingClientRect(this.getInstance(), query)];
case 1: return [2 /*return*/, _a.sent()];
}
});
});
},
// 隐藏键盘,失去焦点
handleHide: function () {
this.setData({
inputValue: [],
matchWordsList: [],
displayStr: '',
showMoreWords: false,
});
triggerEventOnly(this, 'close');
},
// 点击键盘key值
handleKeyClick: function (e) {
if (this.data.loading)
return;
var _a = e.currentTarget.dataset.value, value = _a === void 0 ? '' : _a;
if (!value)
return;
var inputValue = __spreadArray(__spreadArray([], this.data.inputValue, true), [value], false);
this.setData(__assign({ inputValue: __spreadArray([], inputValue, true) }, this.computeMatchWords(inputValue)));
},
// 点击删除
handleDelete: function () {
var inputValue = __spreadArray([], this.data.inputValue, true);
if (this.data.inputValue.length === 0)
return;
inputValue.pop();
this.setData(__assign({ inputValue: __spreadArray([], inputValue, true) }, this.computeMatchWords(inputValue)));
},
// 计算展示值和候选字列表
computeMatchWords: function (inputValue) {
var displayStr = Array.isArray(inputValue)
? inputValue.join('')
: inputValue;
var curMatchWords = matchWordsRecommend(wordsData, displayStr);
return {
displayStr: displayStr,
matchWordsList: curMatchWords,
};
},
// 点击查看更多
hanleLookMore: function () {
if (this.data.matchWordsList.length <= this.data.maxDisplayNum) {
this.handleHide();
return;
}
this.setData({
showMoreWords: !this.data.showMoreWords,
});
},
// 计算每行可以展示的最大字数
computeMaxDisplayNum: function () {
return __awaiter(this, void 0, void 0, function () {
var _a, singleWords, wordsWrap, maxDisplayNumInOneLine;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, Promise.all([
this.getBoundingClientRect('.ant-rare-words-keyboard-match_words_hidden'),
this.getBoundingClientRect('.ant-rare-words-keyboard-match_words_inner'),
])];
case 1:
_a = _b.sent(), singleWords = _a[0], wordsWrap = _a[1];
if (!(wordsWrap === null || wordsWrap === void 0 ? void 0 : wordsWrap.width) || !(singleWords === null || singleWords === void 0 ? void 0 : singleWords.width))
return [2 /*return*/];
maxDisplayNumInOneLine = parseInt(((wordsWrap === null || wordsWrap === void 0 ? void 0 : wordsWrap.width) / (singleWords === null || singleWords === void 0 ? void 0 : singleWords.width)).toString(), 10);
this.setData({ maxDisplayNum: maxDisplayNumInOneLine });
return [2 /*return*/];
}
});
});
},
// 加载字体
loadFont: function () {
var _this = this;
this.setData({
loading: true,
});
loadFontFace()
.then(function () {
_this.setData({ showErrorPage: false, loading: false });
})
.catch(function (err) {
_this.setData({ showErrorPage: true, loading: false });
triggerEvent(_this, 'error', err);
});
},
// 点击重试
handleRetry: function () {
this.loadFont();
},
handleWordClick: function (e) {
var _a = e.currentTarget.dataset.value, value = _a === void 0 ? '' : _a;
if (!value)
return;
triggerEvent(this, 'change', value);
this.handleHide();
},
}, {
loading: false,
inputValue: [],
displayStr: '',
matchWordsList: [],
showMoreWords: false,
pinyinMaps: PINYIN_MAP,
maxDisplayNum: 0,
showErrorPage: false, // 是否展示错误页
}, null, {
didMount: function () {
this.loadFont();
this.computeMaxDisplayNum();
},
});

View File

@ -0,0 +1,9 @@
{
"component": true,
"usingComponents": {
"icon": "../Icon/index",
"result": "../Result/index",
"button": "../Button/index",
"loading": "../Loading/index"
}
}

View File

@ -0,0 +1,341 @@
@import (reference) '../style/themes/index.less';
@keyframes number-input-cursor {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
.ant-rare-words-keyboard {
color: @COLOR_TEXT_PRIMARY;
width: 0;
height: 0;
position: relative;
overflow: hidden;
&-modal {
z-index: 998;
position: fixed;
bottom: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.45);
&.hide {
visibility: hidden;
}
}
&-kb {
background: @COLOR_BACKGROUND;
max-height: 1200 * @rpx;
min-width: 100vw;
position: fixed;
bottom: 0;
left: 0;
transition: all 200ms linear;
z-index: 999;
&.hide {
transform: translateY(100%);
max-height: 0;
}
&_iphonex-safe {
height: calc(constant(safe-area-inset-bottom) - 20 * @rpx);
height: calc(env(safe-area-inset-bottom) - 20 * @rpx);
width: 100%;
background-color: @COLOR_BACKGROUND;
}
}
&_header {
background-color: @COLOR_BACKGROUND;
}
&-input_value {
position: absolute;
top: -64 * @rpx;
left: 0;
display: inline-block;
height: 64 * @rpx;
line-height: 64 * @rpx;
border-top-left-radius: 8 * @rpx;
border-top-right-radius: 8 * @rpx;
background-color: @COLOR_BACKGROUND;
padding-left: 20 * @rpx;
padding-right: 20 * @rpx;
border: 1 * @rpx solid #eee;
border-bottom: 0;
letter-spacing: 2 * @rpx;
box-sizing: border-box;
font-size: 24 * @rpx;
color: #333;
&.hide {
display: none;
}
}
&-match_words {
display: flex;
flex-flow: row nowrap;
align-items: flex-start;
justify-content: flex-start;
padding: 20 * @rpx 24 * @rpx 20 * @rpx 8 * @rpx;
background: @COLOR_BACKGROUND;
overflow: hidden;
font-family: 'rare-words-font';
&.absolute {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-sizing: border-box;
z-index: 10000;
padding-left: 0;
overflow: auto;
}
&_wrap {
min-height: 96 * @rpx;
&::before {
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
background: @COLOR_TEXT_WEAK_DEFAULT;
width: 100%;
height: 2 * @rpx;
transform: scaleY(0.5);
transform-origin: 0 0;
}
}
&_item_tips {
padding-left: 8 * @rpx;
font-size: 28 * @rpx;
color: @COLOR_TEXT_SECONDARY_DEFAULT;
line-height: 34 * @rpx;
&.loading {
display: flex;
flex-flow: row nowrap;
align-items: center;
}
}
&_inner {
flex: 1;
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: flex-start;
overflow: hidden;
height: 56 * @rpx;
white-space: nowrap;
box-sizing: border-box;
margin-right: -32 * @rpx;
padding-right: 42 * @rpx;
&.all {
height: auto;
margin-top: -20 * @rpx;
position: relative;
padding-left: 8 * @rpx;
padding-right: 42 * @rpx;
&::after {
content: '';
display: block;
position: absolute;
left: -64 * @rpx;
bottom: 0;
background: @COLOR_TEXT_WEAK_DEFAULT;
width: 100%;
height: 2 * @rpx;
transform: scaleY(0.5);
transform-origin: 0 0;
}
}
}
&_item {
color: @COLOR_TEXT_PRIMARY_DEFAULT;
width: 73 * @rpx;
padding-left: 16 * @rpx;
padding-right: 16 * @rpx;
box-sizing: border-box;
&.all {
padding-top: 20 * @rpx;
padding-bottom: 20 * @rpx;
position: relative;
&::after {
content: '';
display: block;
position: absolute;
left: -20 * @rpx;
bottom: 0;
background: @COLOR_TEXT_WEAK_DEFAULT;
width: 100%;
height: 2 * @rpx;
transform: scaleY(0.5);
transform-origin: 0 0;
}
}
&_text {
font-size: 42 * @rpx;
line-height: 57 * @rpx;
user-select: none;
color: @COLOR_TEXT_PRIMARY_DEFAULT;
&:active {
color: @COLOR_BRAND1_DEFAULT;
}
&:hover {
color: @COLOR_BRAND1_DEFAULT;
}
}
}
&_hidden {
visibility: hidden;
position: absolute;
top: -19998 * @rpx;
left: -19998 * @rpx;
width: 73 * @rpx;
padding-left: 16 * @rpx;
padding-right: 16 * @rpx;
box-sizing: border-box;
}
&_right {
width: 48 * @rpx;
height: 48 * @rpx;
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
position: relative;
margin-top: 4 * @rpx;
color: @COLOR_TEXT_PRIMARY_DEFAULT;
&.sticky {
position: sticky !important;
top: 0 !important;
left: 0 !important;
}
&.overflow {
&::before {
content: '';
display: block;
width: 10 * @rpx;
height: 100%;
background: linear-gradient(to right, transparent, #d8d8d8);
position: absolute;
left: -32 * @rpx;
}
}
}
}
&-loading {
min-height: 34 * @rpx;
margin-right: 12 * @rpx;
}
&_delete {
font-size: 48 * @rpx;
}
&_down {
font-size: 48 * @rpx;
}
&_pinyin {
background: @COLOR_BACKGROUND;
padding-top: 16 * @rpx;
padding-bottom: 16 * @rpx;
&_row {
display: flex;
flex-flow: row nowrap;
justify-content: center;
background: @COLOR_BACKGROUND;
margin-bottom: 16 * @rpx;
&:last-child {
margin-bottom: 0;
}
}
&_key {
position: relative;
display: flex;
align-items: center;
justify-content: center;
height: 88 * @rpx;
width: 63 * @rpx;
background: @COLOR_WHITE_DEFAULT;
font-size: 36 * @rpx;
color: @COLOR_TEXT_PRIMARY_DEFAULT;
box-sizing: border-box;
border-radius: 8 * @rpx;
margin-right: 12 * @rpx;
user-select: none;
&:active {
background: @COLOR_BRAND1_DEFAULT;
color: @COLOR_WHITE_DEFAULT;
}
&:last-child {
margin-right: 0;
}
&.delete {
width: 80 * @rpx;
}
}
}
&_error {
background: @COLOR_BACKGROUND;
padding-top: 30 * @rpx;
padding-bottom: 30 * @rpx;
.ant-result-main {
background: none;
margin-bottom: 0;
padding-top: 40 * @rpx;
padding-bottom: 40 * @rpx;
}
.ant-result-message {
text-align: center;
}
&-btns {
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
}
}
}

View File

@ -0,0 +1,76 @@
import { IBaseProps } from '../_util/base';
export interface ICommonError {
detail: Error;
errorCode: string;
message: string;
onRetry?: () => Promise<void>;
}
export declare enum InputTypes {
stroke = "stroke",
pinyin = "pinyin",
handwriting = "handwriting"
}
export interface IPinYinMapItem {
label: string;
value: string;
extraClassName?: string;
}
export interface IWordsItem {
charId?: string;
unicodeChar: string;
unicodeCodePoint: string;
unicodeFont: string | null;
pinYinChars: string[];
splitChars: string[];
weight?: number | null;
type?: string;
extInfo?: string | null;
sort?: number;
}
export type IFilterType = 'pinyin' | 'split' | 'all';
export interface IWordsItem {
charId?: string;
unicodeChar: string;
unicodeCodePoint: string;
unicodeFont: string | null;
pinYinChars: string[];
splitChars: string[];
weight?: number | null;
type?: string;
extInfo?: string | null;
sort?: number;
}
export type IWordsData = IWordsItem[];
export interface IRareWordsKeyboardProps extends IBaseProps {
/**
* @title 是否可见
*/
visible?: boolean;
/**
* @title 键盘类型
*/
type?: InputTypes | string;
/**
* @title 是否展示蒙层
* @description 默认 true
*/
showMask?: boolean;
/**
* @description 安全距离
* @default true
*/
safeArea?: boolean;
/**
* @title 关闭的时候触发的回调
*/
onClose?: () => void;
/**
* @title 输入完成的时候触发的回调
*/
onChange?: (value: string) => void;
/**
* @title 组件错误的时候的回调
*/
onError?: (err: Error) => void;
}
export declare const RareWordsKeyboardProps: Partial<IRareWordsKeyboardProps>;

View File

@ -0,0 +1,12 @@
export var InputTypes;
(function (InputTypes) {
InputTypes["stroke"] = "stroke";
InputTypes["pinyin"] = "pinyin";
InputTypes["handwriting"] = "handwriting";
})(InputTypes || (InputTypes = {}));
export var RareWordsKeyboardProps = {
visible: false,
type: 'pinyin',
showMask: true,
safeArea: true,
};

View File

@ -0,0 +1,51 @@
import { IWordsData, IFilterType } from './props';
/**
* json转字符串
* @param {string} data 需要转json的字符串
* @return {object} json 字符串
*/
export declare function safeJSONparse(data: string): object;
/**
* 判断数组是否为空
*/
export declare function isWordsDataEmpty(arr: any): boolean;
/**
* 清除字符串里的数字
*/
export declare function clearNumberInStr(str: string): string;
/**
* 格式化字库数据
* @param datas ZDatas 数据
* @return {IWordsData} 字库
*/
export declare function formatZDatas(datas?: any[]): any[];
/**
* 候选字推荐序函数
* 考虑两个维度一个是输入值和生僻字的匹配程度比如你输入YA 雅是完全匹配,炎是模糊匹配,排列的时候肯定”雅“在前面,
* 如果除了”雅“还有一个”亚“,两个都是完全匹配,这个时候就看哪个字占比高,哪个就排在前面
* @param {IWordsData} wordsData 字库数据
* @param {string} inputValue 当前输入的值
* @param {string} filterKey 过滤依据的key值
* @return {IWordsData} 返回符合要求并且排序好的候选项列表
*/
export declare function matchWordsRecommend(wordsData?: IWordsData, inputValue?: string, filterKey?: IFilterType): IWordsData;
/**
* 字库过滤,只挑选符合要求的候选字
* @param {IWordsData} wordsData 字库数据
* @param {string} inputValue 当前输入的值
* @param {string} filterKey 过滤依据的key值
* @return {IWordsData} 返回符合要求并且排序好的候选项列表
*/
export declare function wordsFilter(wordsData?: IWordsData, inputValue?: string, filterKey?: IFilterType): IWordsData;
/**
* 候选项排序,用户选择可能性高的候选项排在前面
* @param {IWordsData} wordsData 字库数据
* @param {string} inputValue 当前输入的值
* @param {string} filterKey 过滤依据的key值
* @return {IWordsData} 返回符合要求并且排序好的候选项列表
*/
export declare function wordsSorter(wordsData: IWordsData, inputValue: string, filterKey?: IFilterType): IWordsData;
/**
* 加载远程字体
*/
export declare function loadFontFace(): Promise<void>;

View File

@ -0,0 +1,259 @@
import { __assign, __awaiter, __generator, __spreadArray } from "tslib";
import { ZDATAS } from './zdatas';
import { loadFontFace as loadFontFaceJSAPI } from '../_util/jsapi/load-font-face';
/**
* json转字符串
* @param {string} data 需要转json的字符串
* @return {object} json 字符串
*/
export function safeJSONparse(data) {
var result;
try {
result = JSON.parse(data);
}
catch (_a) {
result = {};
}
return result || {};
}
/**
* 判断数组是否为空
*/
export function isWordsDataEmpty(arr) {
var _a;
if (!arr)
return true;
if (!Array.isArray(arr))
return true;
if (arr.length === 0)
return true;
// 数据合法性校验
if (!((_a = arr === null || arr === void 0 ? void 0 : arr[0]) === null || _a === void 0 ? void 0 : _a.charId))
return true;
return false;
}
/**
* 清除字符串里的数字
*/
export function clearNumberInStr(str) {
return str.replace(/[0-9]/gi, '');
}
/**
* 格式化字库数据
* @param datas ZDatas 数据
* @return {IWordsData} 字库
*/
export function formatZDatas(datas) {
if (datas === void 0) { datas = []; }
return datas.map(function (item) {
return __assign(__assign({}, item), { pinYinChars: item.pinYinChars.map(function (i) { return i.char; }), splitChars: item.splitChars.map(function (i) { return i.char; }) });
});
}
/**
* 候选字推荐序函数
* 考虑两个维度一个是输入值和生僻字的匹配程度比如你输入YA 雅是完全匹配,炎是模糊匹配,排列的时候肯定”雅“在前面,
* 如果除了”雅“还有一个”亚“,两个都是完全匹配,这个时候就看哪个字占比高,哪个就排在前面
* @param {IWordsData} wordsData 字库数据
* @param {string} inputValue 当前输入的值
* @param {string} filterKey 过滤依据的key值
* @return {IWordsData} 返回符合要求并且排序好的候选项列表
*/
export function matchWordsRecommend(wordsData, inputValue, filterKey) {
if (wordsData === void 0) { wordsData = []; }
if (inputValue === void 0) { inputValue = ''; }
if (filterKey === void 0) { filterKey = 'all'; }
return wordsSorter(wordsFilter(wordsData, inputValue, filterKey), inputValue, filterKey);
}
/**
* 字库过滤,只挑选符合要求的候选字
* @param {IWordsData} wordsData 字库数据
* @param {string} inputValue 当前输入的值
* @param {string} filterKey 过滤依据的key值
* @return {IWordsData} 返回符合要求并且排序好的候选项列表
*/
export function wordsFilter(wordsData, inputValue, filterKey) {
if (wordsData === void 0) { wordsData = []; }
if (inputValue === void 0) { inputValue = ''; }
if (filterKey === void 0) { filterKey = 'all'; }
// 字库数据为空降级为使用本地数据
if (!wordsData || isWordsDataEmpty(wordsData))
wordsData = formatZDatas(ZDATAS.datas);
if (!inputValue)
return [];
switch (filterKey) {
case 'all':
/* eslint-disable-next-line no-case-declarations */
var matchPinyinArr = filterByPinyin(wordsData, inputValue);
/* eslint-disable-next-line no-case-declarations */
var matchSplitArr = filterBySplitWord(wordsData, inputValue);
return mergeMatchWordsArr(matchPinyinArr, matchSplitArr);
case 'pinyin':
return filterByPinyin(wordsData, inputValue);
case 'split':
return filterBySplitWord(wordsData, inputValue);
default:
return [];
break;
}
}
/**
* 根据拼音过滤候选项
* @param {IWordsData} wordsData 字库数据
* @param {string} inputValue 当前输入的值
* @return {IWordsData} 返回符合要求并候选项列表
*/
function filterByPinyin(wordsData, inputValue) {
if (wordsData === void 0) { wordsData = []; }
if (inputValue === void 0) { inputValue = ''; }
var keyTranslate = inputValue.toUpperCase();
return wordsData.filter(function (item) {
var pinYinChars = (item === null || item === void 0 ? void 0 : item.pinYinChars) || [];
if (pinYinChars.length === 0)
return false;
return (pinYinChars.filter(function (pinyinItem) {
return pinyinItem.indexOf(keyTranslate) > -1;
}).length > 0);
});
}
/**
* 根据拆字过滤候选项
* @param {IWordsData} wordsData 字库数据
* @param {string} inputValue 当前输入的值
* @return {IWordsData} 返回符合要求并候选项列表
*/
function filterBySplitWord(wordsData, inputValue) {
if (wordsData === void 0) { wordsData = []; }
if (inputValue === void 0) { inputValue = ''; }
return wordsData.filter(function (item) {
var splitChars = item.splitChars || [];
if (splitChars.length === 0) {
return false;
}
return (splitChars.filter(function (splitItem) {
return splitItem.indexOf(inputValue) > -1;
}).length > 0);
});
}
/**
* 合并多个候选项数组
* @param {IWordsData} pinyinMatchArr 拼音匹配的候选项
* @param {IWordsData} splitMatchArr 拼音匹配的候选项
* @return {IWordsData} 返回合并后的候选项列表
*/
function mergeMatchWordsArr(pinyinMatchArr, splitMatchArr) {
var unDuplicate = __spreadArray(__spreadArray([], pinyinMatchArr, true), splitMatchArr, true);
if (unDuplicate.length === 0)
return unDuplicate;
var results = [];
unDuplicate.forEach(function (item) {
var findDuplicateWords = results.filter(function (item2) {
return item.unicodeCodePoint === item2.unicodeCodePoint;
});
if (findDuplicateWords.length === 0)
results.push(item);
});
return results;
}
/**
* 候选项排序,用户选择可能性高的候选项排在前面
* @param {IWordsData} wordsData 字库数据
* @param {string} inputValue 当前输入的值
* @param {string} filterKey 过滤依据的key值
* @return {IWordsData} 返回符合要求并且排序好的候选项列表
*/
export function wordsSorter(wordsData, inputValue, filterKey) {
if (filterKey === void 0) { filterKey = 'all'; }
switch (filterKey) {
case 'all':
// 当输入值以字母开头使用拼音排序
if (/^[a-zA-Z0-9]+$/.test(inputValue)) {
return sortByPinyin(wordsData, inputValue);
}
return sortBySplitWord(wordsData, inputValue);
case 'pinyin':
return sortByPinyin(wordsData, inputValue);
case 'split':
return sortBySplitWord(wordsData, inputValue);
default:
return [];
break;
}
}
/**
* 根据拼音给候选项排序
* @param {IWordsData} wordsData 字库数据
* @param {string} inputValue 当前输入的值
* @return {IWordsData} 返回符合要求并候选项列表
*/
function sortByPinyin(wordsData, inputValue) {
if (wordsData === void 0) { wordsData = []; }
if (inputValue === void 0) { inputValue = ''; }
var arr = wordsData.slice();
// 清除输入值中的数字
var keyTranslate = clearNumberInStr(inputValue.toUpperCase());
arr.forEach(function (item) {
var sort = 0;
var pinYinChars = (item.pinYinChars || []).map(function (pinyin) {
return clearNumberInStr(pinyin.toUpperCase());
});
// 拼音完全匹配 + 10000
if (pinYinChars.indexOf(keyTranslate) > -1)
sort += 10000;
// 拼音模糊匹配 + 5000
if (pinYinChars.filter(function (splitKey) { return splitKey.indexOf(keyTranslate) === 0; })
.length > 0) {
sort += 5000;
}
// 加上当前字的权重
sort += item.weight || 0;
/* eslint-disable no-param-reassign */
item.sort = sort;
});
// 根据最终排序值排序
arr.sort(function (item1, item2) { return (item2.sort || 0) - (item1.sort || 0); });
return arr;
}
/**
* 根据拆字给候选项排序
* @param {IWordsData} wordsData 字库数据
* @param {string} inputValue 当前输入的值
* @return {IWordsData} 返回符合要求并候选项列表
*/
function sortBySplitWord(wordsData, inputValue) {
if (wordsData === void 0) { wordsData = []; }
if (inputValue === void 0) { inputValue = ''; }
var arr = wordsData.slice();
arr.forEach(function (item) {
var sort = 0;
var p = item.splitChars || [];
// 拆字完全匹配 + 10000
if (p.indexOf(inputValue) > -1)
sort += 10000;
// 拆字模糊匹配 + 5000
if (p.filter(function (splitKey) { return splitKey.indexOf(inputValue) === 0; }).length > 0) {
sort += 5000;
}
// 加上当前字的权重
sort += item.weight || 0;
/* eslint-disable no-param-reassign */
item.sort = sort;
});
// 根据最终排序值排序
arr.sort(function (item1, item2) { return (item2.sort || 0) - (item1.sort || 0); });
return arr;
}
/**
* 加载远程字体
*/
export function loadFontFace() {
return __awaiter(this, void 0, void 0, function () {
var fontName;
return __generator(this, function (_a) {
fontName = "url(\"".concat(ZDATAS.fontUrl, "\")");
return [2 /*return*/, loadFontFaceJSAPI({
family: 'rare-words-font',
source: fontName,
})];
});
});
}

View File

@ -0,0 +1,27 @@
export declare const ZDATAS: {
version: string;
fontUrl: string;
datas: ({
charId: string;
unicodeChar: string;
unicodeCodePoint: string;
pinYinChars: {
char: string;
}[];
splitChars: {
char: string;
}[];
weight: string;
} | {
charId: string;
unicodeChar: string;
unicodeCodePoint: string;
pinYinChars: {
char: string;
}[];
splitChars: {
char: string;
}[];
weight: number;
})[];
};

File diff suppressed because one or more lines are too long