@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,135 @@
1
+ <!--
2
+ @component DatePicker
3
+ 日期选择器组件,基于 Bits UI headless + DaisyUI 样式。
4
+ 包含日期输入框 + 弹出日历,支持键盘分段输入。
5
+
6
+ @prop {DateValue} value - 选中日期(双向绑定)
7
+ @prop {DateValue} minValue - 最小可选日期
8
+ @prop {DateValue} maxValue - 最大可选日期
9
+ @prop {string} placeholder - 输入框占位文本
10
+ @prop {boolean} disabled - 是否禁用
11
+ @prop {string} error - 错误消息
12
+ @prop {function} onchange - 日期变更回调
13
+
14
+ @example
15
+ ```svelte
16
+ <script>
17
+ import { CalendarDate } from '@internationalized/date'
18
+ let date = $state(new CalendarDate(2024, 6, 15))
19
+ </script>
20
+ <DatePicker bind:value={date} />
21
+ ```
22
+ -->
23
+ <script lang='ts'>
24
+ import type { DateValue } from '@internationalized/date'
25
+ import { DatePicker as BitsDatePicker } from 'bits-ui'
26
+
27
+ interface Props {
28
+ /** 选中日期(双向绑定) */
29
+ value?: DateValue
30
+ /** 最小可选日期 */
31
+ minValue?: DateValue
32
+ /** 最大可选日期 */
33
+ maxValue?: DateValue
34
+ /** 周起始日(0=周日,1=周一,默认 1) */
35
+ weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6
36
+ /** 自定义不可用日期判断函数 */
37
+ isDateUnavailable?: (date: DateValue) => boolean
38
+ /** 是否禁用 */
39
+ disabled?: boolean
40
+ /** 错误消息 */
41
+ error?: string
42
+ /** 自定义类名 */
43
+ class?: string
44
+ /** 日期变更回调 */
45
+ onchange?: (value: DateValue | undefined) => void
46
+ }
47
+
48
+ let {
49
+ value = $bindable(),
50
+ minValue,
51
+ maxValue,
52
+ weekStartsOn = 1,
53
+ isDateUnavailable,
54
+ disabled = false,
55
+ error,
56
+ class: className = '',
57
+ onchange,
58
+ }: Props = $props()
59
+ </script>
60
+
61
+ <div class='fieldset w-full {className}'>
62
+ <BitsDatePicker.Root
63
+ bind:value
64
+ {minValue}
65
+ {maxValue}
66
+ {weekStartsOn}
67
+ {isDateUnavailable}
68
+ {disabled}
69
+ onValueChange={v => onchange?.(v)}
70
+ >
71
+ <BitsDatePicker.Input class="input flex items-center gap-0.5 pr-2 {error ? 'input-error' : ''}">
72
+ {#snippet children({ segments })}
73
+ {#each segments as { part, value: segValue }}
74
+ <BitsDatePicker.Segment
75
+ {part}
76
+ class='rounded px-0.5 py-0.5 text-sm tabular-nums focus:bg-primary focus:text-primary-content focus:outline-none data-[type=literal]:px-0 data-[type=literal]:text-base-content/50'
77
+ >
78
+ {segValue}
79
+ </BitsDatePicker.Segment>
80
+ {/each}
81
+ <BitsDatePicker.Trigger class='ml-auto btn btn-ghost btn-xs btn-circle'>
82
+ <span class='icon-[tabler--calendar] size-4'></span>
83
+ </BitsDatePicker.Trigger>
84
+ {/snippet}
85
+ </BitsDatePicker.Input>
86
+
87
+ <BitsDatePicker.Content class='z-50 mt-1 rounded-xl border border-base-content/10 bg-base-100 p-3 shadow-lg' sideOffset={4}>
88
+ <BitsDatePicker.Calendar>
89
+ {#snippet children({ months, weekdays })}
90
+ <BitsDatePicker.Header class='flex items-center justify-between px-1 pb-3'>
91
+ <BitsDatePicker.PrevButton class='btn btn-ghost btn-sm btn-circle'>
92
+ <span class='icon-[tabler--chevron-left] size-4'></span>
93
+ </BitsDatePicker.PrevButton>
94
+ <BitsDatePicker.Heading class='text-sm font-semibold' />
95
+ <BitsDatePicker.NextButton class='btn btn-ghost btn-sm btn-circle'>
96
+ <span class='icon-[tabler--chevron-right] size-4'></span>
97
+ </BitsDatePicker.NextButton>
98
+ </BitsDatePicker.Header>
99
+
100
+ {#each months as month}
101
+ <BitsDatePicker.Grid class='w-full border-collapse'>
102
+ <BitsDatePicker.GridHead>
103
+ <BitsDatePicker.GridRow class='flex w-full'>
104
+ {#each weekdays as day}
105
+ <BitsDatePicker.HeadCell class='w-9 text-center text-xs font-medium text-base-content/50'>
106
+ {day}
107
+ </BitsDatePicker.HeadCell>
108
+ {/each}
109
+ </BitsDatePicker.GridRow>
110
+ </BitsDatePicker.GridHead>
111
+
112
+ <BitsDatePicker.GridBody>
113
+ {#each month.weeks as weekDates}
114
+ <BitsDatePicker.GridRow class='flex w-full'>
115
+ {#each weekDates as date}
116
+ <BitsDatePicker.Cell {date} month={month.value} class='p-0'>
117
+ <BitsDatePicker.Day class='inline-flex size-9 items-center justify-center rounded-lg text-sm transition-colors hover:bg-base-200 data-[selected]:bg-primary data-[selected]:text-primary-content data-[disabled]:opacity-30 data-[unavailable]:line-through data-[unavailable]:opacity-30 data-[outside-month]:text-base-content/30'>
118
+ {date.day}
119
+ </BitsDatePicker.Day>
120
+ </BitsDatePicker.Cell>
121
+ {/each}
122
+ </BitsDatePicker.GridRow>
123
+ {/each}
124
+ </BitsDatePicker.GridBody>
125
+ </BitsDatePicker.Grid>
126
+ {/each}
127
+ {/snippet}
128
+ </BitsDatePicker.Calendar>
129
+ </BitsDatePicker.Content>
130
+ </BitsDatePicker.Root>
131
+
132
+ {#if error}
133
+ <span class='fieldset-label text-error'>{error}</span>
134
+ {/if}
135
+ </div>
@@ -0,0 +1,46 @@
1
+ import type { DateValue } from '@internationalized/date';
2
+ interface Props {
3
+ /** 选中日期(双向绑定) */
4
+ value?: DateValue;
5
+ /** 最小可选日期 */
6
+ minValue?: DateValue;
7
+ /** 最大可选日期 */
8
+ maxValue?: DateValue;
9
+ /** 周起始日(0=周日,1=周一,默认 1) */
10
+ weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
11
+ /** 自定义不可用日期判断函数 */
12
+ isDateUnavailable?: (date: DateValue) => boolean;
13
+ /** 是否禁用 */
14
+ disabled?: boolean;
15
+ /** 错误消息 */
16
+ error?: string;
17
+ /** 自定义类名 */
18
+ class?: string;
19
+ /** 日期变更回调 */
20
+ onchange?: (value: DateValue | undefined) => void;
21
+ }
22
+ /**
23
+ * DatePicker
24
+ * 日期选择器组件,基于 Bits UI headless + DaisyUI 样式。
25
+ * 包含日期输入框 + 弹出日历,支持键盘分段输入。
26
+ *
27
+ * @prop {DateValue} value - 选中日期(双向绑定)
28
+ * @prop {DateValue} minValue - 最小可选日期
29
+ * @prop {DateValue} maxValue - 最大可选日期
30
+ * @prop {string} placeholder - 输入框占位文本
31
+ * @prop {boolean} disabled - 是否禁用
32
+ * @prop {string} error - 错误消息
33
+ * @prop {function} onchange - 日期变更回调
34
+ *
35
+ * @example
36
+ * ```svelte
37
+ * <script>
38
+ * import { CalendarDate } from '@internationalized/date'
39
+ * let date = $state(new CalendarDate(2024, 6, 15))
40
+ * </script>
41
+ * <DatePicker bind:value={date} />
42
+ * ```
43
+ */
44
+ declare const DatePicker: import("svelte").Component<Props, {}, "value">;
45
+ type DatePicker = ReturnType<typeof DatePicker>;
46
+ export default DatePicker;
@@ -0,0 +1,113 @@
1
+ <!--
2
+ =============================================================================
3
+ @h-ai/ui - Drawer 组件
4
+ =============================================================================
5
+ 抽屉组件
6
+
7
+ 使用 Svelte 5 Runes ($props, $derived, $effect, $bindable)
8
+ 使用 primitives 组件:IconButton
9
+ =============================================================================
10
+ -->
11
+ <script lang='ts'>
12
+ import type { DrawerProps } from '../../types.js'
13
+ import { uiM } from '../../messages.js'
14
+ import { cn, generateId } from '../../utils.js'
15
+ import IconButton from '../primitives/IconButton.svelte'
16
+ import ToggleCheckbox from '../primitives/ToggleCheckbox.svelte'
17
+
18
+ let {
19
+ open = $bindable(false),
20
+ title = '',
21
+ position = 'right',
22
+ size = 'md',
23
+ closeOnBackdrop = true,
24
+ showClose = true,
25
+ class: className = '',
26
+ onclose,
27
+ children,
28
+ }: DrawerProps = $props()
29
+
30
+ const id = generateId('drawer')
31
+
32
+ const sizeMap = {
33
+ 'xs': 'w-60',
34
+ 'sm': 'w-72',
35
+ 'md': 'w-80',
36
+ 'lg': 'w-96',
37
+ 'xl': 'w-[30rem]',
38
+ '2xl': 'w-[34rem]',
39
+ '3xl': 'w-[38rem]',
40
+ '4xl': 'w-[42rem]',
41
+ }
42
+
43
+ const drawerClass = $derived(
44
+ cn(
45
+ 'drawer',
46
+ position === 'right' && 'drawer-end',
47
+ ),
48
+ )
49
+
50
+ const sideClass = $derived(
51
+ cn(
52
+ 'drawer-side z-50',
53
+ ),
54
+ )
55
+
56
+ const contentClass = $derived(
57
+ cn(
58
+ 'menu bg-base-200 text-base-content min-h-full p-4',
59
+ sizeMap[size],
60
+ className,
61
+ ),
62
+ )
63
+
64
+ function handleClose() {
65
+ open = false
66
+ onclose?.()
67
+ }
68
+
69
+ function handleBackdropClick() {
70
+ if (closeOnBackdrop) {
71
+ handleClose()
72
+ }
73
+ }
74
+ </script>
75
+
76
+ <div class={drawerClass}>
77
+ <ToggleCheckbox {id} class='drawer-toggle' bind:checked={open} />
78
+
79
+ <div class={sideClass}>
80
+ <div
81
+ role='button'
82
+ tabindex='0'
83
+ aria-label={uiM('drawer_close')}
84
+ class='drawer-overlay'
85
+ onclick={handleBackdropClick}
86
+ onkeydown={e => e.key === 'Enter' && handleBackdropClick()}
87
+ ></div>
88
+
89
+ <div class={contentClass}>
90
+ <div class='flex items-center justify-between mb-4'>
91
+ {#if title}
92
+ <h3 class='text-lg font-bold'>{title}</h3>
93
+ {:else}
94
+ <div></div>
95
+ {/if}
96
+
97
+ {#if showClose}
98
+ <IconButton size='sm' variant='ghost' label={uiM('common_close')} onclick={handleClose}>
99
+ {#snippet children()}
100
+ <svg xmlns='http://www.w3.org/2000/svg' class='h-5 w-5' fill='none' viewBox='0 0 24 24' stroke='currentColor'>
101
+ <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M6 18L18 6M6 6l12 12' />
102
+ </svg>
103
+ {/snippet}
104
+ </IconButton>
105
+ {/if}
106
+ </div>
107
+
108
+ {#if children}
109
+ {@render children()}
110
+ {/if}
111
+ </div>
112
+ </div>
113
+ </div>
@@ -0,0 +1,4 @@
1
+ import type { DrawerProps } from '../../types.js';
2
+ declare const Drawer: import("svelte").Component<DrawerProps, {}, "open">;
3
+ type Drawer = ReturnType<typeof Drawer>;
4
+ export default Drawer;
@@ -0,0 +1,91 @@
1
+ <!--
2
+ @component Dropdown
3
+ 下拉菜单组件,支持 click/hover 触发。
4
+ -->
5
+ <script lang='ts'>
6
+ import type { DropdownProps } from '../../types.js'
7
+ import { cn } from '../../utils.js'
8
+ import BareButton from '../primitives/BareButton.svelte'
9
+
10
+ const {
11
+ items,
12
+ trigger = 'click',
13
+ position = 'bottom',
14
+ align = 'start',
15
+ class: className = '',
16
+ onselect,
17
+ children,
18
+ }: DropdownProps = $props()
19
+
20
+ let isOpen = $state(false)
21
+
22
+ const positionMap = {
23
+ top: 'dropdown-top',
24
+ right: 'dropdown-right',
25
+ bottom: 'dropdown-bottom',
26
+ left: 'dropdown-left',
27
+ }
28
+
29
+ const alignMap = {
30
+ start: 'dropdown-start',
31
+ center: '',
32
+ end: 'dropdown-end',
33
+ }
34
+
35
+ const dropdownClass = $derived(
36
+ cn(
37
+ 'dropdown',
38
+ positionMap[position],
39
+ alignMap[align],
40
+ trigger === 'hover' && 'dropdown-hover',
41
+ isOpen && 'dropdown-open',
42
+ className,
43
+ ),
44
+ )
45
+
46
+ function handleSelect(key: string) {
47
+ isOpen = false
48
+ onselect?.(key)
49
+ }
50
+
51
+ function toggleDropdown() {
52
+ if (trigger === 'click') {
53
+ isOpen = !isOpen
54
+ }
55
+ }
56
+ </script>
57
+
58
+ <div class={dropdownClass}>
59
+ <BareButton
60
+ tabindex={0}
61
+ role='button'
62
+ onclick={toggleDropdown}
63
+ onkeydown={e => e.key === 'Enter' && toggleDropdown()}
64
+ >
65
+ {#if children}
66
+ {@render children()}
67
+ {/if}
68
+ </BareButton>
69
+
70
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
71
+ <ul tabindex='0' class='dropdown-content menu bg-base-100 rounded-xl z-[1] w-52 p-1.5 shadow-lg border border-base-content/6 animate-[hai-scale-in_0.15s_cubic-bezier(0.16,1,0.3,1)]'>
72
+ {#each items as item}
73
+ {#if item.divider}
74
+ <li class='divider'></li>
75
+ {:else}
76
+ <li>
77
+ <BareButton
78
+ class={cn('w-full text-left text-[13px] rounded-lg', item.disabled && 'disabled')}
79
+ disabled={item.disabled}
80
+ onclick={() => handleSelect(item.key)}
81
+ >
82
+ {#if item.icon}
83
+ <span>{item.icon}</span>
84
+ {/if}
85
+ {item.label}
86
+ </BareButton>
87
+ </li>
88
+ {/if}
89
+ {/each}
90
+ </ul>
91
+ </div>
@@ -0,0 +1,8 @@
1
+ import type { DropdownProps } from '../../types.js';
2
+ /**
3
+ * Dropdown
4
+ * 下拉菜单组件,支持 click/hover 触发。
5
+ */
6
+ declare const Dropdown: import("svelte").Component<DropdownProps, {}, "">;
7
+ type Dropdown = ReturnType<typeof Dropdown>;
8
+ export default Dropdown;
@@ -0,0 +1,83 @@
1
+ <!--
2
+ =============================================================================
3
+ @h-ai/ui - Empty 组件
4
+ =============================================================================
5
+ 空状态展示组件
6
+
7
+ 使用 Svelte 5 Runes ($props, $derived)
8
+ =============================================================================
9
+ -->
10
+ <script lang='ts'>
11
+ import type { EmptyProps } from '../../types.js'
12
+ import { uiM } from '../../messages.js'
13
+ import { cn } from '../../utils.js'
14
+
15
+ const {
16
+ title,
17
+ description = '',
18
+ icon = 'inbox',
19
+ size = 'md',
20
+ class: className = '',
21
+ action,
22
+ children,
23
+ }: EmptyProps = $props()
24
+
25
+ const displayTitle = $derived(title ?? uiM('empty_title'))
26
+
27
+ const containerClass = $derived(
28
+ cn(
29
+ 'flex flex-col items-center justify-center py-8 text-center',
30
+ size === 'sm' && 'py-4',
31
+ size === 'lg' && 'py-12',
32
+ className,
33
+ ),
34
+ )
35
+
36
+ const iconSize = $derived(
37
+ size === 'sm' ? 'w-12 h-12' : size === 'lg' ? 'w-24 h-24' : 'w-16 h-16',
38
+ )
39
+
40
+ const titleSize = $derived(
41
+ size === 'sm' ? 'text-sm' : size === 'lg' ? 'text-xl' : 'text-base',
42
+ )
43
+ </script>
44
+
45
+ <div class={containerClass}>
46
+ <!-- 图标区域 -->
47
+ <div class='text-base-content/30 mb-4 {iconSize}'>
48
+ {#if children}
49
+ {@render children()}
50
+ {:else if icon === 'inbox'}
51
+ <svg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor' class='w-full h-full'>
52
+ <path stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4' />
53
+ </svg>
54
+ {:else if icon === 'search'}
55
+ <svg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor' class='w-full h-full'>
56
+ <path stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z' />
57
+ </svg>
58
+ {:else if icon === 'file'}
59
+ <svg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor' class='w-full h-full'>
60
+ <path stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z' />
61
+ </svg>
62
+ {:else if icon === 'error'}
63
+ <svg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='currentColor' class='w-full h-full'>
64
+ <path stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z' />
65
+ </svg>
66
+ {/if}
67
+ </div>
68
+
69
+ <!-- 标题 -->
70
+ <h3 class='font-medium text-base-content/70 {titleSize}'>{displayTitle}</h3>
71
+
72
+ <!-- 描述 -->
73
+ {#if description}
74
+ <p class='mt-1 text-sm text-base-content/50 max-w-sm'>{description}</p>
75
+ {/if}
76
+
77
+ <!-- 操作按钮插槽 -->
78
+ {#if action}
79
+ <div class='mt-4'>
80
+ {@render action()}
81
+ </div>
82
+ {/if}
83
+ </div>
@@ -0,0 +1,4 @@
1
+ import type { EmptyProps } from '../../types.js';
2
+ declare const Empty: import("svelte").Component<EmptyProps, {}, "">;
3
+ type Empty = ReturnType<typeof Empty>;
4
+ export default Empty;
@@ -0,0 +1,96 @@
1
+ <!--
2
+ =============================================================================
3
+ @h-ai/ui - Form 组件
4
+ =============================================================================
5
+ 表单容器组件,提供统一的表单提交、验证和重置功能
6
+
7
+ 使用 Svelte 5 Runes ($props, $state)
8
+ =============================================================================
9
+ -->
10
+ <script lang='ts'>
11
+ import type { FormProps } from '../../types.js'
12
+ import { cn } from '../../utils.js'
13
+
14
+ const {
15
+ class: className = '',
16
+ loading = false,
17
+ disabled = false,
18
+ onsubmit,
19
+ onreset,
20
+ onerror,
21
+ children,
22
+ }: FormProps = $props()
23
+
24
+ let formElement: HTMLFormElement
25
+
26
+ const formClass = $derived(
27
+ cn(
28
+ 'form',
29
+ loading && 'opacity-70 pointer-events-none',
30
+ className,
31
+ ),
32
+ )
33
+
34
+ async function handleSubmit(e: SubmitEvent) {
35
+ e.preventDefault()
36
+ if (loading || disabled)
37
+ return
38
+
39
+ try {
40
+ const formData = new FormData(formElement)
41
+ const data: Record<string, unknown> = {}
42
+
43
+ for (const [key, value] of formData.entries()) {
44
+ // 处理多值字段(如 checkbox 组)
45
+ if (data[key] !== undefined) {
46
+ if (Array.isArray(data[key])) {
47
+ (data[key] as unknown[]).push(value)
48
+ }
49
+ else {
50
+ data[key] = [data[key], value]
51
+ }
52
+ }
53
+ else {
54
+ data[key] = value
55
+ }
56
+ }
57
+
58
+ await onsubmit?.(data)
59
+ }
60
+ catch (error) {
61
+ onerror?.(error)
62
+ }
63
+ }
64
+
65
+ function handleReset(e: Event) {
66
+ e.preventDefault()
67
+ formElement?.reset()
68
+ onreset?.()
69
+ }
70
+
71
+ /** 重置表单 */
72
+ export function reset() {
73
+ formElement?.reset()
74
+ }
75
+
76
+ /** 获取表单数据 */
77
+ export function getData(): Record<string, unknown> {
78
+ const formData = new FormData(formElement)
79
+ const data: Record<string, unknown> = {}
80
+ for (const [key, value] of formData.entries()) {
81
+ data[key] = value
82
+ }
83
+ return data
84
+ }
85
+ </script>
86
+
87
+ <form
88
+ bind:this={formElement}
89
+ class={formClass}
90
+ onsubmit={handleSubmit}
91
+ onreset={handleReset}
92
+ >
93
+ {#if children}
94
+ {@render children()}
95
+ {/if}
96
+ </form>
@@ -0,0 +1,7 @@
1
+ import type { FormProps } from '../../types.js';
2
+ declare const Form: import("svelte").Component<FormProps, {
3
+ reset: () => void;
4
+ getData: () => Record<string, unknown>;
5
+ }, "">;
6
+ type Form = ReturnType<typeof Form>;
7
+ export default Form;
@@ -0,0 +1,56 @@
1
+ <!--
2
+ =============================================================================
3
+ @h-ai/ui - FormField 组件
4
+ =============================================================================
5
+ 表单字段包装器,统一 label/error/hint 展示
6
+
7
+ 使用 Svelte 5 Runes ($props, $derived)
8
+ =============================================================================
9
+ -->
10
+ <script lang='ts'>
11
+ import type { FormFieldProps } from '../../types.js'
12
+ import { cn } from '../../utils.js'
13
+
14
+ const {
15
+ label = '',
16
+ error = '',
17
+ hint = '',
18
+ required = false,
19
+ class: className = '',
20
+ children,
21
+ }: FormFieldProps = $props()
22
+
23
+ const fieldClass = $derived(
24
+ cn(
25
+ 'fieldset w-full',
26
+ className,
27
+ ),
28
+ )
29
+ </script>
30
+
31
+ <div class={fieldClass}>
32
+ {#if label}
33
+ <legend class='fieldset-legend'>
34
+ {label}
35
+ {#if required}
36
+ <span class='text-error'>*</span>
37
+ {/if}
38
+ </legend>
39
+ {/if}
40
+
41
+ <div class='field-content'>
42
+ {#if children}
43
+ {@render children()}
44
+ {/if}
45
+ </div>
46
+
47
+ {#if error || hint}
48
+ <div>
49
+ {#if error}
50
+ <span class='fieldset-label text-error'>{error}</span>
51
+ {:else if hint}
52
+ <span class='fieldset-label text-base-content/60'>{hint}</span>
53
+ {/if}
54
+ </div>
55
+ {/if}
56
+ </div>
@@ -0,0 +1,4 @@
1
+ import type { FormFieldProps } from '../../types.js';
2
+ declare const FormField: import("svelte").Component<FormFieldProps, {}, "">;
3
+ type FormField = ReturnType<typeof FormField>;
4
+ export default FormField;