@h-ai/ui 0.1.0-alpha.28 → 0.1.0-alpha.30

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 (187) hide show
  1. package/README.md +12 -0
  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 +6 -2
  43. package/dist/components/compounds/MessageContainer.svelte.d.ts +2 -1
  44. package/dist/components/compounds/Modal.svelte +9 -7
  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 +6 -4
  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 +6 -4
  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 +6 -3
  117. package/dist/components/scenes/ai/AiDocumentEditor.svelte.d.ts +3 -1
  118. package/dist/components/scenes/ai/MarkdownRenderer.svelte +8 -7
  119. package/dist/components/scenes/ai/MarkdownRenderer.svelte.d.ts +3 -1
  120. package/dist/components/scenes/ai/document-types.d.ts +2 -1
  121. package/dist/components/scenes/ai/table/AiTableEditor.svelte +6 -3
  122. package/dist/components/scenes/ai/table/AiTableEditor.svelte.d.ts +3 -1
  123. package/dist/components/scenes/ai/table/table-types.d.ts +2 -1
  124. package/dist/components/scenes/app/FeedbackModal.svelte +5 -2
  125. package/dist/components/scenes/app/FeedbackModal.svelte.d.ts +3 -1
  126. package/dist/components/scenes/app/LanguageSwitch.svelte +6 -2
  127. package/dist/components/scenes/app/LanguageSwitch.svelte.d.ts +3 -1
  128. package/dist/components/scenes/app/SettingsLayout.svelte +6 -3
  129. package/dist/components/scenes/app/SettingsLayout.svelte.d.ts +2 -1
  130. package/dist/components/scenes/app/SettingsModal.svelte +6 -3
  131. package/dist/components/scenes/app/SettingsModal.svelte.d.ts +3 -1
  132. package/dist/components/scenes/app/ThemeColorPicker.svelte +6 -3
  133. package/dist/components/scenes/app/ThemeColorPicker.svelte.d.ts +3 -1
  134. package/dist/components/scenes/app/ThemeSelector.svelte +6 -3
  135. package/dist/components/scenes/app/ThemeSelector.svelte.d.ts +3 -1
  136. package/dist/components/scenes/app/ThemeToggle.svelte +6 -2
  137. package/dist/components/scenes/app/ThemeToggle.svelte.d.ts +3 -1
  138. package/dist/components/scenes/crud/CrudDeleteConfirm.svelte +16 -11
  139. package/dist/components/scenes/crud/CrudDeleteConfirm.svelte.d.ts +2 -1
  140. package/dist/components/scenes/crud/CrudDetailDrawer.svelte +6 -3
  141. package/dist/components/scenes/crud/CrudDetailDrawer.svelte.d.ts +2 -2
  142. package/dist/components/scenes/crud/CrudDetailPanel.svelte +6 -3
  143. package/dist/components/scenes/crud/CrudDetailPanel.svelte.d.ts +2 -2
  144. package/dist/components/scenes/crud/CrudEditPanel.svelte +6 -3
  145. package/dist/components/scenes/crud/CrudEditPanel.svelte.d.ts +2 -2
  146. package/dist/components/scenes/crud/CrudFilterBar.svelte +6 -2
  147. package/dist/components/scenes/crud/CrudFilterBar.svelte.d.ts +2 -1
  148. package/dist/components/scenes/crud/CrudPage.svelte +6 -2
  149. package/dist/components/scenes/crud/CrudPage.svelte.d.ts +2 -1
  150. package/dist/components/scenes/crud/crud-types.d.ts +2 -2
  151. package/dist/components/scenes/crypto/EncryptedInput.svelte +6 -3
  152. package/dist/components/scenes/crypto/EncryptedInput.svelte.d.ts +3 -2
  153. package/dist/components/scenes/crypto/HashDisplay.svelte +6 -3
  154. package/dist/components/scenes/crypto/HashDisplay.svelte.d.ts +3 -1
  155. package/dist/components/scenes/crypto/SignatureDisplay.svelte +6 -3
  156. package/dist/components/scenes/crypto/SignatureDisplay.svelte.d.ts +3 -1
  157. package/dist/components/scenes/error/ErrorPage.svelte +6 -3
  158. package/dist/components/scenes/error/ErrorPage.svelte.d.ts +2 -1
  159. package/dist/components/scenes/iam/AuthShell.svelte +6 -3
  160. package/dist/components/scenes/iam/AuthShell.svelte.d.ts +2 -1
  161. package/dist/components/scenes/iam/ChangePasswordForm.svelte +6 -3
  162. package/dist/components/scenes/iam/ChangePasswordForm.svelte.d.ts +3 -1
  163. package/dist/components/scenes/iam/ForgotPasswordForm.svelte +6 -3
  164. package/dist/components/scenes/iam/ForgotPasswordForm.svelte.d.ts +3 -1
  165. package/dist/components/scenes/iam/LoginForm.svelte +6 -3
  166. package/dist/components/scenes/iam/LoginForm.svelte.d.ts +3 -1
  167. package/dist/components/scenes/iam/PasswordInput.svelte +6 -4
  168. package/dist/components/scenes/iam/PasswordInput.svelte.d.ts +3 -2
  169. package/dist/components/scenes/iam/RegisterForm.svelte +6 -4
  170. package/dist/components/scenes/iam/RegisterForm.svelte.d.ts +3 -1
  171. package/dist/components/scenes/iam/ResetPasswordForm.svelte +6 -3
  172. package/dist/components/scenes/iam/ResetPasswordForm.svelte.d.ts +3 -1
  173. package/dist/components/scenes/iam/UserProfile.svelte +6 -3
  174. package/dist/components/scenes/iam/UserProfile.svelte.d.ts +3 -1
  175. package/dist/components/scenes/storage/AvatarUpload.svelte +11 -8
  176. package/dist/components/scenes/storage/AvatarUpload.svelte.d.ts +3 -1
  177. package/dist/components/scenes/storage/FileList.svelte +6 -3
  178. package/dist/components/scenes/storage/FileList.svelte.d.ts +3 -1
  179. package/dist/components/scenes/storage/FileUpload.svelte +6 -3
  180. package/dist/components/scenes/storage/FileUpload.svelte.d.ts +3 -1
  181. package/dist/components/scenes/storage/ImageUpload.svelte +12 -9
  182. package/dist/components/scenes/storage/ImageUpload.svelte.d.ts +3 -1
  183. package/dist/components/scenes/types.d.ts +16 -16
  184. package/dist/types.d.ts +43 -36
  185. package/dist/utils.d.ts +6 -1
  186. package/dist/utils.js +15 -0
  187. package/package.json +2 -2
