@peng_kai/kit 0.1.3 → 0.1.5

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.
@@ -29,7 +29,7 @@ const loading = computed(() => {
29
29
  });
30
30
 
31
31
  function filter() {
32
- props.filterParams?.update?.();
32
+ props.filterParams?.update?.({ page: 1 });
33
33
  emits('filter');
34
34
  }
35
35
 
@@ -42,7 +42,7 @@ function reset() {
42
42
 
43
43
  <template>
44
44
  <div class="flex-none flex w-min ml-auto">
45
- <AButton class="mr-2 filter-btn" type="primary" htmlType="submit" :loading="loading" @click="filter()">
45
+ <AButton class="filter-btn mr2" type="primary" htmlType="submit" :loading="loading" @click="filter()">
46
46
  查询
47
47
  </AButton>
48
48
  <AButton :disabled="loading" @click="reset()">
@@ -4,6 +4,15 @@ import { reactive } from 'vue';
4
4
  interface PageParams { page?: string | number, page_size?: string | number };
5
5
  const defaultPageParams: PageParams = { page: 1, page_size: 10 };
6
6
 
7
+ /**
8
+ * 用于管理筛选参数
9
+ *
10
+ * @param _api - API 函数。
11
+ * @param buildParams - 构建参数的函数。
12
+ * @param pageParams - 默认的页面参数。
13
+ *
14
+ * @returns 包含筛选参数和更新函数的对象。
15
+ */
7
16
  export function useFilterParams<R extends Api.Request, AP extends Api.GetParam<R>, BP extends AP>(
8
17
  _api: R,
9
18
  buildParams: () => BP,
@@ -16,7 +16,7 @@ async function getRoutes() {
16
16
  for (const name in routeFiles) {
17
17
  const module: any = await routeFiles[name]();
18
18
 
19
- if (Object.hasOwn(module?.default ?? {}, RouteSymbol))
19
+ if (module?.default?.[RouteSymbol])
20
20
  Array.prototype.push.apply(routes, module.default());
21
21
  }
22
22
 
@@ -16,7 +16,7 @@ export async function getRouteGuards() {
16
16
  for (const name in routeGuardFiles) {
17
17
  const module: any = await routeGuardFiles[name]();
18
18
 
19
- if (Object.hasOwn(module?.default ?? {}, RouteGuardSymbol)) {
19
+ if (module?.default?.[RouteGuardSymbol]) {
20
20
  const guard = module.default;
21
21
 
22
22
  routeGuards.push(guard);
@@ -11,7 +11,7 @@ export async function getStartups() {
11
11
  const module: any = await moduleLoader();
12
12
  const plugin: StartupFn = module?.default ?? {};
13
13
 
14
- if (!Object.hasOwn(plugin, StartupSymbol))
14
+ if (!plugin?.[StartupSymbol])
15
15
  continue;
16
16
 
17
17
  startupPaths.push(path);
@@ -85,14 +85,71 @@
85
85
  display: flex;
86
86
  min-height: 56px;
87
87
  align-items: center;
88
- justify-content: center;
88
+ justify-content: flex-end;
89
89
  padding: 0 var(--padding-size);
90
90
  border-top: 1px solid var(--antd-colorBorderSecondary);
91
91
  margin: 0;
92
92
  }
93
93
  }
94
94
 
95
- // 查询器基本样式
95
+ // 抽屉的基本款样式
96
+ .ant-drawer.antd-cover__basic-drawer {
97
+ --padding-size: 22px;
98
+
99
+ // --min-body-height: ;
100
+ // --max-body-height: ;
101
+ // --body-height: ;
102
+
103
+ .ant-drawer-content {
104
+ padding: 0;
105
+ }
106
+
107
+ .ant-drawer-close {
108
+ display: flex;
109
+ align-items: center;
110
+ justify-content: center;
111
+ width: 22px;
112
+ height: 22px;
113
+ padding: 0;
114
+ }
115
+
116
+ .ant-drawer-header {
117
+ display: flex;
118
+ align-items: center;
119
+ min-height: 56px;
120
+ padding: 0 var(--padding-size);
121
+ margin: 0;
122
+ border-bottom: 1px solid var(--antd-colorBorderSecondary);
123
+ }
124
+
125
+ .ant-drawer-body {
126
+ height: var(--body-height, auto);
127
+ min-height: var(--min-body-height, auto);
128
+ max-height: var(--max-body-height, auto);
129
+ padding: var(--padding-size);
130
+ overflow-y: auto;
131
+
132
+ &:empty {
133
+ height: var(--min-body-height, 150px);
134
+ }
135
+ }
136
+
137
+ .ant-drawer-footer {
138
+ display: flex;
139
+ align-items: center;
140
+ justify-content: flex-end;
141
+ min-height: 56px;
142
+ padding: 0 var(--padding-size);
143
+ margin: 0;
144
+ border-top: 1px solid var(--antd-colorBorderSecondary);
145
+
146
+ & > *:not(:first-of-type) {
147
+ margin-left: 8px;
148
+ }
149
+ }
150
+ }
151
+
152
+ // 查询器表单基本样式
96
153
  .ant-form.ant-form__filter {
97
154
  display: flex;
98
155
  flex-wrap: wrap;
@@ -4,7 +4,7 @@ export declare interface AppPermissionCodes {}
4
4
  export declare interface AppRouteNames {}
5
5
 
6
6
  /** 权限 code 类型辅助(permission code) */
7
- export const pc_ = createSelfKeyProxy<{ [K in keyof AppPermissionCodes]: K }>();
7
+ export const PC = createSelfKeyProxy<{ [K in keyof AppPermissionCodes]: K }>();
8
8
 
9
9
  /** 路由 name 类型辅助(route name) */
10
- export const rn_ = createSelfKeyProxy<{ [K in keyof AppRouteNames]: K }>();
10
+ export const RN = createSelfKeyProxy<{ [K in keyof AppRouteNames]: K }>();
@@ -6,7 +6,7 @@ import type { ComponentProps } from 'vue-component-type-helpers';
6
6
  import type { Writable } from 'type-fest';
7
7
  import { useComponentRef } from '../../vue';
8
8
 
9
- const defaultDrawerProps: DrawerProps = { open: false, destroyOnClose: true };
9
+ const defaultDrawerProps: DrawerProps = { open: false, destroyOnClose: true, rootClassName: 'antd-cover__basic-drawer' };
10
10
 
11
11
  interface IComponentConfig<Comp extends Component> {
12
12
  is: Comp
@@ -34,7 +34,7 @@ export function useAntdDrawer<Comp extends Component>(
34
34
  _drawerProps.open = false;
35
35
  };
36
36
 
37
- const DrawerExtra = defineComponent({
37
+ const DrawerFooter = defineComponent({
38
38
  setup() {
39
39
  const cancelBtnProps: ButtonProps = reactive({ onClick: close });
40
40
  const confirmBtnProps: ButtonProps = reactive({
@@ -62,7 +62,7 @@ export function useAntdDrawer<Comp extends Component>(
62
62
  },
63
63
  });
64
64
 
65
- _drawerProps.extra = _drawerProps.extra === undefined ? h(DrawerExtra) : _drawerProps.extra;
65
+ _drawerProps.footer = _drawerProps.footer === undefined ? h(DrawerFooter) : _drawerProps.footer;
66
66
  _drawerProps['onUpdate:open'] = (visiable) => {
67
67
  _drawerProps.open = visiable;
68
68
  };
@@ -1,4 +1,4 @@
1
- import { computed } from 'vue';
1
+ import { computed, reactive } from 'vue';
2
2
  import type { UseQueryReturnType } from '@tanstack/vue-query';
3
3
  import type { Table, TableProps } from 'ant-design-vue';
4
4
  import type { ColumnType } from 'ant-design-vue/es/table/interface';
@@ -11,6 +11,7 @@ export function useAntdTable<
11
11
  type RecordType = GetRecordType<UQRR>;
12
12
  type LocalTableProps = TableProps<RecordType>;
13
13
  type LocalColumnsType = NonNullable<LocalTableProps['columns']>;
14
+ type LocalTableRowSelection = NonNullable<LocalTableProps['rowSelection']>;
14
15
 
15
16
  const { data, isFetching, isLoading } = uqrt;
16
17
 
@@ -18,7 +19,15 @@ export function useAntdTable<
18
19
  const page = queryParams.page_size !== pagination.pageSize ? 1 : pagination.current;
19
20
  Object.assign(queryParams, { page, page_size: pagination.pageSize ?? 10 });
20
21
  };
21
- const defineColumns = (columnsFn: () => LocalColumnsType) => computed(columnsFn);
22
+ const defineColumns = (columnsGetter: () => LocalColumnsType) => computed(columnsGetter);
23
+ const defineRowSelection = (rowSelectionGetter: () => LocalTableRowSelection) => {
24
+ const rowSelection = reactive(rowSelectionGetter());
25
+
26
+ rowSelection.selectedRowKeys ??= [];
27
+ rowSelection.onChange ??= keys => rowSelection.selectedRowKeys = keys;
28
+
29
+ return rowSelection;
30
+ };
22
31
 
23
32
  const tableProps = computed<LocalTableProps>(() => {
24
33
  const { list, pagination } = data.value ?? {};
@@ -60,6 +69,8 @@ export function useAntdTable<
60
69
  bodyCellType,
61
70
  /** 【类型辅助】用于定义出类型精确的 columns */
62
71
  defineColumns,
72
+ /** 【类型辅助】用于定义出类型精确的 rowSelection */
73
+ defineRowSelection,
63
74
  onPaginationChange,
64
75
  };
65
76
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@peng_kai/kit",
3
3
  "type": "module",
4
- "version": "0.1.3",
4
+ "version": "0.1.5",
5
5
  "description": "",
6
6
  "author": "",
7
7
  "license": "ISC",
@@ -29,6 +29,7 @@
29
29
  "@babel/types": "^7.23.5",
30
30
  "@tanstack/vue-query": "^4.37.1",
31
31
  "@vueuse/core": "^10.6.1",
32
+ "a-calc": "^1.3.8",
32
33
  "ant-design-vue": "^4.0.7",
33
34
  "axios": "^1.6.2",
34
35
  "bignumber.js": "^9.1.2",
package/pnpm-lock.yaml CHANGED
@@ -23,6 +23,9 @@ dependencies:
23
23
  '@vueuse/core':
24
24
  specifier: ^10.6.1
25
25
  version: 10.6.1(vue@3.3.8)
26
+ a-calc:
27
+ specifier: ^1.3.8
28
+ version: 1.3.8
26
29
  ant-design-vue:
27
30
  specifier: ^4.0.7
28
31
  version: 4.0.7(vue@3.3.8)
@@ -1549,6 +1552,12 @@ packages:
1549
1552
  through: 2.3.8
1550
1553
  dev: true
1551
1554
 
1555
+ /a-calc@1.3.8:
1556
+ resolution: {integrity: sha512-/YQ+RActls7GQYXjCYP135DEwMC7tdUFfEiR65pnjsZ4N1Uvtz3MKlpw2RHI0hoDraJ2Ih9zjcAAERxnKL4qng==}
1557
+ dependencies:
1558
+ typescript-treasure: 0.0.9
1559
+ dev: false
1560
+
1552
1561
  /acorn-jsx@5.3.2(acorn@8.11.2):
1553
1562
  resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
1554
1563
  peerDependencies:
@@ -4963,6 +4972,10 @@ packages:
4963
4972
  engines: {node: '>=16'}
4964
4973
  dev: true
4965
4974
 
4975
+ /typescript-treasure@0.0.9:
4976
+ resolution: {integrity: sha512-QPmpqJvQqZ7rt2iVNzPrtQNSFs1zVuTuP+jzE3np7qytEUcfSKtAW8RTDslldeAwaJjVJa0UM3ps1uVddpEMqQ==}
4977
+ dev: false
4978
+
4966
4979
  /typescript@5.2.2:
4967
4980
  resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
4968
4981
  engines: {node: '>=14.17'}
@@ -1,4 +1,5 @@
1
1
  import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
2
+ import { isSSR } from '../utils';
2
3
 
3
4
  export { createRequest };
4
5
 
@@ -17,6 +18,9 @@ function createRequest<Req, OResp, Resp = Api.TransformPageResult<OResp>>(
17
18
  // 返回 API 数据中的 data 字段值,默认
18
19
  async function request(reqData: Req, config?: ReqConfig): Promise<Api.GetDataField<Resp>>;
19
20
  async function request(reqData: Req, config?: ReqConfig): Promise<any> {
21
+ // if (isSSR())
22
+ // return null;
23
+
20
24
  const params = paramBuilder(reqData);
21
25
  const serviceName = params.headers?.['Service-Name'] ?? '';
22
26
  const service = createRequest.services[serviceName]?.server;
package/request/type.d.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  declare namespace Api {
2
- type Request = ((reqData: any, options?: Options) => Promise<any>) & { id: string };
2
+ type Request = ((reqData: any, options?: Options) => Promise<any>) & {
3
+ id: string
4
+ setDefaultConfig: (config: Partial<import('axios').AxiosRequestConfig>) => Request
5
+ };
3
6
  // type RequestPagination = (reqData: Partial<PageParam>, options?: Options) => Promise<PaginationData<any>>;
4
7
  interface PageParam {
5
8
  page: number
package/utils/date.ts ADDED
@@ -0,0 +1,44 @@
1
+ import dayjs from 'dayjs';
2
+ import relativeTime from 'dayjs/plugin/relativeTime';
3
+ import 'dayjs/locale/zh';
4
+ import 'dayjs/locale/en';
5
+
6
+ export { default as dayjs } from 'dayjs';
7
+
8
+ dayjs.locale('zh');
9
+ dayjs.extend(relativeTime);
10
+
11
+ /**
12
+ * 返回给定日期的一天的开始时间。
13
+ * @param day - 要获取一天的开始时间的日期。
14
+ * @returns 一天的开始时间作为Unix时间戳,如果输入无效则返回 undefined。
15
+ */
16
+ export function startOfDay(day: dayjs.ConfigType) {
17
+ const _day = dayjs(day);
18
+ return _day.isValid() ? _day.startOf('day').valueOf() : undefined;
19
+ }
20
+
21
+ /**
22
+ * 计算给定日期的当天结束时间。
23
+ * @param day - 要计算当天结束时间的日期。
24
+ * @returns 表示当天结束时间的时间戳值,如果输入无效则返回 undefined。
25
+ */
26
+ export function endOfDay(day: dayjs.ConfigType) {
27
+ const _day = dayjs(day);
28
+ return _day.isValid() ? _day.endOf('day').valueOf() : undefined;
29
+ }
30
+
31
+ /**
32
+ * 将秒数转换为时长格式化时间
33
+ * @param seconds 秒数
34
+ * @returns 时长格式化时间
35
+ */
36
+ export function secondsToDuration(seconds: number) {
37
+ const units = [['天', 24 * 60 * 60], ['时', 60 * 60], ['分', 60], ['秒', 1]] as const;
38
+
39
+ return units.reduce((duration, [label, durationValue]) => {
40
+ const value = Math.floor(seconds / durationValue);
41
+ seconds %= durationValue;
42
+ return value > 0 ? duration += `${value + label}` : duration;
43
+ }, '');
44
+ }
package/utils/index.ts CHANGED
@@ -18,9 +18,7 @@ export const ENV = {
18
18
  * @param dur 时长
19
19
  */
20
20
  export function sleep(dur: number) {
21
- return new Promise((resolve) => {
22
- setTimeout(resolve, dur);
23
- });
21
+ return new Promise(resolve => setTimeout(resolve, dur));
24
22
  }
25
23
 
26
24
  /**
@@ -30,9 +28,8 @@ export function hasToken() {
30
28
  return document.cookie.includes('has_token=1');
31
29
  }
32
30
 
33
- export function fixed() {
34
-
35
- // return (12).toFixed
31
+ export function isSSR() {
32
+ return typeof window === 'undefined';
36
33
  }
37
34
 
38
35
  /**
@@ -55,6 +52,15 @@ export function desensitize(str: string | undefined | null, startChars = 4, endC
55
52
  return truncatedStr;
56
53
  }
57
54
 
55
+ /**
56
+ * 生成指定长度的随机字符串
57
+ * @param length 要生成的随机字符串的长度
58
+ */
59
+ export function randomString(length: number) {
60
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
61
+ return Array.from({ length }, () => characters[Math.floor(Math.random() * characters.length)]).join('');
62
+ }
63
+
58
64
  /**
59
65
  * 对应链的浏览器地址
60
66
  * @param chain 链名
@@ -90,6 +96,10 @@ export function getScanBrowser(chain: string, hash: string, type: 'transaction'
90
96
  return `https://suiexplorer.com/${_type}/${hash}`;
91
97
  },
92
98
  ZKSYNC: () => `https://explorer.zksync.io/${evmType()}/${hash}`,
99
+ SOLANA: () => {
100
+ const _type = (<TypeMap>{ address: 'account' })[type] ?? type;
101
+ return `https://solscan.io/${_type}/${hash}`;
102
+ },
93
103
  }[_chain] ?? (() => '');
94
104
 
95
105
  return urlFn();
@@ -113,6 +123,10 @@ export function removeUrlSearchParam(key: string) {
113
123
  window.history.replaceState({}, '', url);
114
124
  }
115
125
 
126
+ /**
127
+ * 创建一个带有自身键的代理对象
128
+ * @returns 带有自身键的代理对象
129
+ */
116
130
  export function createSelfKeyProxy<T extends object>() {
117
131
  return new Proxy({} as T, {
118
132
  get(_, p) {
@@ -0,0 +1,49 @@
1
+ import { calc } from 'a-calc';
2
+
3
+ export { default as bn } from 'bignumber.js';
4
+ export { calc } from 'a-calc';
5
+
6
+ /**
7
+ * 常用的数值格式化规则
8
+ *
9
+ * 命名规则:
10
+ * - d-decimal: 保留的小数位
11
+ * - p-pad: 当小数位不够填充指定的小数位时,是否填充0
12
+ * - r-round: 舍入规则。可选规则: R5四舍五入、R6四舍六入、R1向上取整、R0向下取整
13
+ * - t-thousand: 是否使用千位符
14
+ * - n-number: 返回数字类型
15
+ */
16
+ export const numFmt = {
17
+ /** 保留18位小数,千位符 */
18
+ t: (num: any, err: any = null) => calc('a | <=18 ,', { a: String(num), _error: err }) as string | null,
19
+ /** 舍去小数,四舍五入,千位符 */
20
+ d0r5t: (num: any, err: any = null) => calc('a | =0 ~5 ,', { a: String(num), _error: err }) as string | null,
21
+ /** 舍去小数,向下取整,千位符 */
22
+ d0r0t: (num: any, err: any = null) => calc('a | =0 ~- ,', { a: String(num), _error: err }) as string | null,
23
+ /** 保留2位小数,四舍五入,千位符 */
24
+ d2r5t: (num: any, err: any = null) => calc('a | <=2 ~5 ,', { a: String(num), _error: err }) as string | null,
25
+ /** 保留2位小数,向下取整,千位符 */
26
+ d2r0t: (num: any, err: any = null) => calc('a | <=2 ~- ,', { a: String(num), _error: err }) as string | null,
27
+ /** 保留6位小数,四舍五入,千位符 */
28
+ d6r5t: (num: any, err: any = null) => calc('a | <=6 ~5 ,', { a: String(num), _error: err }) as string | null,
29
+ /** 保留6位小数,向下取整,千位符 */
30
+ d6r0t: (num: any, err: any = null) => calc('a | <=6 ~- ,', { a: String(num), _error: err }) as string | null,
31
+ /** 保留8位小数,四舍五入,千位符 */
32
+ d8r5t: (num: any, err: any = null) => calc('a | <=8 ~5 ,', { a: String(num), _error: err }) as string | null,
33
+ /** 保留8位小数,向下取整,千位符 */
34
+ d8r0t: (num: any, err: any = null) => calc('a | <=8 ~- ,', { a: String(num), _error: err }) as string | null,
35
+ };
36
+
37
+ /**
38
+ * 将给定的金额转换为格式化的字符串表示
39
+ * @param amount - 要转换的金额。
40
+ * @param decimal - 格式化字符串中包含的小数位数。默认为 0。
41
+ * @returns 金额的格式化字符串表示。
42
+ */
43
+ export function toAmount(amount: any, decimal: string | number = 0) {
44
+ const res = calc('a / 10 ** d', { a: String(amount), d: Number(decimal), _error: null });
45
+ const fmt = (fmt: keyof typeof numFmt) => (numFmt[fmt] ?? numFmt.t)(res);
46
+ fmt.toString = () => numFmt.t(res);
47
+
48
+ return fmt;
49
+ }
@@ -2,7 +2,13 @@ import { ref } from 'vue';
2
2
  import type { Component } from 'vue';
3
3
  import type { ComponentExposed } from 'vue-component-type-helpers';
4
4
 
5
- export function useComponentRef<C extends Component>(_component: C) {
5
+ /**
6
+ * 组件引用
7
+ * @param component 组件实例
8
+ * @returns 组件引用的代理对象
9
+ */
10
+ // eslint-disable-next-line unused-imports/no-unused-vars
11
+ export function useComponentRef<C extends Component>(component: C) {
6
12
  const _cpt = ref<any>();
7
13
  const refFn = (cpt: any) => {
8
14
  _cpt.value = cpt;
@@ -18,4 +18,9 @@ function _useIsDark() {
18
18
  return isDark;
19
19
  }
20
20
 
21
+ /**
22
+ * 返回一个布尔值,表示当前主题是否为暗色模式。
23
+ *
24
+ * @returns 当前主题是否为暗色模式的布尔值
25
+ */
21
26
  const useIsDark = createSharedComposable(_useIsDark);
@@ -1,5 +1,8 @@
1
1
  import { onMounted, ref } from 'vue';
2
2
 
3
+ /**
4
+ * 指示组件是否已挂载
5
+ */
3
6
  export function useIsMounted() {
4
7
  const mounted = ref(false);
5
8
 
@@ -1,5 +1,13 @@
1
- import { onMounted, ref } from 'vue';
1
+ import { h, onMounted, ref } from 'vue';
2
+ import type { VNode } from 'vue';
3
+ import type { ArrayValues } from 'type-fest';
4
+ import { randomString } from '../../utils';
2
5
 
6
+ /**
7
+ * 使用选择器获取传送目标
8
+ * @param selectors 选择器字符串
9
+ * @returns 传送目标的引用
10
+ */
3
11
  export function useTeleportTarget(selectors: string) {
4
12
  const target = ref<HTMLElement | null>();
5
13
 
@@ -10,4 +18,29 @@ export function useTeleportTarget(selectors: string) {
10
18
  });
11
19
 
12
20
  return target;
13
- }
21
+ }
22
+
23
+ /**
24
+ * 基于提供的顶级类和目标创建传送门选择器
25
+ * @param topClass 传送门选择器的顶级类
26
+ * @param targets 传送门的目标
27
+ */
28
+ export function createTeleportSelectors<TG extends string[]>(topClass: string, targets: TG) {
29
+ type TGK = ArrayValues<TG>;
30
+ type TRet = { topClass: string }
31
+ & { [K in `${TGK}Selector`]: string }
32
+ & { [K in `${TGK}Class`]: string }
33
+ & { [K in `${TGK}Target`]: (className?: string, tag?: string) => VNode };
34
+
35
+ const ret: Record<string, any> = {};
36
+ ret.topClass = `${topClass}-${randomString(6)}`;
37
+
38
+ targets.forEach((target) => {
39
+ const _target = ret[`${target}Class`] = `${target}_${randomString(6)}`;
40
+
41
+ ret[`${target}Selector`] = `.${ret.topClass} .${_target}`;
42
+ ret[`${target}Target`] = (className: string = '', tag: string = 'div') => h(tag, { className: `${_target} ${className}` });
43
+ });
44
+
45
+ return ret as TRet;
46
+ }
package/vue/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { useComponentRef } from './hooks/useComponentRef';
2
- export { useTeleportTarget } from './hooks/useTeleportTarget';
2
+ export { useTeleportTarget, createTeleportSelectors } from './hooks/useTeleportTarget';
3
3
  export { useIsMounted } from './hooks/useIsMounted';
4
4
  export { useIsDark } from './hooks/useIsDark';
5
5
  export { InfiniteQuery } from './components/infinite-query';