@h-ai/ui 0.1.0-alpha.29 → 0.1.0-alpha.31

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 (194) hide show
  1. package/README.md +50 -3
  2. package/dist/components/compounds/Accordion.svelte +6 -3
  3. package/dist/components/compounds/Accordion.svelte.d.ts +3 -1
  4. package/dist/components/compounds/ActionSheet.svelte +11 -8
  5. package/dist/components/compounds/ActionSheet.svelte.d.ts +3 -1
  6. package/dist/components/compounds/Alert.svelte +6 -4
  7. package/dist/components/compounds/Alert.svelte.d.ts +3 -2
  8. package/dist/components/compounds/AppBar.svelte +13 -9
  9. package/dist/components/compounds/AppBar.svelte.d.ts +3 -1
  10. package/dist/components/compounds/BottomNav.svelte +13 -10
  11. package/dist/components/compounds/BottomNav.svelte.d.ts +3 -1
  12. package/dist/components/compounds/Breadcrumb.svelte +6 -4
  13. package/dist/components/compounds/Breadcrumb.svelte.d.ts +3 -2
  14. package/dist/components/compounds/Calendar.svelte +7 -2
  15. package/dist/components/compounds/Calendar.svelte.d.ts +3 -1
  16. package/dist/components/compounds/Card.svelte +6 -4
  17. package/dist/components/compounds/Card.svelte.d.ts +3 -2
  18. package/dist/components/compounds/Combobox.svelte +6 -2
  19. package/dist/components/compounds/Combobox.svelte.d.ts +3 -1
  20. package/dist/components/compounds/Confirm.svelte +9 -7
  21. package/dist/components/compounds/Confirm.svelte.d.ts +3 -2
  22. package/dist/components/compounds/DataTable.svelte +6 -2
  23. package/dist/components/compounds/DataTable.svelte.d.ts +2 -1
  24. package/dist/components/compounds/DatePicker.svelte +7 -2
  25. package/dist/components/compounds/DatePicker.svelte.d.ts +3 -1
  26. package/dist/components/compounds/Drawer.svelte +6 -4
  27. package/dist/components/compounds/Drawer.svelte.d.ts +3 -2
  28. package/dist/components/compounds/Dropdown.svelte +6 -4
  29. package/dist/components/compounds/Dropdown.svelte.d.ts +3 -2
  30. package/dist/components/compounds/Empty.svelte +6 -4
  31. package/dist/components/compounds/Empty.svelte.d.ts +3 -2
  32. package/dist/components/compounds/Form.svelte +11 -9
  33. package/dist/components/compounds/Form.svelte.d.ts +3 -2
  34. package/dist/components/compounds/FormField.svelte +6 -4
  35. package/dist/components/compounds/FormField.svelte.d.ts +3 -2
  36. package/dist/components/compounds/InfiniteScroll.svelte +10 -7
  37. package/dist/components/compounds/InfiniteScroll.svelte.d.ts +3 -1
  38. package/dist/components/compounds/MessageBoxContainer.svelte +6 -1
  39. package/dist/components/compounds/MessageBoxContainer.svelte.d.ts +3 -17
  40. package/dist/components/compounds/MessageBoxDialog.svelte +9 -7
  41. package/dist/components/compounds/MessageBoxDialog.svelte.d.ts +2 -1
  42. package/dist/components/compounds/MessageContainer.svelte +43 -66
  43. package/dist/components/compounds/MessageContainer.svelte.d.ts +2 -1
  44. package/dist/components/compounds/Modal.svelte +29 -43
  45. package/dist/components/compounds/Modal.svelte.d.ts +3 -2
  46. package/dist/components/compounds/PageHeader.svelte +6 -2
  47. package/dist/components/compounds/PageHeader.svelte.d.ts +3 -1
  48. package/dist/components/compounds/Pagination.svelte +6 -4
  49. package/dist/components/compounds/Pagination.svelte.d.ts +3 -2
  50. package/dist/components/compounds/Popover.svelte +10 -8
  51. package/dist/components/compounds/Popover.svelte.d.ts +3 -2
  52. package/dist/components/compounds/PullRefresh.svelte +11 -8
  53. package/dist/components/compounds/PullRefresh.svelte.d.ts +3 -1
  54. package/dist/components/compounds/Result.svelte +6 -4
  55. package/dist/components/compounds/Result.svelte.d.ts +3 -2
  56. package/dist/components/compounds/SafeArea.svelte +6 -3
  57. package/dist/components/compounds/SafeArea.svelte.d.ts +3 -1
  58. package/dist/components/compounds/Skeleton.svelte +6 -4
  59. package/dist/components/compounds/Skeleton.svelte.d.ts +3 -2
  60. package/dist/components/compounds/Steps.svelte +6 -4
  61. package/dist/components/compounds/Steps.svelte.d.ts +3 -2
  62. package/dist/components/compounds/SwipeCell.svelte +6 -3
  63. package/dist/components/compounds/SwipeCell.svelte.d.ts +3 -1
  64. package/dist/components/compounds/Tabs.svelte +6 -4
  65. package/dist/components/compounds/Tabs.svelte.d.ts +3 -2
  66. package/dist/components/compounds/TagInput.svelte +11 -9
  67. package/dist/components/compounds/TagInput.svelte.d.ts +3 -2
  68. package/dist/components/compounds/Timeline.svelte +6 -3
  69. package/dist/components/compounds/Timeline.svelte.d.ts +3 -1
  70. package/dist/components/compounds/ToastContainer.svelte +6 -2
  71. package/dist/components/compounds/ToastContainer.svelte.d.ts +2 -1
  72. package/dist/components/compounds/Tooltip.svelte +6 -4
  73. package/dist/components/compounds/Tooltip.svelte.d.ts +3 -2
  74. package/dist/components/primitives/Avatar.svelte +6 -4
  75. package/dist/components/primitives/Avatar.svelte.d.ts +3 -2
  76. package/dist/components/primitives/Badge.svelte +6 -4
  77. package/dist/components/primitives/Badge.svelte.d.ts +3 -2
  78. package/dist/components/primitives/BareButton.svelte +15 -12
  79. package/dist/components/primitives/BareButton.svelte.d.ts +3 -2
  80. package/dist/components/primitives/BareInput.svelte +37 -34
  81. package/dist/components/primitives/BareInput.svelte.d.ts +3 -2
  82. package/dist/components/primitives/Button.svelte +12 -10
  83. package/dist/components/primitives/Button.svelte.d.ts +3 -2
  84. package/dist/components/primitives/Checkbox.svelte +6 -4
  85. package/dist/components/primitives/Checkbox.svelte.d.ts +3 -2
  86. package/dist/components/primitives/IconButton.svelte +6 -4
  87. package/dist/components/primitives/IconButton.svelte.d.ts +3 -2
  88. package/dist/components/primitives/Input.svelte +6 -4
  89. package/dist/components/primitives/Input.svelte.d.ts +3 -2
  90. package/dist/components/primitives/Progress.svelte +6 -4
  91. package/dist/components/primitives/Progress.svelte.d.ts +3 -2
  92. package/dist/components/primitives/Radio.svelte +6 -4
  93. package/dist/components/primitives/Radio.svelte.d.ts +2 -2
  94. package/dist/components/primitives/Range.svelte +6 -3
  95. package/dist/components/primitives/Range.svelte.d.ts +3 -1
  96. package/dist/components/primitives/Rating.svelte +6 -3
  97. package/dist/components/primitives/Rating.svelte.d.ts +3 -1
  98. package/dist/components/primitives/Select.svelte +255 -48
  99. package/dist/components/primitives/Select.svelte.d.ts +2 -2
  100. package/dist/components/primitives/Spinner.svelte +6 -4
  101. package/dist/components/primitives/Spinner.svelte.d.ts +3 -2
  102. package/dist/components/primitives/Switch.svelte +6 -4
  103. package/dist/components/primitives/Switch.svelte.d.ts +3 -2
  104. package/dist/components/primitives/Tag.svelte +6 -4
  105. package/dist/components/primitives/Tag.svelte.d.ts +3 -2
  106. package/dist/components/primitives/Textarea.svelte +34 -19
  107. package/dist/components/primitives/Textarea.svelte.d.ts +3 -2
  108. package/dist/components/primitives/ToggleCheckbox.svelte +13 -10
  109. package/dist/components/primitives/ToggleCheckbox.svelte.d.ts +3 -2
  110. package/dist/components/primitives/ToggleInput.svelte +13 -10
  111. package/dist/components/primitives/ToggleInput.svelte.d.ts +3 -2
  112. package/dist/components/primitives/ToggleRadio.svelte +13 -10
  113. package/dist/components/primitives/ToggleRadio.svelte.d.ts +3 -2
  114. package/dist/components/scenes/ai/AiDocumentDownloadMenu.svelte +8 -5
  115. package/dist/components/scenes/ai/AiDocumentDownloadMenu.svelte.d.ts +3 -1
  116. package/dist/components/scenes/ai/AiDocumentEditor.svelte +40 -10
  117. package/dist/components/scenes/ai/AiDocumentEditor.svelte.d.ts +3 -1
  118. package/dist/components/scenes/ai/MarkdownRenderer.svelte +49 -7
  119. package/dist/components/scenes/ai/MarkdownRenderer.svelte.d.ts +3 -1
  120. package/dist/components/scenes/ai/document-parse.d.ts +2 -0
  121. package/dist/components/scenes/ai/document-parse.js +16 -17
  122. package/dist/components/scenes/ai/document-types.d.ts +6 -1
  123. package/dist/components/scenes/ai/markdown-parse.d.ts +2 -0
  124. package/dist/components/scenes/ai/markdown-parse.js +17 -20
  125. package/dist/components/scenes/ai/safe-html.d.ts +16 -0
  126. package/dist/components/scenes/ai/safe-html.js +284 -0
  127. package/dist/components/scenes/ai/table/AiTableEditor.svelte +6 -3
  128. package/dist/components/scenes/ai/table/AiTableEditor.svelte.d.ts +3 -1
  129. package/dist/components/scenes/ai/table/table-types.d.ts +2 -1
  130. package/dist/components/scenes/app/FeedbackModal.svelte +5 -2
  131. package/dist/components/scenes/app/FeedbackModal.svelte.d.ts +3 -1
  132. package/dist/components/scenes/app/LanguageSwitch.svelte +6 -2
  133. package/dist/components/scenes/app/LanguageSwitch.svelte.d.ts +3 -1
  134. package/dist/components/scenes/app/SettingsLayout.svelte +6 -3
  135. package/dist/components/scenes/app/SettingsLayout.svelte.d.ts +2 -1
  136. package/dist/components/scenes/app/SettingsModal.svelte +6 -3
  137. package/dist/components/scenes/app/SettingsModal.svelte.d.ts +3 -1
  138. package/dist/components/scenes/app/ThemeColorPicker.svelte +6 -3
  139. package/dist/components/scenes/app/ThemeColorPicker.svelte.d.ts +3 -1
  140. package/dist/components/scenes/app/ThemeSelector.svelte +6 -3
  141. package/dist/components/scenes/app/ThemeSelector.svelte.d.ts +3 -1
  142. package/dist/components/scenes/app/ThemeToggle.svelte +6 -2
  143. package/dist/components/scenes/app/ThemeToggle.svelte.d.ts +3 -1
  144. package/dist/components/scenes/crud/CrudDeleteConfirm.svelte +16 -11
  145. package/dist/components/scenes/crud/CrudDeleteConfirm.svelte.d.ts +2 -1
  146. package/dist/components/scenes/crud/CrudDetailDrawer.svelte +6 -3
  147. package/dist/components/scenes/crud/CrudDetailDrawer.svelte.d.ts +2 -2
  148. package/dist/components/scenes/crud/CrudDetailPanel.svelte +6 -3
  149. package/dist/components/scenes/crud/CrudDetailPanel.svelte.d.ts +2 -2
  150. package/dist/components/scenes/crud/CrudEditPanel.svelte +6 -3
  151. package/dist/components/scenes/crud/CrudEditPanel.svelte.d.ts +2 -2
  152. package/dist/components/scenes/crud/CrudFilterBar.svelte +6 -2
  153. package/dist/components/scenes/crud/CrudFilterBar.svelte.d.ts +2 -1
  154. package/dist/components/scenes/crud/CrudPage.svelte +6 -2
  155. package/dist/components/scenes/crud/CrudPage.svelte.d.ts +2 -1
  156. package/dist/components/scenes/crud/crud-types.d.ts +2 -2
  157. package/dist/components/scenes/crypto/EncryptedInput.svelte +6 -3
  158. package/dist/components/scenes/crypto/EncryptedInput.svelte.d.ts +3 -2
  159. package/dist/components/scenes/crypto/HashDisplay.svelte +6 -3
  160. package/dist/components/scenes/crypto/HashDisplay.svelte.d.ts +3 -1
  161. package/dist/components/scenes/crypto/SignatureDisplay.svelte +6 -3
  162. package/dist/components/scenes/crypto/SignatureDisplay.svelte.d.ts +3 -1
  163. package/dist/components/scenes/error/ErrorPage.svelte +6 -3
  164. package/dist/components/scenes/error/ErrorPage.svelte.d.ts +2 -1
  165. package/dist/components/scenes/iam/AuthShell.svelte +6 -3
  166. package/dist/components/scenes/iam/AuthShell.svelte.d.ts +2 -1
  167. package/dist/components/scenes/iam/ChangePasswordForm.svelte +6 -3
  168. package/dist/components/scenes/iam/ChangePasswordForm.svelte.d.ts +3 -1
  169. package/dist/components/scenes/iam/ForgotPasswordForm.svelte +6 -3
  170. package/dist/components/scenes/iam/ForgotPasswordForm.svelte.d.ts +3 -1
  171. package/dist/components/scenes/iam/LoginForm.svelte +6 -3
  172. package/dist/components/scenes/iam/LoginForm.svelte.d.ts +3 -1
  173. package/dist/components/scenes/iam/PasswordInput.svelte +6 -4
  174. package/dist/components/scenes/iam/PasswordInput.svelte.d.ts +3 -2
  175. package/dist/components/scenes/iam/RegisterForm.svelte +6 -4
  176. package/dist/components/scenes/iam/RegisterForm.svelte.d.ts +3 -1
  177. package/dist/components/scenes/iam/ResetPasswordForm.svelte +6 -3
  178. package/dist/components/scenes/iam/ResetPasswordForm.svelte.d.ts +3 -1
  179. package/dist/components/scenes/iam/UserProfile.svelte +6 -3
  180. package/dist/components/scenes/iam/UserProfile.svelte.d.ts +3 -1
  181. package/dist/components/scenes/storage/AvatarUpload.svelte +11 -8
  182. package/dist/components/scenes/storage/AvatarUpload.svelte.d.ts +3 -1
  183. package/dist/components/scenes/storage/FileList.svelte +6 -3
  184. package/dist/components/scenes/storage/FileList.svelte.d.ts +3 -1
  185. package/dist/components/scenes/storage/FileUpload.svelte +6 -3
  186. package/dist/components/scenes/storage/FileUpload.svelte.d.ts +3 -1
  187. package/dist/components/scenes/storage/ImageUpload.svelte +12 -9
  188. package/dist/components/scenes/storage/ImageUpload.svelte.d.ts +3 -1
  189. package/dist/components/scenes/types.d.ts +20 -16
  190. package/dist/styles/global.css +5 -0
  191. package/dist/types.d.ts +48 -41
  192. package/dist/utils.d.ts +6 -1
  193. package/dist/utils.js +16 -1
  194. package/package.json +2 -2
