clxx 2.1.2 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -20
- package/README.md +768 -35
- package/build/Ago/index.d.ts +0 -1
- package/build/Alert/Wrapper.d.ts +0 -1
- package/build/Alert/Wrapper.js +12 -12
- package/build/Alert/index.js +2 -2
- package/build/AutoGrid/index.js +16 -21
- package/build/AutoGrid/style.d.ts +5 -5
- package/build/CarouselNotice/index.d.ts +0 -1
- package/build/CarouselNotice/index.js +6 -6
- package/build/CarouselNotice/style.d.ts +6 -1
- package/build/CarouselNotice/style.js +7 -7
- package/build/Clickable/index.d.ts +5 -5
- package/build/Clickable/index.js +11 -8
- package/build/Container/index.d.ts +2 -2
- package/build/Container/index.js +85 -60
- package/build/Countdowner/index.d.ts +3 -3
- package/build/Countdowner/index.js +18 -11
- package/build/Dialog/Wrapper.d.ts +0 -1
- package/build/Dialog/Wrapper.js +7 -10
- package/build/Dialog/style.d.ts +15 -10
- package/build/Dialog/style.js +88 -88
- package/build/Effect/useInterval.d.ts +1 -1
- package/build/Effect/useInterval.js +1 -1
- package/build/Effect/useUpdate.d.ts +1 -1
- package/build/Effect/useUpdate.js +1 -1
- package/build/Effect/useWindowResize.d.ts +4 -2
- package/build/Effect/useWindowResize.js +28 -11
- package/build/Flex/index.d.ts +0 -1
- package/build/Indicator/index.js +22 -23
- package/build/Indicator/style.d.ts +6 -1
- package/build/Indicator/style.js +7 -7
- package/build/Loading/Wrapper.js +2 -2
- package/build/Loading/style.d.ts +12 -2
- package/build/Loading/style.js +14 -14
- package/build/Overlay/index.d.ts +1 -1
- package/build/Overlay/index.js +41 -37
- package/build/SafeArea/index.d.ts +1 -2
- package/build/SafeArea/index.js +6 -6
- package/build/ScrollView/index.d.ts +1 -1
- package/build/ScrollView/index.js +111 -27
- package/build/Toast/Toast.js +4 -4
- package/build/Toast/style.d.ts +42 -12
- package/build/Toast/style.js +54 -54
- package/build/index.d.ts +3 -0
- package/build/index.js +3 -0
- package/build/utils/Countdown.d.ts +3 -1
- package/build/utils/Countdown.js +5 -2
- package/build/utils/createApp.d.ts +14 -13
- package/build/utils/createApp.js +58 -42
- package/build/utils/cssUtil.d.ts +2 -2
- package/build/utils/cssUtil.js +24 -13
- package/build/utils/defaultScroll.d.ts +0 -1
- package/build/utils/defaultScroll.js +8 -5
- package/build/utils/is.d.ts +23 -4
- package/build/utils/is.js +97 -15
- package/build/utils/jsonp.js +2 -2
- package/build/utils/request.js +12 -2
- package/package.json +15 -12
- package/test/README.md +16 -0
- package/test/eslint.config.js +29 -0
- package/test/index.html +13 -0
- package/test/jsconfig.json +8 -0
- package/test/package.json +27 -0
- package/test/public/vite.svg +1 -0
- package/test/src/ago/index.jsx +30 -0
- package/test/src/alert/index.jsx +111 -0
- package/test/src/autogrid/index.css +0 -0
- package/test/src/autogrid/index.jsx +26 -0
- package/test/src/carouse-notice/index.jsx +59 -0
- package/test/src/clickable/index.css +21 -0
- package/test/src/clickable/index.jsx +39 -0
- package/test/src/countdown/index.jsx +95 -0
- package/test/src/dialog/index.jsx +104 -0
- package/test/src/dialog/index.module.css +5 -0
- package/test/src/image-picker/index.css +0 -0
- package/test/src/image-picker/index.jsx +88 -0
- package/test/src/index/index.jsx +46 -0
- package/test/src/index.css +49 -0
- package/test/src/index.jsx +31 -0
- package/test/src/indicator/index.jsx +25 -0
- package/test/src/loading/index.jsx +36 -0
- package/test/src/overlay/index.jsx +31 -0
- package/test/src/privacy/index.css +13 -0
- package/test/src/privacy/index.jsx +34 -0
- package/test/src/scrollview/index.css +10 -0
- package/test/src/scrollview/index.jsx +52 -0
- package/test/src/toast/index.jsx +86 -0
- package/test/vite.config.js +15 -0
package/build/utils/cssUtil.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Interpolation, Theme } from '@emotion/react';
|
|
2
2
|
/**
|
|
3
3
|
* 匹配所有的CSS数值类型的值
|
|
4
4
|
*/
|
|
@@ -39,4 +39,4 @@ export declare function splitValue(value: number | string, defaultUnit?: string)
|
|
|
39
39
|
* @param style
|
|
40
40
|
* @returns
|
|
41
41
|
*/
|
|
42
|
-
export declare function adaptive(style:
|
|
42
|
+
export declare function adaptive(style: Record<string, Interpolation<Theme>>): import("@emotion/react").SerializedStyles;
|
package/build/utils/cssUtil.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { css } from
|
|
2
|
-
import { getContextValue } from
|
|
1
|
+
import { css } from '@emotion/react';
|
|
2
|
+
import { getContextValue } from '../context';
|
|
3
3
|
/**
|
|
4
4
|
* 匹配所有的CSS数值类型的值
|
|
5
5
|
*/
|
|
@@ -10,11 +10,11 @@ export const CSSValueReg = /^((?:\-)?(?:\d+\.?|\.\d+|\d+\.\d+))([a-zA-Z%]*)$/;
|
|
|
10
10
|
* @param value 长度值
|
|
11
11
|
* @param defaultUnit 默认长度值单位
|
|
12
12
|
*/
|
|
13
|
-
export function normalizeUnit(value, defaultUnit =
|
|
14
|
-
if (typeof value ===
|
|
13
|
+
export function normalizeUnit(value, defaultUnit = 'px') {
|
|
14
|
+
if (typeof value === 'number') {
|
|
15
15
|
return value + defaultUnit;
|
|
16
16
|
}
|
|
17
|
-
if (typeof value ===
|
|
17
|
+
if (typeof value === 'string') {
|
|
18
18
|
const result = value.match(CSSValueReg);
|
|
19
19
|
if (Array.isArray(result)) {
|
|
20
20
|
return result[2]
|
|
@@ -39,17 +39,17 @@ export function normalizeUnit(value, defaultUnit = "px") {
|
|
|
39
39
|
* @param value
|
|
40
40
|
* @param defaultUnit
|
|
41
41
|
*/
|
|
42
|
-
export function splitValue(value, defaultUnit =
|
|
43
|
-
if (typeof value ===
|
|
42
|
+
export function splitValue(value, defaultUnit = 'px') {
|
|
43
|
+
if (typeof value === 'number') {
|
|
44
44
|
return { num: value, unit: defaultUnit };
|
|
45
45
|
}
|
|
46
|
-
if (typeof value ===
|
|
46
|
+
if (typeof value === 'string') {
|
|
47
47
|
const result = value.match(CSSValueReg);
|
|
48
48
|
if (Array.isArray(result)) {
|
|
49
49
|
return { num: parseFloat(result[1]), unit: result[2] || defaultUnit };
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
throw new Error(
|
|
52
|
+
throw new Error('Invalid numeric format');
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
55
|
* 生成自适应的样式,仅供库内部使用
|
|
@@ -65,13 +65,24 @@ export function adaptive(style) {
|
|
|
65
65
|
const normal = {};
|
|
66
66
|
for (let name in style) {
|
|
67
67
|
let value = style[name];
|
|
68
|
-
if (typeof value !==
|
|
68
|
+
if (typeof value !== 'number') {
|
|
69
|
+
normal[name] = value;
|
|
70
|
+
}
|
|
71
|
+
else if ([
|
|
72
|
+
'flex',
|
|
73
|
+
'flexGrow',
|
|
74
|
+
'flexShrink',
|
|
75
|
+
'lineHeight',
|
|
76
|
+
'fontWeight',
|
|
77
|
+
'zIndex',
|
|
78
|
+
].includes(name) &&
|
|
79
|
+
typeof value === 'number') {
|
|
69
80
|
normal[name] = value;
|
|
70
81
|
}
|
|
71
82
|
else {
|
|
72
|
-
normal[name] = (value * 100) / 750 +
|
|
73
|
-
max[name] = (value * ctx.maxDocWidth) / 750 +
|
|
74
|
-
min[name] = (value * ctx.minDocWidth) / 750 +
|
|
83
|
+
normal[name] = (value * 100) / 750 + 'vw';
|
|
84
|
+
max[name] = (value * ctx.maxDocWidth) / 750 + 'px';
|
|
85
|
+
min[name] = (value * ctx.minDocWidth) / 750 + 'px';
|
|
75
86
|
}
|
|
76
87
|
}
|
|
77
88
|
return css(Object.assign(Object.assign({}, normal), { [`@media (min-width: ${ctx.maxDocWidth}px)`]: max, [`@media (max-width: ${ctx.minDocWidth}px)`]: min }));
|
|
@@ -11,17 +11,20 @@ try {
|
|
|
11
11
|
// eslint-disable-next-line no-empty
|
|
12
12
|
}
|
|
13
13
|
catch (err) { }
|
|
14
|
+
/**
|
|
15
|
+
* 触摸移动事件处理器
|
|
16
|
+
*/
|
|
17
|
+
const touchMoveHandler = (event) => {
|
|
18
|
+
event.preventDefault();
|
|
19
|
+
};
|
|
14
20
|
/**
|
|
15
21
|
* 禁用和启用默认滚动
|
|
16
22
|
*/
|
|
17
23
|
export const defaultScroll = {
|
|
18
|
-
handler(event) {
|
|
19
|
-
event.preventDefault();
|
|
20
|
-
},
|
|
21
24
|
disable() {
|
|
22
|
-
document.documentElement.addEventListener('touchmove',
|
|
25
|
+
document.documentElement.addEventListener('touchmove', touchMoveHandler, passiveSupported ? { capture: false, passive: false } : false);
|
|
23
26
|
},
|
|
24
27
|
enable() {
|
|
25
|
-
document.documentElement.removeEventListener('touchmove',
|
|
28
|
+
document.documentElement.removeEventListener('touchmove', touchMoveHandler, passiveSupported ? { capture: false } : false);
|
|
26
29
|
},
|
|
27
30
|
};
|
package/build/utils/is.d.ts
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @param env
|
|
4
|
-
* @returns
|
|
2
|
+
* 环境类型定义
|
|
5
3
|
*/
|
|
6
|
-
export
|
|
4
|
+
export type EnvType = "ios" | "android" | "wechat" | "qq" | "alipay" | "weibo" | "douyin" | "xiaohongshu" | "toutiao" | "baidu" | "touchable";
|
|
5
|
+
/**
|
|
6
|
+
* 常用的简单环境判断
|
|
7
|
+
* @param env 环境类型
|
|
8
|
+
* @returns 是否匹配该环境
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* if (is('ios')) {
|
|
13
|
+
* // iOS 特定逻辑
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* if (is('wechat')) {
|
|
17
|
+
* // 微信内逻辑
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function is(env: EnvType): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* 清除缓存(用于测试或特殊场景)
|
|
24
|
+
*/
|
|
25
|
+
export declare function clearIsCache(): void;
|
package/build/utils/is.js
CHANGED
|
@@ -1,29 +1,111 @@
|
|
|
1
|
+
// 缓存 UserAgent,避免重复获取
|
|
2
|
+
const UA = window.navigator.userAgent;
|
|
3
|
+
// 预编译正则表达式,提升性能
|
|
4
|
+
const REGEX_PATTERNS = {
|
|
5
|
+
ios: /iPhone|iPad|iPod/i,
|
|
6
|
+
// iPadOS 13+ 会显示为 Mac,需要通过 maxTouchPoints 判断
|
|
7
|
+
ipad: /Macintosh/i,
|
|
8
|
+
android: /Android/i,
|
|
9
|
+
wechat: /MicroMessenger/i,
|
|
10
|
+
// QQ 有多种形式:手Q、QQ浏览器等
|
|
11
|
+
qq: /\s(QQ|MQQBrowser)\//i,
|
|
12
|
+
alipay: /AlipayClient/i,
|
|
13
|
+
weibo: /Weibo/i,
|
|
14
|
+
douyin: /aweme/i,
|
|
15
|
+
xiaohongshu: /xhsdiscover/i,
|
|
16
|
+
toutiao: /NewsArticle/i,
|
|
17
|
+
baidu: /baiduboxapp/i,
|
|
18
|
+
};
|
|
19
|
+
// 结果缓存,避免重复判断
|
|
20
|
+
const cache = new Map();
|
|
1
21
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* @returns
|
|
22
|
+
* 判断是否为触摸设备
|
|
23
|
+
* 综合多种方式判断,提高准确性
|
|
5
24
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
25
|
+
function isTouchable() {
|
|
26
|
+
// 1. 检查是否支持触摸事件
|
|
27
|
+
const hasTouchEvent = 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
|
28
|
+
// 2. 检查是否为移动设备 UA
|
|
29
|
+
const isMobileUA = /Mobile|Android|iPhone|iPad|iPod/i.test(UA);
|
|
30
|
+
// 3. 综合判断
|
|
31
|
+
return hasTouchEvent && isMobileUA;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 判断是否为 iPad(包括 iPadOS 13+ 伪装成 Mac 的情况)
|
|
35
|
+
*/
|
|
36
|
+
function isIPad() {
|
|
37
|
+
// iPadOS 13+ 显示为 Mac,但有触摸点
|
|
38
|
+
if (REGEX_PATTERNS.ipad.test(UA) && navigator.maxTouchPoints > 1) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return /iPad/i.test(UA);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 常用的简单环境判断
|
|
45
|
+
* @param env 环境类型
|
|
46
|
+
* @returns 是否匹配该环境
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* if (is('ios')) {
|
|
51
|
+
* // iOS 特定逻辑
|
|
52
|
+
* }
|
|
53
|
+
*
|
|
54
|
+
* if (is('wechat')) {
|
|
55
|
+
* // 微信内逻辑
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export function is(env) {
|
|
60
|
+
// 从缓存中获取结果
|
|
61
|
+
if (cache.has(env)) {
|
|
62
|
+
return cache.get(env);
|
|
63
|
+
}
|
|
64
|
+
let result = false;
|
|
9
65
|
switch (env.toLowerCase()) {
|
|
10
66
|
case "ios":
|
|
11
|
-
|
|
67
|
+
result = REGEX_PATTERNS.ios.test(UA) || isIPad();
|
|
68
|
+
break;
|
|
12
69
|
case "android":
|
|
13
|
-
|
|
70
|
+
result = REGEX_PATTERNS.android.test(UA);
|
|
71
|
+
break;
|
|
14
72
|
case "wechat":
|
|
15
|
-
|
|
73
|
+
result = REGEX_PATTERNS.wechat.test(UA);
|
|
74
|
+
break;
|
|
16
75
|
case "qq":
|
|
17
|
-
|
|
76
|
+
result = REGEX_PATTERNS.qq.test(UA);
|
|
77
|
+
break;
|
|
18
78
|
case "alipay":
|
|
19
|
-
|
|
79
|
+
result = REGEX_PATTERNS.alipay.test(UA);
|
|
80
|
+
break;
|
|
20
81
|
case "weibo":
|
|
21
|
-
|
|
82
|
+
result = REGEX_PATTERNS.weibo.test(UA);
|
|
83
|
+
break;
|
|
22
84
|
case "douyin":
|
|
23
|
-
|
|
85
|
+
result = REGEX_PATTERNS.douyin.test(UA);
|
|
86
|
+
break;
|
|
87
|
+
case "xiaohongshu":
|
|
88
|
+
result = REGEX_PATTERNS.xiaohongshu.test(UA);
|
|
89
|
+
break;
|
|
90
|
+
case "toutiao":
|
|
91
|
+
result = REGEX_PATTERNS.toutiao.test(UA);
|
|
92
|
+
break;
|
|
93
|
+
case "baidu":
|
|
94
|
+
result = REGEX_PATTERNS.baidu.test(UA);
|
|
95
|
+
break;
|
|
24
96
|
case "touchable":
|
|
25
|
-
|
|
97
|
+
result = isTouchable();
|
|
98
|
+
break;
|
|
26
99
|
default:
|
|
27
|
-
|
|
100
|
+
result = false;
|
|
28
101
|
}
|
|
102
|
+
// 缓存结果
|
|
103
|
+
cache.set(env, result);
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 清除缓存(用于测试或特殊场景)
|
|
108
|
+
*/
|
|
109
|
+
export function clearIsCache() {
|
|
110
|
+
cache.clear();
|
|
29
111
|
}
|
package/build/utils/jsonp.js
CHANGED
|
@@ -13,8 +13,8 @@ let JSONP_INDEX = 1;
|
|
|
13
13
|
* @param url
|
|
14
14
|
* @param callbackName
|
|
15
15
|
*/
|
|
16
|
-
export function jsonp(
|
|
17
|
-
return __awaiter(this,
|
|
16
|
+
export function jsonp(url_1) {
|
|
17
|
+
return __awaiter(this, arguments, void 0, function* (url, callbackName = 'callback') {
|
|
18
18
|
return new Promise((resolve, reject) => {
|
|
19
19
|
// 生成全局唯一的
|
|
20
20
|
JSONP_INDEX += 1;
|
package/build/utils/request.js
CHANGED
|
@@ -209,16 +209,25 @@ export function parseRequestOption(option) {
|
|
|
209
209
|
export function sendRequest(option) {
|
|
210
210
|
return __awaiter(this, void 0, void 0, function* () {
|
|
211
211
|
const { url, fetchOption, timeout } = parseRequestOption(option);
|
|
212
|
+
const controller = new AbortController();
|
|
212
213
|
return Promise.race([
|
|
213
214
|
// 网络请求
|
|
214
|
-
fetch(url, fetchOption)
|
|
215
|
+
fetch(url, Object.assign(Object.assign({}, fetchOption), { signal: controller.signal }))
|
|
215
216
|
.then((response) => {
|
|
216
217
|
return response.json();
|
|
217
218
|
})
|
|
218
219
|
.then((result) => {
|
|
219
220
|
return result;
|
|
220
221
|
})
|
|
221
|
-
.catch(() => {
|
|
222
|
+
.catch((error) => {
|
|
223
|
+
// 如果是主动取消的请求,返回超时错误
|
|
224
|
+
if (error.name === 'AbortError') {
|
|
225
|
+
const result = {
|
|
226
|
+
code: -10001,
|
|
227
|
+
message: "Network request timeout",
|
|
228
|
+
};
|
|
229
|
+
return result;
|
|
230
|
+
}
|
|
222
231
|
const result = {
|
|
223
232
|
code: -10000,
|
|
224
233
|
message: "An exception occurred in the network request",
|
|
@@ -228,6 +237,7 @@ export function sendRequest(option) {
|
|
|
228
237
|
// 超时逻辑
|
|
229
238
|
new Promise((resolve) => {
|
|
230
239
|
window.setTimeout(() => {
|
|
240
|
+
controller.abort(); // 取消请求
|
|
231
241
|
const result = {
|
|
232
242
|
code: -10001,
|
|
233
243
|
message: "Network request timeout",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clxx",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.4",
|
|
4
4
|
"description": "Basic JS library for mobile devices",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"module": "./build/index.js",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"start": "tsc -w --pretty",
|
|
12
|
-
"build": "
|
|
12
|
+
"build": "rimraf ./build && tsc",
|
|
13
13
|
"pub": "npm run build && npm publish"
|
|
14
14
|
},
|
|
15
15
|
"repository": {
|
|
@@ -34,18 +34,21 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@emotion/react": "^11.
|
|
38
|
-
"dayjs": "^1.11.
|
|
37
|
+
"@emotion/react": "^11.14.0",
|
|
38
|
+
"dayjs": "^1.11.18",
|
|
39
39
|
"history": "^5.3.0",
|
|
40
|
-
"lodash": "^4.17.21"
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
"lodash": "^4.17.21"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"react": "^19.2.0",
|
|
44
|
+
"react-dom": "^19.2.0"
|
|
43
45
|
},
|
|
44
46
|
"devDependencies": {
|
|
45
|
-
"@types/lodash": "^4.
|
|
46
|
-
"@types/react": "^
|
|
47
|
-
"@types/react-dom": "^
|
|
48
|
-
"csstype": "^3.1.
|
|
49
|
-
"
|
|
47
|
+
"@types/lodash": "^4.17.20",
|
|
48
|
+
"@types/react": "^19.2.2",
|
|
49
|
+
"@types/react-dom": "^19.2.2",
|
|
50
|
+
"csstype": "^3.1.3",
|
|
51
|
+
"rimraf": "^6.0.1",
|
|
52
|
+
"typescript": "^5.9.3"
|
|
50
53
|
}
|
|
51
54
|
}
|
package/test/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# React + Vite
|
|
2
|
+
|
|
3
|
+
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
|
4
|
+
|
|
5
|
+
Currently, two official plugins are available:
|
|
6
|
+
|
|
7
|
+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
|
|
8
|
+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
|
9
|
+
|
|
10
|
+
## React Compiler
|
|
11
|
+
|
|
12
|
+
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
|
|
13
|
+
|
|
14
|
+
## Expanding the ESLint configuration
|
|
15
|
+
|
|
16
|
+
If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import js from '@eslint/js'
|
|
2
|
+
import globals from 'globals'
|
|
3
|
+
import reactHooks from 'eslint-plugin-react-hooks'
|
|
4
|
+
import reactRefresh from 'eslint-plugin-react-refresh'
|
|
5
|
+
import { defineConfig, globalIgnores } from 'eslint/config'
|
|
6
|
+
|
|
7
|
+
export default defineConfig([
|
|
8
|
+
globalIgnores(['dist']),
|
|
9
|
+
{
|
|
10
|
+
files: ['**/*.{js,jsx}'],
|
|
11
|
+
extends: [
|
|
12
|
+
js.configs.recommended,
|
|
13
|
+
reactHooks.configs['recommended-latest'],
|
|
14
|
+
reactRefresh.configs.vite,
|
|
15
|
+
],
|
|
16
|
+
languageOptions: {
|
|
17
|
+
ecmaVersion: 2020,
|
|
18
|
+
globals: globals.browser,
|
|
19
|
+
parserOptions: {
|
|
20
|
+
ecmaVersion: 'latest',
|
|
21
|
+
ecmaFeatures: { jsx: true },
|
|
22
|
+
sourceType: 'module',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
rules: {
|
|
26
|
+
'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
])
|
package/test/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>test</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="root"></div>
|
|
11
|
+
<script type="module" src="/src/index.jsx"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "test",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"lint": "eslint .",
|
|
10
|
+
"preview": "vite preview"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"react": "^19.1.1",
|
|
14
|
+
"react-dom": "^19.1.1"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@eslint/js": "^9.36.0",
|
|
18
|
+
"@types/react": "^19.1.16",
|
|
19
|
+
"@types/react-dom": "^19.1.9",
|
|
20
|
+
"@vitejs/plugin-react": "^5.0.4",
|
|
21
|
+
"eslint": "^9.36.0",
|
|
22
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
23
|
+
"eslint-plugin-react-refresh": "^0.4.22",
|
|
24
|
+
"globals": "^16.4.0",
|
|
25
|
+
"vite": "^7.1.7"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Ago } from "@";
|
|
3
|
+
|
|
4
|
+
export default function Index() {
|
|
5
|
+
return (
|
|
6
|
+
<div>
|
|
7
|
+
<p>2019-11-2</p>
|
|
8
|
+
<Ago date="2019-11-2" style={{ color: "red" }} />
|
|
9
|
+
<hr />
|
|
10
|
+
<p>2020-06-02</p>
|
|
11
|
+
<Ago date="2020-6-2" style={{ color: "red" }} />
|
|
12
|
+
<hr />
|
|
13
|
+
<p>2018/06/02</p>
|
|
14
|
+
<Ago date="2018/06/02" style={{ color: "red" }} />
|
|
15
|
+
<hr />
|
|
16
|
+
<p>2018/07/06 12:04:36</p>
|
|
17
|
+
<Ago date="2018/07/06 12:04:36" style={{ color: "red" }} />
|
|
18
|
+
<hr />
|
|
19
|
+
<p>Date.now()</p>
|
|
20
|
+
<Ago date={Date.now()} style={{ color: "red" }} />
|
|
21
|
+
<hr />
|
|
22
|
+
<p>new Date("2012-07-16 12:30:06")</p>
|
|
23
|
+
<Ago date={new Date("2012-07-16 12:30:06")} style={{ color: "red" }} />
|
|
24
|
+
<hr />
|
|
25
|
+
<p>(时间戳:毫秒)1583314718595</p>
|
|
26
|
+
<Ago date={1583314718595} style={{ color: "red" }} />
|
|
27
|
+
<hr />
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { showAlert, RowCenter } from "@";
|
|
3
|
+
|
|
4
|
+
export default function Index () {
|
|
5
|
+
return (
|
|
6
|
+
<div>
|
|
7
|
+
<p>
|
|
8
|
+
<button
|
|
9
|
+
onClick={() => {
|
|
10
|
+
showAlert({
|
|
11
|
+
title: "允许“车轮查违章”在您使用该应用时访问你的位置吗",
|
|
12
|
+
description: "访问位置将查找定位信息",
|
|
13
|
+
// showCancel: true,
|
|
14
|
+
onCancel() {
|
|
15
|
+
console.log("cancel");
|
|
16
|
+
},
|
|
17
|
+
onConfirm() {
|
|
18
|
+
console.log("confirm");
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
}}
|
|
22
|
+
>
|
|
23
|
+
普通弹框
|
|
24
|
+
</button>
|
|
25
|
+
</p>
|
|
26
|
+
<p>
|
|
27
|
+
<button
|
|
28
|
+
onClick={() => {
|
|
29
|
+
showAlert({
|
|
30
|
+
title: "这是一个带取消的弹框",
|
|
31
|
+
confirm: "知道了",
|
|
32
|
+
showCancel: true,
|
|
33
|
+
});
|
|
34
|
+
}}
|
|
35
|
+
>
|
|
36
|
+
带取消弹框
|
|
37
|
+
</button>
|
|
38
|
+
</p>
|
|
39
|
+
<p>
|
|
40
|
+
<button
|
|
41
|
+
onClick={() => {
|
|
42
|
+
showAlert({
|
|
43
|
+
description: "这是一个带标题的弹框",
|
|
44
|
+
showCancel: true,
|
|
45
|
+
onCancel() {
|
|
46
|
+
console.log("cancel");
|
|
47
|
+
},
|
|
48
|
+
onConfirm() {
|
|
49
|
+
console.log("confirm");
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}}
|
|
53
|
+
>
|
|
54
|
+
带标题弹框
|
|
55
|
+
</button>
|
|
56
|
+
</p>
|
|
57
|
+
|
|
58
|
+
<p>
|
|
59
|
+
<button
|
|
60
|
+
onClick={() => {
|
|
61
|
+
showAlert({
|
|
62
|
+
description: "定制按钮的内容",
|
|
63
|
+
showCancel: true,
|
|
64
|
+
confirm: (
|
|
65
|
+
<RowCenter style={{ height: "100%" }}>
|
|
66
|
+
<svg style={{ width: ".24rem" }} viewBox="0 0 24 24">
|
|
67
|
+
<path
|
|
68
|
+
fill="gray"
|
|
69
|
+
d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"
|
|
70
|
+
/>
|
|
71
|
+
</svg>
|
|
72
|
+
用户信息
|
|
73
|
+
</RowCenter>
|
|
74
|
+
),
|
|
75
|
+
});
|
|
76
|
+
}}
|
|
77
|
+
>
|
|
78
|
+
定制按钮的内容
|
|
79
|
+
</button>
|
|
80
|
+
</p>
|
|
81
|
+
<p>
|
|
82
|
+
<button
|
|
83
|
+
onClick={() => {
|
|
84
|
+
showAlert({
|
|
85
|
+
description: "标题、按钮、内容都是可定制的",
|
|
86
|
+
title: (
|
|
87
|
+
<h2 style={{ textAlign: "center", color: "red", margin: 0 }}>
|
|
88
|
+
大标题
|
|
89
|
+
</h2>
|
|
90
|
+
),
|
|
91
|
+
showCancel: true,
|
|
92
|
+
confirm: (
|
|
93
|
+
<RowCenter style={{ height: "100%" }}>
|
|
94
|
+
<svg style={{ width: ".24rem" }} viewBox="0 0 24 24">
|
|
95
|
+
<path
|
|
96
|
+
fill="gray"
|
|
97
|
+
d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"
|
|
98
|
+
/>
|
|
99
|
+
</svg>
|
|
100
|
+
用户信息
|
|
101
|
+
</RowCenter>
|
|
102
|
+
),
|
|
103
|
+
});
|
|
104
|
+
}}
|
|
105
|
+
>
|
|
106
|
+
标题、按钮、内容都是可定制的
|
|
107
|
+
</button>
|
|
108
|
+
</p>
|
|
109
|
+
</div>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import "./index.css";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { AutoGrid } from "@";
|
|
4
|
+
|
|
5
|
+
export default function Index() {
|
|
6
|
+
return (
|
|
7
|
+
<div>
|
|
8
|
+
<p>简单测试</p>
|
|
9
|
+
<AutoGrid cols={4} gap={".1rem"} isSquare itemStyle={{ background: "yellow" }}>
|
|
10
|
+
<div style={{ width: "400px", backgroundColor: "red" }}>3143214112</div>
|
|
11
|
+
{[<span key={1}>1</span>, <span key={2}>2</span>, <span key={3}>3</span>]}, . :<span>1</span>
|
|
12
|
+
<span>2</span>
|
|
13
|
+
<span>3</span>
|
|
14
|
+
{false}
|
|
15
|
+
{null}
|
|
16
|
+
{undefined}
|
|
17
|
+
{0}
|
|
18
|
+
{[]}
|
|
19
|
+
{""}
|
|
20
|
+
{true}
|
|
21
|
+
{() => <>123</>}
|
|
22
|
+
<p>最后一个</p>
|
|
23
|
+
</AutoGrid>
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
26
|
+
}
|