@h-ai/ui 0.1.0-alpha.67 → 0.1.0-alpha.68
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.en.md +31 -5
- package/README.ja.md +31 -5
- package/README.md +64 -38
- package/dist/components/compounds/Accordion.svelte +24 -0
- package/dist/components/compounds/Accordion.svelte.d.ts +34 -0
- package/dist/components/compounds/ActionSheet.svelte +24 -0
- package/dist/components/compounds/ActionSheet.svelte.d.ts +38 -0
- package/dist/components/compounds/Alert.svelte +15 -4
- package/dist/components/compounds/Alert.svelte.d.ts +10 -0
- package/dist/components/compounds/AppBar.svelte +24 -0
- package/dist/components/compounds/AppBar.svelte.d.ts +33 -0
- package/dist/components/compounds/BottomNav.svelte +37 -0
- package/dist/components/compounds/BottomNav.svelte.d.ts +43 -0
- package/dist/components/compounds/Breadcrumb.svelte +11 -0
- package/dist/components/compounds/Breadcrumb.svelte.d.ts +20 -0
- package/dist/components/compounds/Calendar.svelte +20 -6
- package/dist/components/compounds/Calendar.svelte.d.ts +20 -6
- package/dist/components/compounds/Card.svelte +10 -0
- package/dist/components/compounds/Card.svelte.d.ts +10 -0
- package/dist/components/compounds/Combobox.svelte +35 -18
- package/dist/components/compounds/Combobox.svelte.d.ts +35 -18
- package/dist/components/compounds/Confirm.svelte +11 -0
- package/dist/components/compounds/Confirm.svelte.d.ts +21 -0
- package/dist/components/compounds/DataTable.svelte +40 -17
- package/dist/components/compounds/DataTable.svelte.d.ts +9 -13
- package/dist/components/compounds/DatePicker.svelte +20 -6
- package/dist/components/compounds/DatePicker.svelte.d.ts +20 -6
- package/dist/components/compounds/Drawer.svelte +11 -0
- package/dist/components/compounds/Drawer.svelte.d.ts +21 -0
- package/dist/components/compounds/Dropdown.svelte +10 -0
- package/dist/components/compounds/Dropdown.svelte.d.ts +10 -0
- package/dist/components/compounds/Empty.svelte +16 -5
- package/dist/components/compounds/Empty.svelte.d.ts +20 -0
- package/dist/components/compounds/Form.svelte +37 -2
- package/dist/components/compounds/Form.svelte.d.ts +20 -0
- package/dist/components/compounds/FormField.svelte +11 -0
- package/dist/components/compounds/FormField.svelte.d.ts +20 -0
- package/dist/components/compounds/FormLayout.svelte +13 -1
- package/dist/components/compounds/FormLayout.svelte.d.ts +13 -0
- package/dist/components/compounds/InfiniteScroll.svelte +24 -0
- package/dist/components/compounds/InfiniteScroll.svelte.d.ts +34 -0
- package/dist/components/compounds/MessageBoxContainer.svelte +11 -0
- package/dist/components/compounds/MessageBoxContainer.svelte.d.ts +21 -0
- package/dist/components/compounds/MessageBoxDialog.svelte +14 -0
- package/dist/components/compounds/MessageBoxDialog.svelte.d.ts +21 -0
- package/dist/components/compounds/MessageContainer.svelte +11 -0
- package/dist/components/compounds/MessageContainer.svelte.d.ts +21 -0
- package/dist/components/compounds/Modal.svelte +10 -0
- package/dist/components/compounds/Modal.svelte.d.ts +10 -0
- package/dist/components/compounds/PageHeader.svelte +21 -8
- package/dist/components/compounds/PageHeader.svelte.d.ts +21 -8
- package/dist/components/compounds/Pagination.svelte +34 -8
- package/dist/components/compounds/Pagination.svelte.d.ts +20 -0
- package/dist/components/compounds/Popover.svelte +11 -0
- package/dist/components/compounds/Popover.svelte.d.ts +20 -0
- package/dist/components/compounds/PullRefresh.svelte +24 -0
- package/dist/components/compounds/PullRefresh.svelte.d.ts +32 -0
- package/dist/components/compounds/Result.svelte +11 -0
- package/dist/components/compounds/Result.svelte.d.ts +20 -0
- package/dist/components/compounds/SafeArea.svelte +24 -0
- package/dist/components/compounds/SafeArea.svelte.d.ts +32 -0
- package/dist/components/compounds/Skeleton.svelte +10 -0
- package/dist/components/compounds/Skeleton.svelte.d.ts +10 -0
- package/dist/components/compounds/Steps.svelte +11 -0
- package/dist/components/compounds/Steps.svelte.d.ts +20 -0
- package/dist/components/compounds/SwipeCell.svelte +24 -0
- package/dist/components/compounds/SwipeCell.svelte.d.ts +37 -0
- package/dist/components/compounds/TableToolbar.svelte +66 -28
- package/dist/components/compounds/TableToolbar.svelte.d.ts +29 -19
- package/dist/components/compounds/Tabs.svelte +58 -10
- package/dist/components/compounds/Tabs.svelte.d.ts +10 -0
- package/dist/components/compounds/TagInput.svelte +11 -0
- package/dist/components/compounds/TagInput.svelte.d.ts +20 -0
- package/dist/components/compounds/Timeline.svelte +24 -0
- package/dist/components/compounds/Timeline.svelte.d.ts +34 -0
- package/dist/components/compounds/ToastContainer.svelte +11 -0
- package/dist/components/compounds/ToastContainer.svelte.d.ts +26 -0
- package/dist/components/compounds/Tooltip.svelte +11 -0
- package/dist/components/compounds/Tooltip.svelte.d.ts +22 -0
- package/dist/components/compounds/accordion-types.d.ts +10 -1
- package/dist/components/compounds/action-sheet-types.d.ts +9 -0
- package/dist/components/compounds/bottom-nav-types.d.ts +9 -0
- package/dist/components/compounds/swipe-cell-types.d.ts +9 -0
- package/dist/components/compounds/timeline-types.d.ts +9 -0
- package/dist/components/control-size.d.ts +17 -0
- package/dist/components/control-size.js +8 -0
- package/dist/components/primitives/Avatar.svelte +10 -0
- package/dist/components/primitives/Avatar.svelte.d.ts +10 -0
- package/dist/components/primitives/Badge.svelte +10 -0
- package/dist/components/primitives/Badge.svelte.d.ts +10 -0
- package/dist/components/primitives/BareButton.svelte +11 -0
- package/dist/components/primitives/BareButton.svelte.d.ts +20 -0
- package/dist/components/primitives/BareInput.svelte +11 -0
- package/dist/components/primitives/BareInput.svelte.d.ts +20 -0
- package/dist/components/primitives/Button.svelte +10 -0
- package/dist/components/primitives/Button.svelte.d.ts +10 -0
- package/dist/components/primitives/Checkbox.svelte +11 -0
- package/dist/components/primitives/Checkbox.svelte.d.ts +20 -0
- package/dist/components/primitives/IconButton.svelte +11 -0
- package/dist/components/primitives/IconButton.svelte.d.ts +20 -0
- package/dist/components/primitives/Input.svelte +10 -0
- package/dist/components/primitives/Input.svelte.d.ts +10 -0
- package/dist/components/primitives/Progress.svelte +11 -0
- package/dist/components/primitives/Progress.svelte.d.ts +20 -0
- package/dist/components/primitives/Radio.svelte +11 -0
- package/dist/components/primitives/Radio.svelte.d.ts +20 -0
- package/dist/components/primitives/Range.svelte +24 -0
- package/dist/components/primitives/Range.svelte.d.ts +34 -0
- package/dist/components/primitives/Rating.svelte +24 -0
- package/dist/components/primitives/Rating.svelte.d.ts +34 -0
- package/dist/components/primitives/Select.svelte +11 -0
- package/dist/components/primitives/Select.svelte.d.ts +21 -0
- package/dist/components/primitives/Spinner.svelte +11 -0
- package/dist/components/primitives/Spinner.svelte.d.ts +20 -0
- package/dist/components/primitives/Switch.svelte +11 -0
- package/dist/components/primitives/Switch.svelte.d.ts +20 -0
- package/dist/components/primitives/Tag.svelte +11 -0
- package/dist/components/primitives/Tag.svelte.d.ts +20 -0
- package/dist/components/primitives/Textarea.svelte +11 -0
- package/dist/components/primitives/Textarea.svelte.d.ts +21 -0
- package/dist/components/primitives/ToggleCheckbox.svelte +11 -0
- package/dist/components/primitives/ToggleCheckbox.svelte.d.ts +20 -0
- package/dist/components/primitives/ToggleInput.svelte +11 -0
- package/dist/components/primitives/ToggleInput.svelte.d.ts +20 -0
- package/dist/components/primitives/ToggleRadio.svelte +11 -0
- package/dist/components/primitives/ToggleRadio.svelte.d.ts +20 -0
- package/dist/components/scenes/ai/AiDocumentDownloadMenu.svelte +27 -0
- package/dist/components/scenes/ai/AiDocumentDownloadMenu.svelte.d.ts +27 -0
- package/dist/components/scenes/ai/AiDocumentEditor.svelte +79 -0
- package/dist/components/scenes/ai/AiDocumentEditor.svelte.d.ts +23 -0
- package/dist/components/scenes/ai/MarkdownRenderer.svelte +11 -0
- package/dist/components/scenes/ai/MarkdownRenderer.svelte.d.ts +28 -0
- package/dist/components/scenes/ai/code-preview.d.ts +28 -0
- package/dist/components/scenes/ai/code-preview.js +20 -0
- package/dist/components/scenes/ai/document-download.d.ts +52 -0
- package/dist/components/scenes/ai/document-download.js +30 -2
- package/dist/components/scenes/ai/document-parse.d.ts +71 -14
- package/dist/components/scenes/ai/document-parse.js +19 -9
- package/dist/components/scenes/ai/document-types.d.ts +222 -88
- package/dist/components/scenes/ai/editor-markdown-extensions.d.ts +16 -0
- package/dist/components/scenes/ai/editor-markdown-extensions.js +16 -0
- package/dist/components/scenes/ai/highlight.d.ts +11 -0
- package/dist/components/scenes/ai/highlight.js +11 -0
- package/dist/components/scenes/ai/markdown-parse.d.ts +8 -2
- package/dist/components/scenes/ai/markdown-parse.js +2 -2
- package/dist/components/scenes/ai/mermaid-host-sync.d.ts +38 -0
- package/dist/components/scenes/ai/mermaid-host-sync.js +30 -0
- package/dist/components/scenes/ai/mermaid-render.d.ts +23 -0
- package/dist/components/scenes/ai/mermaid-render.js +23 -0
- package/dist/components/scenes/ai/safe-html.d.ts +54 -6
- package/dist/components/scenes/ai/safe-html.js +54 -6
- package/dist/components/scenes/ai/table/AiTableEditor.svelte +48 -0
- package/dist/components/scenes/ai/table/AiTableEditor.svelte.d.ts +24 -0
- package/dist/components/scenes/ai/table/table-types.d.ts +79 -0
- package/dist/components/scenes/app/FeedbackModal.svelte +45 -5
- package/dist/components/scenes/app/FeedbackModal.svelte.d.ts +45 -5
- package/dist/components/scenes/app/LanguageSwitch.svelte +29 -19
- package/dist/components/scenes/app/LanguageSwitch.svelte.d.ts +28 -19
- package/dist/components/scenes/app/SettingsLayout.svelte +21 -9
- package/dist/components/scenes/app/SettingsLayout.svelte.d.ts +21 -9
- package/dist/components/scenes/app/SettingsModal.svelte +23 -0
- package/dist/components/scenes/app/SettingsModal.svelte.d.ts +23 -0
- package/dist/components/scenes/app/ThemeColorPicker.svelte +31 -0
- package/dist/components/scenes/app/ThemeColorPicker.svelte.d.ts +31 -0
- package/dist/components/scenes/app/ThemeSelector.svelte +21 -6
- package/dist/components/scenes/app/ThemeSelector.svelte.d.ts +21 -6
- package/dist/components/scenes/app/ThemeToggle.svelte +21 -4
- package/dist/components/scenes/app/ThemeToggle.svelte.d.ts +21 -4
- package/dist/components/scenes/app/index.d.ts +1 -1
- package/dist/components/scenes/app/index.js +1 -1
- package/dist/components/scenes/charts/Chart.svelte +11 -0
- package/dist/components/scenes/charts/Chart.svelte.d.ts +20 -0
- package/dist/components/scenes/charts/chart-theme.d.ts +25 -1
- package/dist/components/scenes/charts/chart-theme.js +25 -1
- package/dist/components/scenes/charts/chart-types.d.ts +83 -7
- package/dist/components/scenes/charts/renderers/LineChart.svelte +53 -0
- package/dist/components/scenes/charts/renderers/LineChart.svelte.d.ts +13 -0
- package/dist/components/scenes/crud/CrudDeleteConfirm.svelte +10 -0
- package/dist/components/scenes/crud/CrudDeleteConfirm.svelte.d.ts +10 -0
- package/dist/components/scenes/crud/CrudDetailDrawer.svelte +8 -0
- package/dist/components/scenes/crud/CrudDetailDrawer.svelte.d.ts +8 -0
- package/dist/components/scenes/crud/CrudDetailPanel.svelte +18 -0
- package/dist/components/scenes/crud/CrudDetailPanel.svelte.d.ts +18 -0
- package/dist/components/scenes/crud/CrudEditPanel.svelte +10 -0
- package/dist/components/scenes/crud/CrudEditPanel.svelte.d.ts +10 -0
- package/dist/components/scenes/crud/CrudFilterBar.svelte +18 -0
- package/dist/components/scenes/crud/CrudFilterBar.svelte.d.ts +18 -0
- package/dist/components/scenes/crud/CrudPage.svelte +37 -5
- package/dist/components/scenes/crud/CrudPage.svelte.d.ts +35 -3
- package/dist/components/scenes/crud/crud-controller.svelte.d.ts +142 -23
- package/dist/components/scenes/crud/crud-controller.svelte.js +22 -11
- package/dist/components/scenes/crud/crud-form-validation.d.ts +12 -0
- package/dist/components/scenes/crud/crud-form-validation.js +12 -0
- package/dist/components/scenes/crud/crud-types.d.ts +79 -8
- package/dist/components/scenes/crud/nav-adapter.d.ts +14 -0
- package/dist/components/scenes/crud/nav-adapter.js +8 -0
- package/dist/components/scenes/crypto/EncryptedInput.svelte +24 -0
- package/dist/components/scenes/crypto/EncryptedInput.svelte.d.ts +34 -0
- package/dist/components/scenes/crypto/HashDisplay.svelte +11 -0
- package/dist/components/scenes/crypto/HashDisplay.svelte.d.ts +21 -0
- package/dist/components/scenes/crypto/SignatureDisplay.svelte +11 -0
- package/dist/components/scenes/crypto/SignatureDisplay.svelte.d.ts +21 -0
- package/dist/components/scenes/error/ErrorPage.svelte +8 -1
- package/dist/components/scenes/error/ErrorPage.svelte.d.ts +8 -1
- package/dist/components/scenes/error/error-presets.d.ts +40 -4
- package/dist/components/scenes/error/error-presets.js +22 -2
- package/dist/components/scenes/guide/GuideHost.svelte +27 -0
- package/dist/components/scenes/guide/GuideHost.svelte.d.ts +27 -0
- package/dist/components/scenes/guide/HelpCenter.svelte +27 -0
- package/dist/components/scenes/guide/HelpCenter.svelte.d.ts +27 -0
- package/dist/components/scenes/iam/AuthPanel.svelte +26 -2
- package/dist/components/scenes/iam/AuthPanel.svelte.d.ts +25 -0
- package/dist/components/scenes/iam/AuthShell.svelte +8 -3
- package/dist/components/scenes/iam/AuthShell.svelte.d.ts +8 -3
- package/dist/components/scenes/iam/ChangePasswordForm.svelte +10 -0
- package/dist/components/scenes/iam/ChangePasswordForm.svelte.d.ts +10 -0
- package/dist/components/scenes/iam/ForgotPasswordForm.svelte +11 -0
- package/dist/components/scenes/iam/ForgotPasswordForm.svelte.d.ts +21 -0
- package/dist/components/scenes/iam/LoginForm.svelte +24 -31
- package/dist/components/scenes/iam/LoginForm.svelte.d.ts +10 -0
- package/dist/components/scenes/iam/PasswordInput.svelte +23 -0
- package/dist/components/scenes/iam/PasswordInput.svelte.d.ts +23 -0
- package/dist/components/scenes/iam/PermGuard.svelte +21 -11
- package/dist/components/scenes/iam/PermGuard.svelte.d.ts +30 -0
- package/dist/components/scenes/iam/RegisterForm.svelte +10 -0
- package/dist/components/scenes/iam/RegisterForm.svelte.d.ts +10 -0
- package/dist/components/scenes/iam/ResetPasswordForm.svelte +10 -0
- package/dist/components/scenes/iam/ResetPasswordForm.svelte.d.ts +10 -0
- package/dist/components/scenes/iam/UserProfile.svelte +11 -0
- package/dist/components/scenes/iam/UserProfile.svelte.d.ts +21 -0
- package/dist/components/scenes/iam/auth-error-message.d.ts +10 -0
- package/dist/components/scenes/iam/auth-error-message.js +10 -0
- package/dist/components/scenes/iam/password-utils.d.ts +39 -1
- package/dist/components/scenes/iam/password-utils.js +39 -1
- package/dist/components/scenes/iam/permission-context.svelte.d.ts +33 -23
- package/dist/components/scenes/iam/permission-context.svelte.js +20 -22
- package/dist/components/scenes/storage/AvatarUpload.svelte +11 -0
- package/dist/components/scenes/storage/AvatarUpload.svelte.d.ts +20 -0
- package/dist/components/scenes/storage/FileList.svelte +13 -2
- package/dist/components/scenes/storage/FileList.svelte.d.ts +20 -0
- package/dist/components/scenes/storage/FileUpload.svelte +37 -2
- package/dist/components/scenes/storage/FileUpload.svelte.d.ts +21 -0
- package/dist/components/scenes/storage/ImageUpload.svelte +11 -0
- package/dist/components/scenes/storage/ImageUpload.svelte.d.ts +21 -0
- package/dist/components/scenes/types.d.ts +352 -11
- package/dist/guide-storage.d.ts +13 -1
- package/dist/guide-storage.js +13 -1
- package/dist/guide-types.d.ts +67 -2
- package/dist/guide.svelte.d.ts +22 -1
- package/dist/guide.svelte.js +22 -1
- package/dist/i18n.svelte.d.ts +64 -3
- package/dist/i18n.svelte.js +99 -18
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -2
- package/dist/internal/browser-safety.d.ts +51 -2
- package/dist/internal/browser-safety.js +45 -7
- package/dist/internal/form-context.d.ts +73 -0
- package/dist/internal/form-context.js +57 -0
- package/dist/internal/form-validation.svelte.d.ts +42 -0
- package/dist/internal/form-validation.svelte.js +26 -0
- package/dist/internal/icon-safety.d.ts +7 -0
- package/dist/internal/icon-safety.js +7 -0
- package/dist/internal/locale.d.ts +19 -0
- package/dist/internal/locale.js +21 -0
- package/dist/message.svelte.d.ts +90 -0
- package/dist/message.svelte.js +84 -0
- package/dist/messagebox.svelte.d.ts +61 -13
- package/dist/messagebox.svelte.js +55 -13
- package/dist/messages/en-US.json +6 -1
- package/dist/messages/ja-JP.json +389 -0
- package/dist/messages/zh-CN.json +6 -1
- package/dist/messages.d.ts +24 -3
- package/dist/messages.js +18 -3
- package/dist/styles/design-tokens.css +4 -2
- package/dist/styles/global.css +28 -8
- package/dist/styles/theme.css +2 -0
- package/dist/theme-config.d.ts +173 -0
- package/dist/theme-config.js +143 -0
- package/dist/toast.svelte.d.ts +114 -4
- package/dist/toast.svelte.js +108 -4
- package/dist/types.d.ts +526 -9
- package/dist/utils/platform.svelte.d.ts +28 -15
- package/dist/utils/platform.svelte.js +19 -14
- package/dist/utils.d.ts +102 -0
- package/dist/utils.js +93 -0
- package/package.json +66 -6
|
@@ -4,6 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
使用 Svelte 5 Runes ($props, $state, $derived)
|
|
6
6
|
使用 compounds/primitives 组件:Drawer, Modal, FormField, Input, Select, Textarea, Checkbox, Button
|
|
7
|
+
|
|
8
|
+
@example
|
|
9
|
+
```ts
|
|
10
|
+
import { mount, unmount } from 'svelte'
|
|
11
|
+
import type { ComponentProps } from 'svelte'
|
|
12
|
+
import { CrudEditPanel } from '@h-ai/ui'
|
|
13
|
+
const props: ComponentProps<typeof CrudEditPanel> = { open: true, mode: 'edit', title: '编辑用户', fields: [{ id: 'email', label: '邮箱', type: 'email' }], formData: { email: 'ada@example.com' } }
|
|
14
|
+
const component = mount(CrudEditPanel, { target: document.body, props })
|
|
15
|
+
await unmount(component)
|
|
16
|
+
```
|
|
7
17
|
-->
|
|
8
18
|
<script lang='ts'>
|
|
9
19
|
import type { Snippet } from 'svelte'
|
|
@@ -31,6 +31,16 @@ type $$ComponentProps = {
|
|
|
31
31
|
*
|
|
32
32
|
* 使用 Svelte 5 Runes ($props, $state, $derived)
|
|
33
33
|
* 使用 compounds/primitives 组件:Drawer, Modal, FormField, Input, Select, Textarea, Checkbox, Button
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* import { mount, unmount } from 'svelte'
|
|
38
|
+
* import type { ComponentProps } from 'svelte'
|
|
39
|
+
* import { CrudEditPanel } from '@h-ai/ui'
|
|
40
|
+
* const props: ComponentProps<typeof CrudEditPanel> = { open: true, mode: 'edit', title: '编辑用户', fields: [{ id: 'email', label: '邮箱', type: 'email' }], formData: { email: 'ada@example.com' } }
|
|
41
|
+
* const component = mount(CrudEditPanel, { target: document.body, props })
|
|
42
|
+
* await unmount(component)
|
|
43
|
+
* ```
|
|
34
44
|
*/
|
|
35
45
|
declare const CrudEditPanel: import("svelte").Component<$$ComponentProps, {}, "open" | "formData">;
|
|
36
46
|
type CrudEditPanel = ReturnType<typeof CrudEditPanel>;
|
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
CRUD 搜索 + 过滤栏组件
|
|
4
4
|
|
|
5
5
|
使用 Svelte 5 Runes ($props, $state)
|
|
6
|
+
|
|
7
|
+
@example
|
|
8
|
+
```ts
|
|
9
|
+
import { mount, unmount } from 'svelte'
|
|
10
|
+
import type { ComponentProps } from 'svelte'
|
|
11
|
+
import { CrudFilterBar } from '@h-ai/ui'
|
|
12
|
+
const props: ComponentProps<typeof CrudFilterBar> = { searchable: true, filterFields: [{ id: 'active', label: '状态', type: 'boolean' }], filterValues: { active: true } }
|
|
13
|
+
const component = mount(CrudFilterBar, { target: document.body, props })
|
|
14
|
+
await unmount(component)
|
|
15
|
+
```
|
|
6
16
|
-->
|
|
7
17
|
<script lang='ts'>
|
|
8
18
|
import type { DataAttributes } from '../../../types.js'
|
|
@@ -12,6 +22,14 @@
|
|
|
12
22
|
import Input from '../../primitives/Input.svelte'
|
|
13
23
|
import Select from '../../primitives/Select.svelte'
|
|
14
24
|
|
|
25
|
+
/**
|
|
26
|
+
* 工具栏过滤字段的局部视图;值由宿主条件查询消费。
|
|
27
|
+
*
|
|
28
|
+
* @example 模块内部上下文
|
|
29
|
+
* ```ts
|
|
30
|
+
* const example: FilterFieldDef = { id: 'active', label: '状态', type: 'boolean' }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
15
33
|
type FilterFieldDef = {
|
|
16
34
|
id: string
|
|
17
35
|
label: string | (() => string)
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { DataAttributes } from '../../../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 工具栏过滤字段的局部视图;值由宿主条件查询消费。
|
|
4
|
+
*
|
|
5
|
+
* @example 模块内部上下文
|
|
6
|
+
* ```ts
|
|
7
|
+
* const example: FilterFieldDef = { id: 'active', label: '状态', type: 'boolean' }
|
|
8
|
+
* ```
|
|
9
|
+
*/
|
|
2
10
|
type FilterFieldDef = {
|
|
3
11
|
id: string;
|
|
4
12
|
label: string | (() => string);
|
|
@@ -33,6 +41,16 @@ type $$ComponentProps = {
|
|
|
33
41
|
* CRUD 搜索 + 过滤栏组件
|
|
34
42
|
*
|
|
35
43
|
* 使用 Svelte 5 Runes ($props, $state)
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* import { mount, unmount } from 'svelte'
|
|
48
|
+
* import type { ComponentProps } from 'svelte'
|
|
49
|
+
* import { CrudFilterBar } from '@h-ai/ui'
|
|
50
|
+
* const props: ComponentProps<typeof CrudFilterBar> = { searchable: true, filterFields: [{ id: 'active', label: '状态', type: 'boolean' }], filterValues: { active: true } }
|
|
51
|
+
* const component = mount(CrudFilterBar, { target: document.body, props })
|
|
52
|
+
* await unmount(component)
|
|
53
|
+
* ```
|
|
36
54
|
*/
|
|
37
55
|
declare const CrudFilterBar: import("svelte").Component<$$ComponentProps, {}, "searchValue" | "filterValues">;
|
|
38
56
|
type CrudFilterBar = ReturnType<typeof CrudFilterBar>;
|
|
@@ -8,7 +8,15 @@
|
|
|
8
8
|
使用 compounds 组件:Card, DataTable, PageHeader, Pagination, Drawer, Modal
|
|
9
9
|
|
|
10
10
|
@example
|
|
11
|
-
|
|
11
|
+
```svelte
|
|
12
|
+
<script lang="ts">
|
|
13
|
+
import { CrudPage, defineCrud } from '@h-ai/ui'
|
|
14
|
+
import type { CrudPageProps } from '@h-ai/ui'
|
|
15
|
+
const crud = defineCrud({ name: 'users', label: '用户', fields: [{ id: 'email', label: '邮箱', type: 'email', validation: { required: true } }], api: { list: async () => ({ items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }) } })
|
|
16
|
+
const props: CrudPageProps = { crud, data: { items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }, permissions: { create: true, update: true, delete: false } }
|
|
17
|
+
</script>
|
|
18
|
+
<CrudPage {...props} />
|
|
19
|
+
```
|
|
12
20
|
-->
|
|
13
21
|
<script lang='ts'>
|
|
14
22
|
import type { Snippet } from 'svelte'
|
|
@@ -34,11 +42,27 @@
|
|
|
34
42
|
|
|
35
43
|
// ─── 类型定义 ───
|
|
36
44
|
|
|
45
|
+
/**
|
|
46
|
+
* 详情/列表对字段定义的局部视图,不是独立的公开资源模型。
|
|
47
|
+
*
|
|
48
|
+
* @example 模块内部上下文
|
|
49
|
+
* ```ts
|
|
50
|
+
* const example: FieldDef = { id: 'email', label: '邮箱', type: 'email', inDetail: true }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
37
53
|
type FieldDef = CrudFieldDef
|
|
38
54
|
|
|
39
55
|
// 使用 method shorthand 语法(双向协变)以兼容来自 @h-ai/kit 的 CrudOperations 类型
|
|
40
56
|
// 详见:https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-6.html#strict-function-types
|
|
41
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* CrudPage 使用的异步资源操作集合。
|
|
59
|
+
*
|
|
60
|
+
* @example 模块内部上下文
|
|
61
|
+
* ```ts
|
|
62
|
+
* const api: CrudApi = { list: async () => ({ items: [{ id: 'u1' }], total: 1, page: 1, pageSize: 20 }) }
|
|
63
|
+
* const page = await api.list({ page: 1 })
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
42
66
|
type CrudApi = {
|
|
43
67
|
/** 获取当前分页、筛选和排序结果。 */
|
|
44
68
|
list(params: Record<string, unknown>): Promise<{ items: Record<string, unknown>[], total: number, page: number, pageSize: number }>
|
|
@@ -52,7 +76,15 @@
|
|
|
52
76
|
remove?(id: string): Promise<void>
|
|
53
77
|
}
|
|
54
78
|
|
|
55
|
-
/**
|
|
79
|
+
/**
|
|
80
|
+
* 声明式 CRUD 资源及字段转换能力。
|
|
81
|
+
*
|
|
82
|
+
* @example 模块内部上下文
|
|
83
|
+
* ```ts
|
|
84
|
+
* const definition: CrudDef = crud
|
|
85
|
+
* const fields = definition.getListFields()
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
56
88
|
type CrudDef = {
|
|
57
89
|
/** 资源元信息与后端 API。 */
|
|
58
90
|
resource: {
|
|
@@ -238,7 +270,7 @@
|
|
|
238
270
|
/** 是否使用紧凑列表密度。 */
|
|
239
271
|
const isCompact = $derived(density === 'compact')
|
|
240
272
|
/** 页面主体垂直间距;列表卡片会占满其余可用高度。 */
|
|
241
|
-
const pageGapClass = 'flex min-h-0 h-full flex-col gap-5'
|
|
273
|
+
const pageGapClass = 'flex min-h-0 h-full min-w-0 flex-1 flex-col gap-5'
|
|
242
274
|
/** 行内操作按钮尺寸。 */
|
|
243
275
|
const actionButtonSize = $derived(isCompact ? 'xs' : 'sm')
|
|
244
276
|
/** 行内操作图标尺寸。 */
|
|
@@ -255,7 +287,7 @@
|
|
|
255
287
|
: 'flex min-h-0 flex-1 flex-col overflow-hidden rounded-[1.25rem] border-base-content/7 shadow-sm [&>.card-body]:min-h-0 [&>.card-body]:flex-1',
|
|
256
288
|
)
|
|
257
289
|
/** 分页栏样式;shrink-0 保证它始终贴在卡片底部。 */
|
|
258
|
-
const paginationBarClass = 'shrink-0 border-t border-base-content/5 px-4 py-3'
|
|
290
|
+
const paginationBarClass = 'mt-auto shrink-0 border-t border-base-content/5 px-4 py-3'
|
|
259
291
|
|
|
260
292
|
// 表单展示配置(抽屉 / 弹窗)
|
|
261
293
|
/** 编辑/新建面板类型。 */
|
|
@@ -3,8 +3,24 @@ import type { DataAttributes } from '../../../types.js';
|
|
|
3
3
|
import type { CrudFieldDef } from './crud-controller.svelte.js';
|
|
4
4
|
import type { CrudDensity, CrudFormConfig, CrudPaginationConfig, CrudToolbarStyle } from './crud-types.js';
|
|
5
5
|
import type { NavAdapter } from './nav-adapter.js';
|
|
6
|
+
/**
|
|
7
|
+
* 详情/列表对字段定义的局部视图,不是独立的公开资源模型。
|
|
8
|
+
*
|
|
9
|
+
* @example 模块内部上下文
|
|
10
|
+
* ```ts
|
|
11
|
+
* const example: FieldDef = { id: 'email', label: '邮箱', type: 'email', inDetail: true }
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
6
14
|
type FieldDef = CrudFieldDef;
|
|
7
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* CrudPage 使用的异步资源操作集合。
|
|
17
|
+
*
|
|
18
|
+
* @example 模块内部上下文
|
|
19
|
+
* ```ts
|
|
20
|
+
* const api: CrudApi = { list: async () => ({ items: [{ id: 'u1' }], total: 1, page: 1, pageSize: 20 }) }
|
|
21
|
+
* const page = await api.list({ page: 1 })
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
8
24
|
type CrudApi = {
|
|
9
25
|
/** 获取当前分页、筛选和排序结果。 */
|
|
10
26
|
list(params: Record<string, unknown>): Promise<{
|
|
@@ -22,7 +38,15 @@ type CrudApi = {
|
|
|
22
38
|
/** 删除一条记录。 */
|
|
23
39
|
remove?(id: string): Promise<void>;
|
|
24
40
|
};
|
|
25
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* 声明式 CRUD 资源及字段转换能力。
|
|
43
|
+
*
|
|
44
|
+
* @example 模块内部上下文
|
|
45
|
+
* ```ts
|
|
46
|
+
* const definition: CrudDef = crud
|
|
47
|
+
* const fields = definition.getListFields()
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
26
50
|
type CrudDef = {
|
|
27
51
|
/** 资源元信息与后端 API。 */
|
|
28
52
|
resource: {
|
|
@@ -163,7 +187,15 @@ type $$ComponentProps = {
|
|
|
163
187
|
* 使用 compounds 组件:Card, DataTable, PageHeader, Pagination, Drawer, Modal
|
|
164
188
|
*
|
|
165
189
|
* @example
|
|
166
|
-
*
|
|
190
|
+
* ```svelte
|
|
191
|
+
* <script lang="ts">
|
|
192
|
+
* import { CrudPage, defineCrud } from '@h-ai/ui'
|
|
193
|
+
* import type { CrudPageProps } from '@h-ai/ui'
|
|
194
|
+
* const crud = defineCrud({ name: 'users', label: '用户', fields: [{ id: 'email', label: '邮箱', type: 'email', validation: { required: true } }], api: { list: async () => ({ items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }) } })
|
|
195
|
+
* const props: CrudPageProps = { crud, data: { items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }, permissions: { create: true, update: true, delete: false } }
|
|
196
|
+
* </script>
|
|
197
|
+
* <CrudPage {...props} />
|
|
198
|
+
* ```
|
|
167
199
|
*/
|
|
168
200
|
declare const CrudPage: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
169
201
|
type CrudPage = ReturnType<typeof CrudPage>;
|
|
@@ -15,16 +15,48 @@
|
|
|
15
15
|
import type { PaginatedResult } from '@h-ai/core';
|
|
16
16
|
import type { FormColSpan } from '../../../types.js';
|
|
17
17
|
import type { NavAdapter } from './nav-adapter.js';
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* 字段展示形式;与 `CrudEditPanel` / `CrudFilterBar` 支持的类型对齐,保留 `string` 以兼容 `@h-ai/kit`。
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import type { CrudFieldType } from '@h-ai/ui'
|
|
24
|
+
* const example: CrudFieldType = 'email'
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
19
27
|
export type CrudFieldType = 'text' | 'string' | 'textarea' | 'select' | 'radio' | 'multi-select' | 'boolean' | 'checkbox' | 'email' | 'url' | 'tel' | 'password' | 'number' | 'date' | 'datetime' | 'date-range' | 'custom';
|
|
20
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* 可解析为字符串的文本值(支持 i18n 函数)。
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import type { CrudText } from '@h-ai/ui'
|
|
34
|
+
* const example: CrudText = () => '邮箱'
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
21
37
|
export type CrudText = string | (() => string);
|
|
22
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* 选项项(select / radio / multi-select)。
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* import type { CrudOption } from '@h-ai/ui'
|
|
44
|
+
* const example: CrudOption = { label: '启用', value: true }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
23
47
|
export interface CrudOption {
|
|
24
48
|
label: string;
|
|
25
49
|
value: string | number | boolean;
|
|
26
50
|
}
|
|
27
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* 字段定义(与 `CrudPage` 的字段模型对齐)。
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* import type { CrudFieldDef } from '@h-ai/ui'
|
|
57
|
+
* const example: CrudFieldDef = { id: 'email', label: '邮箱', type: 'email', inList: true, validation: { required: true } }
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
28
60
|
export interface CrudFieldDef {
|
|
29
61
|
/** 字段 id(对应数据对象的属性名)。 */
|
|
30
62
|
id: string;
|
|
@@ -73,12 +105,29 @@ export interface CrudFieldDef {
|
|
|
73
105
|
/** 排序权重(升序)。 */
|
|
74
106
|
order?: number;
|
|
75
107
|
}
|
|
76
|
-
/**
|
|
108
|
+
/**
|
|
109
|
+
* 列表请求附加项;用于 latest-wins 取消旧请求。
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* import type { CrudListOptions } from '@h-ai/ui'
|
|
114
|
+
* const example: CrudListOptions = { signal: new AbortController().signal }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
77
117
|
export interface CrudListOptions {
|
|
78
118
|
/** 取消信号;旧请求被新请求取代时触发 abort。 */
|
|
79
119
|
signal?: AbortSignal;
|
|
80
120
|
}
|
|
81
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* CRUD API 集合。列表返回标准 `PaginatedResult<T>`,避免各页面重复 page/pageSize/total 映射。
|
|
123
|
+
* @typeParam T - 字段值或资源条目的数据类型。
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* import type { CrudApi } from '@h-ai/ui'
|
|
128
|
+
* const example: CrudApi<Record<string, unknown>> = { list: async () => ({ items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }) }
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
82
131
|
export interface CrudApi<T> {
|
|
83
132
|
/** 分页列表;第二参数携带取消信号,实现方可透传给 fetch。 */
|
|
84
133
|
list: (params: Record<string, unknown>, options?: CrudListOptions) => Promise<PaginatedResult<T>>;
|
|
@@ -91,7 +140,16 @@ export interface CrudApi<T> {
|
|
|
91
140
|
/** 删除一条记录。 */
|
|
92
141
|
remove?: (id: string) => Promise<void>;
|
|
93
142
|
}
|
|
94
|
-
/**
|
|
143
|
+
/**
|
|
144
|
+
* 资源定义。
|
|
145
|
+
* @typeParam T - 字段值或资源条目的数据类型。
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```ts
|
|
149
|
+
* import type { CrudResource } from '@h-ai/ui'
|
|
150
|
+
* const example: CrudResource<Record<string, unknown>> = { name: 'users', label: '用户', fields: [{ id: 'email', label: '邮箱', type: 'email', validation: { required: true } }], api: { list: async () => ({ items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }) } }
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
95
153
|
export interface CrudResource<T> {
|
|
96
154
|
/** 资源名称(用于识别业务实体)。 */
|
|
97
155
|
name: string;
|
|
@@ -110,7 +168,15 @@ export interface CrudResource<T> {
|
|
|
110
168
|
/** 资源 CRUD API。 */
|
|
111
169
|
api: CrudApi<T>;
|
|
112
170
|
}
|
|
113
|
-
/**
|
|
171
|
+
/**
|
|
172
|
+
* DataTable 列定义(适配 `CrudPage`)。
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```ts
|
|
176
|
+
* import type { CrudTableColumn } from '@h-ai/ui'
|
|
177
|
+
* const example: CrudTableColumn = { key: 'email', label: '邮箱', width: '16rem' }
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
114
180
|
export interface CrudTableColumn {
|
|
115
181
|
key: string;
|
|
116
182
|
label: string;
|
|
@@ -118,7 +184,18 @@ export interface CrudTableColumn {
|
|
|
118
184
|
align?: 'left' | 'center' | 'right';
|
|
119
185
|
render?: (item: Record<string, unknown>) => string;
|
|
120
186
|
}
|
|
121
|
-
/**
|
|
187
|
+
/**
|
|
188
|
+
* `CrudPage` 所需的 crud 对象形状(`defineCrud` 的返回值)。
|
|
189
|
+
* @typeParam T - 字段值或资源条目的数据类型。
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```ts
|
|
193
|
+
* import { defineCrud } from '@h-ai/ui'
|
|
194
|
+
* import type { CrudDef } from '@h-ai/ui'
|
|
195
|
+
* const definition: CrudDef<Record<string, unknown>> = defineCrud({ name: 'users', label: '用户', fields: [{ id: 'email', label: '邮箱', type: 'email', validation: { required: true } }], api: { list: async () => ({ items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }) } })
|
|
196
|
+
* const columns = definition.toTableColumns()
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
122
199
|
export interface CrudDef<T> {
|
|
123
200
|
resource: CrudResource<T>;
|
|
124
201
|
getListFields: () => CrudFieldDef[];
|
|
@@ -130,7 +207,16 @@ export interface CrudDef<T> {
|
|
|
130
207
|
getDefaultValues: () => Record<string, unknown>;
|
|
131
208
|
api: CrudApi<T>;
|
|
132
209
|
}
|
|
133
|
-
/**
|
|
210
|
+
/**
|
|
211
|
+
* `CrudPage` 的 `data` 形状。
|
|
212
|
+
* @typeParam T - 字段值或资源条目的数据类型。
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```ts
|
|
216
|
+
* import type { CrudData } from '@h-ai/ui'
|
|
217
|
+
* const example: CrudData<Record<string, unknown>> = { items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20, filters: { active: true } }
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
134
220
|
export interface CrudData<T> {
|
|
135
221
|
items: T[];
|
|
136
222
|
total: number;
|
|
@@ -138,7 +224,21 @@ export interface CrudData<T> {
|
|
|
138
224
|
pageSize: number;
|
|
139
225
|
filters: Record<string, unknown>;
|
|
140
226
|
}
|
|
141
|
-
/**
|
|
227
|
+
/**
|
|
228
|
+
* CRUD 控制器:托管列表数据与 SPA 导航适配器。
|
|
229
|
+
* @typeParam T - 字段值或资源条目的数据类型。
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```ts
|
|
233
|
+
* import { defineCrud, createCrudController } from '@h-ai/ui'
|
|
234
|
+
* import type { CrudController } from '@h-ai/ui'
|
|
235
|
+
* const crud = defineCrud({ name: 'users', label: '用户', fields: [{ id: 'email', label: '邮箱', type: 'email', validation: { required: true } }], api: { list: async () => ({ items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }) } })
|
|
236
|
+
* const controller: CrudController<Record<string, unknown>> = createCrudController(crud, { autoLoad: false, syncUrl: false })
|
|
237
|
+
* await controller.load()
|
|
238
|
+
* if (controller.error) throw controller.error
|
|
239
|
+
* const users = controller.data.items
|
|
240
|
+
* ```
|
|
241
|
+
*/
|
|
142
242
|
export interface CrudController<T> {
|
|
143
243
|
/** 传给 `<CrudPage data={...}>` 的响应式数据对象。 */
|
|
144
244
|
readonly data: CrudData<T>;
|
|
@@ -155,7 +255,15 @@ export interface CrudController<T> {
|
|
|
155
255
|
/** 最新一轮请求错误;已有成功数据时仍保留原列表。 */
|
|
156
256
|
readonly error: Error | undefined;
|
|
157
257
|
}
|
|
158
|
-
/**
|
|
258
|
+
/**
|
|
259
|
+
* CRUD 控制器创建选项。
|
|
260
|
+
*
|
|
261
|
+
* @example
|
|
262
|
+
* ```ts
|
|
263
|
+
* import type { CrudControllerOptions } from '@h-ai/ui'
|
|
264
|
+
* const example: CrudControllerOptions = { autoLoad: false, keepPreviousData: true, syncUrl: true }
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
159
267
|
export interface CrudControllerOptions {
|
|
160
268
|
/** 是否在创建后立即加载;不可见 / 惰性页签应设为 false(默认 true)。 */
|
|
161
269
|
autoLoad?: boolean;
|
|
@@ -173,9 +281,15 @@ export interface CrudControllerOptions {
|
|
|
173
281
|
* @param result - 后端返回的分页结果。
|
|
174
282
|
* @param map - 单条映射函数。
|
|
175
283
|
* @returns 条目被映射、分页元数据不变的新分页结果。
|
|
284
|
+
* @typeParam T - 字段值或资源条目的数据类型。
|
|
285
|
+
* @typeParam R - 转换结果的数据类型。
|
|
176
286
|
*
|
|
177
287
|
* @example
|
|
178
|
-
*
|
|
288
|
+
* ```ts
|
|
289
|
+
* import { mapPaginated } from '@h-ai/ui'
|
|
290
|
+
* const page = mapPaginated({ items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }, user => ({ ...user, label: user.email }))
|
|
291
|
+
* const email = page.items[0]?.label
|
|
292
|
+
* ```
|
|
179
293
|
*/
|
|
180
294
|
export declare function mapPaginated<T, R>(result: PaginatedResult<T>, map: (item: T, index: number) => R): PaginatedResult<R>;
|
|
181
295
|
/**
|
|
@@ -185,14 +299,14 @@ export declare function mapPaginated<T, R>(result: PaginatedResult<T>, map: (ite
|
|
|
185
299
|
*
|
|
186
300
|
* @param resource - 资源定义(字段、标签、API)。
|
|
187
301
|
* @returns `CrudPage` 可直接消费的 `crud` 对象。
|
|
302
|
+
* @typeParam T - 字段值或资源条目的数据类型。
|
|
188
303
|
*
|
|
189
304
|
* @example
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
* })
|
|
305
|
+
* ```ts
|
|
306
|
+
* import { defineCrud } from '@h-ai/ui'
|
|
307
|
+
* const crud = defineCrud({ name: 'users', label: '用户', fields: [{ id: 'email', label: '邮箱', type: 'email', validation: { required: true } }], api: { list: async () => ({ items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }) } })
|
|
308
|
+
* const columns = crud.toTableColumns()
|
|
309
|
+
* ```
|
|
196
310
|
*/
|
|
197
311
|
export declare function defineCrud<T extends Record<string, unknown>>(resource: CrudResource<T>): CrudDef<T>;
|
|
198
312
|
/**
|
|
@@ -206,11 +320,16 @@ export declare function defineCrud<T extends Record<string, unknown>>(resource:
|
|
|
206
320
|
* @param crud - `defineCrud` 的返回值。
|
|
207
321
|
* @param options - 加载策略;默认立即加载、失败保留旧数据、回填地址栏。
|
|
208
322
|
* @returns 含响应式 `data`、`nav` 适配器与 `load` / `reload` 的控制器。
|
|
323
|
+
* @typeParam T - 字段值或资源条目的数据类型。
|
|
209
324
|
*
|
|
210
325
|
* @example
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
326
|
+
* ```ts
|
|
327
|
+
* import { defineCrud, createCrudController } from '@h-ai/ui'
|
|
328
|
+
* const crud = defineCrud({ name: 'users', label: '用户', fields: [{ id: 'email', label: '邮箱', type: 'email', validation: { required: true } }], api: { list: async () => ({ items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }) } })
|
|
329
|
+
* const controller = createCrudController(crud, { autoLoad: false, syncUrl: false })
|
|
330
|
+
* await controller.load()
|
|
331
|
+
* if (controller.error) throw controller.error
|
|
332
|
+
* const users = controller.data.items
|
|
333
|
+
* ```
|
|
215
334
|
*/
|
|
216
335
|
export declare function createCrudController<T extends Record<string, unknown>>(crud: CrudDef<T>, options?: CrudControllerOptions): CrudController<T>;
|
|
@@ -28,9 +28,15 @@ function resolveText(text) {
|
|
|
28
28
|
* @param result - 后端返回的分页结果。
|
|
29
29
|
* @param map - 单条映射函数。
|
|
30
30
|
* @returns 条目被映射、分页元数据不变的新分页结果。
|
|
31
|
+
* @typeParam T - 字段值或资源条目的数据类型。
|
|
32
|
+
* @typeParam R - 转换结果的数据类型。
|
|
31
33
|
*
|
|
32
34
|
* @example
|
|
33
|
-
*
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { mapPaginated } from '@h-ai/ui'
|
|
37
|
+
* const page = mapPaginated({ items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }, user => ({ ...user, label: user.email }))
|
|
38
|
+
* const email = page.items[0]?.label
|
|
39
|
+
* ```
|
|
34
40
|
*/
|
|
35
41
|
export function mapPaginated(result, map) {
|
|
36
42
|
return {
|
|
@@ -47,14 +53,14 @@ export function mapPaginated(result, map) {
|
|
|
47
53
|
*
|
|
48
54
|
* @param resource - 资源定义(字段、标签、API)。
|
|
49
55
|
* @returns `CrudPage` 可直接消费的 `crud` 对象。
|
|
56
|
+
* @typeParam T - 字段值或资源条目的数据类型。
|
|
50
57
|
*
|
|
51
58
|
* @example
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* })
|
|
59
|
+
* ```ts
|
|
60
|
+
* import { defineCrud } from '@h-ai/ui'
|
|
61
|
+
* const crud = defineCrud({ name: 'users', label: '用户', fields: [{ id: 'email', label: '邮箱', type: 'email', validation: { required: true } }], api: { list: async () => ({ items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }) } })
|
|
62
|
+
* const columns = crud.toTableColumns()
|
|
63
|
+
* ```
|
|
58
64
|
*/
|
|
59
65
|
export function defineCrud(resource) {
|
|
60
66
|
const fields = [...resource.fields].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
|
@@ -91,12 +97,17 @@ export function defineCrud(resource) {
|
|
|
91
97
|
* @param crud - `defineCrud` 的返回值。
|
|
92
98
|
* @param options - 加载策略;默认立即加载、失败保留旧数据、回填地址栏。
|
|
93
99
|
* @returns 含响应式 `data`、`nav` 适配器与 `load` / `reload` 的控制器。
|
|
100
|
+
* @typeParam T - 字段值或资源条目的数据类型。
|
|
94
101
|
*
|
|
95
102
|
* @example
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
103
|
+
* ```ts
|
|
104
|
+
* import { defineCrud, createCrudController } from '@h-ai/ui'
|
|
105
|
+
* const crud = defineCrud({ name: 'users', label: '用户', fields: [{ id: 'email', label: '邮箱', type: 'email', validation: { required: true } }], api: { list: async () => ({ items: [{ id: 'u1', email: 'ada@example.com' }], total: 1, page: 1, pageSize: 20 }) } })
|
|
106
|
+
* const controller = createCrudController(crud, { autoLoad: false, syncUrl: false })
|
|
107
|
+
* await controller.load()
|
|
108
|
+
* if (controller.error) throw controller.error
|
|
109
|
+
* const users = controller.data.items
|
|
110
|
+
* ```
|
|
100
111
|
*/
|
|
101
112
|
export function createCrudController(crud, options = {}) {
|
|
102
113
|
const defaultPageSize = crud.resource.defaultPageSize ?? 10;
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
/** CRUD 客户端字段校验;仅返回消息键,避免错误文案锁定在提交时的语言。 */
|
|
2
2
|
import type { FormValidationIssue } from '../../../internal/form-validation.svelte.js';
|
|
3
3
|
import type { CrudFieldDef } from './crud-controller.svelte.js';
|
|
4
|
+
/**
|
|
5
|
+
* 按字段类型和声明约束生成可翻译错误,不承担服务端验证。
|
|
6
|
+
* @param field - 需要校验的 CRUD 字段定义。
|
|
7
|
+
* @param value - 待处理或校验的值。
|
|
8
|
+
* @returns 可翻译的约束错误;合法输入返回 undefined。
|
|
9
|
+
*
|
|
10
|
+
* @example 模块内部上下文
|
|
11
|
+
* ```ts
|
|
12
|
+
* const issue = getCrudValidationIssue({ id: 'email', label: '邮箱', type: 'email', validation: { required: true } }, '')
|
|
13
|
+
* const key = issue?.key
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
4
16
|
export declare function getCrudValidationIssue(field: CrudFieldDef, value: unknown): FormValidationIssue | undefined;
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 按字段类型和声明约束生成可翻译错误,不承担服务端验证。
|
|
3
|
+
* @param field - 需要校验的 CRUD 字段定义。
|
|
4
|
+
* @param value - 待处理或校验的值。
|
|
5
|
+
* @returns 可翻译的约束错误;合法输入返回 undefined。
|
|
6
|
+
*
|
|
7
|
+
* @example 模块内部上下文
|
|
8
|
+
* ```ts
|
|
9
|
+
* const issue = getCrudValidationIssue({ id: 'email', label: '邮箱', type: 'email', validation: { required: true } }, '')
|
|
10
|
+
* const key = issue?.key
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
1
13
|
export function getCrudValidationIssue(field, value) {
|
|
2
14
|
const rules = field.validation;
|
|
3
15
|
const empty = value === undefined || value === null || (typeof value === 'string' && !value.trim()) || (Array.isArray(value) && value.length === 0);
|