@@ -7,9 +7,10 @@
7
7
  @prop {function} onchange - 颜色变更回调
8
8
  -->
9
9
  <script lang='ts'>
10
+ import type { DataAttributes } from '../../../types.js'
10
11
  import { uiM } from '../../../messages.js'
11
12
  import { DEFAULT_THEME_COLOR, THEME_COLOR_PRESETS } from '../../../theme-config.js'
12
- import { cn } from '../../../utils.js'
13
+ import { cn, getDataAttributes } from '../../../utils.js'
13
14
 
14
15
  const HEX_COLOR_REGEX = /^#[0-9a-f]{6}$/
15
16
  const SHORT_HEX_COLOR_REGEX = /^#[0-9a-f]{3}$/
@@ -37,8 +38,10 @@
37
38
  pickerLabel,
38
39
  customLabel,
39
40
  class: className = '',
40
- }: Props = $props()
41
+ ...restProps
42
+ }: Props & DataAttributes = $props()
41
43
 
44
+ const dataAttributes = $derived(getDataAttributes(restProps))
42
45
  let colorInputRef = $state<HTMLInputElement | null>(null)
43
46
 
44
47
  const defaultPresets = $derived(
@@ -97,7 +100,7 @@
97
100
  }
98
101
  </script>
99
102
 
