@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,164 @@
1
+ /**
2
+ * Markdown source type, used to distinguish plain markdown, document panel, or code-only rendering.
3
+ */
4
+ export type MarkdownSourceKind = 'markdown' | 'document' | 'code';
5
+ export interface MarkdownOutlineItem {
6
+ /** Anchor id for outline navigation and heading sync. */
7
+ id: string;
8
+ /** Plain heading text without inline markdown formatting. */
9
+ text: string;
10
+ /** Heading level (1-6), mapping to h1-h6. */
11
+ level: number;
12
+ /** Numbered heading text for outline display. */
13
+ numberedTitle: string;
14
+ }
15
+ export interface MarkdownCodeBlockItem {
16
+ /** Stable code block id used by preview and DOM bindings. */
17
+ id: string;
18
+ /** Raw code text before highlighting. */
19
+ code: string;
20
+ /** Detected language label, if any. */
21
+ language?: string;
22
+ }
23
+ export interface MarkdownCodeRunRequest {
24
+ /** Code block id for mapping results back to the preview slot. */
25
+ blockId: string;
26
+ /** Raw code text. */
27
+ code: string;
28
+ /** Code language for runtime branching. */
29
+ language?: string;
30
+ /** Current document title for preview metadata or logging. */
31
+ title?: string;
32
+ /** Source kind for contextual runtime decisions. */
33
+ sourceKind: MarkdownSourceKind;
34
+ }
35
+ export interface MarkdownCodeRunResult {
36
+ /** Output kind that drives preview rendering. */
37
+ kind?: 'text' | 'markdown' | 'html';
38
+ /** Preview output content. */
39
+ content: string;
40
+ /** Preview title; default text is used when omitted. */
41
+ title?: string;
42
+ /** Optional preview description. */
43
+ description?: string;
44
+ }
45
+ export interface MarkdownRewriteAction {
46
+ /** Rewrite action id used in callbacks. */
47
+ id: string;
48
+ /** User-facing label for the rewrite action. */
49
+ label: string;
50
+ }
51
+ export interface MarkdownRewriteRequest {
52
+ /** Rewrite action id associated with the UI action. */
53
+ actionId: string;
54
+ /** The selected source text. */
55
+ selectedText: string;
56
+ /** Full document content at the time of the request. */
57
+ content: string;
58
+ /** Current document title. */
59
+ title?: string;
60
+ }
61
+ /**
62
+ * Block-level format actions for the editor toolbar.
63
+ */
64
+ export type MarkdownBlockFormatKind = 'heading' | 'bullet';
65
+ /**
66
+ * Inline format actions for the editor toolbar.
67
+ */
68
+ export type MarkdownInlineFormatKind = 'bold' | 'italic' | 'strike' | 'underline' | 'code' | 'highlight' | 'link';
69
+ export interface MarkdownToolbarDownloadAction {
70
+ /** Action id used to identify the download target. */
71
+ id: string;
72
+ /** Label shown in the download menu. */
73
+ label: string;
74
+ /** Optional short badge displayed beside the menu label. */
75
+ badgeLabel?: string;
76
+ }
77
+ export interface AiDocumentEditorProps {
78
+ /** Markdown source content. */
79
+ content?: string;
80
+ /** Document title displayed in the header. */
81
+ title?: string;
82
+ /** Source kind that affects rendering and interactions. */
83
+ sourceKind?: MarkdownSourceKind;
84
+ /** Default language when sourceKind is `code`. */
85
+ codeLanguage?: string;
86
+ /** Custom class for the outer container. */
87
+ class?: string;
88
+ /** Whether to show the copy button on code blocks. */
89
+ showCopyButton?: boolean;
90
+ /** Whether to show the run button on code blocks. */
91
+ showRunButton?: boolean;
92
+ /** Whether syntax highlighting is enabled. */
93
+ enableHighlight?: boolean;
94
+ /** Whether soft line breaks are rendered as <br>. */
95
+ breaks?: boolean;
96
+ /** Whether to show the left outline panel. */
97
+ showOutline?: boolean;
98
+ /** Whether to show the top toolbar. */
99
+ showToolbar?: boolean;
100
+ /** Initial outline collapsed state. */
101
+ initialOutlineCollapsed?: boolean;
102
+ /** Status text shown in the header or toolbar. */
103
+ statusText?: string;
104
+ /** Whether a rewrite flow is in progress. */
105
+ rewritePending?: boolean;
106
+ /** Available rewrite actions; empty hides the menu. */
107
+ rewriteActions?: MarkdownRewriteAction[];
108
+ /** Callback fired when the close action is clicked. */
109
+ onclose?: () => void;
110
+ /** Whether the close / back action should render as disabled. */
111
+ closeDisabled?: boolean;
112
+ /** Callback fired when the undo action is clicked. */
113
+ onundo?: () => void;
114
+ /** Whether the undo button should render as disabled. */
115
+ undoDisabled?: boolean;
116
+ /** Callback fired when the redo action is clicked. */
117
+ onredo?: () => void;
118
+ /** Whether the redo button should render as disabled. */
119
+ redoDisabled?: boolean;
120
+ /** Code run handler that returns preview results. */
121
+ oncoderun?: (request: MarkdownCodeRunRequest) => MarkdownCodeRunResult | void | Promise<MarkdownCodeRunResult | void>;
122
+ /** Selection rewrite handler for external processing. */
123
+ onrewrite?: (request: MarkdownRewriteRequest) => void | Promise<void>;
124
+ /** Exposes the scroll container for external synchronization. */
125
+ editorScrollHost?: HTMLDivElement | null;
126
+ /** Exposes the content container for editable reads. */
127
+ previewHost?: HTMLElement | null;
128
+ /** Eyebrow label shown above the title. */
129
+ eyebrow?: string;
130
+ /** Primary header text, shown with higher priority. */
131
+ metaText?: string;
132
+ /** Pill status text shown near the title. */
133
+ saveState?: string;
134
+ /** Whether the document body is contenteditable. */
135
+ editable?: boolean;
136
+ /** Download menu items; defaults are used when empty. */
137
+ downloadActions?: MarkdownToolbarDownloadAction[];
138
+ /** Label for the history action. */
139
+ historyActionLabel?: string;
140
+ /** Label for the view version action. */
141
+ versionActionLabel?: string;
142
+ /** Scroll callback for syncing external state. */
143
+ ondocumentscroll?: (event: Event) => void;
144
+ /** Mouseup callback to sync selection state. */
145
+ onpreviewmouseup?: () => void;
146
+ /** Input callback for contenteditable changes. */
147
+ onpreviewinput?: (event: Event) => void;
148
+ /** Blur callback for committing edits. */
149
+ onpreviewblur?: () => void;
150
+ /** Callback fired when a download action is chosen. */
151
+ ondownload?: (actionId: string) => void;
152
+ /** Callback fired when the history action is clicked. */
153
+ onhistory?: () => void;
154
+ /** Custom full-document copy handler. */
155
+ oncopydocument?: () => void | Promise<void>;
156
+ /** Block-format action handler from the selection toolbar. */
157
+ onapplyblockformat?: (kind: MarkdownBlockFormatKind) => void;
158
+ /** Inline-format action handler from the selection toolbar. */
159
+ onapplyinlineformat?: (kind: MarkdownInlineFormatKind) => void;
160
+ /** Selection copy handler for custom behavior. */
161
+ oncopyselection?: () => void | Promise<void>;
162
+ /** Selection annotation handler. */
163
+ onannotation?: () => void | Promise<void>;
164
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @h-ai/ui — AI 场景组件 (AI Scenes)
3
+ *
4
+ * 面向 AI 交互场景的组件,包含 Markdown 渲染器等。
5
+ * 内置中英文翻译,自动响应全局 locale。
6
+ * @module index
7
+ */
8
+ export { default as AiDocumentDownloadMenu } from './AiDocumentDownloadMenu.svelte';
9
+ export { default as AiDocumentEditor } from './AiDocumentEditor.svelte';
10
+ export { downloadAiDocument, resolveDocumentDownloadActions, resolveDocumentMarkdownContent, } from './document-download.js';
11
+ export type { AiDocumentDownloadFormat, AiDocumentDownloadRequest, AiDocumentResolvedDownloadAction, } from './document-download.js';
12
+ export { renderMarkdownDocument } from './document-parse.js';
13
+ export type { MarkdownDocumentParseOptions, MarkdownRenderResult, } from './document-parse.js';
14
+ export type { AiDocumentEditorProps, MarkdownBlockFormatKind, MarkdownCodeBlockItem, MarkdownCodeRunRequest, MarkdownCodeRunResult, MarkdownInlineFormatKind, MarkdownOutlineItem, MarkdownRewriteAction, MarkdownRewriteRequest, MarkdownToolbarDownloadAction, } from './document-types.js';
15
+ export { parseMarkdown } from './markdown-parse.js';
16
+ export type { MarkdownParseOptions } from './markdown-parse.js';
17
+ export { default as MarkdownRenderer } from './MarkdownRenderer.svelte';
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @h-ai/ui — AI 场景组件 (AI Scenes)
3
+ *
4
+ * 面向 AI 交互场景的组件,包含 Markdown 渲染器等。
5
+ * 内置中英文翻译,自动响应全局 locale。
6
+ * @module index
7
+ */
8
+ export { default as AiDocumentDownloadMenu } from './AiDocumentDownloadMenu.svelte';
9
+ export { default as AiDocumentEditor } from './AiDocumentEditor.svelte';
10
+ export { downloadAiDocument, resolveDocumentDownloadActions, resolveDocumentMarkdownContent, } from './document-download.js';
11
+ export { renderMarkdownDocument } from './document-parse.js';
12
+ export { parseMarkdown } from './markdown-parse.js';
13
+ export { default as MarkdownRenderer } from './MarkdownRenderer.svelte';
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @h-ai/ui — Markdown 解析工具
3
+ *
4
+ * 基于 marked + highlight.js 的 Markdown 解析引擎。
5
+ * 支持 GFM(GitHub Flavored Markdown),包含代码高亮、表格、任务列表等。
6
+ * @module markdown-parse
7
+ */
8
+ /**
9
+ * Markdown 解析配置
10
+ */
11
+ export interface MarkdownParseOptions {
12
+ /** 是否启用代码语法高亮(默认 true) */
13
+ enableHighlight?: boolean;
14
+ /** 是否显示代码块的复制按钮(默认 true) */
15
+ showCopyButton?: boolean;
16
+ /** 是否将换行符转换为 <br>(默认 true,适合 AI 输出) */
17
+ breaks?: boolean;
18
+ }
19
+ /**
20
+ * 将 Markdown 文本解析为 HTML
21
+ *
22
+ * @param content - Markdown 源文本
23
+ * @param options - 可选的解析配置
24
+ * @returns 解析后的 HTML 字符串
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * const html = parseMarkdown('# Hello\n\nWorld')
29
+ * // => '<h1>Hello</h1>\n<p>World</p>\n'
30
+ * ```
31
+ */
32
+ export declare function parseMarkdown(content: string, options?: MarkdownParseOptions): string;
@@ -0,0 +1,161 @@
1
+ /**
2
+ * @h-ai/ui — Markdown 解析工具
3
+ *
4
+ * 基于 marked + highlight.js 的 Markdown 解析引擎。
5
+ * 支持 GFM(GitHub Flavored Markdown),包含代码高亮、表格、任务列表等。
6
+ * @module markdown-parse
7
+ */
8
+ import hljs from 'highlight.js/lib/common';
9
+ import { Marked } from 'marked';
10
+ /**
11
+ * 对 HTML 特殊字符进行转义
12
+ *
13
+ * @param text - 原始文本
14
+ * @returns 转义后的安全文本
15
+ */
16
+ function escapeHtml(text) {
17
+ return text
18
+ .replace(/&/g, '&amp;')
19
+ .replace(/</g, '&lt;')
20
+ .replace(/>/g, '&gt;')
21
+ .replace(/"/g, '&quot;')
22
+ .replace(/'/g, '&#39;');
23
+ }
24
+ /**
25
+ * 创建自定义渲染器对象
26
+ *
27
+ * @param options - 解析配置
28
+ * @returns marked RendererObject
29
+ */
30
+ function createRendererObject(options) {
31
+ return {
32
+ // 代码块:语法高亮 + 语言标签 + 复制按钮
33
+ code({ text, lang }) {
34
+ const language = lang && hljs.getLanguage(lang) ? lang : '';
35
+ let highlighted;
36
+ if (options.enableHighlight && language) {
37
+ highlighted = hljs.highlight(text, { language }).value;
38
+ }
39
+ else if (options.enableHighlight) {
40
+ highlighted = hljs.highlightAuto(text).value;
41
+ }
42
+ else {
43
+ highlighted = escapeHtml(text);
44
+ }
45
+ const langLabel = language
46
+ ? `<span class="hai-md-code-lang">${escapeHtml(language)}</span>`
47
+ : '';
48
+ const copyBtn = options.showCopyButton
49
+ ? `<button type="button" class="hai-md-copy-btn" data-copy-code aria-label="Copy code"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button>`
50
+ : '';
51
+ return `<div class="hai-md-code-block">`
52
+ + `<div class="hai-md-code-header">${langLabel}${copyBtn}</div>`
53
+ + `<pre><code class="hljs${language ? ` language-${escapeHtml(language)}` : ''}">${highlighted}</code></pre>`
54
+ + `</div>`;
55
+ },
56
+ // 原始 HTML 块:转义以防止 XSS
57
+ html(token) {
58
+ return escapeHtml('text' in token ? token.text : '');
59
+ },
60
+ // 链接:外部链接自动添加 target="_blank",阻止危险协议
61
+ link({ href, title, tokens }) {
62
+ const text = this.parser.parseInline(tokens);
63
+ // 安全检查:仅允许安全协议
64
+ const safeHref = href && /^(?:https?:\/\/|\/|#|mailto:)/i.test(href) ? href : '';
65
+ const isExternal = safeHref && (safeHref.startsWith('http://') || safeHref.startsWith('https://'));
66
+ const attrs = [
67
+ `href="${escapeHtml(safeHref)}"`,
68
+ title ? `title="${escapeHtml(title)}"` : '',
69
+ isExternal ? 'target="_blank" rel="noopener noreferrer"' : '',
70
+ ].filter(Boolean).join(' ');
71
+ return `<a ${attrs}>${text}</a>`;
72
+ },
73
+ // 图片:添加 loading="lazy",验证 src 协议
74
+ image({ href, title, text }) {
75
+ // 安全检查:仅允许安全协议
76
+ const safeSrc = href && /^(?:https?:\/\/|\/|data:image\/)/i.test(href) ? href : '';
77
+ const attrs = [
78
+ `src="${escapeHtml(safeSrc)}"`,
79
+ `alt="${escapeHtml(text || '')}"`,
80
+ title ? `title="${escapeHtml(title)}"` : '',
81
+ 'loading="lazy"',
82
+ 'class="hai-md-img"',
83
+ ].filter(Boolean).join(' ');
84
+ return `<img ${attrs} />`;
85
+ },
86
+ // 表格:添加响应式包裹容器
87
+ table(token) {
88
+ let headerHtml = '';
89
+ for (const cell of token.header) {
90
+ const align = cell.align ? ` style="text-align:${cell.align}"` : '';
91
+ headerHtml += `<th${align}>${this.parser.parseInline(cell.tokens)}</th>`;
92
+ }
93
+ let bodyHtml = '';
94
+ for (const row of token.rows) {
95
+ let rowHtml = '';
96
+ for (const cell of row) {
97
+ const align = cell.align ? ` style="text-align:${cell.align}"` : '';
98
+ rowHtml += `<td${align}>${this.parser.parseInline(cell.tokens)}</td>`;
99
+ }
100
+ bodyHtml += `<tr>${rowHtml}</tr>`;
101
+ }
102
+ return `<div class="hai-md-table-wrap">`
103
+ + `<table><thead><tr>${headerHtml}</tr></thead><tbody>${bodyHtml}</tbody></table>`
104
+ + `</div>`;
105
+ },
106
+ };
107
+ }
108
+ /**
109
+ * 创建 Markdown 解析器实例
110
+ *
111
+ * @param options - 解析配置
112
+ * @returns 配置好的 Marked 实例
113
+ */
114
+ function createMarkedInstance(options) {
115
+ return new Marked({
116
+ renderer: createRendererObject(options),
117
+ gfm: true,
118
+ breaks: options.breaks,
119
+ });
120
+ }
121
+ /** 默认配置 */
122
+ const DEFAULT_OPTIONS = {
123
+ enableHighlight: true,
124
+ showCopyButton: true,
125
+ breaks: true,
126
+ };
127
+ /** 缓存 Marked 实例,避免重复创建 */
128
+ let cachedInstance = null;
129
+ let cachedOptionsKey = '';
130
+ /**
131
+ * 获取配置签名,用于实例缓存比较
132
+ */
133
+ function getOptionsKey(options) {
134
+ return `${options.enableHighlight}-${options.showCopyButton}-${options.breaks}`;
135
+ }
136
+ /**
137
+ * 将 Markdown 文本解析为 HTML
138
+ *
139
+ * @param content - Markdown 源文本
140
+ * @param options - 可选的解析配置
141
+ * @returns 解析后的 HTML 字符串
142
+ *
143
+ * @example
144
+ * ```ts
145
+ * const html = parseMarkdown('# Hello\n\nWorld')
146
+ * // => '<h1>Hello</h1>\n<p>World</p>\n'
147
+ * ```
148
+ */
149
+ export function parseMarkdown(content, options) {
150
+ if (!content)
151
+ return '';
152
+ const mergedOptions = { ...DEFAULT_OPTIONS, ...options };
153
+ const key = getOptionsKey(mergedOptions);
154
+ if (!cachedInstance || cachedOptionsKey !== key) {
155
+ cachedInstance = createMarkedInstance(mergedOptions);
156
+ cachedOptionsKey = key;
157
+ }
158
+ const result = cachedInstance.parse(content);
159
+ // marked.parse 可能返回 string | Promise<string>,此处同步调用
160
+ return typeof result === 'string' ? result : '';
161
+ }
@@ -0,0 +1,160 @@
1
+ <!--
2
+ @component FeedbackModal
3
+ 用户反馈模态框,支持 Bug 报告、功能建议等多种反馈类型。
4
+
5
+ @prop {boolean} open - 是否显示模态框(双向绑定)
6
+ @prop {function} onsubmit - 提交反馈的回调
7
+
8
+ @example
9
+ <FeedbackModal
10
+ bind:open={showFeedback}
11
+ onsubmit={async (data) => { await submitFeedback(data) }}
12
+ />
13
+ -->
14
+ <script lang='ts'>
15
+ import Modal from '../../compounds/Modal.svelte'
16
+ import Button from '../../primitives/Button.svelte'
17
+ import Input from '../../primitives/Input.svelte'
18
+ import Select from '../../primitives/Select.svelte'
19
+ import Textarea from '../../primitives/Textarea.svelte'
20
+
21
+ type FeedbackType = 'bug' | 'feature' | 'question' | 'other'
22
+
23
+ interface FeedbackData {
24
+ type: FeedbackType
25
+ description: string
26
+ contact?: string
27
+ }
28
+
29
+ /** i18n 文案配置 */
30
+ interface FeedbackLabels {
31
+ title?: string
32
+ description?: string
33
+ typeLabel?: string
34
+ contentLabel?: string
35
+ contentPlaceholder?: string
36
+ contactLabel?: string
37
+ contactPlaceholder?: string
38
+ cancel?: string
39
+ submit?: string
40
+ errorEmpty?: string
41
+ errorSubmit?: string
42
+ types?: {
43
+ bug?: string
44
+ feature?: string
45
+ question?: string
46
+ other?: string
47
+ }
48
+ }
49
+
50
+ import { uiM } from '../../../messages.js'
51
+
52
+ interface Props {
53
+ open?: boolean
54
+ labels?: FeedbackLabels
55
+ onsubmit?: (data: FeedbackData) => Promise<void>
56
+ }
57
+
58
+ let { open = $bindable(false), labels = {}, onsubmit }: Props = $props()
59
+
60
+ // 文案优先使用传入的 labels,缺省回退到内置消息 uiM(...)
61
+
62
+ let feedbackType = $state<FeedbackType>('bug')
63
+ let description = $state('')
64
+ let contact = $state('')
65
+ let loading = $state(false)
66
+ let error = $state('')
67
+
68
+ const typeOptions = $derived([
69
+ { value: 'bug', label: labels.types?.bug ?? uiM('feedback_type_bug') },
70
+ { value: 'feature', label: labels.types?.feature ?? uiM('feedback_type_feature') },
71
+ { value: 'question', label: labels.types?.question ?? uiM('feedback_type_question') },
72
+ { value: 'other', label: labels.types?.other ?? uiM('feedback_type_other') },
73
+ ])
74
+
75
+ async function handleSubmit() {
76
+ if (!description.trim()) {
77
+ error = labels.errorEmpty ?? uiM('feedback_error_empty')
78
+ return
79
+ }
80
+
81
+ loading = true
82
+ error = ''
83
+
84
+ try {
85
+ await onsubmit?.({
86
+ type: feedbackType,
87
+ description: description.trim(),
88
+ contact: contact.trim() || undefined,
89
+ })
90
+ open = false
91
+ resetForm()
92
+ }
93
+ catch (e) {
94
+ error = e instanceof Error ? e.message : (labels.errorSubmit ?? uiM('feedback_error_submit'))
95
+ }
96
+ finally {
97
+ loading = false
98
+ }
99
+ }
100
+
101
+ function resetForm() {
102
+ feedbackType = 'bug'
103
+ description = ''
104
+ contact = ''
105
+ error = ''
106
+ }
107
+ </script>
108
+
109
+ <Modal bind:open title={labels.title ?? uiM('feedback_title')}>
110
+ <p class='text-base-content/70 mb-4'>{labels.description ?? uiM('feedback_description')}</p>
111
+
112
+ {#if error}
113
+ <div class='alert alert-error mb-4'>
114
+ <span class='icon-[tabler--alert-circle] size-5'></span>
115
+ <span>{error}</span>
116
+ </div>
117
+ {/if}
118
+
119
+ <div class='space-y-4'>
120
+ <div class='fieldset'>
121
+ <legend class='fieldset-legend'>{labels.typeLabel ?? uiM('feedback_type_label')}</legend>
122
+ <Select
123
+ id='feedback-type'
124
+ options={typeOptions}
125
+ bind:value={feedbackType}
126
+ />
127
+ </div>
128
+
129
+ <div class='fieldset'>
130
+ <legend class='fieldset-legend'>{labels.contentLabel ?? uiM('feedback_content_label')} <span class='text-error'>*</span></legend>
131
+ <Textarea
132
+ id='feedback-desc'
133
+ class='h-32'
134
+ placeholder={labels.contentPlaceholder ?? uiM('feedback_content_placeholder')}
135
+ bind:value={description}
136
+ />
137
+ </div>
138
+
139
+ <div class='fieldset'>
140
+ <legend class='fieldset-legend'>{labels.contactLabel ?? uiM('feedback_contact_label')}</legend>
141
+ <Input
142
+ id='feedback-contact'
143
+ type='text'
144
+ class='w-full'
145
+ placeholder={labels.contactPlaceholder ?? uiM('feedback_contact_placeholder')}
146
+ bind:value={contact}
147
+ autocomplete='email'
148
+ />
149
+ </div>
150
+ </div>
151
+
152
+ {#snippet footer()}
153
+ <Button variant='ghost' onclick={() => open = false}>
154
+ {labels.cancel ?? uiM('feedback_cancel')}
155
+ </Button>
156
+ <Button variant='primary' {loading} onclick={handleSubmit}>
157
+ {labels.submit ?? uiM('feedback_submit')}
158
+ </Button>
159
+ {/snippet}
160
+ </Modal>
@@ -0,0 +1,47 @@
1
+ type FeedbackType = 'bug' | 'feature' | 'question' | 'other';
2
+ interface FeedbackData {
3
+ type: FeedbackType;
4
+ description: string;
5
+ contact?: string;
6
+ }
7
+ /** i18n 文案配置 */
8
+ interface FeedbackLabels {
9
+ title?: string;
10
+ description?: string;
11
+ typeLabel?: string;
12
+ contentLabel?: string;
13
+ contentPlaceholder?: string;
14
+ contactLabel?: string;
15
+ contactPlaceholder?: string;
16
+ cancel?: string;
17
+ submit?: string;
18
+ errorEmpty?: string;
19
+ errorSubmit?: string;
20
+ types?: {
21
+ bug?: string;
22
+ feature?: string;
23
+ question?: string;
24
+ other?: string;
25
+ };
26
+ }
27
+ interface Props {
28
+ open?: boolean;
29
+ labels?: FeedbackLabels;
30
+ onsubmit?: (data: FeedbackData) => Promise<void>;
31
+ }
32
+ /**
33
+ * FeedbackModal
34
+ * 用户反馈模态框,支持 Bug 报告、功能建议等多种反馈类型。
35
+ *
36
+ * @prop {boolean} open - 是否显示模态框(双向绑定)
37
+ * @prop {function} onsubmit - 提交反馈的回调
38
+ *
39
+ * @example
40
+ * <FeedbackModal
41
+ * bind:open={showFeedback}
42
+ * onsubmit={async (data) => { await submitFeedback(data) }}
43
+ * />
44
+ */
45
+ declare const FeedbackModal: import("svelte").Component<Props, {}, "open">;
46
+ type FeedbackModal = ReturnType<typeof FeedbackModal>;
47
+ export default FeedbackModal;