@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
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { DataAttributes } from '../../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* SafeArea 组件的属性契约;通过公开组件配置使用。
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { mount, unmount, createRawSnippet } from 'svelte'
|
|
9
|
+
* import type { ComponentProps } from 'svelte'
|
|
10
|
+
* import { SafeArea } from '@h-ai/ui'
|
|
11
|
+
* const props: ComponentProps<typeof SafeArea> = { position: 'all', children: createRawSnippet(() => ({ render: () => "<main>页面内容</main>" })) }
|
|
12
|
+
* const component = mount(SafeArea, { target: document.body, props })
|
|
13
|
+
* await unmount(component)
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
3
16
|
interface Props {
|
|
4
17
|
/** 安全区域位置 */
|
|
5
18
|
position?: 'top' | 'bottom' | 'all';
|
|
@@ -9,6 +22,25 @@ interface Props {
|
|
|
9
22
|
children: Snippet;
|
|
10
23
|
}
|
|
11
24
|
type $$ComponentProps = Props & DataAttributes;
|
|
25
|
+
/**
|
|
26
|
+
* SafeArea
|
|
27
|
+
* @h-ai/ui — SafeArea(安全区域包裹组件)
|
|
28
|
+
*
|
|
29
|
+
* 用法:
|
|
30
|
+
* <SafeArea position="top">
|
|
31
|
+
* <AppBar />
|
|
32
|
+
* </SafeArea>
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* import { mount, unmount, createRawSnippet } from 'svelte'
|
|
37
|
+
* import type { ComponentProps } from 'svelte'
|
|
38
|
+
* import { SafeArea } from '@h-ai/ui'
|
|
39
|
+
* const props: ComponentProps<typeof SafeArea> = { position: 'all', children: createRawSnippet(() => ({ render: () => "<main>页面内容</main>" })) }
|
|
40
|
+
* const component = mount(SafeArea, { target: document.body, props })
|
|
41
|
+
* await unmount(component)
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
12
44
|
declare const SafeArea: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
13
45
|
type SafeArea = ReturnType<typeof SafeArea>;
|
|
14
46
|
export default SafeArea;
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component Skeleton
|
|
3
3
|
骨架屏占位组件,用于加载状态展示。
|
|
4
|
+
|
|
5
|
+
@example
|
|
6
|
+
```ts
|
|
7
|
+
import { mount, unmount } from 'svelte'
|
|
8
|
+
import type { ComponentProps } from 'svelte'
|
|
9
|
+
import { Skeleton } from '@h-ai/ui'
|
|
10
|
+
const props: ComponentProps<typeof Skeleton> = { variant: 'text', count: 3 }
|
|
11
|
+
const component = mount(Skeleton, { target: document.body, props })
|
|
12
|
+
await unmount(component)
|
|
13
|
+
```
|
|
4
14
|
-->
|
|
5
15
|
<script lang='ts'>
|
|
6
16
|
import type { DataAttributes, SkeletonProps } from '../../types.js'
|
|
@@ -3,6 +3,16 @@ type $$ComponentProps = SkeletonProps & DataAttributes;
|
|
|
3
3
|
/**
|
|
4
4
|
* Skeleton
|
|
5
5
|
* 骨架屏占位组件,用于加载状态展示。
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { mount, unmount } from 'svelte'
|
|
10
|
+
* import type { ComponentProps } from 'svelte'
|
|
11
|
+
* import { Skeleton } from '@h-ai/ui'
|
|
12
|
+
* const props: ComponentProps<typeof Skeleton> = { variant: 'text', count: 3 }
|
|
13
|
+
* const component = mount(Skeleton, { target: document.body, props })
|
|
14
|
+
* await unmount(component)
|
|
15
|
+
* ```
|
|
6
16
|
*/
|
|
7
17
|
declare const Skeleton: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
18
|
type Skeleton = ReturnType<typeof Skeleton>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
+
@component Steps
|
|
2
3
|
=============================================================================
|
|
3
4
|
@h-ai/ui - Steps 组件
|
|
4
5
|
=============================================================================
|
|
@@ -6,6 +7,16 @@
|
|
|
6
7
|
|
|
7
8
|
使用 Svelte 5 Runes ($props, $derived)
|
|
8
9
|
=============================================================================
|
|
10
|
+
|
|
11
|
+
@example
|
|
12
|
+
```ts
|
|
13
|
+
import { mount, unmount } from 'svelte'
|
|
14
|
+
import type { ComponentProps } from 'svelte'
|
|
15
|
+
import { Steps } from '@h-ai/ui'
|
|
16
|
+
const props: ComponentProps<typeof Steps> = { items: [{ title: '填写资料' }, { title: '确认' }], current: 0 }
|
|
17
|
+
const component = mount(Steps, { target: document.body, props })
|
|
18
|
+
await unmount(component)
|
|
19
|
+
```
|
|
9
20
|
-->
|
|
10
21
|
<script lang='ts'>
|
|
11
22
|
import type { DataAttributes, StepsProps } from '../../types.js'
|
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
import type { DataAttributes, StepsProps } from '../../types.js';
|
|
2
2
|
type $$ComponentProps = StepsProps & DataAttributes;
|
|
3
|
+
/**
|
|
4
|
+
* Steps
|
|
5
|
+
* =============================================================================
|
|
6
|
+
* @h-ai/ui - Steps 组件
|
|
7
|
+
* =============================================================================
|
|
8
|
+
* 步骤条组件
|
|
9
|
+
*
|
|
10
|
+
* 使用 Svelte 5 Runes ($props, $derived)
|
|
11
|
+
* =============================================================================
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { mount, unmount } from 'svelte'
|
|
16
|
+
* import type { ComponentProps } from 'svelte'
|
|
17
|
+
* import { Steps } from '@h-ai/ui'
|
|
18
|
+
* const props: ComponentProps<typeof Steps> = { items: [{ title: '填写资料' }, { title: '确认' }], current: 0 }
|
|
19
|
+
* const component = mount(Steps, { target: document.body, props })
|
|
20
|
+
* await unmount(component)
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
3
23
|
declare const Steps: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
4
24
|
type Steps = ReturnType<typeof Steps>;
|
|
5
25
|
export default Steps;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
+
@component SwipeCell
|
|
2
3
|
@h-ai/ui — SwipeCell(滑动操作 — 列表项左滑删除等)
|
|
3
4
|
|
|
4
5
|
用法:
|
|
@@ -10,6 +11,16 @@
|
|
|
10
11
|
>
|
|
11
12
|
<div class="p-4">列表项内容</div>
|
|
12
13
|
</SwipeCell>
|
|
14
|
+
|
|
15
|
+
@example
|
|
16
|
+
```ts
|
|
17
|
+
import { mount, unmount, createRawSnippet } from 'svelte'
|
|
18
|
+
import type { ComponentProps } from 'svelte'
|
|
19
|
+
import { SwipeCell } from '@h-ai/ui'
|
|
20
|
+
const props: ComponentProps<typeof SwipeCell> = { actions: [{ id: 'remove', label: '删除', variant: 'error' }], children: createRawSnippet(() => ({ render: () => "<p>向左滑动显示操作。</p>" })) }
|
|
21
|
+
const component = mount(SwipeCell, { target: document.body, props })
|
|
22
|
+
await unmount(component)
|
|
23
|
+
```
|
|
13
24
|
-->
|
|
14
25
|
<script lang='ts'>
|
|
15
26
|
import type { Snippet } from 'svelte'
|
|
@@ -20,6 +31,19 @@
|
|
|
20
31
|
// eslint-disable-next-line no-import-assign -- type re-export
|
|
21
32
|
export type { SwipeCellAction }
|
|
22
33
|
|
|
34
|
+
/**
|
|
35
|
+
* SwipeCell 组件的属性契约;通过公开组件配置使用。
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* import { mount, unmount, createRawSnippet } from 'svelte'
|
|
40
|
+
* import type { ComponentProps } from 'svelte'
|
|
41
|
+
* import { SwipeCell } from '@h-ai/ui'
|
|
42
|
+
* const props: ComponentProps<typeof SwipeCell> = { actions: [{ id: 'remove', label: '删除', variant: 'error' }], children: createRawSnippet(() => ({ render: () => "<p>向左滑动显示操作。</p>" })) }
|
|
43
|
+
* const component = mount(SwipeCell, { target: document.body, props })
|
|
44
|
+
* await unmount(component)
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
23
47
|
interface Props {
|
|
24
48
|
/** 右侧操作列表 */
|
|
25
49
|
actions: SwipeCellAction[]
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { DataAttributes } from '../../types.js';
|
|
3
3
|
import type { SwipeCellAction } from './swipe-cell-types.js';
|
|
4
|
+
/**
|
|
5
|
+
* SwipeCell 组件的属性契约;通过公开组件配置使用。
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { mount, unmount, createRawSnippet } from 'svelte'
|
|
10
|
+
* import type { ComponentProps } from 'svelte'
|
|
11
|
+
* import { SwipeCell } from '@h-ai/ui'
|
|
12
|
+
* const props: ComponentProps<typeof SwipeCell> = { actions: [{ id: 'remove', label: '删除', variant: 'error' }], children: createRawSnippet(() => ({ render: () => "<p>向左滑动显示操作。</p>" })) }
|
|
13
|
+
* const component = mount(SwipeCell, { target: document.body, props })
|
|
14
|
+
* await unmount(component)
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
4
17
|
interface Props {
|
|
5
18
|
/** 右侧操作列表 */
|
|
6
19
|
actions: SwipeCellAction[];
|
|
@@ -14,6 +27,30 @@ interface Props {
|
|
|
14
27
|
children: Snippet;
|
|
15
28
|
}
|
|
16
29
|
type $$ComponentProps = Props & DataAttributes;
|
|
30
|
+
/**
|
|
31
|
+
* SwipeCell
|
|
32
|
+
* @h-ai/ui — SwipeCell(滑动操作 — 列表项左滑删除等)
|
|
33
|
+
*
|
|
34
|
+
* 用法:
|
|
35
|
+
* <SwipeCell
|
|
36
|
+
* actions={[
|
|
37
|
+
* { id: 'delete', label: '删除', variant: 'error' },
|
|
38
|
+
* ]}
|
|
39
|
+
* onaction={(id) => handleAction(id)}
|
|
40
|
+
* >
|
|
41
|
+
* <div class="p-4">列表项内容</div>
|
|
42
|
+
* </SwipeCell>
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* import { mount, unmount, createRawSnippet } from 'svelte'
|
|
47
|
+
* import type { ComponentProps } from 'svelte'
|
|
48
|
+
* import { SwipeCell } from '@h-ai/ui'
|
|
49
|
+
* const props: ComponentProps<typeof SwipeCell> = { actions: [{ id: 'remove', label: '删除', variant: 'error' }], children: createRawSnippet(() => ({ render: () => "<p>向左滑动显示操作。</p>" })) }
|
|
50
|
+
* const component = mount(SwipeCell, { target: document.body, props })
|
|
51
|
+
* await unmount(component)
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
17
54
|
declare const SwipeCell: import("svelte").Component<$$ComponentProps, {
|
|
18
55
|
SwipeCellAction: typeof SwipeCellAction;
|
|
19
56
|
}, "">;
|
|
@@ -25,23 +25,14 @@
|
|
|
25
25
|
@prop {Function} onPrimaryAction - 主操作回调
|
|
26
26
|
|
|
27
27
|
@example
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
sortableColumns={[{ key: 'name', label: '名称' }]}
|
|
37
|
-
sortBy="name"
|
|
38
|
-
sortDirection="asc"
|
|
39
|
-
onsearch={(v) => handleSearch(v)}
|
|
40
|
-
onfilterchange={(f) => handleFilter(f)}
|
|
41
|
-
onsort={(key, dir) => handleSort(key, dir)}
|
|
42
|
-
>
|
|
43
|
-
<Button size="sm" onclick={handleExport}>导出</Button>
|
|
44
|
-
</TableToolbar>
|
|
28
|
+
```ts
|
|
29
|
+
import { mount, unmount } from 'svelte'
|
|
30
|
+
import type { ComponentProps } from 'svelte'
|
|
31
|
+
import { TableToolbar } from '@h-ai/ui'
|
|
32
|
+
const props: ComponentProps<typeof TableToolbar> = { searchable: true, searchValue: 'Ada', filterFields: [{ id: 'active', label: '状态', type: 'boolean' }] }
|
|
33
|
+
const component = mount(TableToolbar, { target: document.body, props })
|
|
34
|
+
await unmount(component)
|
|
35
|
+
```
|
|
45
36
|
-->
|
|
46
37
|
<script lang='ts'>
|
|
47
38
|
import type { Snippet } from 'svelte'
|
|
@@ -50,7 +41,14 @@
|
|
|
50
41
|
import { uiM } from '../../messages.js'
|
|
51
42
|
import { getDataAttributes } from '../../utils.js'
|
|
52
43
|
|
|
53
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* 工具栏筛选字段定义。
|
|
46
|
+
*
|
|
47
|
+
* @example 模块内部上下文
|
|
48
|
+
* ```ts
|
|
49
|
+
* const example: FilterFieldDef = { id: 'active', label: '状态', type: 'boolean' }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
54
52
|
type FilterFieldDef = {
|
|
55
53
|
/** 筛选字段 key,同时作为回调中的属性名。 */
|
|
56
54
|
id: string
|
|
@@ -74,7 +72,19 @@
|
|
|
74
72
|
options?: Array<{ label: string, value: string | number | boolean }> | (() => Array<{ label: string, value: string | number | boolean }>)
|
|
75
73
|
}
|
|
76
74
|
|
|
77
|
-
/**
|
|
75
|
+
/**
|
|
76
|
+
* TableToolbar 对外入参。
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* import { mount, unmount } from 'svelte'
|
|
81
|
+
* import type { ComponentProps } from 'svelte'
|
|
82
|
+
* import { TableToolbar } from '@h-ai/ui'
|
|
83
|
+
* const props: ComponentProps<typeof TableToolbar> = { searchable: true, searchValue: 'Ada', filterFields: [{ id: 'active', label: '状态', type: 'boolean' }] }
|
|
84
|
+
* const component = mount(TableToolbar, { target: document.body, props })
|
|
85
|
+
* await unmount(component)
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
78
88
|
type TableToolbarProps = {
|
|
79
89
|
/** 是否显示搜索框,默认 true。 */
|
|
80
90
|
searchable?: boolean
|
|
@@ -158,6 +168,19 @@
|
|
|
158
168
|
let sortOpen = $state(false)
|
|
159
169
|
/** 用于检测外部点击的根节点。 */
|
|
160
170
|
let rootElement = $state<HTMLElement | null>(null)
|
|
171
|
+
let filterTrigger = $state<HTMLButtonElement>()
|
|
172
|
+
let sortTrigger = $state<HTMLButtonElement>()
|
|
173
|
+
let filterPanel = $state<HTMLDivElement>()
|
|
174
|
+
let sortPanel = $state<HTMLDivElement>()
|
|
175
|
+
const toolbarId = $props.id()
|
|
176
|
+
|
|
177
|
+
// 弹层渲染后直接进入可用输入;关闭与外部点击不抢夺其它控件焦点。
|
|
178
|
+
$effect(() => {
|
|
179
|
+
const panel = filterOpen ? filterPanel : sortOpen ? sortPanel : undefined
|
|
180
|
+
const control = panel?.querySelector<HTMLElement>('input:not(:disabled), select:not(:disabled)')
|
|
181
|
+
?? panel?.querySelector<HTMLElement>('button:not(:disabled)')
|
|
182
|
+
control?.focus()
|
|
183
|
+
})
|
|
161
184
|
|
|
162
185
|
// ─── 日期范围本地输入 ───
|
|
163
186
|
/** 日期范围起始输入框草稿。 */
|
|
@@ -373,23 +396,28 @@
|
|
|
373
396
|
|
|
374
397
|
/** Escape 键关闭当前弹层。 */
|
|
375
398
|
const handleKeyDown = (event: KeyboardEvent) => {
|
|
376
|
-
if (event.key === 'Escape') {
|
|
399
|
+
if (event.key === 'Escape' && !event.defaultPrevented && (filterOpen || sortOpen)) {
|
|
400
|
+
event.preventDefault()
|
|
401
|
+
event.stopPropagation()
|
|
402
|
+
const trigger = filterOpen ? filterTrigger : sortTrigger
|
|
377
403
|
filterOpen = false
|
|
378
404
|
sortOpen = false
|
|
405
|
+
trigger?.focus()
|
|
379
406
|
}
|
|
380
407
|
}
|
|
381
408
|
|
|
382
409
|
document.addEventListener('pointerdown', handlePointerDown)
|
|
383
|
-
|
|
410
|
+
const root = rootElement
|
|
411
|
+
root?.addEventListener('keydown', handleKeyDown)
|
|
384
412
|
|
|
385
413
|
return () => {
|
|
386
414
|
document.removeEventListener('pointerdown', handlePointerDown)
|
|
387
|
-
|
|
415
|
+
root?.removeEventListener('keydown', handleKeyDown)
|
|
388
416
|
}
|
|
389
417
|
})
|
|
390
418
|
</script>
|
|
391
419
|
|
|
392
|
-
<div {...dataAttributes} bind:this={rootElement} class='flex items-center justify-between gap-3 flex-wrap {className}'>
|
|
420
|
+
<div {...dataAttributes} bind:this={rootElement} class='relative flex min-w-0 w-full items-center justify-between gap-3 flex-wrap {className}'>
|
|
393
421
|
<!-- 左侧信息区:标题、说明等不参与表格操作的内容。 -->
|
|
394
422
|
{#if leading}
|
|
395
423
|
<div class='min-w-0 flex-1'>
|
|
@@ -421,13 +449,15 @@
|
|
|
421
449
|
|
|
422
450
|
<!-- 筛选弹层按钮 -->
|
|
423
451
|
{#if hasFilters}
|
|
424
|
-
<div
|
|
452
|
+
<div>
|
|
425
453
|
<button
|
|
454
|
+
bind:this={filterTrigger}
|
|
426
455
|
type='button'
|
|
427
456
|
aria-expanded={filterOpen}
|
|
457
|
+
aria-controls={filterOpen ? `${toolbarId}-filters` : undefined}
|
|
428
458
|
aria-haspopup='dialog'
|
|
429
459
|
aria-label={uiM('toolbar_filter')}
|
|
430
|
-
class='btn btn-sm btn-square border-base-content/15 bg-base-100 {activeFilterCount > 0 ? 'border-primary/50 text-primary bg-primary/5' : ''}'
|
|
460
|
+
class='relative btn btn-sm btn-square border-base-content/15 bg-base-100 {activeFilterCount > 0 ? 'border-primary/50 text-primary bg-primary/5' : ''}'
|
|
431
461
|
title={uiM('toolbar_filter')}
|
|
432
462
|
onclick={toggleFilterPopover}
|
|
433
463
|
>
|
|
@@ -441,9 +471,11 @@
|
|
|
441
471
|
|
|
442
472
|
{#if filterOpen}
|
|
443
473
|
<div
|
|
474
|
+
bind:this={filterPanel}
|
|
475
|
+
id={`${toolbarId}-filters`}
|
|
444
476
|
role='dialog'
|
|
445
477
|
aria-label={uiM('toolbar_filter_conditions')}
|
|
446
|
-
class='absolute top-full right-0 mt-2 z-50 w-[min(22rem,calc(100vw-2rem))] rounded-xl border border-base-content/10 bg-base-100 p-4 shadow-lg'
|
|
478
|
+
class='absolute top-full right-0 mt-2 z-50 w-[min(22rem,100%,calc(100vw-2rem))] max-h-[60vh] overflow-y-auto rounded-xl border border-base-content/10 bg-base-100 p-4 shadow-lg'
|
|
447
479
|
>
|
|
448
480
|
<div class='flex items-center justify-between mb-3'>
|
|
449
481
|
<h3 class='text-sm font-semibold text-base-content'>{uiM('toolbar_filter')}</h3>
|
|
@@ -555,10 +587,12 @@
|
|
|
555
587
|
|
|
556
588
|
<!-- 排序弹层按钮 -->
|
|
557
589
|
{#if hasSortableColumns}
|
|
558
|
-
<div
|
|
590
|
+
<div>
|
|
559
591
|
<button
|
|
592
|
+
bind:this={sortTrigger}
|
|
560
593
|
type='button'
|
|
561
594
|
aria-expanded={sortOpen}
|
|
595
|
+
aria-controls={sortOpen ? `${toolbarId}-sort` : undefined}
|
|
562
596
|
aria-haspopup='dialog'
|
|
563
597
|
aria-label={uiM('toolbar_sort')}
|
|
564
598
|
class='btn btn-sm btn-square border-base-content/15 bg-base-100 {sortBy ? 'border-primary/50 text-primary bg-primary/5' : ''}'
|
|
@@ -570,9 +604,11 @@
|
|
|
570
604
|
|
|
571
605
|
{#if sortOpen}
|
|
572
606
|
<div
|
|
607
|
+
bind:this={sortPanel}
|
|
608
|
+
id={`${toolbarId}-sort`}
|
|
573
609
|
role='dialog'
|
|
574
610
|
aria-label={uiM('toolbar_sort_conditions')}
|
|
575
|
-
class='absolute top-full right-0 mt-2 z-50 w-[min(18rem,calc(100vw-2rem))] rounded-xl border border-base-content/10 bg-base-100 p-4 shadow-lg'
|
|
611
|
+
class='absolute top-full right-0 mt-2 z-50 w-[min(18rem,100%,calc(100vw-2rem))] max-h-[60vh] overflow-y-auto rounded-xl border border-base-content/10 bg-base-100 p-4 shadow-lg'
|
|
576
612
|
>
|
|
577
613
|
<div class='flex items-center justify-between mb-3'>
|
|
578
614
|
<h3 class='text-sm font-semibold text-base-content'>{uiM('toolbar_sort')}</h3>
|
|
@@ -652,6 +688,7 @@
|
|
|
652
688
|
type='button'
|
|
653
689
|
class='btn btn-sm join-item border-base-content/15 bg-base-100 {viewMode === 'table' ? 'text-primary bg-primary/5' : ''}'
|
|
654
690
|
aria-label={uiM('toolbar_view_table')}
|
|
691
|
+
aria-pressed={viewMode === 'table'}
|
|
655
692
|
title={uiM('toolbar_view_table')}
|
|
656
693
|
onclick={() => {
|
|
657
694
|
viewMode = 'table'
|
|
@@ -664,6 +701,7 @@
|
|
|
664
701
|
type='button'
|
|
665
702
|
class='btn btn-sm join-item border-base-content/15 bg-base-100 {viewMode === 'card' ? 'text-primary bg-primary/5' : ''}'
|
|
666
703
|
aria-label={uiM('toolbar_view_card')}
|
|
704
|
+
aria-pressed={viewMode === 'card'}
|
|
667
705
|
title={uiM('toolbar_view_card')}
|
|
668
706
|
onclick={() => {
|
|
669
707
|
viewMode = 'card'
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { DataAttributes } from '../../types.js';
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* 工具栏筛选字段定义。
|
|
5
|
+
*
|
|
6
|
+
* @example 模块内部上下文
|
|
7
|
+
* ```ts
|
|
8
|
+
* const example: FilterFieldDef = { id: 'active', label: '状态', type: 'boolean' }
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
4
11
|
type FilterFieldDef = {
|
|
5
12
|
/** 筛选字段 key,同时作为回调中的属性名。 */
|
|
6
13
|
id: string;
|
|
@@ -29,7 +36,19 @@ type FilterFieldDef = {
|
|
|
29
36
|
value: string | number | boolean;
|
|
30
37
|
}>);
|
|
31
38
|
};
|
|
32
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* TableToolbar 对外入参。
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { mount, unmount } from 'svelte'
|
|
45
|
+
* import type { ComponentProps } from 'svelte'
|
|
46
|
+
* import { TableToolbar } from '@h-ai/ui'
|
|
47
|
+
* const props: ComponentProps<typeof TableToolbar> = { searchable: true, searchValue: 'Ada', filterFields: [{ id: 'active', label: '状态', type: 'boolean' }] }
|
|
48
|
+
* const component = mount(TableToolbar, { target: document.body, props })
|
|
49
|
+
* await unmount(component)
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
33
52
|
type TableToolbarProps = {
|
|
34
53
|
/** 是否显示搜索框,默认 true。 */
|
|
35
54
|
searchable?: boolean;
|
|
@@ -106,23 +125,14 @@ type TableToolbarProps = {
|
|
|
106
125
|
* @prop {Function} onPrimaryAction - 主操作回调
|
|
107
126
|
*
|
|
108
127
|
* @example
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* sortableColumns={[{ key: 'name', label: '名称' }]}
|
|
118
|
-
* sortBy="name"
|
|
119
|
-
* sortDirection="asc"
|
|
120
|
-
* onsearch={(v) => handleSearch(v)}
|
|
121
|
-
* onfilterchange={(f) => handleFilter(f)}
|
|
122
|
-
* onsort={(key, dir) => handleSort(key, dir)}
|
|
123
|
-
* >
|
|
124
|
-
* <Button size="sm" onclick={handleExport}>导出</Button>
|
|
125
|
-
* </TableToolbar>
|
|
128
|
+
* ```ts
|
|
129
|
+
* import { mount, unmount } from 'svelte'
|
|
130
|
+
* import type { ComponentProps } from 'svelte'
|
|
131
|
+
* import { TableToolbar } from '@h-ai/ui'
|
|
132
|
+
* const props: ComponentProps<typeof TableToolbar> = { searchable: true, searchValue: 'Ada', filterFields: [{ id: 'active', label: '状态', type: 'boolean' }] }
|
|
133
|
+
* const component = mount(TableToolbar, { target: document.body, props })
|
|
134
|
+
* await unmount(component)
|
|
135
|
+
* ```
|
|
126
136
|
*/
|
|
127
137
|
declare const TableToolbar: import("svelte").Component<TableToolbarProps, {}, "searchValue" | "filterValues" | "sortBy" | "sortDirection" | "viewMode">;
|
|
128
138
|
type TableToolbar = ReturnType<typeof TableToolbar>;
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component Tabs
|
|
3
3
|
标签页组件,支持 line/card/pills 三种样式。
|
|
4
|
+
|
|
5
|
+
@example
|
|
6
|
+
```ts
|
|
7
|
+
import { mount, unmount } from 'svelte'
|
|
8
|
+
import type { ComponentProps } from 'svelte'
|
|
9
|
+
import { Tabs } from '@h-ai/ui'
|
|
10
|
+
const props: ComponentProps<typeof Tabs> = { items: [{ key: 'profile', label: '资料' }, { key: 'security', label: '安全' }], active: 'profile', lazy: true }
|
|
11
|
+
const component = mount(Tabs, { target: document.body, props })
|
|
12
|
+
await unmount(component)
|
|
13
|
+
```
|
|
4
14
|
-->
|
|
5
15
|
<script lang='ts'>
|
|
6
16
|
import type { DataAttributes, TabsProps } from '../../types.js'
|
|
7
17
|
import { SvelteSet } from 'svelte/reactivity'
|
|
8
18
|
import { cn, getDataAttributes } from '../../utils.js'
|
|
9
|
-
import BareButton from '../primitives/BareButton.svelte'
|
|
10
19
|
|
|
11
20
|
let {
|
|
12
21
|
items,
|
|
@@ -22,13 +31,15 @@
|
|
|
22
31
|
}: TabsProps & DataAttributes = $props()
|
|
23
32
|
|
|
24
33
|
const dataAttributes = $derived(getDataAttributes(restProps))
|
|
34
|
+
const tabsId = $props.id()
|
|
35
|
+
let tablist = $state<HTMLDivElement>()
|
|
25
36
|
// 已激活过的页签集合,用于惰性挂载(不预加载不可见页签)。
|
|
26
37
|
const activatedKeys = new SvelteSet<string>()
|
|
27
38
|
|
|
28
|
-
//
|
|
39
|
+
// 初始或选项变化后选中可用页签,避免激活禁用项或已删除项。
|
|
29
40
|
$effect(() => {
|
|
30
|
-
if (!active &&
|
|
31
|
-
active = items
|
|
41
|
+
if (!items.some(item => item.key === active && !item.disabled)) {
|
|
42
|
+
active = items.find(item => !item.disabled)?.key ?? ''
|
|
32
43
|
}
|
|
33
44
|
})
|
|
34
45
|
|
|
@@ -65,6 +76,7 @@
|
|
|
65
76
|
const tabsClass = $derived(
|
|
66
77
|
cn(
|
|
67
78
|
'tabs',
|
|
79
|
+
'max-w-full flex-nowrap overflow-x-auto',
|
|
68
80
|
typeMap[type],
|
|
69
81
|
sizeMap[size],
|
|
70
82
|
className,
|
|
@@ -72,30 +84,66 @@
|
|
|
72
84
|
)
|
|
73
85
|
|
|
74
86
|
function handleSelect(key: string) {
|
|
87
|
+
if (active === key)
|
|
88
|
+
return
|
|
75
89
|
active = key
|
|
76
90
|
onchange?.(key)
|
|
77
91
|
}
|
|
92
|
+
|
|
93
|
+
// 自动激活模式:方向键移动焦点并选择,跳过禁用项且支持首尾循环。
|
|
94
|
+
function handleKeydown(event: KeyboardEvent, key: string) {
|
|
95
|
+
const enabled = items.filter(item => !item.disabled)
|
|
96
|
+
if (!enabled.length)
|
|
97
|
+
return
|
|
98
|
+
const index = enabled.findIndex(item => item.key === key)
|
|
99
|
+
const rtl = getComputedStyle(event.currentTarget as HTMLElement).direction === 'rtl'
|
|
100
|
+
let next: number
|
|
101
|
+
switch (event.key) {
|
|
102
|
+
case 'ArrowRight':
|
|
103
|
+
next = index + (rtl ? -1 : 1)
|
|
104
|
+
break
|
|
105
|
+
case 'ArrowLeft':
|
|
106
|
+
next = index + (rtl ? 1 : -1)
|
|
107
|
+
break
|
|
108
|
+
case 'Home':
|
|
109
|
+
next = 0
|
|
110
|
+
break
|
|
111
|
+
case 'End':
|
|
112
|
+
next = enabled.length - 1
|
|
113
|
+
break
|
|
114
|
+
default: return
|
|
115
|
+
}
|
|
116
|
+
event.preventDefault()
|
|
117
|
+
const selected = enabled[(next + enabled.length) % enabled.length]
|
|
118
|
+
handleSelect(selected.key)
|
|
119
|
+
tablist?.querySelectorAll<HTMLButtonElement>('[role="tab"]:not(:disabled)')[(next + enabled.length) % enabled.length]?.focus()
|
|
120
|
+
}
|
|
78
121
|
</script>
|
|
79
122
|
|
|
80
|
-
<div {...dataAttributes} role='tablist' class={tabsClass}>
|
|
123
|
+
<div {...dataAttributes} bind:this={tablist} role='tablist' class={tabsClass}>
|
|
81
124
|
{#each items as item (item.key)}
|
|
82
|
-
<
|
|
125
|
+
<button
|
|
126
|
+
type='button'
|
|
127
|
+
id={`${tabsId}-${encodeURIComponent(item.key)}`}
|
|
83
128
|
role='tab'
|
|
84
|
-
|
|
85
|
-
|
|
129
|
+
aria-selected={active === item.key}
|
|
130
|
+
aria-controls={children ? `${tabsId}-panel` : undefined}
|
|
131
|
+
tabindex={active === item.key ? 0 : -1}
|
|
132
|
+
class={cn('tab shrink-0', active === item.key && 'tab-active')}
|
|
86
133
|
disabled={item.disabled}
|
|
87
134
|
onclick={() => handleSelect(item.key)}
|
|
135
|
+
onkeydown={event => handleKeydown(event, item.key)}
|
|
88
136
|
>
|
|
89
137
|
{#if item.icon}
|
|
90
138
|
<span class='mr-1'>{item.icon}</span>
|
|
91
139
|
{/if}
|
|
92
140
|
{item.label}
|
|
93
|
-
</
|
|
141
|
+
</button>
|
|
94
142
|
{/each}
|
|
95
143
|
</div>
|
|
96
144
|
|
|
97
145
|
{#if children}
|
|
98
|
-
<div class='py-4'>
|
|
146
|
+
<div id={`${tabsId}-panel`} role='tabpanel' aria-labelledby={active ? `${tabsId}-${encodeURIComponent(active)}` : undefined} tabindex='0' class='min-w-0 py-4'>
|
|
99
147
|
{@render children({ active, isActivated })}
|
|
100
148
|
</div>
|
|
101
149
|
{/if}
|
|
@@ -3,6 +3,16 @@ type $$ComponentProps = TabsProps & DataAttributes;
|
|
|
3
3
|
/**
|
|
4
4
|
* Tabs
|
|
5
5
|
* 标签页组件,支持 line/card/pills 三种样式。
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { mount, unmount } from 'svelte'
|
|
10
|
+
* import type { ComponentProps } from 'svelte'
|
|
11
|
+
* import { Tabs } from '@h-ai/ui'
|
|
12
|
+
* const props: ComponentProps<typeof Tabs> = { items: [{ key: 'profile', label: '资料' }, { key: 'security', label: '安全' }], active: 'profile', lazy: true }
|
|
13
|
+
* const component = mount(Tabs, { target: document.body, props })
|
|
14
|
+
* await unmount(component)
|
|
15
|
+
* ```
|
|
6
16
|
*/
|
|
7
17
|
declare const Tabs: import("svelte").Component<$$ComponentProps, {}, "active">;
|
|
8
18
|
type Tabs = ReturnType<typeof Tabs>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
+
@component TagInput
|
|
2
3
|
=============================================================================
|
|
3
4
|
@h-ai/ui - TagInput 组件
|
|
4
5
|
=============================================================================
|
|
@@ -6,6 +7,16 @@
|
|
|
6
7
|
|
|
7
8
|
使用 Svelte 5 Runes ($props, $state, $bindable)
|
|
8
9
|
=============================================================================
|
|
10
|
+
|
|
11
|
+
@example
|
|
12
|
+
```ts
|
|
13
|
+
import { mount, unmount } from 'svelte'
|
|
14
|
+
import type { ComponentProps } from 'svelte'
|
|
15
|
+
import { TagInput } from '@h-ai/ui'
|
|
16
|
+
const props: ComponentProps<typeof TagInput> = { tags: ['Svelte'], maxTags: 5 }
|
|
17
|
+
const component = mount(TagInput, { target: document.body, props })
|
|
18
|
+
await unmount(component)
|
|
19
|
+
```
|
|
9
20
|
-->
|
|
10
21
|
<script lang='ts'>
|
|
11
22
|
import type { DataAttributes, TagInputProps } from '../../types.js'
|
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
import type { DataAttributes, TagInputProps } from '../../types.js';
|
|
2
2
|
type $$ComponentProps = TagInputProps & DataAttributes;
|
|
3
|
+
/**
|
|
4
|
+
* TagInput
|
|
5
|
+
* =============================================================================
|
|
6
|
+
* @h-ai/ui - TagInput 组件
|
|
7
|
+
* =============================================================================
|
|
8
|
+
* 标签输入框组件
|
|
9
|
+
*
|
|
10
|
+
* 使用 Svelte 5 Runes ($props, $state, $bindable)
|
|
11
|
+
* =============================================================================
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { mount, unmount } from 'svelte'
|
|
16
|
+
* import type { ComponentProps } from 'svelte'
|
|
17
|
+
* import { TagInput } from '@h-ai/ui'
|
|
18
|
+
* const props: ComponentProps<typeof TagInput> = { tags: ['Svelte'], maxTags: 5 }
|
|
19
|
+
* const component = mount(TagInput, { target: document.body, props })
|
|
20
|
+
* await unmount(component)
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
3
23
|
declare const TagInput: import("svelte").Component<$$ComponentProps, {}, "tags">;
|
|
4
24
|
type TagInput = ReturnType<typeof TagInput>;
|
|
5
25
|
export default TagInput;
|