100
- <div class={cn('theme-color-picker', className)}>
103
+ <div {...dataAttributes} class={cn('theme-color-picker', className)}>
101
104
  <div class='flex flex-wrap items-center gap-2'>
102
105
  {#each normalizedPresets as preset (preset.value)}
103
106
  <button
@@ -1,3 +1,4 @@
1
+ import type { DataAttributes } from '../../../types.js';
1
2
  interface ThemeColorPreset {
2
3
  value: string;
3
4
  label: string;
@@ -11,6 +12,7 @@ interface Props {
11
12
  customLabel?: string;
12
13
  class?: string;
13
14
  }
15
+ type $$ComponentProps = Props & DataAttributes;
14
16
  /**
15
17
  * ThemeColorPicker
16
18
  * 主题色选择器,提供预置主题色与原生取色盘能力。
@@ -19,6 +21,6 @@ interface Props {
19
21
  * @prop {Array<{ value: string, label: string }>} presets - 预置主题色列表
20
22
  * @prop {function} onchange - 颜色变更回调
21
23
  */
22
- declare const ThemeColorPicker: import("svelte").Component<Props, {}, "">;
24
+ declare const ThemeColorPicker: import("svelte").Component<$$ComponentProps, {}, "">;
23
25
  type ThemeColorPicker = ReturnType<typeof ThemeColorPicker>;
24
26
  export default ThemeColorPicker;
@@ -17,9 +17,10 @@
17
17
  -->
18
18
  <script lang='ts'>
19
19
  import type { ThemeInfo } from '../../../theme-config.js'
20
+ import type { DataAttributes } from '../../../types.js'
20
21
  import { uiM } from '../../../messages.js'
21
22
  import { THEME_GROUPS, THEMES } from '../../../theme-config.js'
22
- import { cn } from '../../../utils.js'
23
+ import { cn, getDataAttributes } from '../../../utils.js'
23
24
  import BareButton from '../../primitives/BareButton.svelte'
24
25
 
25
26
  interface Props {
@@ -45,8 +46,10 @@
45
46
  compact = false,
46
47
  grouped = true,
47
48
  class: className = '',
48
- }: Props = $props()
49
+ ...restProps
50
+ }: Props & DataAttributes = $props()
49
51
 
52
+ const dataAttributes = $derived(getDataAttributes(restProps))
50
53
  const displaySelectLabel = $derived(selectLabel ?? uiM('theme_selector_label'))
51
54
 
52
55
  let open = $state(false)
@@ -83,7 +86,7 @@
83
86
  })