@@ -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;
@@ -12,9 +12,10 @@
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 { ErrorPreset } from './error-presets.js'
16
17
  import { uiM } from '../../../messages.js'
17
- import { cn } from '../../../utils.js'
18
+ import { cn, getDataAttributes } from '../../../utils.js'
18
19
  import Button from '../../primitives/Button.svelte'
19
20
  import { ERROR_PRESETS, resolveErrorPreset } from './error-presets.js'
20
21
 
@@ -31,6 +32,7 @@
31
32
  icon,
32
33
  actions,
33
34
  class: className = '',
35
+ ...restProps
34
36
  }: {
35
37
  /** HTTP 状态码或预设标识;未命中预设时回退到最接近的预设 */
36
38
  status?: number | string | ErrorPreset
@@ -55,8 +57,9 @@
55
57
  /** 自定义操作区插槽(提供时覆盖默认按钮) */
56
58
  actions?: Snippet
57
59
  class?: string
58
- } = $props()
60
+ } & DataAttributes = $props()
59
61
 
62
+ const dataAttributes = $derived(getDataAttributes(restProps))
60
63
  const preset = $derived(ERROR_PRESETS[resolveErrorPreset(status)])
61
64
  const displayCode = $derived(code ?? preset.code)
62
65
  const displayTitle = $derived(title ?? uiM(preset.titleKey))
@@ -77,7 +80,7 @@
77
80
  }
78
81
  </script>
79
82
 
80
- <div class={cn('flex min-h-[60vh] w-full flex-col items-center justify-center px-6 py-12 text-center', className)}>
83
+ <div {...dataAttributes} class={cn('flex min-h-[60vh] w-full flex-col items-center justify-center px-6 py-12 text-center', className)}>
81
84
  <!-- 图标 -->
82
85
  <div class='mb-6 flex size-16 items-center justify-center rounded-2xl bg-base-content/5 text-base-content/40'>
