@xiao-ying/miniapp-hooks 1.1.0
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 +35 -0
- package/README.md +47 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/use-auth-state.d.ts +18 -0
- package/dist/use-auth-state.d.ts.map +1 -0
- package/dist/use-auth-state.js +44 -0
- package/dist/use-auth-state.js.map +1 -0
- package/dist/use-brightness.d.ts +13 -0
- package/dist/use-brightness.d.ts.map +1 -0
- package/dist/use-brightness.js +38 -0
- package/dist/use-brightness.js.map +1 -0
- package/dist/use-foreground.d.ts +12 -0
- package/dist/use-foreground.d.ts.map +1 -0
- package/dist/use-foreground.js +24 -0
- package/dist/use-foreground.js.map +1 -0
- package/dist/use-haptic-feedback.d.ts +20 -0
- package/dist/use-haptic-feedback.d.ts.map +1 -0
- package/dist/use-haptic-feedback.js +21 -0
- package/dist/use-haptic-feedback.js.map +1 -0
- package/dist/use-media-query.d.ts +20 -0
- package/dist/use-media-query.d.ts.map +1 -0
- package/dist/use-media-query.js +36 -0
- package/dist/use-media-query.js.map +1 -0
- package/dist/use-sdk-error.d.ts +47 -0
- package/dist/use-sdk-error.d.ts.map +1 -0
- package/dist/use-sdk-error.js +60 -0
- package/dist/use-sdk-error.js.map +1 -0
- package/dist/use-share.d.ts +23 -0
- package/dist/use-share.d.ts.map +1 -0
- package/dist/use-share.js +72 -0
- package/dist/use-share.js.map +1 -0
- package/dist/use-storage.d.ts +37 -0
- package/dist/use-storage.d.ts.map +1 -0
- package/dist/use-storage.js +132 -0
- package/dist/use-storage.js.map +1 -0
- package/package.json +43 -0
- package/src/index.ts +36 -0
- package/src/use-auth-state.ts +51 -0
- package/src/use-brightness.ts +44 -0
- package/src/use-foreground.ts +28 -0
- package/src/use-haptic-feedback.ts +32 -0
- package/src/use-media-query.ts +48 -0
- package/src/use-sdk-error.ts +110 -0
- package/src/use-share.ts +84 -0
- package/src/use-storage.ts +170 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Shanghai Plum Technology Ltd. Software License Agreement
|
|
2
|
+
|
|
3
|
+
This License Agreement ("Agreement") is a legal agreement between you (either an individual or a single entity, hereafter "Licensee") and Shanghai Plum Technology Ltd. ("Plum") for the software product accompanying this Agreement, which includes computer software and may include associated media, printed materials, and "online" or electronic documentation ("Software").
|
|
4
|
+
|
|
5
|
+
BY INSTALLING, COPYING, OR OTHERWISE USING THE SOFTWARE, YOU AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO THE TERMS OF THIS AGREEMENT, DO NOT INSTALL OR USE THE SOFTWARE.
|
|
6
|
+
|
|
7
|
+
1. Grant of License. Plum grants Licensee a non-exclusive, non-transferable, limited license to use the Software solely for Licensee's internal business purposes, subject to the terms and conditions of this Agreement. THIS LICENSE IS GRANTED ONLY TO ENTITIES OR INDIVIDUALS WHO HAVE OBTAINED AN OFFICIAL SERVICE AGREEMENT OR WRITTEN AUTHORIZATION FROM PLUM.
|
|
8
|
+
|
|
9
|
+
2. Ownership. The Software is owned and copyrighted by Plum or its suppliers. Your license confers no title or ownership in the Software and is not a sale of any rights in the Software. All rights not expressly granted to you are reserved by Plum.
|
|
10
|
+
|
|
11
|
+
3. Restrictions. You may not:
|
|
12
|
+
* Reverse engineer, decompile, or disassemble the Software, except and only to the extent that such activity is expressly permitted by applicable law notwithstanding this limitation.
|
|
13
|
+
* Modify, translate, or create derivative works based on the Software.
|
|
14
|
+
* Rent, lease, lend, or provide commercial hosting services with the Software.
|
|
15
|
+
* Transfer the Software or this license to any third party.
|
|
16
|
+
* Remove or alter any copyright notices or other proprietary markings on or in the Software.
|
|
17
|
+
* Use the software in any way that violates applicable laws or regulations.
|
|
18
|
+
|
|
19
|
+
4. Termination. Without prejudice to any other rights, Plum may terminate this Agreement if you fail to comply with any of the terms and conditions of this Agreement. In such event, you must destroy all copies of the Software and all of its component parts.
|
|
20
|
+
|
|
21
|
+
5. Limited Warranty. Plum warrants that the media on which the Software is distributed (if any) will be free from defects in materials and workmanship for a period of thirty (30) days from the date of delivery. Plum's entire liability and your exclusive remedy for any breach of this limited warranty shall be, at Plum's option, either (a) return of the price paid, or (b) replacement of the defective media.
|
|
22
|
+
|
|
23
|
+
6. Disclaimer of Warranties. EXCEPT AS PROVIDED ABOVE, THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. PLUM DISCLAIMS ALL OTHER WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
24
|
+
|
|
25
|
+
7. Limitation of Liability. IN NO EVENT SHALL PLUM BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFIT, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE, EVEN IF PLUM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
26
|
+
|
|
27
|
+
8. Governing Law. This Agreement shall be governed by and construed in accordance with the laws of the People's Republic of China, without regard to its conflict of law principles.
|
|
28
|
+
|
|
29
|
+
9. Entire Agreement. This Agreement constitutes the entire agreement between the parties with respect to the subject matter hereof and supersedes all prior or contemporaneous communications and proposals, whether oral or written.
|
|
30
|
+
|
|
31
|
+
10. Severability. If any provision of this Agreement is held to be invalid or unenforceable, the remaining provisions of this Agreement will remain in full force and effect.
|
|
32
|
+
|
|
33
|
+
Shanghai Plum Technology Ltd.
|
|
34
|
+
Address: Shanghai, China.
|
|
35
|
+
Email: liplum@liplum.net
|
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# @xiao-ying/miniapp-hooks
|
|
2
|
+
|
|
3
|
+
基于 `@xiao-ying/miniapp-sdk` 的通用 React hooks(不包含 cloud/snapshot)。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @xiao-ying/miniapp-hooks @xiao-ying/miniapp-sdk react
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Hook 列表
|
|
12
|
+
|
|
13
|
+
- `useBrightness()`:订阅原生/浏览器亮度变化,返回 `{ brightness, isDark }`。
|
|
14
|
+
- `useForeground()`:订阅前后台变化,返回 `{ isForeground }`。
|
|
15
|
+
- `useMediaQuery()`:暴露注入的 `mediaQuery`(安全区、DPR、尺寸)。
|
|
16
|
+
- `useStorage(key, options?)`:与 `xy.onStorageChange` 同步,提供 `value`、`loading`、`error` 以及 `setValue/remove/refresh`。
|
|
17
|
+
- `useShare(input?)`:注册分享处理器,自动补齐默认 path/title。
|
|
18
|
+
- `useHapticFeedback(options?)`(别名 `useHapticPress`):封装 `xy.vibrate`。
|
|
19
|
+
- `useSdkError(options?)`:订阅 `xy.onError`,缓存过滤后的错误并返回 `latest`、`errors`、`clear`。
|
|
20
|
+
- `useAuthState()`:订阅登录态变化,返回 `{ authState, hasAuthPermission, isSignedIn, userId }`。
|
|
21
|
+
|
|
22
|
+
> cloud/snapshot hooks 已迁移到:
|
|
23
|
+
> - `@xiao-ying/miniapp-cloud-kit`(core API)
|
|
24
|
+
> - `@xiao-ying/miniapp-cloud-hooks`(SWR hooks)
|
|
25
|
+
|
|
26
|
+
## 快速示例
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { useBrightness, useStorage } from '@xiao-ying/miniapp-hooks'
|
|
30
|
+
|
|
31
|
+
const Preferences = () => {
|
|
32
|
+
const { brightness, isDark } = useBrightness()
|
|
33
|
+
const theme = isDark ? 'dark' : 'light'
|
|
34
|
+
const storage = useStorage<string>('nickname', { defaultValue: '游客' })
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div data-theme={theme}>
|
|
38
|
+
<p>当前模式: {brightness}</p>
|
|
39
|
+
<input
|
|
40
|
+
value={storage.value ?? ''}
|
|
41
|
+
onChange={(e) => storage.setValue(e.target.value)}
|
|
42
|
+
placeholder="输入昵称"
|
|
43
|
+
/>
|
|
44
|
+
</div>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { useBrightness } from './use-brightness.js';
|
|
2
|
+
export { useForeground } from './use-foreground.js';
|
|
3
|
+
export { useMediaQuery, type UseMediaQueryResult } from './use-media-query.js';
|
|
4
|
+
export { useStorage, type UseStorageOptions, type UseStorageResult } from './use-storage.js';
|
|
5
|
+
export { useShare } from './use-share.js';
|
|
6
|
+
export { useHapticFeedback, type UseHapticFeedbackOptions } from './use-haptic-feedback.js';
|
|
7
|
+
export { useSdkError, type UseSdkErrorOptions, type UseSdkErrorResult, type UseSdkErrorFilter } from './use-sdk-error.js';
|
|
8
|
+
export { useHapticFeedback as useHapticPress } from './use-haptic-feedback.js';
|
|
9
|
+
export { useAuthState } from './use-auth-state.js';
|
|
10
|
+
export type { XYSdk, XYMediaQuery, XYSafeAreaInsets, XYViewportSize, XYBrightnessEvent, XYStorageEvent, XyShareData, XyShareHandlerPayload, MaybePromise } from '@xiao-ying/miniapp-sdk';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EACL,aAAa,EACb,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,KAAK,wBAAwB,EAAE,MAAM,0BAA0B,CAAA;AAC3F,OAAO,EACL,WAAW,EACX,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACvB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,iBAAiB,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAElD,YAAY,EACV,KAAK,EACL,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,YAAY,EACb,MAAM,wBAAwB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
export { useBrightness } from './use-brightness.js';
|
|
3
|
+
export { useForeground } from './use-foreground.js';
|
|
4
|
+
export { useMediaQuery } from './use-media-query.js';
|
|
5
|
+
export { useStorage } from './use-storage.js';
|
|
6
|
+
export { useShare } from './use-share.js';
|
|
7
|
+
export { useHapticFeedback } from './use-haptic-feedback.js';
|
|
8
|
+
export { useSdkError } from './use-sdk-error.js';
|
|
9
|
+
// Backward compatibility
|
|
10
|
+
export { useHapticFeedback as useHapticPress } from './use-haptic-feedback.js';
|
|
11
|
+
export { useAuthState } from './use-auth-state.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EACL,aAAa,EAEd,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,UAAU,EAGX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAiC,MAAM,0BAA0B,CAAA;AAC3F,OAAO,EACL,WAAW,EAIZ,MAAM,oBAAoB,CAAA;AAC3B,yBAAyB;AACzB,OAAO,EAAE,iBAAiB,IAAI,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { XYAuthState } from '@xiao-ying/miniapp-sdk';
|
|
2
|
+
type AuthState = XYAuthState | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* 获取并订阅宿主认证状态,提供常用派生字段。
|
|
5
|
+
*
|
|
6
|
+
* @returns `{ authState, hasAuthPermission, isSignedIn, userId }`
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const { isSignedIn } = useAuthState()
|
|
10
|
+
*/
|
|
11
|
+
export declare const useAuthState: () => {
|
|
12
|
+
authState: AuthState;
|
|
13
|
+
hasAuthPermission: boolean;
|
|
14
|
+
isSignedIn: boolean;
|
|
15
|
+
userId: string | undefined;
|
|
16
|
+
};
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=use-auth-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-auth-state.d.ts","sourceRoot":"","sources":["../src/use-auth-state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAGzD,KAAK,SAAS,GAAG,WAAW,GAAG,SAAS,CAAA;AAYxC;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY;;;;;CA0BxB,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
2
|
+
const readAuthState = () => {
|
|
3
|
+
try {
|
|
4
|
+
const current = xy.getAuthState();
|
|
5
|
+
if (typeof current === 'undefined')
|
|
6
|
+
return undefined;
|
|
7
|
+
return current ?? { state: 'notSignedIn' };
|
|
8
|
+
}
|
|
9
|
+
catch (_) {
|
|
10
|
+
return { state: 'notSignedIn' };
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* 获取并订阅宿主认证状态,提供常用派生字段。
|
|
15
|
+
*
|
|
16
|
+
* @returns `{ authState, hasAuthPermission, isSignedIn, userId }`
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const { isSignedIn } = useAuthState()
|
|
20
|
+
*/
|
|
21
|
+
export const useAuthState = () => {
|
|
22
|
+
const [authState, setAuthState] = useState(() => readAuthState());
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (typeof xy.onAuthStateChange !== 'function')
|
|
25
|
+
return;
|
|
26
|
+
const unsubscribe = xy.onAuthStateChange((next) => {
|
|
27
|
+
if (typeof next === 'undefined') {
|
|
28
|
+
setAuthState(undefined);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
setAuthState(next ?? { state: 'notSignedIn' });
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return unsubscribe;
|
|
35
|
+
}, []);
|
|
36
|
+
const derived = useMemo(() => ({
|
|
37
|
+
authState,
|
|
38
|
+
hasAuthPermission: typeof authState !== 'undefined',
|
|
39
|
+
isSignedIn: authState?.state === 'signedIn',
|
|
40
|
+
userId: authState?.state === 'signedIn' ? authState.userId : undefined,
|
|
41
|
+
}), [authState]);
|
|
42
|
+
return derived;
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=use-auth-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-auth-state.js","sourceRoot":"","sources":["../src/use-auth-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAMpD,MAAM,aAAa,GAAG,GAAc,EAAE;IACpC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,EAAE,CAAA;QACjC,IAAI,OAAO,OAAO,KAAK,WAAW;YAAE,OAAO,SAAS,CAAA;QACpD,OAAO,OAAO,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,CAAA;IAC5C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAA;IACjC,CAAC;AACH,CAAC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,EAAE;IAC/B,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAY,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC,CAAA;IAE5E,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,EAAE,CAAC,iBAAiB,KAAK,UAAU;YAAE,OAAM;QACtD,MAAM,WAAW,GAAG,EAAE,CAAC,iBAAiB,CAAC,CAAC,IAAI,EAAE,EAAE;YAChD,IAAI,OAAO,IAAI,KAAK,WAAW,EAAE,CAAC;gBAChC,YAAY,CAAC,SAAS,CAAC,CAAA;YACzB,CAAC;iBAAM,CAAC;gBACN,YAAY,CAAC,IAAI,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAA;YAChD,CAAC;QACH,CAAC,CAAC,CAAA;QACF,OAAO,WAAW,CAAA;IACpB,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,OAAO,GAAG,OAAO,CACrB,GAAG,EAAE,CAAC,CAAC;QACL,SAAS;QACT,iBAAiB,EAAE,OAAO,SAAS,KAAK,WAAW;QACnD,UAAU,EAAE,SAAS,EAAE,KAAK,KAAK,UAAU;QAC3C,MAAM,EAAE,SAAS,EAAE,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;KACvE,CAAC,EACF,CAAC,SAAS,CAAC,CACZ,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 订阅宿主亮度变化并返回当前亮度信息。
|
|
3
|
+
*
|
|
4
|
+
* @returns `{ brightness, isDark }`,亮度变化会触发重新渲染。
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const { brightness, isDark } = useBrightness()
|
|
8
|
+
*/
|
|
9
|
+
export declare const useBrightness: () => {
|
|
10
|
+
brightness: "light" | "dark";
|
|
11
|
+
isDark: boolean;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=use-brightness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-brightness.d.ts","sourceRoot":"","sources":["../src/use-brightness.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,QAAO;IAAE,UAAU,EAAE,OAAO,GAAG,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAiC/E,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* 订阅宿主亮度变化并返回当前亮度信息。
|
|
4
|
+
*
|
|
5
|
+
* @returns `{ brightness, isDark }`,亮度变化会触发重新渲染。
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const { brightness, isDark } = useBrightness()
|
|
9
|
+
*/
|
|
10
|
+
export const useBrightness = () => {
|
|
11
|
+
const [brightness, setBrightness] = useState(() => {
|
|
12
|
+
try {
|
|
13
|
+
return xy.brightness() === 'dark' ? 'dark' : 'light';
|
|
14
|
+
}
|
|
15
|
+
catch (_) {
|
|
16
|
+
return 'light';
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (typeof xy.onBrightnessChange !== 'function') {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const unsubscribe = xy.onBrightnessChange((event) => {
|
|
24
|
+
const next = event?.brightness === 'dark' ? 'dark' : 'light';
|
|
25
|
+
setBrightness(next);
|
|
26
|
+
});
|
|
27
|
+
return () => {
|
|
28
|
+
if (typeof unsubscribe === 'function') {
|
|
29
|
+
unsubscribe();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}, [xy]);
|
|
33
|
+
return useMemo(() => ({
|
|
34
|
+
brightness,
|
|
35
|
+
isDark: brightness === 'dark'
|
|
36
|
+
}), [brightness]);
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=use-brightness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-brightness.js","sourceRoot":"","sources":["../src/use-brightness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEpD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAsD,EAAE;IACnF,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAmB,GAAG,EAAE;QAClE,IAAI,CAAC;YACH,OAAO,EAAE,CAAC,UAAU,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;QACtD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,OAAO,CAAA;QAChB,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,EAAE,CAAC,kBAAkB,KAAK,UAAU,EAAE,CAAC;YAChD,OAAM;QACR,CAAC;QAED,MAAM,WAAW,GAAG,EAAE,CAAC,kBAAkB,CAAC,CAAC,KAAK,EAAE,EAAE;YAClD,MAAM,IAAI,GAAG,KAAK,EAAE,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAA;YAC5D,aAAa,CAAC,IAAI,CAAC,CAAA;QACrB,CAAC,CAAC,CAAA;QAEF,OAAO,GAAG,EAAE;YACV,IAAI,OAAO,WAAW,KAAK,UAAU,EAAE,CAAC;gBACtC,WAAW,EAAE,CAAA;YACf,CAAC;QACH,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAER,OAAO,OAAO,CACZ,GAAG,EAAE,CAAC,CAAC;QACL,UAAU;QACV,MAAM,EAAE,UAAU,KAAK,MAAM;KAC9B,CAAC,EACF,CAAC,UAAU,CAAC,CACb,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 订阅前后台状态变化并返回当前前台状态。
|
|
3
|
+
*
|
|
4
|
+
* @returns `{ isForeground }`。
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const { isForeground } = useForeground()
|
|
8
|
+
*/
|
|
9
|
+
export declare const useForeground: () => {
|
|
10
|
+
isForeground: boolean;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=use-foreground.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-foreground.d.ts","sourceRoot":"","sources":["../src/use-foreground.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,QAAO;IAAE,YAAY,EAAE,OAAO,CAAA;CAkBvD,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* 订阅前后台状态变化并返回当前前台状态。
|
|
4
|
+
*
|
|
5
|
+
* @returns `{ isForeground }`。
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const { isForeground } = useForeground()
|
|
9
|
+
*/
|
|
10
|
+
export const useForeground = () => {
|
|
11
|
+
const [isForeground, setIsForeground] = useState(() => !!xy.isForeground());
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const offBg = xy.onBackground(() => setIsForeground(false));
|
|
14
|
+
const offFg = xy.onForeground(() => setIsForeground(true));
|
|
15
|
+
return () => {
|
|
16
|
+
offBg();
|
|
17
|
+
offFg();
|
|
18
|
+
};
|
|
19
|
+
}, []);
|
|
20
|
+
return useMemo(() => ({
|
|
21
|
+
isForeground
|
|
22
|
+
}), [isForeground]);
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=use-foreground.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-foreground.js","sourceRoot":"","sources":["../src/use-foreground.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACpD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAA8B,EAAE;IAC3D,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAU,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,CAAA;IAEpF,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAA;QAC3D,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAA;QAC1D,OAAO,GAAG,EAAE;YACV,KAAK,EAAE,CAAA;YACP,KAAK,EAAE,CAAA;QACT,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,OAAO,CACZ,GAAG,EAAE,CAAC,CAAC;QACL,YAAY;KACb,CAAC,EACF,CAAC,YAAY,CAAC,CACf,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { XYVibrateImpact } from '@xiao-ying/miniapp-sdk';
|
|
2
|
+
/**
|
|
3
|
+
* 触感反馈 Hook 的配置项。
|
|
4
|
+
*
|
|
5
|
+
* @param impact - 震动强度;传 `false` 禁用。
|
|
6
|
+
* @param disabled - 是否禁用。
|
|
7
|
+
*/
|
|
8
|
+
export interface UseHapticFeedbackOptions {
|
|
9
|
+
impact?: XYVibrateImpact | false;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 返回可复用的触感反馈触发函数;禁用或不支持时为空操作。
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const haptic = useHapticFeedback({ impact: 'medium' })
|
|
17
|
+
* <button onClick={haptic}>Click</button>
|
|
18
|
+
*/
|
|
19
|
+
export declare const useHapticFeedback: (options?: UseHapticFeedbackOptions) => (() => void);
|
|
20
|
+
//# sourceMappingURL=use-haptic-feedback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-haptic-feedback.d.ts","sourceRoot":"","sources":["../src/use-haptic-feedback.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAE7D;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,eAAe,GAAG,KAAK,CAAA;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAS,wBAA6B,KAAG,CAAC,MAAM,IAAI,CAUrF,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* 返回可复用的触感反馈触发函数;禁用或不支持时为空操作。
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* const haptic = useHapticFeedback({ impact: 'medium' })
|
|
7
|
+
* <button onClick={haptic}>Click</button>
|
|
8
|
+
*/
|
|
9
|
+
export const useHapticFeedback = (options = {}) => {
|
|
10
|
+
const { impact = 'selection', disabled = false } = options;
|
|
11
|
+
return useCallback(() => {
|
|
12
|
+
if (disabled || impact === false)
|
|
13
|
+
return;
|
|
14
|
+
if (typeof xy.vibrate !== 'function')
|
|
15
|
+
return;
|
|
16
|
+
void xy.vibrate({ impact }).catch(() => {
|
|
17
|
+
/* best-effort */
|
|
18
|
+
});
|
|
19
|
+
}, [disabled, impact, xy]);
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=use-haptic-feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-haptic-feedback.js","sourceRoot":"","sources":["../src/use-haptic-feedback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAcnC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,UAAoC,EAAE,EAAgB,EAAE;IACxF,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IAE1D,OAAO,WAAW,CAAC,GAAG,EAAE;QACtB,IAAI,QAAQ,IAAI,MAAM,KAAK,KAAK;YAAE,OAAM;QACxC,IAAI,OAAO,EAAE,CAAC,OAAO,KAAK,UAAU;YAAE,OAAM;QAC5C,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACrC,iBAAiB;QACnB,CAAC,CAAC,CAAA;IACJ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAA;AAC5B,CAAC,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { XYMediaQuery } from '@xiao-ying/miniapp-sdk';
|
|
2
|
+
/**
|
|
3
|
+
* useMediaQuery 的返回结果(安全区、尺寸、DPR 等)。
|
|
4
|
+
*
|
|
5
|
+
* @property safeAreaInsets - 安全区内边距(px)。
|
|
6
|
+
* @property size - 视口尺寸(px)。
|
|
7
|
+
* @property devicePixelRatio - 设备 DPR。
|
|
8
|
+
*/
|
|
9
|
+
export interface UseMediaQueryResult extends XYMediaQuery {
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 获取媒体查询信息(安全区/尺寸/DPR),基于当前 `xy.mediaQuery` 快照。
|
|
13
|
+
*
|
|
14
|
+
* @returns 规范化后的媒体查询信息(数值兜底)。
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const { safeAreaInsets } = useMediaQuery()
|
|
18
|
+
*/
|
|
19
|
+
export declare const useMediaQuery: () => UseMediaQueryResult;
|
|
20
|
+
//# sourceMappingURL=use-media-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-media-query.d.ts","sourceRoot":"","sources":["../src/use-media-query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAE1D;;;;;;GAMG;AACH,MAAM,WAAW,mBAAoB,SAAQ,YAAY;CACxD;AAOD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,QAAO,mBAqBhC,CAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
const clampInset = (value) => {
|
|
3
|
+
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
4
|
+
return 0;
|
|
5
|
+
return Math.max(0, value);
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* 获取媒体查询信息(安全区/尺寸/DPR),基于当前 `xy.mediaQuery` 快照。
|
|
9
|
+
*
|
|
10
|
+
* @returns 规范化后的媒体查询信息(数值兜底)。
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const { safeAreaInsets } = useMediaQuery()
|
|
14
|
+
*/
|
|
15
|
+
export const useMediaQuery = () => {
|
|
16
|
+
return useMemo(() => {
|
|
17
|
+
const mediaQuery = (xy.mediaQuery ?? {});
|
|
18
|
+
const insets = mediaQuery.safeAreaInsets ?? {};
|
|
19
|
+
const statusBarHeight = clampInset(mediaQuery.statusBarHeight);
|
|
20
|
+
const devicePixelRatio = typeof mediaQuery.devicePixelRatio === 'number' && Number.isFinite(mediaQuery.devicePixelRatio)
|
|
21
|
+
? mediaQuery.devicePixelRatio
|
|
22
|
+
: 1;
|
|
23
|
+
return {
|
|
24
|
+
statusBarHeight,
|
|
25
|
+
safeAreaInsets: {
|
|
26
|
+
top: clampInset(insets.top),
|
|
27
|
+
bottom: clampInset(insets.bottom),
|
|
28
|
+
left: clampInset(insets.left),
|
|
29
|
+
right: clampInset(insets.right)
|
|
30
|
+
},
|
|
31
|
+
size: mediaQuery.size,
|
|
32
|
+
devicePixelRatio
|
|
33
|
+
};
|
|
34
|
+
}, [xy.mediaQuery]);
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=use-media-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-media-query.js","sourceRoot":"","sources":["../src/use-media-query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAa/B,MAAM,UAAU,GAAG,CAAC,KAAc,EAAU,EAAE;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAA;IAClE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;AAC3B,CAAC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAwB,EAAE;IACrD,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,UAAU,GAAG,CAAC,EAAE,CAAC,UAAU,IAAI,EAAE,CAA0B,CAAA;QACjE,MAAM,MAAM,GAAG,UAAU,CAAC,cAAc,IAAI,EAAE,CAAA;QAC9C,MAAM,eAAe,GAAG,UAAU,CAAC,UAAU,CAAC,eAAe,CAAC,CAAA;QAC9D,MAAM,gBAAgB,GACpB,OAAO,UAAU,CAAC,gBAAgB,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC;YAC7F,CAAC,CAAC,UAAU,CAAC,gBAAgB;YAC7B,CAAC,CAAC,CAAC,CAAA;QACP,OAAO;YACL,eAAe;YACf,cAAc,EAAE;gBACd,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC;gBAC3B,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;gBACjC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC;gBAC7B,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC;aAChC;YACD,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,gBAAgB;SACjB,CAAA;IACH,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;AACrB,CAAC,CAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { XYErrorInfo } from '@xiao-ying/miniapp-sdk';
|
|
2
|
+
type XYRuntime = XYErrorInfo['runtime'];
|
|
3
|
+
/**
|
|
4
|
+
* SDK 错误过滤条件。
|
|
5
|
+
*
|
|
6
|
+
* - `method`: 过滤指定方法名
|
|
7
|
+
* - `code`: 过滤指定错误码
|
|
8
|
+
* - `runtime`: 过滤运行时(app/browser/unknown)
|
|
9
|
+
*/
|
|
10
|
+
export interface UseSdkErrorFilter {
|
|
11
|
+
method?: string | string[];
|
|
12
|
+
code?: string | string[];
|
|
13
|
+
runtime?: XYRuntime | XYRuntime[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* useSdkError 配置项。
|
|
17
|
+
*
|
|
18
|
+
* @param enabled - 是否启用订阅(默认 `true`)。
|
|
19
|
+
* @param limit - 缓存的错误数量上限(默认 `8`)。
|
|
20
|
+
* @param filter - 过滤条件。
|
|
21
|
+
*/
|
|
22
|
+
export interface UseSdkErrorOptions {
|
|
23
|
+
enabled?: boolean;
|
|
24
|
+
limit?: number;
|
|
25
|
+
filter?: UseSdkErrorFilter;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* useSdkError 返回值。
|
|
29
|
+
*
|
|
30
|
+
* - `latest`: 最新错误
|
|
31
|
+
* - `errors`: 错误列表
|
|
32
|
+
* - `clear`: 清空错误
|
|
33
|
+
*/
|
|
34
|
+
export interface UseSdkErrorResult {
|
|
35
|
+
latest?: XYErrorInfo;
|
|
36
|
+
errors: XYErrorInfo[];
|
|
37
|
+
clear: () => void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 订阅 SDK 错误并在组件内维护错误列表。
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* const { latest, errors, clear } = useSdkError({ filter: { method: 'request' } })
|
|
44
|
+
*/
|
|
45
|
+
export declare const useSdkError: (options?: UseSdkErrorOptions) => UseSdkErrorResult;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=use-sdk-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-sdk-error.d.ts","sourceRoot":"","sources":["../src/use-sdk-error.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAEzD,KAAK,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC,CAAA;AAEvC;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACxB,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,EAAE,CAAA;CAClC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,iBAAiB,CAAA;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAUD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,UAAS,kBAAuB,KAAG,iBAmD9D,CAAA"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
+
const normalizeFilterSet = (value) => {
|
|
3
|
+
if (typeof value === 'undefined')
|
|
4
|
+
return undefined;
|
|
5
|
+
const items = Array.isArray(value) ? value : [value];
|
|
6
|
+
const normalized = items.filter((item) => typeof item === 'string' && item.length > 0);
|
|
7
|
+
if (normalized.length === 0)
|
|
8
|
+
return undefined;
|
|
9
|
+
return new Set(normalized);
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* 订阅 SDK 错误并在组件内维护错误列表。
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* const { latest, errors, clear } = useSdkError({ filter: { method: 'request' } })
|
|
16
|
+
*/
|
|
17
|
+
export const useSdkError = (options = {}) => {
|
|
18
|
+
const { enabled = true, limit = 8, filter } = options;
|
|
19
|
+
const resolvedLimit = Number.isFinite(limit) ? limit : 8;
|
|
20
|
+
const methodSet = useMemo(() => normalizeFilterSet(filter?.method), [filter?.method]);
|
|
21
|
+
const codeSet = useMemo(() => normalizeFilterSet(filter?.code), [filter?.code]);
|
|
22
|
+
const runtimeSet = useMemo(() => normalizeFilterSet(filter?.runtime), [filter?.runtime]);
|
|
23
|
+
const matchesFilter = useCallback((info) => {
|
|
24
|
+
if (methodSet && !methodSet.has(info.method))
|
|
25
|
+
return false;
|
|
26
|
+
if (codeSet && !codeSet.has(info.code))
|
|
27
|
+
return false;
|
|
28
|
+
if (runtimeSet && !runtimeSet.has(info.runtime))
|
|
29
|
+
return false;
|
|
30
|
+
return true;
|
|
31
|
+
}, [methodSet, codeSet, runtimeSet]);
|
|
32
|
+
const [errors, setErrors] = useState([]);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (!enabled || typeof xy.onError !== 'function') {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const unsubscribe = xy.onError((info) => {
|
|
38
|
+
if (!matchesFilter(info))
|
|
39
|
+
return;
|
|
40
|
+
setErrors((prev) => {
|
|
41
|
+
const next = [info, ...prev];
|
|
42
|
+
if (resolvedLimit <= 0)
|
|
43
|
+
return next;
|
|
44
|
+
return next.slice(0, resolvedLimit);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
return () => {
|
|
48
|
+
if (typeof unsubscribe === 'function') {
|
|
49
|
+
unsubscribe();
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}, [enabled, matchesFilter, resolvedLimit, xy]);
|
|
53
|
+
const clear = useCallback(() => setErrors([]), []);
|
|
54
|
+
return useMemo(() => ({
|
|
55
|
+
latest: errors[0],
|
|
56
|
+
errors,
|
|
57
|
+
clear
|
|
58
|
+
}), [errors, clear]);
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=use-sdk-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-sdk-error.js","sourceRoot":"","sources":["../src/use-sdk-error.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { MaybePromise, XyShareData, XyShareHandlerPayload } from '@xiao-ying/miniapp-sdk';
|
|
2
|
+
type SharePayload = Omit<XyShareHandlerPayload, 'path'> & {
|
|
3
|
+
path?: string;
|
|
4
|
+
};
|
|
5
|
+
type ShareHandler = () => MaybePromise<SharePayload | XyShareData | null | undefined>;
|
|
6
|
+
/**
|
|
7
|
+
* 注册分享处理器,自动补齐默认 path 与 title。
|
|
8
|
+
*
|
|
9
|
+
* - 传入函数:自定义动态返回分享数据
|
|
10
|
+
* - 传入对象:作为静态配置
|
|
11
|
+
* - 不传:使用默认配置(自动 path/title)
|
|
12
|
+
*
|
|
13
|
+
* @param input - 处理器函数或静态分享对象。
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* useShare(() => ({
|
|
17
|
+
* title: '示例',
|
|
18
|
+
* path: '/home'
|
|
19
|
+
* }))
|
|
20
|
+
*/
|
|
21
|
+
export declare const useShare: (input?: ShareHandler | SharePayload | XyShareData | null) => void;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=use-share.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-share.d.ts","sourceRoot":"","sources":["../src/use-share.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAE9F,KAAK,YAAY,GAAG,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,GAAG;IACxD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAgCD,KAAK,YAAY,GAAG,MAAM,YAAY,CAAC,YAAY,GAAG,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;AAErF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,QAAQ,GAAI,QAAQ,YAAY,GAAG,YAAY,GAAG,WAAW,GAAG,IAAI,KAAG,IA6BnF,CAAA"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { useEffect, useMemo } from 'react';
|
|
2
|
+
const buildDefaultSharePath = () => {
|
|
3
|
+
if (typeof window === 'undefined' || typeof window.location === 'undefined')
|
|
4
|
+
return undefined;
|
|
5
|
+
const { hash, pathname, search } = window.location;
|
|
6
|
+
// Hash Router:使用 hash 部分作为真实路径(包含查询)
|
|
7
|
+
if (hash && hash !== '#') {
|
|
8
|
+
const hashBody = hash.slice(1); // 去掉开头的 #
|
|
9
|
+
const normalized = hashBody.startsWith('/') ? hashBody : `/${hashBody}`;
|
|
10
|
+
return `/#${normalized}`;
|
|
11
|
+
}
|
|
12
|
+
// 非 hash:直接使用 pathname + search
|
|
13
|
+
const safePath = pathname && pathname.startsWith('/') ? pathname : `/${pathname ?? ''}`;
|
|
14
|
+
const safeSearch = typeof search === 'string' ? search : '';
|
|
15
|
+
return `${safePath || '/'}${safeSearch}`;
|
|
16
|
+
};
|
|
17
|
+
const normalizeSharePath = (path) => {
|
|
18
|
+
const hashIndex = path.indexOf('#');
|
|
19
|
+
if (hashIndex === -1)
|
|
20
|
+
return path;
|
|
21
|
+
const afterHash = path.slice(hashIndex + 1);
|
|
22
|
+
if (!afterHash)
|
|
23
|
+
return '/';
|
|
24
|
+
return afterHash.startsWith('/') ? afterHash : `/${afterHash}`;
|
|
25
|
+
};
|
|
26
|
+
const buildDefaultShareTitle = () => {
|
|
27
|
+
const name = typeof xy.manifest?.name === 'string' ? xy.manifest.name.trim() : '';
|
|
28
|
+
return name || '小应生活';
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* 注册分享处理器,自动补齐默认 path 与 title。
|
|
32
|
+
*
|
|
33
|
+
* - 传入函数:自定义动态返回分享数据
|
|
34
|
+
* - 传入对象:作为静态配置
|
|
35
|
+
* - 不传:使用默认配置(自动 path/title)
|
|
36
|
+
*
|
|
37
|
+
* @param input - 处理器函数或静态分享对象。
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* useShare(() => ({
|
|
41
|
+
* title: '示例',
|
|
42
|
+
* path: '/home'
|
|
43
|
+
* }))
|
|
44
|
+
*/
|
|
45
|
+
export const useShare = (input) => {
|
|
46
|
+
const resolveHandler = useMemo(() => {
|
|
47
|
+
if (typeof input === 'function')
|
|
48
|
+
return input;
|
|
49
|
+
if (!input)
|
|
50
|
+
return () => ({});
|
|
51
|
+
const payload = input;
|
|
52
|
+
return () => payload;
|
|
53
|
+
}, [input]);
|
|
54
|
+
const wrappedHandler = useMemo(() => async () => {
|
|
55
|
+
const res = await resolveHandler();
|
|
56
|
+
if (!res || typeof res !== 'object')
|
|
57
|
+
return res;
|
|
58
|
+
let path = res.path ?? buildDefaultSharePath();
|
|
59
|
+
const title = res.title ?? buildDefaultShareTitle();
|
|
60
|
+
if (!path)
|
|
61
|
+
return null;
|
|
62
|
+
path = normalizeSharePath(path);
|
|
63
|
+
// 返回符合 XyShareData 的结构,确保 path 为 string
|
|
64
|
+
const { path: _ignoredPath, title: _ignoredTitle, ...rest } = res;
|
|
65
|
+
return { ...rest, path, title };
|
|
66
|
+
}, [resolveHandler]);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
xy.setShareHandler(wrappedHandler);
|
|
69
|
+
return () => xy.setShareHandler(null);
|
|
70
|
+
}, [wrappedHandler, xy]);
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=use-share.js.map
|