84
87
  </script>
85
88
 
86
- <div bind:this={containerRef} class={cn('dropdown', align === 'end' ? 'dropdown-end' : '', open ? 'dropdown-open' : '', className)}>
89
+ <div {...dataAttributes} bind:this={containerRef} class={cn('dropdown', align === 'end' ? 'dropdown-end' : '', open ? 'dropdown-open' : '', className)}>
87
90
  <BareButton
88
91
  type='button'
89
92
  class='btn btn-ghost {compact ? 'btn-sm btn-square' : 'gap-2'}'
@@ -1,3 +1,4 @@
1
+ import type { DataAttributes } from '../../../types.js';
1
2
  interface Props {
2
3
  currentTheme?: string;
3
4
  /** 选择主题按钮的 aria-label */
@@ -11,6 +12,7 @@ interface Props {
11
12
  grouped?: boolean;
12
13
  class?: string;
13
14
  }
15
+ type $$ComponentProps = Props & DataAttributes;
14
16
  /**
15
17
  * ThemeSelector
16
18
  * 主题选择器组件,支持内置主题集合的选择和预览。
@@ -28,6 +30,6 @@ interface Props {
28
30
  * grouped
29
31
  * />
30
32
  */
31
- declare const ThemeSelector: import("svelte").Component<Props, {}, "">;
33
+ declare const ThemeSelector: import("svelte").Component<$$ComponentProps, {}, "">;
32
34
  type ThemeSelector = ReturnType<typeof ThemeSelector>;
33
35
  export default ThemeSelector;
@@ -14,8 +14,10 @@
14
14
  />
15
15
  -->
16
16
  <script lang='ts'>
17
+ import type { DataAttributes } from '../../../types.js'
17
18
  import { uiM } from '../../../messages.js'
18
19
  import { isDarkTheme } from '../../../theme-config.js'
20
+ import { getDataAttributes } from '../../../utils.js'
19
21
  import IconButton from '../../primitives/IconButton.svelte'
20
22
 
21
23
  interface Props {
@@ -37,8 +39,10 @@
37
39
  darkTheme = 'dark',
38
40
  labels = {},
39
41
  class: className = '',
40
- }: Props = $props()
42
+ ...restProps
43
+ }: Props & DataAttributes = $props()
41
44
 
45
+ const dataAttributes = $derived(getDataAttributes(restProps))
42
46
  // labels 优先,缺省回退到内置文案
43
47
  const isDark = $derived(isDarkTheme(currentTheme))
44
48
 
@@ -48,7 +52,7 @@
48
52
  }
49
53
  </script>
50
54
 
51
- <div class='tooltip tooltip-bottom {className}' data-tip={isDark ? (labels.switchToLight ?? uiM('theme_switch_to_light')) : (labels.switchToDark ?? uiM('theme_switch_to_dark'))}>
55
+ <div {...dataAttributes} class='tooltip tooltip-bottom {className}' data-tip={isDark ? (labels.switchToLight ?? uiM('theme_switch_to_light')) : (labels.switchToDark ?? uiM('theme_switch_to_dark'))}>
52
56
  <IconButton
53
57
  variant='ghost'
54
58
  size='sm'
@@ -1,3 +1,4 @@
1
+ import type { DataAttributes } from '../../../types.js';
1
2
  interface Props {
2
3
  currentTheme?: string;
3
4
  onchange?: (theme: string) => void;
@@ -9,6 +10,7 @@ interface Props {
9
10
  };
10
11
  class?: string;
11
12
  }
