@h-ai/ui 0.1.0-alpha5

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.
Files changed (234) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +488 -0
  3. package/auto-import.d.ts +96 -0
  4. package/auto-import.js +259 -0
  5. package/dist/components/compounds/Accordion.svelte +142 -0
  6. package/dist/components/compounds/Accordion.svelte.d.ts +25 -0
  7. package/dist/components/compounds/ActionSheet.svelte +116 -0
  8. package/dist/components/compounds/ActionSheet.svelte.d.ts +22 -0
  9. package/dist/components/compounds/Alert.svelte +67 -0
  10. package/dist/components/compounds/Alert.svelte.d.ts +8 -0
  11. package/dist/components/compounds/AppBar.svelte +77 -0
  12. package/dist/components/compounds/AppBar.svelte.d.ts +20 -0
  13. package/dist/components/compounds/BottomNav.svelte +75 -0
  14. package/dist/components/compounds/BottomNav.svelte.d.ts +18 -0
  15. package/dist/components/compounds/Breadcrumb.svelte +49 -0
  16. package/dist/components/compounds/Breadcrumb.svelte.d.ts +4 -0
  17. package/dist/components/compounds/Calendar.svelte +116 -0
  18. package/dist/components/compounds/Calendar.svelte.d.ts +47 -0
  19. package/dist/components/compounds/Card.svelte +77 -0
  20. package/dist/components/compounds/Card.svelte.d.ts +8 -0
  21. package/dist/components/compounds/Combobox.svelte +327 -0
  22. package/dist/components/compounds/Combobox.svelte.d.ts +69 -0
  23. package/dist/components/compounds/Confirm.svelte +90 -0
  24. package/dist/components/compounds/Confirm.svelte.d.ts +4 -0
  25. package/dist/components/compounds/DataTable.svelte +133 -0
  26. package/dist/components/compounds/DataTable.svelte.d.ts +69 -0
  27. package/dist/components/compounds/DatePicker.svelte +135 -0
  28. package/dist/components/compounds/DatePicker.svelte.d.ts +46 -0
  29. package/dist/components/compounds/Drawer.svelte +113 -0
  30. package/dist/components/compounds/Drawer.svelte.d.ts +4 -0
  31. package/dist/components/compounds/Dropdown.svelte +91 -0
  32. package/dist/components/compounds/Dropdown.svelte.d.ts +8 -0
  33. package/dist/components/compounds/Empty.svelte +83 -0
  34. package/dist/components/compounds/Empty.svelte.d.ts +4 -0
  35. package/dist/components/compounds/Form.svelte +96 -0
  36. package/dist/components/compounds/Form.svelte.d.ts +7 -0
  37. package/dist/components/compounds/FormField.svelte +56 -0
  38. package/dist/components/compounds/FormField.svelte.d.ts +4 -0
  39. package/dist/components/compounds/InfiniteScroll.svelte +82 -0
  40. package/dist/components/compounds/InfiniteScroll.svelte.d.ts +22 -0
  41. package/dist/components/compounds/Modal.svelte +123 -0
  42. package/dist/components/compounds/Modal.svelte.d.ts +8 -0
  43. package/dist/components/compounds/PageHeader.svelte +44 -0
  44. package/dist/components/compounds/PageHeader.svelte.d.ts +28 -0
  45. package/dist/components/compounds/Pagination.svelte +157 -0
  46. package/dist/components/compounds/Pagination.svelte.d.ts +4 -0
  47. package/dist/components/compounds/Popover.svelte +137 -0
  48. package/dist/components/compounds/Popover.svelte.d.ts +4 -0
  49. package/dist/components/compounds/PullRefresh.svelte +98 -0
  50. package/dist/components/compounds/PullRefresh.svelte.d.ts +16 -0
  51. package/dist/components/compounds/Result.svelte +84 -0
  52. package/dist/components/compounds/Result.svelte.d.ts +4 -0
  53. package/dist/components/compounds/SafeArea.svelte +37 -0
  54. package/dist/components/compounds/SafeArea.svelte.d.ts +12 -0
  55. package/dist/components/compounds/Skeleton.svelte +75 -0
  56. package/dist/components/compounds/Skeleton.svelte.d.ts +8 -0
  57. package/dist/components/compounds/Steps.svelte +111 -0
  58. package/dist/components/compounds/Steps.svelte.d.ts +4 -0
  59. package/dist/components/compounds/SwipeCell.svelte +115 -0
  60. package/dist/components/compounds/SwipeCell.svelte.d.ts +19 -0
  61. package/dist/components/compounds/Tabs.svelte +79 -0
  62. package/dist/components/compounds/Tabs.svelte.d.ts +8 -0
  63. package/dist/components/compounds/TagInput.svelte +108 -0
  64. package/dist/components/compounds/TagInput.svelte.d.ts +4 -0
  65. package/dist/components/compounds/Timeline.svelte +167 -0
  66. package/dist/components/compounds/Timeline.svelte.d.ts +25 -0
  67. package/dist/components/compounds/ToastContainer.svelte +59 -0
  68. package/dist/components/compounds/ToastContainer.svelte.d.ts +3 -0
  69. package/dist/components/compounds/Tooltip.svelte +41 -0
  70. package/dist/components/compounds/Tooltip.svelte.d.ts +4 -0
  71. package/dist/components/compounds/accordion-types.d.ts +16 -0
  72. package/dist/components/compounds/accordion-types.js +5 -0
  73. package/dist/components/compounds/action-sheet-types.d.ts +14 -0
  74. package/dist/components/compounds/action-sheet-types.js +5 -0
  75. package/dist/components/compounds/bottom-nav-types.d.ts +17 -0
  76. package/dist/components/compounds/bottom-nav-types.js +5 -0
  77. package/dist/components/compounds/index.d.ts +44 -0
  78. package/dist/components/compounds/index.js +54 -0
  79. package/dist/components/compounds/swipe-cell-types.d.ts +14 -0
  80. package/dist/components/compounds/swipe-cell-types.js +5 -0
  81. package/dist/components/compounds/timeline-types.d.ts +20 -0
  82. package/dist/components/compounds/timeline-types.js +5 -0
  83. package/dist/components/index.d.ts +9 -0
  84. package/dist/components/index.js +12 -0
  85. package/dist/components/primitives/Avatar.svelte +102 -0
  86. package/dist/components/primitives/Avatar.svelte.d.ts +8 -0
  87. package/dist/components/primitives/Badge.svelte +33 -0
  88. package/dist/components/primitives/Badge.svelte.d.ts +8 -0
  89. package/dist/components/primitives/BareButton.svelte +45 -0
  90. package/dist/components/primitives/BareButton.svelte.d.ts +4 -0
  91. package/dist/components/primitives/BareInput.svelte +101 -0
  92. package/dist/components/primitives/BareInput.svelte.d.ts +4 -0
  93. package/dist/components/primitives/Button.svelte +60 -0
  94. package/dist/components/primitives/Button.svelte.d.ts +8 -0
  95. package/dist/components/primitives/Checkbox.svelte +58 -0
  96. package/dist/components/primitives/Checkbox.svelte.d.ts +4 -0
  97. package/dist/components/primitives/IconButton.svelte +105 -0
  98. package/dist/components/primitives/IconButton.svelte.d.ts +4 -0
  99. package/dist/components/primitives/Input.svelte +130 -0
  100. package/dist/components/primitives/Input.svelte.d.ts +8 -0
  101. package/dist/components/primitives/Progress.svelte +58 -0
  102. package/dist/components/primitives/Progress.svelte.d.ts +4 -0
  103. package/dist/components/primitives/Radio.svelte +60 -0
  104. package/dist/components/primitives/Radio.svelte.d.ts +25 -0
  105. package/dist/components/primitives/Range.svelte +117 -0
  106. package/dist/components/primitives/Range.svelte.d.ts +27 -0
  107. package/dist/components/primitives/Rating.svelte +148 -0
  108. package/dist/components/primitives/Rating.svelte.d.ts +27 -0
  109. package/dist/components/primitives/Select.svelte +95 -0
  110. package/dist/components/primitives/Select.svelte.d.ts +25 -0
  111. package/dist/components/primitives/Spinner.svelte +54 -0
  112. package/dist/components/primitives/Spinner.svelte.d.ts +4 -0
  113. package/dist/components/primitives/Switch.svelte +53 -0
  114. package/dist/components/primitives/Switch.svelte.d.ts +4 -0
  115. package/dist/components/primitives/Tag.svelte +64 -0
  116. package/dist/components/primitives/Tag.svelte.d.ts +4 -0
  117. package/dist/components/primitives/Textarea.svelte +92 -0
  118. package/dist/components/primitives/Textarea.svelte.d.ts +4 -0
  119. package/dist/components/primitives/ToggleCheckbox.svelte +36 -0
  120. package/dist/components/primitives/ToggleCheckbox.svelte.d.ts +4 -0
  121. package/dist/components/primitives/ToggleInput.svelte +36 -0
  122. package/dist/components/primitives/ToggleInput.svelte.d.ts +4 -0
  123. package/dist/components/primitives/ToggleRadio.svelte +36 -0
  124. package/dist/components/primitives/ToggleRadio.svelte.d.ts +4 -0
  125. package/dist/components/primitives/index.d.ts +26 -0
  126. package/dist/components/primitives/index.js +30 -0
  127. package/dist/components/scenes/ai/AiDocumentDownloadMenu.svelte +387 -0
  128. package/dist/components/scenes/ai/AiDocumentDownloadMenu.svelte.d.ts +38 -0
  129. package/dist/components/scenes/ai/AiDocumentEditor.svelte +2259 -0
  130. package/dist/components/scenes/ai/AiDocumentEditor.svelte.d.ts +4 -0
  131. package/dist/components/scenes/ai/MarkdownRenderer.svelte +460 -0
  132. package/dist/components/scenes/ai/MarkdownRenderer.svelte.d.ts +4 -0
  133. package/dist/components/scenes/ai/document-download.d.ts +40 -0
  134. package/dist/components/scenes/ai/document-download.js +300 -0
  135. package/dist/components/scenes/ai/document-parse.d.ts +28 -0
  136. package/dist/components/scenes/ai/document-parse.js +243 -0
  137. package/dist/components/scenes/ai/document-types.d.ts +164 -0
  138. package/dist/components/scenes/ai/document-types.js +1 -0
  139. package/dist/components/scenes/ai/index.d.ts +17 -0
  140. package/dist/components/scenes/ai/index.js +13 -0
  141. package/dist/components/scenes/ai/markdown-parse.d.ts +32 -0
  142. package/dist/components/scenes/ai/markdown-parse.js +161 -0
  143. package/dist/components/scenes/app/FeedbackModal.svelte +160 -0
  144. package/dist/components/scenes/app/FeedbackModal.svelte.d.ts +47 -0
  145. package/dist/components/scenes/app/LanguageSwitch.svelte +136 -0
  146. package/dist/components/scenes/app/LanguageSwitch.svelte.d.ts +50 -0
  147. package/dist/components/scenes/app/SettingsModal.svelte +174 -0
  148. package/dist/components/scenes/app/SettingsModal.svelte.d.ts +31 -0
  149. package/dist/components/scenes/app/ThemeSelector.svelte +176 -0
  150. package/dist/components/scenes/app/ThemeSelector.svelte.d.ts +31 -0
  151. package/dist/components/scenes/app/ThemeToggle.svelte +76 -0
  152. package/dist/components/scenes/app/ThemeToggle.svelte.d.ts +29 -0
  153. package/dist/components/scenes/app/index.d.ts +11 -0
  154. package/dist/components/scenes/app/index.js +11 -0
  155. package/dist/components/scenes/crud/CrudDeleteConfirm.svelte +39 -0
  156. package/dist/components/scenes/crud/CrudDeleteConfirm.svelte.d.ts +18 -0
  157. package/dist/components/scenes/crud/CrudDetailDrawer.svelte +155 -0
  158. package/dist/components/scenes/crud/CrudDetailDrawer.svelte.d.ts +38 -0
  159. package/dist/components/scenes/crud/CrudEditDrawer.svelte +222 -0
  160. package/dist/components/scenes/crud/CrudEditDrawer.svelte.d.ts +48 -0
  161. package/dist/components/scenes/crud/CrudFilterBar.svelte +96 -0
  162. package/dist/components/scenes/crud/CrudFilterBar.svelte.d.ts +31 -0
  163. package/dist/components/scenes/crud/CrudPage.svelte +499 -0
  164. package/dist/components/scenes/crud/CrudPage.svelte.d.ts +114 -0
  165. package/dist/components/scenes/crud/crud-types.d.ts +135 -0
  166. package/dist/components/scenes/crud/crud-types.js +7 -0
  167. package/dist/components/scenes/crud/index.d.ts +12 -0
  168. package/dist/components/scenes/crud/index.js +11 -0
  169. package/dist/components/scenes/crypto/EncryptedInput.svelte +156 -0
  170. package/dist/components/scenes/crypto/EncryptedInput.svelte.d.ts +32 -0
  171. package/dist/components/scenes/crypto/HashDisplay.svelte +97 -0
  172. package/dist/components/scenes/crypto/HashDisplay.svelte.d.ts +4 -0
  173. package/dist/components/scenes/crypto/SignatureDisplay.svelte +161 -0
  174. package/dist/components/scenes/crypto/SignatureDisplay.svelte.d.ts +4 -0
  175. package/dist/components/scenes/crypto/index.d.ts +9 -0
  176. package/dist/components/scenes/crypto/index.js +11 -0
  177. package/dist/components/scenes/iam/ChangePasswordForm.svelte +134 -0
  178. package/dist/components/scenes/iam/ChangePasswordForm.svelte.d.ts +8 -0
  179. package/dist/components/scenes/iam/ForgotPasswordForm.svelte +147 -0
  180. package/dist/components/scenes/iam/ForgotPasswordForm.svelte.d.ts +4 -0
  181. package/dist/components/scenes/iam/LoginForm.svelte +191 -0
  182. package/dist/components/scenes/iam/LoginForm.svelte.d.ts +8 -0
  183. package/dist/components/scenes/iam/PasswordInput.svelte +203 -0
  184. package/dist/components/scenes/iam/PasswordInput.svelte.d.ts +49 -0
  185. package/dist/components/scenes/iam/PermGuard.svelte +69 -0
  186. package/dist/components/scenes/iam/PermGuard.svelte.d.ts +16 -0
  187. package/dist/components/scenes/iam/RegisterForm.svelte +269 -0
  188. package/dist/components/scenes/iam/RegisterForm.svelte.d.ts +8 -0
  189. package/dist/components/scenes/iam/ResetPasswordForm.svelte +153 -0
  190. package/dist/components/scenes/iam/ResetPasswordForm.svelte.d.ts +8 -0
  191. package/dist/components/scenes/iam/UserProfile.svelte +251 -0
  192. package/dist/components/scenes/iam/UserProfile.svelte.d.ts +4 -0
  193. package/dist/components/scenes/iam/index.d.ts +16 -0
  194. package/dist/components/scenes/iam/index.js +18 -0
  195. package/dist/components/scenes/iam/password-utils.d.ts +15 -0
  196. package/dist/components/scenes/iam/password-utils.js +19 -0
  197. package/dist/components/scenes/iam/permission-context.svelte.d.ts +90 -0
  198. package/dist/components/scenes/iam/permission-context.svelte.js +114 -0
  199. package/dist/components/scenes/index.d.ts +13 -0
  200. package/dist/components/scenes/index.js +20 -0
  201. package/dist/components/scenes/storage/AvatarUpload.svelte +218 -0
  202. package/dist/components/scenes/storage/AvatarUpload.svelte.d.ts +4 -0
  203. package/dist/components/scenes/storage/FileList.svelte +260 -0
  204. package/dist/components/scenes/storage/FileList.svelte.d.ts +4 -0
  205. package/dist/components/scenes/storage/FileUpload.svelte +400 -0
  206. package/dist/components/scenes/storage/FileUpload.svelte.d.ts +7 -0
  207. package/dist/components/scenes/storage/ImageUpload.svelte +285 -0
  208. package/dist/components/scenes/storage/ImageUpload.svelte.d.ts +4 -0
  209. package/dist/components/scenes/storage/index.d.ts +10 -0
  210. package/dist/components/scenes/storage/index.js +12 -0
  211. package/dist/components/scenes/types.d.ts +583 -0
  212. package/dist/components/scenes/types.js +7 -0
  213. package/dist/i18n.svelte.d.ts +44 -0
  214. package/dist/i18n.svelte.js +108 -0
  215. package/dist/index.d.ts +13 -0
  216. package/dist/index.js +19 -0
  217. package/dist/messages/en-US.json +242 -0
  218. package/dist/messages/zh-CN.json +242 -0
  219. package/dist/messages.d.ts +29 -0
  220. package/dist/messages.js +42 -0
  221. package/dist/styles/design-tokens.css +58 -0
  222. package/dist/styles/global.css +218 -0
  223. package/dist/styles/mobile.css +105 -0
  224. package/dist/theme-config.d.ts +92 -0
  225. package/dist/theme-config.js +122 -0
  226. package/dist/toast.svelte.d.ts +45 -0
  227. package/dist/toast.svelte.js +77 -0
  228. package/dist/types.d.ts +944 -0
  229. package/dist/types.js +7 -0
  230. package/dist/utils/platform.svelte.d.ts +54 -0
  231. package/dist/utils/platform.svelte.js +87 -0
  232. package/dist/utils.d.ts +46 -0
  233. package/dist/utils.js +100 -0
  234. package/package.json +69 -0