83
86
  {#if icon}
@@ -1,4 +1,5 @@
1
1
  import type { Snippet } from 'svelte';
2
+ import type { DataAttributes } from '../../../types.js';
2
3
  import type { ErrorPreset } from './error-presets.js';
3
4
  type $$ComponentProps = {
4
5
  /** HTTP 状态码或预设标识;未命中预设时回退到最接近的预设 */
@@ -24,7 +25,7 @@ type $$ComponentProps = {
24
25
  /** 自定义操作区插槽(提供时覆盖默认按钮) */
25
26
  actions?: Snippet;
26
27
  class?: string;
27
- };
28
+ } & DataAttributes;
28
29
  /**
29
30
  * ErrorPage
30
31
  * 通用错误页场景组件
@@ -14,7 +14,8 @@
14
14
  -->
15
15
  <script lang='ts'>
16
16
  import type { Snippet } from 'svelte'
17
- import { cn } from '../../../utils.js'
17
+ import type { DataAttributes } from '../../../types.js'
18
+ import { cn, getDataAttributes } from '../../../utils.js'
18
19
 
19
20
  const {
20
21
  variant = 'card',
@@ -30,6 +31,7 @@
30
31
  footer,
31
32
  children,
32
33
  class: className = '',
34
+ ...restProps
33
35
  }: {
34
36
  /** 布局形态:'card'(居中卡片,默认)或 'split'(左右分栏) */
35
37
  variant?: 'card' | 'split'
@@ -56,15 +58,16 @@
56
58
  /** 表单内容 */
57
59
  children?: Snippet
58
60
  class?: string
59
- } = $props()
61
+ } & DataAttributes = $props()
60
62
 
63
+ const dataAttributes = $derived(getDataAttributes(restProps))
61
64
  const isSplit = $derived(variant === 'split')
62
65
  // split 模式下品牌区已展示 Logo,表单区仅在小屏展示,避免桌面端重复
63
66
  const logoWrapClass = $derived(isSplit ? 'mb-6 flex justify-center lg:hidden' : 'mb-6 flex justify-center')
64
67
  </script>
65
68
 
66
69
  {#snippet formPanel()}
67
- <div class='flex w-full max-w-sm flex-col'>
70
+ <div {...dataAttributes} class='flex w-full max-w-sm flex-col'>
68
71
  {#if logo}
69
72
  <div class={logoWrapClass}>{@render logo()}</div>
70
73
  {/if}
@@ -1,4 +1,5 @@
1
1
  import type { Snippet } from 'svelte';
2
+ import type { DataAttributes } from '../../../types.js';
2
3
  type $$ComponentProps = {
3
4
  /** 布局形态:'card'(居中卡片,默认)或 'split'(左右分栏) */
4
5
  variant?: 'card' | 'split';
@@ -25,7 +26,7 @@ type $$ComponentProps = {
25
26
  /** 表单内容 */
26
27
  children?: Snippet;
27
28
  class?: string;
28
- };
29
+ } & DataAttributes;
29
30
  /**
30
31
  * AuthShell
31
32
  * 认证页布局场景组件
@@ -3,9 +3,10 @@
3
3
  修改密码表单组件。
4
4
  -->
5
5
  <script lang='ts'>
6
+ import type { DataAttributes } from '../../../types.js'
6
7
  import type { ChangePasswordFormData, ChangePasswordFormProps } from '../types.js'
7
8
  import { uiM } from '../../../messages.js'
8
- import { cn } from '../../../utils.js'
9
+ import { cn, getDataAttributes } from '../../../utils.js'
9
10
  import Alert from '../../compounds/Alert.svelte'
10
11
  import Button from '../../primitives/Button.svelte'
11
12
  import { arePasswordsEqual } from './password-utils.js'
@@ -21,8 +22,10 @@
21
22
  class: className = '',
22
23
  errors = {},
23
24
  onsubmit,
24
- }: ChangePasswordFormProps = $props()
25
+ ...restProps
26
+ }: ChangePasswordFormProps & DataAttributes = $props()
25
27
 
28
+ const dataAttributes = $derived(getDataAttributes(restProps))
26
29
  let oldPassword = $state('')
27
30
  let newPassword = $state('')
28
31
  let confirmPassword = $state('')
@@ -66,7 +69,7 @@
66
69
  }
67
70
  </script>
68
71
 
69
- <form class={formClass} onsubmit={handleSubmit}>
72
+ <form {...dataAttributes} class={formClass} onsubmit={handleSubmit}>
70
73
  {#if requireOldPassword}
71
74
  <div class='space-y-1.5'>
72
75
  <label class='text-sm font-medium text-base-content/70' for='old-password'>
@@ -1,8 +1,10 @@
1
+ import type { DataAttributes } from '../../../types.js';
1
2
  import type { ChangePasswordFormProps } from '../types.js';
3
+ type $$ComponentProps = ChangePasswordFormProps & DataAttributes;
2
4
  /**
3
5
  * ChangePasswordForm
4
6
  * 修改密码表单组件。
5
7
  */
6
- declare const ChangePasswordForm: import("svelte").Component<ChangePasswordFormProps, {}, "">;
8
+ declare const ChangePasswordForm: import("svelte").Component<$$ComponentProps, {}, "">;
7
9
  type ChangePasswordForm = ReturnType<typeof ChangePasswordForm>;
8
10
  export default ChangePasswordForm;