13
+ type $$ComponentProps = Props & DataAttributes;
12
14
  /**
13
15
  * ThemeToggle
14
16
  * 主题切换按钮组件,支持明/暗主题快速切换。
@@ -24,6 +26,6 @@ interface Props {
24
26
  * onchange={(theme) => themeStore.set(theme)}
25
27
  * />
26
28
  */
27
- declare const ThemeToggle: import("svelte").Component<Props, {}, "">;
29
+ declare const ThemeToggle: import("svelte").Component<$$ComponentProps, {}, "">;
28
30
  type ThemeToggle = ReturnType<typeof ThemeToggle>;
29
31
  export default ThemeToggle;
@@ -6,7 +6,9 @@
6
6
  使用 compounds 组件:Confirm
7
7
  -->
8
8
  <script lang='ts'>
9
+ import type { DataAttributes } from '../../../types.js'
9
10
  import { uiM } from '../../../messages.js'
11
+ import { getDataAttributes } from '../../../utils.js'
10
12
  import Confirm from '../../compounds/Confirm.svelte'
11
13
 
12
14
  let {
@@ -16,6 +18,7 @@
16
18
  message = '',
17
19
  onconfirm,
18
20
  oncancel,
21
+ ...restProps
19
22
  }: {
20
23
  open?: boolean
21
24
  loading?: boolean
@@ -23,17 +26,19 @@
23
26
  message?: string
24
27
  onconfirm?: () => Promise<void> | void
25
28
  oncancel?: () => void
26
- } = $props()
29
+ } & DataAttributes = $props()
30
+
31
+ const dataAttributes = $derived(getDataAttributes(restProps))
27
32
  </script>
28
33
 
29
- <Confirm
30
- bind:open
31
- title={title || uiM('crud_delete_title')}
32
- message={message || uiM('crud_delete_message')}
33
- confirmText={uiM('crud_delete')}
34
- cancelText={uiM('crud_cancel')}
35
- variant='error'
36
- {loading}
37
- {onconfirm}
38
- {oncancel}
34
+ <Confirm {...dataAttributes}
35
+ bind:open
36
+ title={title || uiM('crud_delete_title')}
37
+ message={message || uiM('crud_delete_message')}
38
+ confirmText={uiM('crud_delete')}
39
+ cancelText={uiM('crud_cancel')}
40
+ variant='error'
41
+ {loading}
42
+ {onconfirm}
43
+ {oncancel}
39
44
  />