@@ -0,0 +1,108 @@
1
+ <!--
2
+ =============================================================================
3
+ @h-ai/ui - TagInput 组件
4
+ =============================================================================
5
+ 标签输入框组件
6
+
7
+ 使用 Svelte 5 Runes ($props, $state, $bindable)
8
+ =============================================================================
9
+ -->
10
+ <script lang='ts'>
11
+ import type { TagInputProps } from '../../types.js'
12
+ import { uiM } from '../../messages.js'
13
+ import { cn, getInputSizeClass } from '../../utils.js'
14
+ import BareInput from '../primitives/BareInput.svelte'
15
+ import Tag from '../primitives/Tag.svelte'
16
+
17
+ let {
18
+ tags = $bindable([]),
19
+ placeholder,
20
+ maxTags = 0,
21
+ allowDuplicates = false,
22
+ disabled = false,
23
+ size = 'md',
24
+ class: className = '',
25
+ onchange,
26
+ }: TagInputProps = $props()
27
+
28
+ let inputValue = $state('')
29
+ let inputElement = $state<HTMLInputElement | undefined>(undefined)
30
+
31
+ const displayPlaceholder = $derived(placeholder ?? uiM('tag_input_placeholder'))
32
+
33
+ const containerClass = $derived(
34
+ cn(
35
+ 'input flex flex-wrap items-center gap-1 min-h-[2.5rem] h-auto py-1',
36
+ getInputSizeClass(size),
37
+ disabled && 'input-disabled',
38
+ className,
39
+ ),
40
+ )
41
+
42
+ const canAddMore = $derived(maxTags === 0 || tags.length < maxTags)
43
+
44
+ function addTag(value: string) {
45
+ const trimmed = value.trim()
46
+ if (!trimmed)
47
+ return
48
+ if (!allowDuplicates && tags.includes(trimmed))
49
+ return
50
+ if (!canAddMore)
51
+ return
52
+
53
+ tags = [...tags, trimmed]
54
+ inputValue = ''
55
+ onchange?.(tags)
56
+ }
57
+
58
+ function removeTag(index: number) {
59
+ tags = tags.filter((_, i) => i !== index)
60
+ onchange?.(tags)
61
+ }
62
+
63
+ function handleKeydown(e: KeyboardEvent) {
64
+ if (e.key === 'Enter') {
65
+ e.preventDefault()
66
+ addTag(inputValue)
67
+ }
68
+ else if (e.key === 'Backspace' && !inputValue && tags.length > 0) {
69
+ removeTag(tags.length - 1)
70
+ }
71
+ }
72
+
73
+ function handleBlur() {
74
+ if (inputValue.trim()) {
75
+ addTag(inputValue)
76
+ }
77
+ }
78
+ </script>
79
+
80
+ <div
81
+ class={containerClass}
82
+ onclick={() => inputElement?.focus()}
83
+ onkeydown={e => e.key === 'Enter' && inputElement?.focus()}
84
+ role='textbox'
85
+ tabindex='-1'
86
+ >
87
+ {#each tags as tag, index (index)}
88
+ <Tag
89
+ text={tag}
90
+ size='sm'
91
+ closable={!disabled}
92
+ onclose={() => removeTag(index)}
93
+ />
94
+ {/each}
95
+
96
+ {#if canAddMore && !disabled}
97
+ <BareInput
98
+ type='text'
99
+ class='flex-1 min-w-[100px] bg-transparent border-none outline-none text-sm'
100
+ bind:value={inputValue}
101
+ bind:inputRef={inputElement}
102
+ placeholder={displayPlaceholder}
103
+ {disabled}
104
+ onkeydown={handleKeydown}
105
+ onblur={handleBlur}
106
+ />
107
+ {/if}
108
+ </div>
@@ -0,0 +1,4 @@
1
+ import type { TagInputProps } from '../../types.js';
2
+ declare const TagInput: import("svelte").Component<TagInputProps, {}, "tags">;
3
+ type TagInput = ReturnType<typeof TagInput>;
4
+ export default TagInput;
@@ -0,0 +1,167 @@
1
+ <!--
2
+ =============================================================================
3
+ @h-ai/ui - Timeline 组件
4
+ =============================================================================
5
+ 时间线组件,支持垂直/水平方向、多种样式变体
6
+
7
+ 使用 Svelte 5 Runes ($props, $derived)
8
+ 使用 DaisyUI timeline 类
9
+ =============================================================================
10
+ -->
11
+
12
+ <script lang='ts'>
13
+ import type { Snippet } from 'svelte'
14
+ import type { TimelineItem } from './timeline-types.js'
15
+ import { cn } from '../../utils.js'
16
+
17
+ interface Props {
18
+ /** 时间线项数据 */
19
+ items: TimelineItem[]
20
+ /** 方向 */
21
+ direction?: 'vertical' | 'horizontal'
22
+ /** 是否响应式(小屏垂直,大屏水平) */
23
+ responsive?: boolean
24
+ /** 内容位置 */
25
+ position?: 'start' | 'end' | 'alternate'
26
+ /** 是否紧凑模式 */
27
+ compact?: boolean
28
+ /** 是否使用盒子样式 */
29
+ boxed?: boolean
30
+ /** 图标对齐方式 */
31
+ snapIcon?: boolean
32
+ /** 自定义类名 */
33
+ class?: string
34
+ /** 自定义项渲染 */
35
+ children?: Snippet<[TimelineItem, number]>
36
+ }
37
+
38
+ const {
39
+ items,
40
+ direction = 'vertical',
41
+ responsive = false,
42
+ position = 'end',
43
+ compact = false,
44
+ boxed = false,
45
+ snapIcon = false,
46
+ class: className = '',
47
+ children,
48
+ }: Props = $props()
49
+
50
+ const timelineClass = $derived(
51
+ cn(
52
+ 'timeline',
53
+ direction === 'vertical' && 'timeline-vertical',
54
+ direction === 'horizontal' && 'timeline-horizontal',
55
+ responsive && 'timeline-vertical lg:timeline-horizontal',
56
+ compact && 'timeline-compact',
57
+ snapIcon && 'timeline-snap-icon',
58
+ className,
59
+ ),
60
+ )
61
+
62
+ function getColorClass(color?: string): string {
63
+ const colorMap: Record<string, string> = {
64
+ primary: 'bg-primary text-primary-content',
65
+ secondary: 'bg-secondary text-secondary-content',
66
+ accent: 'bg-accent text-accent-content',
67
+ success: 'bg-success text-success-content',
68
+ warning: 'bg-warning text-warning-content',
69
+ error: 'bg-error text-error-content',
70
+ info: 'bg-info text-info-content',
71
+ }
72
+ return colorMap[color || 'default'] || 'bg-base-content'
73
+ }
74
+
75
+ function getLineColorClass(item: TimelineItem, isAfter: boolean): string {
76
+ if (!item.completed && isAfter)
77
+ return ''
78
+ return item.color ? `bg-${item.color}` : 'bg-primary'
79
+ }
80
+
81
+ function shouldShowStart(index: number): boolean {
82
+ if (position === 'start')
83
+ return true
84
+ if (position === 'alternate')
85
+ return index % 2 === 0
86
+ return false
87
+ }
88
+
89
+ function shouldShowEnd(index: number): boolean {
90
+ if (position === 'end')
91
+ return true
92
+ if (position === 'alternate')
93
+ return index % 2 === 1
94
+ return false
95
+ }
96
+ </script>
97
+
98
+ <ul class={timelineClass}>
99
+ {#each items as item, index (item.id)}
100
+ <li>
101
+ <!-- 前置连线 -->
102
+ {#if index > 0}
103
+ <hr class={cn(items[index - 1].completed && getLineColorClass(items[index - 1], true))} />
104
+ {/if}
105
+
106
+ <!-- 开始位置内容 -->
107
+ {#if position !== 'end' && shouldShowStart(index)}
108
+ <div class={cn('timeline-start', boxed && 'timeline-box')}>
109
+ {#if children}
110
+ {@render children(item, index)}
111
+ {:else}
112
+ {#if item.time}
113
+ <time class='text-xs text-base-content/60'>{item.time}</time>
114
+ {/if}
115
+ <div class='font-semibold'>{item.title}</div>
116
+ {#if item.description}
117
+ <p class='text-sm text-base-content/70'>{item.description}</p>
118
+ {/if}
119
+ {/if}
120
+ </div>
121
+ {:else if item.time && position === 'end'}
122
+ <div class='timeline-start text-xs text-base-content/60'>
123
+ {item.time}
124
+ </div>
125
+ {/if}
126
+
127
+ <!-- 中间图标 -->
128
+ <div class='timeline-middle'>
129
+ {#if item.icon}
130
+ <span class={cn(
131
+ 'flex h-6 w-6 items-center justify-center rounded-full text-sm',
132
+ getColorClass(item.color),
133
+ )}>
134
+ {item.icon}
135
+ </span>
136
+ {:else}
137
+ <span class={cn(
138
+ 'flex h-4 w-4 rounded-full',
139
+ item.completed ? getColorClass(item.color) : 'bg-base-300',
140
+ )}></span>
141
+ {/if}
142
+ </div>
143
+
144
+ <!-- 结束位置内容 -->
145
+ {#if position !== 'start' && shouldShowEnd(index)}
146
+ <div class={cn('timeline-end', boxed && 'timeline-box')}>
147
+ {#if children}
148
+ {@render children(item, index)}
149
+ {:else}
150
+ {#if item.time && position === 'alternate'}
151
+ <time class='text-xs text-base-content/60'>{item.time}</time>
152
+ {/if}
153
+ <div class='font-semibold'>{item.title}</div>
154
+ {#if item.description}
155
+ <p class='text-sm text-base-content/70'>{item.description}</p>
156
+ {/if}
157
+ {/if}
158
+ </div>
159
+ {/if}
160
+
161
+ <!-- 后置连线 -->
162
+ {#if index < items.length - 1}
163
+ <hr class={cn(item.completed && getLineColorClass(item, true))} />
164
+ {/if}
165
+ </li>
166
+ {/each}
167
+ </ul>
@@ -0,0 +1,25 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { TimelineItem } from './timeline-types.js';
3
+ interface Props {
4
+ /** 时间线项数据 */
5
+ items: TimelineItem[];
6
+ /** 方向 */
7
+ direction?: 'vertical' | 'horizontal';
8
+ /** 是否响应式(小屏垂直,大屏水平) */
9
+ responsive?: boolean;
10
+ /** 内容位置 */
11
+ position?: 'start' | 'end' | 'alternate';
12
+ /** 是否紧凑模式 */
13
+ compact?: boolean;
14
+ /** 是否使用盒子样式 */
15
+ boxed?: boolean;
16
+ /** 图标对齐方式 */
17
+ snapIcon?: boolean;
18
+ /** 自定义类名 */
19
+ class?: string;
20
+ /** 自定义项渲染 */
21
+ children?: Snippet<[TimelineItem, number]>;
22
+ }
23
+ declare const Timeline: import("svelte").Component<Props, {}, "">;
24
+ type Timeline = ReturnType<typeof Timeline>;
25
+ export default Timeline;
@@ -0,0 +1,59 @@
1
+ <!--
2
+ =============================================================================
3
+ @h-ai/ui - ToastContainer 组件
4
+ =============================================================================
5
+ Toast 容器组件,显示所有 Toast 通知
6
+
7
+ 使用 Svelte 5 Runes ($derived)
8
+ =============================================================================
9
+ -->
10
+ <script lang='ts'>
11
+ import { uiM } from '../../messages.js'
12
+ import { toast } from '../../toast.svelte.js'
13
+ import { cn, getAlertVariantClass } from '../../utils.js'
14
+ import IconButton from '../primitives/IconButton.svelte'
15
+
16
+ const positionMap = {
17
+ 'top-right': 'toast-top toast-end',
18
+ 'top-left': 'toast-top toast-start',
19
+ 'bottom-right': 'toast-bottom toast-end',
20
+ 'bottom-left': 'toast-bottom toast-start',
21
+ 'top-center': 'toast-top toast-center',
22
+ 'bottom-center': 'toast-bottom toast-center',
23
+ }
24
+
25
+ // 按位置分组
26
+ const groupedItems = $derived(() => {
27
+ const groups: Record<string, typeof toast.items> = {}
28
+
29
+ for (const item of toast.items) {
30
+ const position = item.position ?? 'top-right'
31
+ if (!groups[position]) {
32
+ groups[position] = []
33
+ }
34
+ groups[position].push(item)
35
+ }
36
+
37
+ return groups
38
+ })
39
+ </script>
40
+
41
+ {#each Object.entries(groupedItems()) as [position, items]}
42
+ <div class={cn('toast z-50', positionMap[position as keyof typeof positionMap])}>
43
+ {#each items as item (item.id)}
44
+ <div class={cn('alert', getAlertVariantClass(item.variant ?? 'info'))}>
45
+ <span>{item.message}</span>
46
+ {#if item.dismissible}
47
+ <IconButton
48
+ variant='ghost'
49
+ size='sm'
50
+ onclick={() => toast.remove(item.id)}
51
+ ariaLabel={uiM('toast_dismiss')}
52
+ >
53
+ ✕
54
+ </IconButton>
55
+ {/if}
56
+ </div>
57
+ {/each}
58
+ </div>
59
+ {/each}
@@ -0,0 +1,3 @@
1
+ declare const ToastContainer: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type ToastContainer = ReturnType<typeof ToastContainer>;
3
+ export default ToastContainer;
@@ -0,0 +1,41 @@
1
+ <!--
2
+ =============================================================================
3
+ @h-ai/ui - Tooltip 组件
4
+ =============================================================================
5
+ 提示框组件
6
+
7
+ 使用 Svelte 5 Runes ($props, $derived)
8
+ =============================================================================
9
+ -->
10
+ <script lang='ts'>
11
+ import type { TooltipProps } from '../../types.js'
12
+ import { cn } from '../../utils.js'
13
+
14
+ const {
15
+ content,
16
+ position = 'top',
17
+ class: className = '',
18
+ children,
19
+ }: TooltipProps = $props()
20
+
21
+ const positionMap = {
22
+ top: 'tooltip-top',
23
+ right: 'tooltip-right',
24
+ bottom: 'tooltip-bottom',
25
+ left: 'tooltip-left',
26
+ }
27
+
28
+ const tooltipClass = $derived(
29
+ cn(
30
+ 'tooltip',
31
+ positionMap[position],
32
+ className,
33
+ ),
34
+ )
35
+ </script>
36
+
37
+ <div class={tooltipClass} data-tip={content}>
38
+ {#if children}
39
+ {@render children()}
40
+ {/if}
41
+ </div>
@@ -0,0 +1,4 @@
1
+ import type { TooltipProps } from '../../types.js';
2
+ declare const Tooltip: import("svelte").Component<TooltipProps, {}, "">;
3
+ type Tooltip = ReturnType<typeof Tooltip>;
4
+ export default Tooltip;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @h-ai/ui — Accordion 类型定义
3
+ * @module accordion-types
4
+ */
5
+ export interface AccordionItem {
6
+ /** 唯一标识 */
7
+ id: string;
8
+ /** 标题 */
9
+ title: string;
10
+ /** 内容(字符串或 Snippet) */
11
+ content?: string;
12
+ /** 是否禁用 */
13
+ disabled?: boolean;
14
+ /** 图标(可选) */
15
+ icon?: string;
16
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @h-ai/ui — Accordion 类型定义
3
+ * @module accordion-types
4
+ */
5
+ export {};
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @h-ai/ui — ActionSheet 类型定义
3
+ * @module action-sheet-types
4
+ */
5
+ export interface ActionSheetItem {
6
+ /** 操作 ID */
7
+ id: string;
8
+ /** 显示文本 */
9
+ label: string;
10
+ /** 是否为危险操作(红色文字) */
11
+ destructive?: boolean;
12
+ /** 是否禁用 */
13
+ disabled?: boolean;
14
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @h-ai/ui — ActionSheet 类型定义
3
+ * @module action-sheet-types
4
+ */
5
+ export {};
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @h-ai/ui — BottomNav 类型定义
3
+ * @module bottom-nav-types
4
+ */
5
+ import type { Snippet } from 'svelte';
6
+ export interface BottomNavItem {
7
+ /** 导航项 ID */
8
+ id: string;
9
+ /** 显示文本 */
10
+ label: string;
11
+ /** 图标 Snippet(与 iconClass 二选一) */
12
+ icon?: Snippet;
13
+ /** CSS 图标类名,如 'icon-[tabler--home]'(与 icon 二选一) */
14
+ iconClass?: string;
15
+ /** 角标数字 */
16
+ badge?: number;
17
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @h-ai/ui — BottomNav 类型定义
3
+ * @module bottom-nav-types
4
+ */
5
+ export {};
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @h-ai/ui — 组合组件 (Compounds)
3
+ *
4
+ * 由多个原子组件组合而成的复杂 UI 模式,提供更完整的交互体验。
5
+ * @module index
6
+ */
7
+ export type { AccordionItem } from './accordion-types.js';
8
+ export { default as Accordion } from './Accordion.svelte';
9
+ export type { ActionSheetItem } from './action-sheet-types.js';
10
+ export { default as ActionSheet } from './ActionSheet.svelte';
11
+ export { default as Alert } from './Alert.svelte';
12
+ export { default as AppBar } from './AppBar.svelte';
13
+ export type { BottomNavItem } from './bottom-nav-types.js';
14
+ export { default as BottomNav } from './BottomNav.svelte';
15
+ export { default as Breadcrumb } from './Breadcrumb.svelte';
16
+ export { default as Calendar } from './Calendar.svelte';
17
+ export { default as Card } from './Card.svelte';
18
+ export { default as Combobox } from './Combobox.svelte';
19
+ export { default as Confirm } from './Confirm.svelte';
20
+ export { default as DataTable } from './DataTable.svelte';
21
+ export { default as DatePicker } from './DatePicker.svelte';
22
+ export { default as Drawer } from './Drawer.svelte';
23
+ export { default as Dropdown } from './Dropdown.svelte';
24
+ export { default as Empty } from './Empty.svelte';
25
+ export { default as Form } from './Form.svelte';
26
+ export { default as FormField } from './FormField.svelte';
27
+ export { default as InfiniteScroll } from './InfiniteScroll.svelte';
28
+ export { default as Modal } from './Modal.svelte';
29
+ export { default as PageHeader } from './PageHeader.svelte';
30
+ export { default as Pagination } from './Pagination.svelte';
31
+ export { default as Popover } from './Popover.svelte';
32
+ export { default as PullRefresh } from './PullRefresh.svelte';
33
+ export { default as Result } from './Result.svelte';
34
+ export { default as SafeArea } from './SafeArea.svelte';
35
+ export { default as Skeleton } from './Skeleton.svelte';
36
+ export { default as Steps } from './Steps.svelte';
37
+ export type { SwipeCellAction } from './swipe-cell-types.js';
38
+ export { default as SwipeCell } from './SwipeCell.svelte';
39
+ export { default as Tabs } from './Tabs.svelte';
40
+ export { default as TagInput } from './TagInput.svelte';
41
+ export type { TimelineItem } from './timeline-types.js';
42
+ export { default as Timeline } from './Timeline.svelte';
43
+ export { default as ToastContainer } from './ToastContainer.svelte';
44
+ export { default as Tooltip } from './Tooltip.svelte';
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @h-ai/ui — 组合组件 (Compounds)
3
+ *
4
+ * 由多个原子组件组合而成的复杂 UI 模式,提供更完整的交互体验。
5
+ * @module index
6
+ */
7
+ export { default as Accordion } from './Accordion.svelte';
8
+ export { default as ActionSheet } from './ActionSheet.svelte';
9
+ // 反馈提示
10
+ export { default as Alert } from './Alert.svelte';
11
+ // 移动端顶部应用栏
12
+ export { default as AppBar } from './AppBar.svelte';
13
+ export { default as BottomNav } from './BottomNav.svelte';
14
+ // 导航控件
15
+ export { default as Breadcrumb } from './Breadcrumb.svelte';
16
+ // 日历(Bits UI headless + DaisyUI 样式)
17
+ export { default as Calendar } from './Calendar.svelte';
18
+ // 数据展示
19
+ export { default as Card } from './Card.svelte';
20
+ // 可搜索下拉选择(Bits UI headless + DaisyUI 样式)
21
+ export { default as Combobox } from './Combobox.svelte';
22
+ export { default as Confirm } from './Confirm.svelte';
23
+ export { default as DataTable } from './DataTable.svelte';
24
+ // 日期选择器(Bits UI headless + DaisyUI 样式)
25
+ export { default as DatePicker } from './DatePicker.svelte';
26
+ // 弹层容器
27
+ export { default as Drawer } from './Drawer.svelte';
28
+ export { default as Dropdown } from './Dropdown.svelte';
29
+ // 状态占位
30
+ export { default as Empty } from './Empty.svelte';
31
+ // 表单组合
32
+ export { default as Form } from './Form.svelte';
33
+ export { default as FormField } from './FormField.svelte';
34
+ // 无限滚动 / 上拉加载
35
+ export { default as InfiniteScroll } from './InfiniteScroll.svelte';
36
+ export { default as Modal } from './Modal.svelte';
37
+ // 页面头部
38
+ export { default as PageHeader } from './PageHeader.svelte';
39
+ export { default as Pagination } from './Pagination.svelte';
40
+ export { default as Popover } from './Popover.svelte';
41
+ // 下拉刷新
42
+ export { default as PullRefresh } from './PullRefresh.svelte';
43
+ export { default as Result } from './Result.svelte';
44
+ // 安全区域包裹
45
+ export { default as SafeArea } from './SafeArea.svelte';
46
+ export { default as Skeleton } from './Skeleton.svelte';
47
+ export { default as Steps } from './Steps.svelte';
48
+ export { default as SwipeCell } from './SwipeCell.svelte';
49
+ export { default as Tabs } from './Tabs.svelte';
50
+ export { default as TagInput } from './TagInput.svelte';
51
+ export { default as Timeline } from './Timeline.svelte';
52
+ // Toast(统一使用 store 驱动模式)
53
+ export { default as ToastContainer } from './ToastContainer.svelte';
54
+ export { default as Tooltip } from './Tooltip.svelte';
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @h-ai/ui — SwipeCell 类型定义
3
+ * @module swipe-cell-types
4
+ */
5
+ export interface SwipeCellAction {
6
+ /** 操作 ID */
7
+ id: string;
8
+ /** 显示文本 */
9
+ label: string;
10
+ /** 按钮变体 */
11
+ variant?: 'primary' | 'error' | 'warning' | 'info';
12
+ /** 按钮宽度(px) */
13
+ width?: number;
14
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @h-ai/ui — SwipeCell 类型定义
3
+ * @module swipe-cell-types
4
+ */
5
+ export {};
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @h-ai/ui — Timeline 类型定义
3
+ * @module timeline-types
4
+ */
5
+ export interface TimelineItem {
6
+ /** 唯一标识 */
7
+ id: string;
8
+ /** 标题 */
9
+ title: string;
10
+ /** 描述内容 */
11
+ description?: string;
12
+ /** 时间/日期标签 */
13
+ time?: string;
14
+ /** 图标(可选,支持 emoji 或字符) */
15
+ icon?: string;
16
+ /** 状态颜色 */
17
+ color?: 'default' | 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'error' | 'info';
18
+ /** 是否已完成 */
19
+ completed?: boolean;
20
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @h-ai/ui — Timeline 类型定义
3
+ * @module timeline-types
4
+ */
5
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @h-ai/ui — 组件导出
3
+ *
4
+ * 组件按三层划分:
5
+ * @module index
6
+ */
7
+ export * from './compounds/index.js';
8
+ export * from './primitives/index.js';
9
+ export * from './scenes/index.js';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @h-ai/ui — 组件导出
3
+ *
4
+ * 组件按三层划分:
5
+ * @module index
6
+ */
7
+ // 组合组件
8
+ export * from './compounds/index.js';
9
+ // 原子组件
10
+ export * from './primitives/index.js';
11
+ // 场景组件
12
+ export * from './scenes/index.js';