xladmin 0.1.8 → 0.2.7

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/README.md CHANGED
@@ -1,64 +1,82 @@
1
- # xladmin
1
+ <div align="center">
2
+ <a href="./README.md">
3
+ <img src="https://img.shields.io/badge/English-blue?style=for-the-badge" alt="English">
4
+ </a>
5
+ <a href="./docs/README.ru.md">
6
+ <img src="https://img.shields.io/badge/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9-red?style=for-the-badge" alt="Russian">
7
+ </a>
8
+ </div>
2
9
 
3
- `xladmin` это React + MUI frontend-пакет для admin UI поверх backend-пакета `xladmin`.
10
+ # xladmin
4
11
 
5
- Важно:
12
+ `xladmin` is the framework-agnostic React frontend for the `xladmin` backend.
6
13
 
7
- - имя пакета в npm: `xladmin`
8
- - импорт во frontend: `from 'xladmin'`
9
- - исходники монорепы: [Artasov/xladmin](https://github.com/Artasov/xladmin)
14
+ ## Install
10
15
 
11
- ## Что есть в библиотеке
16
+ ```bash
17
+ npm install xladmin
18
+ ```
12
19
 
13
- - transport-agnostic `XLAdminClient`
14
- - helpers для `axios` и `fetch`
15
- - `Shell`, `OverviewPage`, `ModelPage`, `ObjectPage`
16
- - `ModelsBlocks`, `FieldEditor`, `FormDialog`
17
- - встроенный RU / EN i18n
18
- - right sidebar list filters from backend `list_filters`
19
- - форматирование `date` и `datetime`
20
- - форматирование и редактирование `JSON` полей
21
- - ширины колонок списка через `FieldConfig.width_px`
22
- - image-preview через `FieldConfig.display_kind="image"`
23
- - обрезка длинных текстов в list-view
24
- - delete preview dialog перед single delete и bulk delete
25
- - сохранение раскрытости `ModelsBlocks` в `localStorage`
26
- - встроенная MUI theme `defaultAdminTheme`
20
+ You also need one router adapter:
27
21
 
28
- Короткие имена считаются основными. Старые `Admin*` имена оставлены как alias для совместимости.
22
+ - `xladmin-next`
23
+ - `xladmin-react-router`
29
24
 
30
- ## Основной API
25
+ ## What It Exports
31
26
 
32
- - `createXLAdminClient(...)`
33
- - `createAxiosXLAdminClient(...)`
34
- - `createFetchXLAdminClient(...)`
35
27
  - `Shell`
36
28
  - `OverviewPage`
37
29
  - `ModelPage`
38
30
  - `ObjectPage`
39
- - `ModelsBlocks`
40
- - `DeletePreviewDialog`
41
- - `defaultAdminTheme`
31
+ - `FormDialog`
32
+ - `FieldEditor`
33
+ - `NavLink`
34
+ - `createAxiosXLAdminClient(...)`
35
+ - `createFetchXLAdminClient(...)`
36
+ - `createBrowserXLAdminRouter(...)`
37
+ - admin types, i18n helpers, and default theme
38
+
39
+ ## Minimal Example
40
+
41
+ ```tsx
42
+ import {useEffect, useMemo, useState} from 'react';
43
+ import {Shell, OverviewPage, createAxiosXLAdminClient, type AdminModelMeta, type AdminModelsBlockMeta} from 'xladmin';
44
+ import axios from 'axios';
45
+
46
+ const api = axios.create({baseURL: '/api/admin'});
47
+
48
+ export function AdminApp() {
49
+ const client = useMemo(() => createAxiosXLAdminClient(api), []);
50
+ const [models, setModels] = useState<AdminModelMeta[]>([]);
51
+ const [blocks, setBlocks] = useState<AdminModelsBlockMeta[]>([]);
42
52
 
43
- ## Совместимость
53
+ useEffect(() => {
54
+ client.getModels().then((response) => {
55
+ setModels(response.items);
56
+ setBlocks(response.blocks);
57
+ });
58
+ }, [client]);
44
59
 
45
- - `React >=19,<20`
46
- - `React DOM >=19,<20`
47
- - `Next >=15,<17`
48
- - `@mui/material >=7,<8`
49
- - `@mui/icons-material >=7,<8`
50
- - `@mui/x-date-pickers >=8,<9`
51
- - `dayjs >=1,<2`
52
- - `axios >=1,<2` — опционально, только если проект использует axios-helper
60
+ return (
61
+ <Shell client={client} models={models} blocks={blocks} basePath="/admin" locale="en">
62
+ <OverviewPage client={client} basePath="/admin" />
63
+ </Shell>
64
+ );
65
+ }
66
+ ```
53
67
 
54
- ## Как подключать
68
+ For framework routing, use one of the adapter packages instead of the default browser router.
55
69
 
56
- Библиотека не требует именно `axios`.
70
+ ## Development
57
71
 
58
- Можно использовать:
72
+ ```bash
73
+ npm test
74
+ npm run check
75
+ npm run build
76
+ ```
59
77
 
60
- - `createAxiosXLAdminClient(api)` — если проект уже живёт на `axios instance`
61
- - `createFetchXLAdminClient({...})` — если проект работает через `fetch`
62
- - свой `XLAdminClient` — если проекту нужен полностью свой transport
78
+ ## Docs
63
79
 
64
- Практическая интеграция вынесена в [docs/HOW_TO_USE.md](docs/HOW_TO_USE.md).
80
+ - [Russian README](./docs/README.ru.md)
81
+ - [Frontend workspace](../../README.md)
82
+ - [Monorepo root](../../../README.md)
@@ -0,0 +1,22 @@
1
+ import type { XLAdminClient } from './client';
2
+ import type { AdminDetailResponse, AdminListResponse } from './types';
3
+ type ClientCacheBucket = {
4
+ detailResponseCache: Map<string, AdminDetailResponse>;
5
+ inFlightDetailRequests: Map<string, Promise<AdminDetailResponse>>;
6
+ listResponseCache: Map<string, AdminListResponse>;
7
+ inFlightListRequests: Map<string, Promise<AdminListResponse>>;
8
+ modelVersions: Map<string, number>;
9
+ };
10
+ export declare function buildDetailCacheKey(slug: string, id: string | number): string;
11
+ export declare function buildListCacheKey(slug: string, params: {
12
+ q?: string;
13
+ sort?: string;
14
+ limit?: number;
15
+ offset?: number;
16
+ } & Record<string, unknown>): string;
17
+ export declare function getClientCacheBucket(client: XLAdminClient): ClientCacheBucket;
18
+ export declare function getModelCacheVersion(client: XLAdminClient, slug: string): number;
19
+ export declare function setCachedListResponse(client: XLAdminClient, key: string, response: AdminListResponse): void;
20
+ export declare function setCachedDetailResponse(client: XLAdminClient, key: string, response: AdminDetailResponse): void;
21
+ export declare function invalidateModelCache(client: XLAdminClient, slug: string): void;
22
+ export {};
package/dist/client.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  import type { AdminChoicesResponse, AdminDeletePreviewResponse, AdminDetailResponse, AdminListResponse, AdminModelMeta, AdminModelsResponse, AdminObjectActionResponse } from './types';
2
+ export type XLAdminRequestOptions = {
3
+ signal?: AbortSignal;
4
+ };
2
5
  export type XLAdminClient = {
3
6
  getModels: () => Promise<AdminModelsResponse>;
4
7
  getModel: (slug: string) => Promise<AdminModelMeta>;
@@ -21,19 +24,19 @@ export type XLAdminClient = {
21
24
  processed: number;
22
25
  } & Record<string, unknown>>;
23
26
  runObjectAction: (slug: string, id: string | number, actionSlug: string, payload?: Record<string, unknown>) => Promise<AdminObjectActionResponse>;
24
- getChoices: (slug: string, fieldName: string, q?: string, ids?: Array<string | number>) => Promise<AdminChoicesResponse>;
25
- getFilterChoices: (slug: string, filterSlug: string, q?: string, ids?: Array<string | number>) => Promise<AdminChoicesResponse>;
27
+ getChoices: (slug: string, fieldName: string, q?: string, ids?: Array<string | number>, options?: XLAdminRequestOptions) => Promise<AdminChoicesResponse>;
28
+ getFilterChoices: (slug: string, filterSlug: string, q?: string, ids?: Array<string | number>, options?: XLAdminRequestOptions) => Promise<AdminChoicesResponse>;
26
29
  };
27
30
  type XLAdminTransportResponse<T> = T | {
28
31
  data: T;
29
32
  };
30
33
  export type XLAdminTransport = {
31
- get: <T>(url: string, options?: {
34
+ get: <T>(url: string, options?: XLAdminRequestOptions & {
32
35
  params?: Record<string, unknown>;
33
36
  }) => Promise<XLAdminTransportResponse<T>>;
34
- post: <T>(url: string, body?: Record<string, unknown>) => Promise<XLAdminTransportResponse<T>>;
35
- patch: <T>(url: string, body: Record<string, unknown>) => Promise<XLAdminTransportResponse<T>>;
36
- delete: (url: string) => Promise<unknown>;
37
+ post: <T>(url: string, body?: Record<string, unknown>, options?: XLAdminRequestOptions) => Promise<XLAdminTransportResponse<T>>;
38
+ patch: <T>(url: string, body: Record<string, unknown>, options?: XLAdminRequestOptions) => Promise<XLAdminTransportResponse<T>>;
39
+ delete: (url: string, options?: XLAdminRequestOptions) => Promise<unknown>;
37
40
  };
38
41
  export type XLAdminAxiosLike = XLAdminTransport;
39
42
  export type XLAdminFetchClientConfig = {
@@ -1,9 +1,11 @@
1
1
  import type { XLAdminClient } from '../client';
2
+ import type { XLAdminRouter } from '../router';
2
3
  type AdminModelPageProps = {
3
4
  client: XLAdminClient;
4
5
  basePath: string;
5
6
  slug: string;
7
+ router?: XLAdminRouter;
6
8
  };
7
9
  export type ModelPageProps = AdminModelPageProps;
8
- export declare function ModelPage({ client, basePath, slug }: ModelPageProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare function ModelPage({ client, basePath, slug, router }: ModelPageProps): import("react/jsx-runtime").JSX.Element;
9
11
  export {};
@@ -1,11 +1,13 @@
1
1
  import type { CSSProperties, ReactNode } from 'react';
2
+ import type { XLAdminRouter } from '../router';
2
3
  type AdminNavLinkProps = {
3
4
  href: string;
4
5
  children: ReactNode;
5
6
  style?: CSSProperties;
6
7
  title?: string;
7
8
  onClick?: () => void;
9
+ router?: XLAdminRouter;
8
10
  };
9
11
  export type NavLinkProps = AdminNavLinkProps;
10
- export declare function NavLink({ href, children, style, title, onClick }: NavLinkProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function NavLink({ href, children, style, title, onClick, router }: NavLinkProps): import("react/jsx-runtime").JSX.Element;
11
13
  export {};
@@ -1,11 +1,13 @@
1
1
  import 'dayjs/locale/en.js';
2
2
  import 'dayjs/locale/ru.js';
3
3
  import type { XLAdminClient } from '../client';
4
+ import type { XLAdminRouter } from '../router';
4
5
  type AdminObjectPageProps = {
5
6
  client: XLAdminClient;
6
7
  slug: string;
7
8
  id: string;
9
+ router?: XLAdminRouter;
8
10
  };
9
11
  export type ObjectPageProps = AdminObjectPageProps;
10
- export declare function ObjectPage({ client, slug, id }: ObjectPageProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function ObjectPage({ client, slug, id, router }: ObjectPageProps): import("react/jsx-runtime").JSX.Element;
11
13
  export {};
@@ -1,6 +1,7 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import { type Theme } from '@mui/material/styles';
3
3
  import type { XLAdminClient } from '../client';
4
+ import type { XLAdminRouter } from '../router';
4
5
  import type { AdminModelMeta, AdminModelsBlockMeta } from '../types';
5
6
  type AdminShellProps = {
6
7
  client: XLAdminClient;
@@ -10,7 +11,8 @@ type AdminShellProps = {
10
11
  locale?: string | null;
11
12
  children: ReactNode;
12
13
  theme?: Theme;
14
+ router?: XLAdminRouter;
13
15
  };
14
16
  export type ShellProps = AdminShellProps;
15
- export declare function Shell({ client, models, blocks, basePath, locale, children, theme }: ShellProps): import("react/jsx-runtime").JSX.Element;
17
+ export declare function Shell({ client, models, blocks, basePath, locale, children, theme, router }: ShellProps): import("react/jsx-runtime").JSX.Element;
16
18
  export {};
@@ -0,0 +1,73 @@
1
+ import type { XLAdminClient } from '../../client';
2
+ import type { AdminTranslationKey } from '../../i18n';
3
+ import type { XLAdminRouter } from '../../router';
4
+ import type { AdminDeletePreviewResponse, AdminListResponse } from '../../types';
5
+ type UseModelPageControllerOptions = {
6
+ client: XLAdminClient;
7
+ slug: string;
8
+ pathname: string;
9
+ locationSearch: string;
10
+ router: XLAdminRouter;
11
+ t: (key: AdminTranslationKey, params?: Record<string, string | number>) => string;
12
+ };
13
+ export declare function useModelPageController({ client, slug, pathname, locationSearch, router, t, }: UseModelPageControllerOptions): {
14
+ allVisibleSelected: boolean;
15
+ appliedFilters: Record<string, string>;
16
+ appliedQuery: string;
17
+ bulkActionMenuAnchor: HTMLElement | null;
18
+ bulkActions: import("../..").AdminBulkActionMeta[];
19
+ createOpen: boolean;
20
+ currentPage: number;
21
+ data: AdminListResponse | null;
22
+ deletePreview: AdminDeletePreviewResponse | null;
23
+ deletePreviewError: string | null;
24
+ deletePreviewOpen: boolean;
25
+ error: string | null;
26
+ fieldMap: Map<string, import("../..").AdminFieldMeta>;
27
+ filtersOpen: boolean;
28
+ handleConfirmDelete: () => Promise<void>;
29
+ handleFilterChange: (filterSlug: string, value: string) => void;
30
+ handleOpenRowMenu: (event: {
31
+ currentTarget: HTMLElement;
32
+ }, rowId: string | number) => void;
33
+ handlePageChange: (nextPage: number) => void;
34
+ handlePageInputCommit: () => void;
35
+ handleResetFilters: () => void;
36
+ handleRowDelete: (rowId: string | number) => Promise<void>;
37
+ handleRunNamedBulkAction: (actionSlug: string) => Promise<void>;
38
+ handleSearchCommit: (nextQuery: string) => void;
39
+ handleToggleAllVisible: (checked: boolean) => void;
40
+ handleToggleSelection: (rowId: string | number, checked: boolean) => void;
41
+ hasListFilters: boolean;
42
+ hasVisibleSelection: boolean;
43
+ isDeletePreviewLoading: boolean;
44
+ isDeleteSubmitting: boolean;
45
+ isLoading: boolean;
46
+ listFields: string[];
47
+ listFilters: import("../..").AdminListFilterMeta[];
48
+ meta: import("../..").AdminModelMeta | null;
49
+ pageInput: string;
50
+ pendingDeleteIds: (string | number)[];
51
+ pendingDeleteMode: "single" | "bulk";
52
+ refresh: () => Promise<void>;
53
+ rowActionMenuAnchor: HTMLElement | null;
54
+ rowActionMenuId: string | number | null;
55
+ rows: Record<string, unknown>[];
56
+ selectedIdSet: Set<string>;
57
+ selectedIds: (string | number)[];
58
+ setBulkActionMenuAnchor: import("react").Dispatch<import("react").SetStateAction<HTMLElement | null>>;
59
+ setCreateOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
60
+ setDeletePreview: import("react").Dispatch<import("react").SetStateAction<AdminDeletePreviewResponse | null>>;
61
+ setDeletePreviewError: import("react").Dispatch<import("react").SetStateAction<string | null>>;
62
+ setDeletePreviewOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
63
+ setFiltersOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
64
+ setPageInput: import("react").Dispatch<import("react").SetStateAction<string>>;
65
+ setPendingDeleteIds: import("react").Dispatch<import("react").SetStateAction<(string | number)[]>>;
66
+ setRowActionMenuAnchor: import("react").Dispatch<import("react").SetStateAction<HTMLElement | null>>;
67
+ setRowActionMenuId: import("react").Dispatch<import("react").SetStateAction<string | number | null>>;
68
+ sortFields: string[];
69
+ toggleSort: (fieldName: string) => void;
70
+ total: number;
71
+ totalPages: number;
72
+ };
73
+ export {};
@@ -0,0 +1,46 @@
1
+ import type { XLAdminClient } from '../../client';
2
+ import type { AdminTranslationKey } from '../../i18n';
3
+ import type { XLAdminRouter } from '../../router';
4
+ import type { AdminDeletePreviewResponse, AdminDetailResponse } from '../../types';
5
+ type UseObjectPageControllerOptions = {
6
+ client: XLAdminClient;
7
+ slug: string;
8
+ id: string;
9
+ listPath: string;
10
+ router: XLAdminRouter;
11
+ t: (key: AdminTranslationKey, params?: Record<string, string | number>) => string;
12
+ };
13
+ export declare function useObjectPageController({ client, slug, id, listPath, router, t, }: UseObjectPageControllerOptions): {
14
+ actionsAnchorEl: HTMLElement | null;
15
+ activeActionSlug: string | null;
16
+ data: AdminDetailResponse | null;
17
+ deleteConfirmOpen: boolean;
18
+ deletePreview: AdminDeletePreviewResponse | null;
19
+ deletePreviewError: string | null;
20
+ detailFields: string[];
21
+ editableFieldNames: Set<string>;
22
+ error: string | null;
23
+ fieldMap: Map<string, import("../..").AdminFieldMeta>;
24
+ handleDelete: () => Promise<void>;
25
+ handleFieldChange: (fieldName: string, nextValue: unknown) => void;
26
+ handleNavigateBack: () => void;
27
+ handleOpenDeletePreview: () => Promise<void>;
28
+ handleRunObjectAction: (actionSlug: string) => Promise<void>;
29
+ handleSave: () => Promise<void>;
30
+ initialValues: Record<string, unknown>;
31
+ isActionsMenuOpen: boolean;
32
+ isDeletePreviewLoading: boolean;
33
+ isDeleting: boolean;
34
+ isDirty: boolean;
35
+ isLoading: boolean;
36
+ isSaving: boolean;
37
+ meta: import("../..").AdminModelMeta | null;
38
+ objectActions: import("../..").AdminObjectActionMeta[];
39
+ objectTitle: string;
40
+ setActionsAnchorEl: import("react").Dispatch<import("react").SetStateAction<HTMLElement | null>>;
41
+ setDeleteConfirmOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
42
+ setDeletePreview: import("react").Dispatch<import("react").SetStateAction<AdminDeletePreviewResponse | null>>;
43
+ setDeletePreviewError: import("react").Dispatch<import("react").SetStateAction<string | null>>;
44
+ values: Record<string, unknown>;
45
+ };
46
+ export {};
@@ -0,0 +1,15 @@
1
+ type UseRemoteChoicesOptions<T> = {
2
+ enabled: boolean;
3
+ debounceMs?: number;
4
+ initialItems?: T[];
5
+ resetKey?: string;
6
+ queryKey: string;
7
+ load: (signal: AbortSignal) => Promise<T[]>;
8
+ merge?: (current: T[], next: T[]) => T[];
9
+ };
10
+ type UseRemoteChoicesResult<T> = {
11
+ items: T[];
12
+ isLoading: boolean;
13
+ };
14
+ export declare function useRemoteChoices<T>({ enabled, debounceMs, initialItems, resetKey, queryKey, load, merge, }: UseRemoteChoicesOptions<T>): UseRemoteChoicesResult<T>;
15
+ export {};
package/dist/i18n.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import type { AdminLocale } from './types';
3
- type AdminTranslationKey = 'admin_title' | 'loading' | 'overview' | 'overview_title' | 'overview_subtitle' | 'all_models' | 'all_models_description' | 'models_load_error' | 'model_load_error' | 'object_load_error' | 'object_save_error' | 'object_delete_error' | 'object_action_error' | 'search' | 'filters' | 'active_filters' | 'reset_filters' | 'create' | 'all' | 'actions' | 'selected_count' | 'delete' | 'save' | 'saving' | 'deleting' | 'executing' | 'cancel' | 'objects_count' | 'yes' | 'no' | 'delete_object_title' | 'delete_bulk_title' | 'delete_preview_hint' | 'delete_preview_blocked_hint' | 'delete_preview_roots' | 'delete_preview_delete' | 'delete_preview_protect' | 'delete_preview_set_null' | 'delete_preview_total' | 'delete_preview_empty' | 'delete_preview_loading' | 'delete_preview_error' | 'delete_preview_no_selection' | 'delete_effect_delete' | 'delete_effect_protect' | 'delete_effect_set_null' | 'invalid_json' | 'back' | 'menu' | 'show_details' | 'hide_details' | 'staff_only';
3
+ export type AdminTranslationKey = 'admin_title' | 'loading' | 'overview' | 'overview_title' | 'overview_subtitle' | 'all_models' | 'all_models_description' | 'models_load_error' | 'model_load_error' | 'object_load_error' | 'object_save_error' | 'object_delete_error' | 'object_action_error' | 'search' | 'filters' | 'active_filters' | 'reset_filters' | 'create' | 'all' | 'actions' | 'selected_count' | 'delete' | 'save' | 'saving' | 'deleting' | 'executing' | 'cancel' | 'objects_count' | 'yes' | 'no' | 'delete_object_title' | 'delete_bulk_title' | 'delete_preview_hint' | 'delete_preview_blocked_hint' | 'delete_preview_roots' | 'delete_preview_delete' | 'delete_preview_protect' | 'delete_preview_set_null' | 'delete_preview_total' | 'delete_preview_empty' | 'delete_preview_loading' | 'delete_preview_error' | 'delete_preview_no_selection' | 'delete_effect_delete' | 'delete_effect_protect' | 'delete_effect_set_null' | 'invalid_json' | 'back' | 'menu' | 'show_details' | 'hide_details' | 'staff_only';
4
4
  type AdminLocaleProviderProps = {
5
5
  locale?: string | null;
6
6
  children: ReactNode;
package/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
- export { createAxiosXLAdminClient, createFetchXLAdminClient, createFetchXLAdminTransport, createXLAdminClient, type XLAdminAxiosLike, type XLAdminClient, type XLAdminFetchClientConfig, type XLAdminTransport, } from './client';
1
+ export { createAxiosXLAdminClient, createFetchXLAdminClient, createFetchXLAdminTransport, createXLAdminClient, type XLAdminAxiosLike, type XLAdminClient, type XLAdminFetchClientConfig, type XLAdminRequestOptions, type XLAdminTransport, } from './client';
2
+ export { XLAdminRouterProvider, buildUrlWithParams, createBrowserXLAdminRouter, handleNavLinkClick, type XLAdminAnchorProps, type XLAdminLocation, type XLAdminRouter, useXLAdminLocation, useXLAdminRouter, } from './router';
2
3
  export { FormDialog, type FormDialogProps } from './components/FormDialog';
3
4
  export { OverviewPage, type OverviewPageProps } from './components/OverviewPage';
4
5
  export { ModelPage, type ModelPageProps } from './components/ModelPage';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export { createAxiosXLAdminClient, createFetchXLAdminClient, createFetchXLAdminTransport, createXLAdminClient, type XLAdminAxiosLike, type XLAdminClient, type XLAdminFetchClientConfig, type XLAdminTransport, } from './client';
1
+ export { createAxiosXLAdminClient, createFetchXLAdminClient, createFetchXLAdminTransport, createXLAdminClient, type XLAdminAxiosLike, type XLAdminClient, type XLAdminFetchClientConfig, type XLAdminRequestOptions, type XLAdminTransport, } from './client';
2
+ export { XLAdminRouterProvider, buildUrlWithParams, createBrowserXLAdminRouter, handleNavLinkClick, type XLAdminAnchorProps, type XLAdminLocation, type XLAdminRouter, useXLAdminLocation, useXLAdminRouter, } from './router';
2
3
  export { FormDialog, type FormDialogProps } from './components/FormDialog';
3
4
  export { OverviewPage, type OverviewPageProps } from './components/OverviewPage';
4
5
  export { ModelPage, type ModelPageProps } from './components/ModelPage';