@@ -1,3 +1,4 @@
1
+ import type { DataAttributes } from '../../../types.js';
1
2
  type $$ComponentProps = {
2
3
  open?: boolean;
3
4
  loading?: boolean;
@@ -5,7 +6,7 @@ type $$ComponentProps = {
5
6
  message?: string;
6
7
  onconfirm?: () => Promise<void> | void;
7
8
  oncancel?: () => void;
8
- };
9
+ } & DataAttributes;
9
10
  /**
10
11
  * CrudDeleteConfirm
11
12
  * CRUD 删除确认对话框
@@ -7,9 +7,10 @@
7
7
  -->
8
8
  <script lang='ts'>
9
9
  import type { Snippet } from 'svelte'
10
- import type { Size } from '../../../types.js'
10
+ import type { DataAttributes, Size } from '../../../types.js'
11
11
  import type { CrudFormVariant } from './crud-types.js'
12
12
  import { uiM } from '../../../messages.js'
13
+ import { getDataAttributes } from '../../../utils.js'
13
14
  import Drawer from '../../compounds/Drawer.svelte'
14
15
  import Modal from '../../compounds/Modal.svelte'
15
16
  import Badge from '../../primitives/Badge.svelte'
@@ -40,6 +41,7 @@
40
41
  onedit,
41
42
  onclose,
42
43
  detailExtra,
44
+ ...restProps
43
45
  }: {
44
46
  open?: boolean
45
47
  item?: Record<string, unknown> | null
@@ -55,8 +57,9 @@
55
57
  onedit?: () => void
56
58
  onclose?: () => void
57
59
  detailExtra?: Snippet<[Record<string, unknown>]>
58
- } = $props()
60
+ } & DataAttributes = $props()
59
61
 
62
+ const dataAttributes = $derived(getDataAttributes(restProps))
60
63
  function resolveText(text: string | (() => string)): string {
61
64
  return typeof text === 'function' ? text() : text
62
65
  }
@@ -121,7 +124,7 @@
121
124
 
122
125
  {#snippet detailBody()}
123
126
  {#if item}
124
- <div class='space-y-4'>
127
+ <div {...dataAttributes} class='space-y-4'>
125
128
  {#each detailFields as field (field.id)}
126
129
  {@const value = item[field.id]}
127
130
  <div>
@@ -1,5 +1,5 @@
1
1
  import type { Snippet } from 'svelte';
2
- import type { Size } from '../../../types.js';
2
+ import type { DataAttributes, Size } from '../../../types.js';
3
3
  import type { CrudFormVariant } from './crud-types.js';
4
4
  type FieldDef = {
5
5
  id: string;
@@ -31,7 +31,7 @@ type $$ComponentProps = {
31
31
  onedit?: () => void;
32
32
  onclose?: () => void;
33
33
  detailExtra?: Snippet<[Record<string, unknown>]>;
34
- };
34
+ } & DataAttributes;
35
35
  /**
36
36
  * CrudDetailDrawer
37
37
  * CRUD 详情组件(只读展示),支持抽屉(drawer)与弹窗(modal)两种展示形式
@@ -7,9 +7,10 @@
7
7
  -->
8
8
  <script lang='ts'>
9
9
  import type { Snippet } from 'svelte'
10
- import type { Size } from '../../../types.js'
10
+ import type { DataAttributes, Size } from '../../../types.js'
11
11
  import type { CrudDensity, CrudFormVariant } from './crud-types.js'
12
12
  import { uiM } from '../../../messages.js'
13
+ import { getDataAttributes } from '../../../utils.js'
13
14
  import Drawer from '../../compounds/Drawer.svelte'
14
15
  import Modal from '../../compounds/Modal.svelte'
15
16
  import Badge from '../../primitives/Badge.svelte'
@@ -41,6 +42,7 @@
41
42
  onedit,
42
43
  onclose,
43
44
  detailExtra,
45
+ ...restProps
44
46
  }: {
45
47
  open?: boolean
46
48
  item?: Record<string, unknown> | null
@@ -57,8 +59,9 @@
57
59
  onedit?: () => void
58
60
  onclose?: () => void
59
61
  detailExtra?: Snippet<[Record<string, unknown>]>
60
- } = $props()
62
+ } & DataAttributes = $props()
61
63
 
64
+ const dataAttributes = $derived(getDataAttributes(restProps))
62
65
  function resolveText(text: string | (() => string)): string {
63
66
  return typeof text === 'function' ? text() : text
64
67
  }
@@ -129,7 +132,7 @@
129
132
 
130
133
  {#snippet detailBody()}
131
134
  {#if item}
132
- <div class={contentClass}>
135
+ <div {...dataAttributes} class={contentClass}>
133
136
  {#each detailFields as field (field.id)}
134
137
  {@const value = item[field.id]}
135
138
  <div>
@@ -1,5 +1,5 @@
1
1
  import type { Snippet } from 'svelte';
2
- import type { Size } from '../../../types.js';
2
+ import type { DataAttributes, Size } from '../../../types.js';
3
3
  import type { CrudDensity, CrudFormVariant } from './crud-types.js';
4
4
  type FieldDef = {
5
5
  id: string;
@@ -32,7 +32,7 @@ type $$ComponentProps = {
32
32
  onedit?: () => void;
33
33
  onclose?: () => void;
34
34
  detailExtra?: Snippet<[Record<string, unknown>]>;
35
- };
35
+ } & DataAttributes;
36
36
  /**
37
37
  * CrudDetailPanel
38
38
  * CRUD 详情组件(只读展示),支持抽屉(drawer)与弹窗(modal)两种展示形式
@@ -7,9 +7,10 @@
7
7
  -->
8
8
  <script lang='ts'>
9
9
  import type { Snippet } from 'svelte'
10
- import type { Size } from '../../../types.js'
10
+ import type { DataAttributes, Size } from '../../../types.js'
11
11
  import type { CrudDensity, CrudFormVariant } from './crud-types.js'
12
12
  import { uiM } from '../../../messages.js'
13
+ import { getDataAttributes } from '../../../utils.js'
13
14
  import Drawer from '../../compounds/Drawer.svelte'
14
15
  import FormField from '../../compounds/FormField.svelte'
15
16
  import Modal from '../../compounds/Modal.svelte'
@@ -49,6 +50,7 @@
49
50
  onclose,
50
51
  editFormExtra,
51
52
  editingItem = null,
53
+ ...restProps
52
54
  }: {
53
55
  open?: boolean
54
56
  mode?: 'create' | 'edit'
@@ -68,8 +70,9 @@
68
70
  onclose?: () => void
69
71
  editFormExtra?: Snippet<[Record<string, unknown> | null, 'create' | 'edit']>
70
72
  editingItem?: Record<string, unknown> | null
71
- } = $props()
73
+ } & DataAttributes = $props()
72
74
 
75
+ const dataAttributes = $derived(getDataAttributes(restProps))
73
76
  function resolveText(text: string | (() => string)): string {
74
77
  return typeof text === 'function' ? text() : text
75
78
  }
@@ -135,7 +138,7 @@
135
138
 
136
139
  {#snippet formFields()}
137
140
  {#if error}
138
- <div class='p-3 bg-error/10 border border-error/20 rounded-lg text-sm text-error flex items-center gap-2'>
141
+ <div {...dataAttributes} class='p-3 bg-error/10 border border-error/20 rounded-lg text-sm text-error flex items-center gap-2'>
139
142
  <span class='icon-[tabler--alert-circle] size-4 shrink-0'></span>
140
143
  <span>{error}</span>
141
144
  </div>
@@ -1,5 +1,5 @@
1
1
  import type { Snippet } from 'svelte';
2
- import type { Size } from '../../../types.js';
2
+ import type { DataAttributes, Size } from '../../../types.js';
3
3
  import type { CrudDensity, CrudFormVariant } from './crud-types.js';
4
4
  type FieldDef = {
5
5
  id: string;
@@ -42,7 +42,7 @@ type $$ComponentProps = {
42
42
  onclose?: () => void;
43
43
  editFormExtra?: Snippet<[Record<string, unknown> | null, 'create' | 'edit']>;
44
44
  editingItem?: Record<string, unknown> | null;
45
- };
45
+ } & DataAttributes;
46
46
  /**
47
47
  * CrudEditPanel
48
48
  * CRUD 编辑/新建表单组件,支持抽屉(drawer)与弹窗(modal)两种展示形式
@@ -5,7 +5,9 @@
5
5
  使用 Svelte 5 Runes ($props, $state)
6
6
  -->
7
7
  <script lang='ts'>
8
+ import type { DataAttributes } from '../../../types.js'
8
9
  import { uiM } from '../../../messages.js'
10
+ import { getDataAttributes } from '../../../utils.js'
9
11
  import BareButton from '../../primitives/BareButton.svelte'
10
12
  import Input from '../../primitives/Input.svelte'
11
13
  import Select from '../../primitives/Select.svelte'
@@ -32,6 +34,7 @@
32
34
  onsearch,
33
35
  onfilterchange,
34
36
  onreset,
37
+ ...restProps
35
38
  }: {
36
39
  searchable?: boolean
37
40
  searchPlaceholder?: string
@@ -41,8 +44,9 @@
41
44
  onsearch?: (search: string) => void
42
45
  onfilterchange?: (filters: Record<string, unknown>) => void
43
46
  onreset?: () => void
44
- } = $props()
47
+ } & DataAttributes = $props()
45
48
 
49
+ const dataAttributes = $derived(getDataAttributes(restProps))
46
50
  let searchTimer: ReturnType<typeof setTimeout> | undefined
47
51
 
48
52
  // 是否存在已激活的搜索/过滤条件(用于显示重置按钮)
@@ -116,7 +120,7 @@
116
120
  }
117
121
  </script>
118
122
 
119
- <div class='flex flex-wrap items-center gap-2 [&_.fieldset]:m-0 [&_.fieldset]:min-w-0'>
123
+ <div {...dataAttributes} class='flex flex-wrap items-center gap-2 [&_.fieldset]:m-0 [&_.fieldset]:min-w-0'>
120
124
  {#if searchable}
121
125
  <div class='relative w-full sm:w-64 md:w-72'>
122
126
  <span class='icon-[tabler--search] pointer-events-none absolute left-3 top-1/2 z-10 size-4 -translate-y-1/2 text-base-content/35'></span>
@@ -1,3 +1,4 @@
1
+ import type { DataAttributes } from '../../../types.js';
1
2
  type FilterFieldDef = {
2
3
  id: string;
3
4
  label: string | (() => string);
@@ -25,7 +26,7 @@ type $$ComponentProps = {
25
26
  onsearch?: (search: string) => void;
26
27
  onfilterchange?: (filters: Record<string, unknown>) => void;
27
28
  onreset?: () => void;
28
- };
29
+ } & DataAttributes;
29
30
  /**
30
31
  * CrudFilterBar
31
32
  * CRUD 搜索 + 过滤栏组件
@@ -12,10 +12,12 @@
12
12
  -->
13
13
  <script lang='ts'>
14
14
  import type { Snippet } from 'svelte'
15
+ import type { DataAttributes } from '../../../types.js'
15
16
  import type { CrudDensity, CrudFormConfig, CrudPaginationConfig } from './crud-types.js'
16
17
  import type { NavAdapter } from './nav-adapter.js'
17
18
  import { SvelteURLSearchParams } from 'svelte/reactivity'
18
19
  import { uiM } from '../../../messages.js'
20
+ import { getDataAttributes } from '../../../utils.js'
19
21
  import Card from '../../compounds/Card.svelte'
20
22
  import DataTable from '../../compounds/DataTable.svelte'
21
23
  import PageHeader from '../../compounds/PageHeader.svelte'
@@ -102,6 +104,7 @@
102
104
  basePath = '',
103
105
  nav = createBrowserNavAdapter(),
104
106
  class: className = '',
107
+ ...restProps
105
108
  }: {
106
109
  crud: CrudDef
107
110
  data: { items: Record<string, unknown>[], total: number, page: number, pageSize: number, filters?: Record<string, unknown> }
@@ -127,8 +130,9 @@
127
130
  */
128
131
  nav?: NavAdapter
129
132
  class?: string
130
- } = $props()
133
+ } & DataAttributes = $props()
131
134
 
135
+ const dataAttributes = $derived(getDataAttributes(restProps))
132
136
  // ─── 状态 ───
133
137
 
134
138
  const keyField = $derived(crud.resource.keyField ?? 'id')
@@ -409,7 +413,7 @@
409
413
  )
410
414
  </script>
411
415
 
412
- <div class='{pageGapClass} {className}'>
416
+ <div {...dataAttributes} class='{pageGapClass} {className}'>
413
417
  <!-- 页面标题 -->
414
418
  <PageHeader title={resourceLabel}>
415
419
  {#snippet actions()}
@@ -1,4 +1,5 @@
1
1
  import type { Snippet } from 'svelte';
2
+ import type { DataAttributes } from '../../../types.js';
2
3
  import type { CrudDensity, CrudFormConfig, CrudPaginationConfig } from './crud-types.js';
3
4
  import type { NavAdapter } from './nav-adapter.js';
4
5
  type FieldDef = {
@@ -105,7 +106,7 @@ type $$ComponentProps = {
105
106
  */
106
107
  nav?: NavAdapter;
107
108
  class?: string;
108
- };
109
+ } & DataAttributes;
109
110
  /**
110
111
  * CrudPage
111
112
  * 通用 CRUD 页面组件
@@ -5,7 +5,7 @@
5
5
  * @module crud-types
6
6
  */
7
7
  import type { Snippet } from 'svelte';
8
- import type { Size } from '../../../types.js';
8
+ import type { DataAttributes, Size } from '../../../types.js';
9
9
  /** CrudPage 权限控制 */
10
10
  export interface CrudPermissions {
11
11
  /** 允许新建 */
@@ -54,7 +54,7 @@ export interface CrudPageData<T = Record<string, unknown>> {
54
54
  filters?: Record<string, unknown>;
55
55
  }
56
56
  /** CrudPage 组件 Props */
57
- export interface CrudPageProps<T = Record<string, unknown>> {
57
+ export interface CrudPageProps<T = Record<string, unknown>> extends DataAttributes {
58
58
  /** CRUD 操作定义(来自 kit.crud.define) */
59
59
  crud: {
60
60
  resource: {
@@ -9,9 +9,10 @@
9
9
  =============================================================================
10
10
  -->
11
11
  <script lang='ts'>
12
- import type { Size } from '../../../types.js'
12
+ import type { DataAttributes, Size } from '../../../types.js'
13
13
  import { writeTextToClipboard } from '../../../internal/browser-safety.js'
14
14
  import { uiM } from '../../../messages.js'
15
+ import { getDataAttributes } from '../../../utils.js'
15
16
  import { BareButton, IconButton, Input } from '../../primitives/index.js'
16
17
 
17
18
  interface Props {
@@ -51,8 +52,10 @@
51
52
  onencrypt,
52
53
  oninput,
53
54
  onchange,
54
- }: Props = $props()
55
+ ...restProps
56
+ }: Props & DataAttributes = $props()
55
57
 
58
+ const dataAttributes = $derived(getDataAttributes(restProps))
56
59
  let showValue = $state(false)
57
60
 
58
61
  // 模拟加密(实际应该调用 crypto 服务)
@@ -93,7 +96,7 @@
93
96
  }
94
97
  </script>
95
98
 
96
- <div class='encrypted-input space-y-2 {className}'>
99
+ <div {...dataAttributes} class='encrypted-input space-y-2 {className}'>
97
100
  <!-- 输入框 -->
98
101
  <div class='relative'>
99
102
  <Input
@@ -1,4 +1,4 @@
1
- import type { Size } from '../../../types.js';
1
+ import type { DataAttributes, Size } from '../../../types.js';
2
2
  interface Props {
3
3
  /** 原始值 */
4
4
  value?: string;
@@ -27,6 +27,7 @@ interface Props {
27
27
  currentTarget: HTMLInputElement;
28
28
  }) => void;
29
29
  }
30
- declare const EncryptedInput: import("svelte").Component<Props, {}, "value" | "encryptedValue">;
30
+ type $$ComponentProps = Props & DataAttributes;
31
+ declare const EncryptedInput: import("svelte").Component<$$ComponentProps, {}, "value" | "encryptedValue">;
31
32
  type EncryptedInput = ReturnType<typeof EncryptedInput>;
32
33
  export default EncryptedInput;
@@ -9,10 +9,11 @@
9
9
  =============================================================================
10
10
  -->
11
11
  <script lang='ts'>
12
+ import type { DataAttributes } from '../../../types.js'
12
13
  import type { HashDisplayProps } from '../types.js'
13
14
  import { writeTextToClipboard } from '../../../internal/browser-safety.js'
14
15
  import { uiM } from '../../../messages.js'
15
- import { cn } from '../../../utils.js'
16
+ import { cn, getDataAttributes } from '../../../utils.js'
16
17
  import { Badge, IconButton } from '../../primitives/index.js'
17
18
 
18
19
  const {
@@ -24,8 +25,10 @@
24
25
  truncateLength = 16,
25
26
  labels = {},
26
27
  class: className = '',
27
- }: HashDisplayProps = $props()
28
+ ...restProps
29
+ }: HashDisplayProps & DataAttributes = $props()
28
30
 
31
+ const dataAttributes = $derived(getDataAttributes(restProps))
29
32
  let copied = $state(false)
30
33
 
31
34
  const containerClass = $derived(
@@ -54,7 +57,7 @@
54
57
  }
55
58
  </script>
56
59
 
57
- <div class={containerClass}>
60
+ <div {...dataAttributes} class={containerClass}>
58
61
  {#if label}
59
62
  <div class='text-xs text-base-content/60 mb-1'>
60
63
  {label}
@@ -1,4 +1,6 @@
1
+ import type { DataAttributes } from '../../../types.js';
1
2
  import type { HashDisplayProps } from '../types.js';
2
- declare const HashDisplay: import("svelte").Component<HashDisplayProps, {}, "">;
3
+ type $$ComponentProps = HashDisplayProps & DataAttributes;
4
+ declare const HashDisplay: import("svelte").Component<$$ComponentProps, {}, "">;
3
5
  type HashDisplay = ReturnType<typeof HashDisplay>;
4
6
  export default HashDisplay;
@@ -9,10 +9,11 @@
9
9
  =============================================================================
10
10
  -->
11
11
  <script lang='ts'>
12
+ import type { DataAttributes } from '../../../types.js'
12
13
  import type { SignatureDisplayProps } from '../types.js'
13
14
  import { writeTextToClipboard } from '../../../internal/browser-safety.js'
14
15
  import { uiM } from '../../../messages.js'
15
- import { cn } from '../../../utils.js'
16
+ import { cn, getDataAttributes } from '../../../utils.js'
16
17
  import { Badge, IconButton } from '../../primitives/index.js'
17
18
 
18
19
  const {
@@ -24,8 +25,10 @@
24
25
  copyable = true,
25
26
  labels = {},
26
27
  class: className = '',
27
- }: SignatureDisplayProps = $props()
28
+ ...restProps
29
+ }: SignatureDisplayProps & DataAttributes = $props()
28
30
 
31
+ const dataAttributes = $derived(getDataAttributes(restProps))
29
32
  let copiedSig = $state(false)
30
33
  let copiedKey = $state(false)
31
34
 
@@ -67,7 +70,7 @@
67
70
  }
68
71
  </script>
69
72
 
70
- <div class={containerClass}>
73
+ <div {...dataAttributes} class={containerClass}>
71
74
  <!-- 签名状态 -->
72
75
  <div class='flex items-center gap-2'>
73
76
  <span class='text-sm font-medium'>{labels.signature ?? uiM('signature_label')} ({algorithm})</span>
@@ -1,4 +1,6 @@
1
+ import type { DataAttributes } from '../../../types.js';
1
2
  import type { SignatureDisplayProps } from '../types.js';
2
- declare const SignatureDisplay: import("svelte").Component<SignatureDisplayProps, {}, "">;
3
+ type $$ComponentProps = SignatureDisplayProps & DataAttributes;
4
+ declare const SignatureDisplay: import("svelte").Component<$$ComponentProps, {}, "">;
3
5
  type SignatureDisplay = ReturnType<typeof SignatureDisplay>;
4
6
  export default SignatureDisplay;