@h-ai/ui 0.1.0-alpha.22 → 0.1.0-alpha.24

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 (28) hide show
  1. package/README.md +39 -5
  2. package/auto-import.d.ts +2 -2
  3. package/auto-import.js +2 -2
  4. package/dist/components/compounds/Card.svelte +1 -1
  5. package/dist/components/compounds/DataTable.svelte +32 -7
  6. package/dist/components/compounds/DataTable.svelte.d.ts +2 -0
  7. package/dist/components/compounds/Drawer.svelte +7 -2
  8. package/dist/components/compounds/Modal.svelte +2 -0
  9. package/dist/components/compounds/Pagination.svelte +57 -16
  10. package/dist/components/primitives/Input.svelte +23 -1
  11. package/dist/components/primitives/Select.svelte +2 -2
  12. package/dist/components/scenes/crud/CrudDetailDrawer.svelte +59 -18
  13. package/dist/components/scenes/crud/CrudDetailDrawer.svelte.d.ts +8 -2
  14. package/dist/components/scenes/crud/CrudDetailPanel.svelte +204 -0
  15. package/dist/components/scenes/crud/CrudDetailPanel.svelte.d.ts +45 -0
  16. package/dist/components/scenes/crud/CrudEditPanel.svelte +281 -0
  17. package/dist/components/scenes/crud/{CrudEditDrawer.svelte.d.ts → CrudEditPanel.svelte.d.ts} +13 -6
  18. package/dist/components/scenes/crud/CrudFilterBar.svelte +22 -18
  19. package/dist/components/scenes/crud/CrudPage.svelte +105 -60
  20. package/dist/components/scenes/crud/CrudPage.svelte.d.ts +6 -4
  21. package/dist/components/scenes/crud/crud-types.d.ts +36 -2
  22. package/dist/components/scenes/crud/index.d.ts +3 -3
  23. package/dist/components/scenes/crud/index.js +3 -3
  24. package/dist/messages/en-US.json +3 -2
  25. package/dist/messages/zh-CN.json +3 -2
  26. package/dist/types.d.ts +10 -0
  27. package/package.json +2 -2
  28. package/dist/components/scenes/crud/CrudEditDrawer.svelte +0 -225
@@ -2,17 +2,17 @@
2
2
  @component CrudPage
3
3
  通用 CRUD 页面组件
4
4
 
5
- 基于声明式资源定义,自动生成列表 + 搜索过滤 + 分页 + 详情抽屉 + 编辑/新建抽屉 + 删除确认。
5
+ 基于声明式资源定义,自动生成列表 + 搜索过滤 + 分页 + 详情查看 + 编辑/新建面板 + 删除确认。
6
6
 
7
7
  使用 Svelte 5 Runes ($props, $state, $derived, $effect)
8
- 使用 compounds 组件:Card, DataTable, PageHeader, Pagination, Drawer
8
+ 使用 compounds 组件:Card, DataTable, PageHeader, Pagination, Drawer, Modal
9
9
 
10
10
  @example
11
11
  <CrudPage crud={userCrud} data={data} permissions={{ create: true, update: true, delete: true }} />
12
12
  -->
13
13
  <script lang='ts'>
14
14
  import type { Snippet } from 'svelte'
15
- import type { Size } from '../../../types.js'
15
+ import type { CrudDensity, CrudFormConfig, CrudPaginationConfig } from './crud-types.js'
16
16
  import type { NavAdapter } from './nav-adapter.js'
17
17
  import { SvelteURLSearchParams } from 'svelte/reactivity'
18
18
  import { uiM } from '../../../messages.js'
@@ -23,8 +23,8 @@
23
23
  import Button from '../../primitives/Button.svelte'
24
24
  import IconButton from '../../primitives/IconButton.svelte'
25
25
  import CrudDeleteConfirm from './CrudDeleteConfirm.svelte'
26
- import CrudDetailDrawer from './CrudDetailDrawer.svelte'
27
- import CrudEditDrawer from './CrudEditDrawer.svelte'
26
+ import CrudDetailPanel from './CrudDetailPanel.svelte'
27
+ import CrudEditPanel from './CrudEditPanel.svelte'
28
28
  import CrudFilterBar from './CrudFilterBar.svelte'
29
29
  import { createBrowserNavAdapter } from './nav-adapter.js'
30
30
 
@@ -87,7 +87,9 @@
87
87
  crud,
88
88
  data,
89
89
  permissions = {},
90
- drawerSize = '2xl' as Size,
90
+ form = {},
91
+ pagination = {},
92
+ density = 'normal',
91
93
  rowClickDetail = true,
92
94
  listItemActions,
93
95
  editFormExtra,
@@ -104,7 +106,9 @@
104
106
  crud: CrudDef
105
107
  data: { items: Record<string, unknown>[], total: number, page: number, pageSize: number, filters?: Record<string, unknown> }
106
108
  permissions?: { create?: boolean, update?: boolean, delete?: boolean }
107
- drawerSize?: Size
109
+ form?: CrudFormConfig
110
+ pagination?: CrudPaginationConfig
111
+ density?: CrudDensity
108
112
  rowClickDetail?: boolean
109
113
  listItemActions?: Snippet<[Record<string, unknown>]>
110
114
  editFormExtra?: Snippet<[Record<string, unknown> | null, 'create' | 'edit']>
@@ -133,9 +137,31 @@
133
137
  const canUpdate = $derived(permissions.update !== false && Boolean(crud.api.update))
134
138
  const canDelete = $derived(permissions.delete !== false && Boolean(crud.api.remove))
135
139
  const searchable = $derived(crud.resource.searchable !== false)
140
+ const isCompact = $derived(density === 'compact')
141
+ const pageGapClass = 'space-y-5'
142
+ const actionButtonSize = $derived(isCompact ? 'xs' : 'sm')
143
+ const actionIconClass = $derived(isCompact ? 'size-3.5' : 'size-4')
144
+ const paginationSize = $derived(isCompact ? 'xs' : 'sm')
145
+ const filterCardClass = 'overflow-hidden rounded-[1.25rem] border-base-content/7 shadow-sm'
146
+ const listCardClass = 'overflow-hidden rounded-[1.25rem] border-base-content/7 shadow-sm'
147
+ const paginationBarClass = 'flex justify-center border-t border-base-content/5 px-4 py-2'
148
+
149
+ // 表单展示配置(抽屉 / 弹窗)
150
+ const formVariant = $derived(form.variant ?? 'drawer')
151
+ const formDrawerSize = $derived(form.drawerSize ?? '2xl')
152
+ const formDrawerWidth = $derived(form.drawerWidth)
153
+ const formModalSize = $derived(form.modalSize ?? '2xl')
154
+ const formModalWidth = $derived(form.modalWidth)
155
+ const formModalHeight = $derived(form.modalHeight)
156
+
157
+ // 分页栏配置
158
+ const paginationShowSizeChanger = $derived(pagination.showSizeChanger !== false)
159
+ const paginationShowJumper = $derived(pagination.showJumper !== false)
160
+ const paginationShowTotal = $derived(pagination.showTotal !== false)
161
+ const paginationPageSizeOptions = $derived(pagination.pageSizeOptions ?? [10, 20, 50, 100])
136
162
 
137
163
  // 视图状态
138
- let drawerMode = $state<'detail' | 'edit' | 'create' | null>(null)
164
+ let panelMode = $state<'detail' | 'edit' | 'create' | null>(null)
139
165
  let selectedItem = $state<Record<string, unknown> | null>(null)
140
166
  let formData = $state<Record<string, unknown>>({})
141
167
  let submitting = $state(false)
@@ -219,29 +245,33 @@
219
245
  navigateWithParams({ page: newPage })
220
246
  }
221
247
 
248
+ function handlePageSizeChange(newPageSize: number) {
249
+ navigateWithParams({ pageSize: newPageSize, page: 1 })
250
+ }
251
+
222
252
  // ─── 打开/关闭抽屉 ───
223
253
 
224
254
  function openDetail(item: Record<string, unknown>) {
225
255
  selectedItem = item
226
- drawerMode = 'detail'
256
+ panelMode = 'detail'
227
257
  }
228
258
 
229
259
  function openCreate() {
230
260
  selectedItem = null
231
261
  formData = { ...crud.getDefaultValues() }
232
262
  formError = ''
233
- drawerMode = 'create'
263
+ panelMode = 'create'
234
264
  }
235
265
 
236
266
  function openEdit(item: Record<string, unknown>) {
237
267
  selectedItem = item
238
268
  formData = { ...item }
239
269
  formError = ''
240
- drawerMode = 'edit'
270
+ panelMode = 'edit'
241
271
  }
242
272
 
243
- function closeDrawer() {
244
- drawerMode = null
273
+ function closePanel() {
274
+ panelMode = null
245
275
  selectedItem = null
246
276
  formError = ''
247
277
  }
@@ -259,18 +289,18 @@
259
289
  submitting = true
260
290
 
261
291
  try {
262
- if (drawerMode === 'create' && crud.api.create) {
292
+ if (panelMode === 'create' && crud.api.create) {
263
293
  const result = await crud.api.create(submitData)
264
294
  const submitted = (result ?? {}) as Record<string, unknown>
265
- closeDrawer()
295
+ closePanel()
266
296
  onaftersubmit?.(submitted, 'create')
267
297
  await nav.refresh?.()
268
298
  }
269
- else if (drawerMode === 'edit' && crud.api.update && selectedItem) {
299
+ else if (panelMode === 'edit' && crud.api.update && selectedItem) {
270
300
  const id = String(selectedItem[keyField])
271
301
  const result = await crud.api.update(id, submitData)
272
302
  const submitted = (result ?? {}) as Record<string, unknown>
273
- closeDrawer()
303
+ closePanel()
274
304
  onaftersubmit?.(submitted, 'edit')
275
305
  await nav.refresh?.()
276
306
  }
@@ -314,7 +344,7 @@
314
344
  deletingItem = null
315
345
  // 如果删除的是当前详情/编辑中的项,关闭抽屉
316
346
  if (selectedItem && String(selectedItem[keyField]) === id) {
317
- closeDrawer()
347
+ closePanel()
318
348
  }
319
349
  onafterdelete?.(deleted)
320
350
  await nav.refresh?.()
@@ -347,17 +377,17 @@
347
377
  const filterFields = $derived(crud.getFilterFields() as FieldDef[])
348
378
 
349
379
  // 抽屉标题
350
- const drawerTitle = $derived(
351
- drawerMode === 'create'
380
+ const panelTitle = $derived(
381
+ panelMode === 'create'
352
382
  ? `${uiM('crud_create')}${resourceLabel}`
353
- : drawerMode === 'edit'
383
+ : panelMode === 'edit'
354
384
  ? `${uiM('crud_edit')}${resourceLabel}`
355
385
  : `${resourceLabel}${uiM('crud_detail')}`,
356
386
  )
357
387
 
358
- // 抽屉 open 状态
359
- const detailOpen = $derived(drawerMode === 'detail')
360
- const editOpen = $derived(drawerMode === 'create' || drawerMode === 'edit')
388
+ // 面板 open 状态
389
+ const detailOpen = $derived(panelMode === 'detail')
390
+ const editOpen = $derived(panelMode === 'create' || panelMode === 'edit')
361
391
 
362
392
  // 用于 DataTable 的 columns(含自定义渲染)
363
393
  const dtColumns = $derived(
@@ -373,7 +403,7 @@
373
403
  )
374
404
  </script>
375
405
 
376
- <div class='space-y-4 {className}'>
406
+ <div class='{pageGapClass} {className}'>
377
407
  <!-- 页面标题 -->
378
408
  <PageHeader title={resourceLabel}>
379
409
  {#snippet actions()}
@@ -381,8 +411,8 @@
381
411
  {@render headerActions()}
382
412
  {/if}
383
413
  {#if canCreate}
384
- <Button variant='primary' onclick={openCreate}>
385
- <span class='icon-[tabler--plus] size-4.5 mr-1'></span>
414
+ <Button variant='primary' size='sm' onclick={openCreate} class='shadow-sm'>
415
+ <span class='icon-[tabler--plus] size-4.5 mr-1.5'></span>
386
416
  {uiM('crud_create')}
387
417
  </Button>
388
418
  {/if}
@@ -391,7 +421,7 @@
391
421
 
392
422
  <!-- 搜索 + 过滤栏 -->
393
423
  {#if searchable || filterFields.length > 0}
394
- <Card>
424
+ <Card padding='sm' class={filterCardClass}>
395
425
  <CrudFilterBar
396
426
  {searchable}
397
427
  searchPlaceholder={searchPlaceholderText}
@@ -406,43 +436,44 @@
406
436
  {/if}
407
437
 
408
438
  <!-- 数据列表 -->
409
- <Card>
439
+ <Card padding='none' class={listCardClass}>
410
440
  <DataTable
411
441
  data={data.items}
412
442
  columns={dtColumns}
413
443
  keyField={keyField}
414
444
  loading={false}
445
+ {density}
415
446
  >
416
447
  {#snippet actions(item)}
417
448
  {#if rowClickDetail}
418
449
  <IconButton
419
450
  variant='ghost'
420
- size='sm'
451
+ size={actionButtonSize}
421
452
  ariaLabel={uiM('crud_detail')}
422
453
  onclick={() => openDetail(item)}
423
454
  >
424
- <span class='icon-[tabler--eye] size-4'></span>
455
+ <span class='icon-[tabler--eye] {actionIconClass}'></span>
425
456
  </IconButton>
426
457
  {/if}
427
458
  {#if canUpdate}
428
459
  <IconButton
429
460
  variant='ghost'
430
- size='sm'
461
+ size={actionButtonSize}
431
462
  ariaLabel={uiM('crud_edit')}
432
463
  onclick={() => openEdit(item)}
433
464
  >
434
- <span class='icon-[tabler--edit] size-4'></span>
465
+ <span class='icon-[tabler--edit] {actionIconClass}'></span>
435
466
  </IconButton>
436
467
  {/if}
437
468
  {#if canDelete}
438
469
  <IconButton
439
470
  variant='ghost'
440
- size='sm'
471
+ size={actionButtonSize}
441
472
  ariaLabel={uiM('crud_delete')}
442
473
  onclick={() => requestDelete(item)}
443
474
  class='hover:text-error'
444
475
  >
445
- <span class='icon-[tabler--trash] size-4'></span>
476
+ <span class='icon-[tabler--trash] {actionIconClass}'></span>
446
477
  </IconButton>
447
478
  {/if}
448
479
  {#if listItemActions}
@@ -451,47 +482,61 @@
451
482
  {/snippet}
452
483
  </DataTable>
453
484
 
454
- <!-- 分页 -->
455
- {#if data.total > data.pageSize}
456
- <div class='flex justify-center p-4 border-t border-base-content/5'>
457
- <Pagination
458
- page={data.page}
459
- total={data.total}
460
- pageSize={data.pageSize}
461
- size='sm'
462
- showTotal
463
- onchange={handlePageChange}
464
- />
465
- </div>
466
- {/if}
485
+ <!-- 分页栏:始终显示,支持每页条数选择与跳页 -->
486
+ <div class={paginationBarClass}>
487
+ <Pagination
488
+ page={data.page}
489
+ total={data.total}
490
+ pageSize={data.pageSize}
491
+ size={paginationSize}
492
+ showTotal={paginationShowTotal}
493
+ showJumper={paginationShowJumper}
494
+ showSizeChanger={paginationShowSizeChanger}
495
+ pageSizeOptions={paginationPageSizeOptions}
496
+ onchange={handlePageChange}
497
+ onpagesizechange={handlePageSizeChange}
498
+ />
499
+ </div>
467
500
  </Card>
468
501
  </div>
469
502
 
470
- <!-- 详情抽屉 -->
471
- <CrudDetailDrawer
503
+ <!-- 详情:抽屉或弹窗 -->
504
+ <CrudDetailPanel
472
505
  open={detailOpen}
473
506
  item={selectedItem}
474
507
  fields={detailFields}
475
- title={drawerTitle}
476
- size={drawerSize}
508
+ {density}
509
+ title={panelTitle}
510
+ variant={formVariant}
511
+ size={formDrawerSize}
512
+ drawerWidth={formDrawerWidth}
513
+ modalSize={formModalSize}
514
+ modalWidth={formModalWidth}
515
+ modalHeight={formModalHeight}
477
516
  canEdit={canUpdate}
478
517
  onedit={switchToEdit}
479
- onclose={closeDrawer}
518
+ onclose={closePanel}
480
519
  {detailExtra}
481
520
  />
482
521
 
483
- <!-- 编辑/新建抽屉 -->
484
- <CrudEditDrawer
522
+ <!-- 编辑/新建:抽屉或弹窗 -->
523
+ <CrudEditPanel
485
524
  open={editOpen}
486
- mode={drawerMode === 'create' ? 'create' : 'edit'}
487
- fields={drawerMode === 'create' ? createFields : editFields}
525
+ mode={panelMode === 'create' ? 'create' : 'edit'}
526
+ fields={panelMode === 'create' ? createFields : editFields}
527
+ {density}
488
528
  bind:formData
489
- title={drawerTitle}
490
- size={drawerSize}
529
+ title={panelTitle}
530
+ variant={formVariant}
531
+ size={formDrawerSize}
532
+ drawerWidth={formDrawerWidth}
533
+ modalSize={formModalSize}
534
+ modalWidth={formModalWidth}
535
+ modalHeight={formModalHeight}
491
536
  {submitting}
492
537
  error={formError}
493
538
  onsubmit={handleSubmit}
494
- onclose={closeDrawer}
539
+ onclose={closePanel}
495
540
  {editFormExtra}
496
541
  editingItem={selectedItem}
497
542
  />
@@ -1,5 +1,5 @@
1
1
  import type { Snippet } from 'svelte';
2
- import type { Size } from '../../../types.js';
2
+ import type { CrudDensity, CrudFormConfig, CrudPaginationConfig } from './crud-types.js';
3
3
  import type { NavAdapter } from './nav-adapter.js';
4
4
  type FieldDef = {
5
5
  id: string;
@@ -84,7 +84,9 @@ type $$ComponentProps = {
84
84
  update?: boolean;
85
85
  delete?: boolean;
86
86
  };
87
- drawerSize?: Size;
87
+ form?: CrudFormConfig;
88
+ pagination?: CrudPaginationConfig;
89
+ density?: CrudDensity;
88
90
  rowClickDetail?: boolean;
89
91
  listItemActions?: Snippet<[Record<string, unknown>]>;
90
92
  editFormExtra?: Snippet<[Record<string, unknown> | null, 'create' | 'edit']>;
@@ -108,10 +110,10 @@ type $$ComponentProps = {
108
110
  * CrudPage
109
111
  * 通用 CRUD 页面组件
110
112
  *
111
- * 基于声明式资源定义,自动生成列表 + 搜索过滤 + 分页 + 详情抽屉 + 编辑/新建抽屉 + 删除确认。
113
+ * 基于声明式资源定义,自动生成列表 + 搜索过滤 + 分页 + 详情查看 + 编辑/新建面板 + 删除确认。
112
114
  *
113
115
  * 使用 Svelte 5 Runes ($props, $state, $derived, $effect)
114
- * 使用 compounds 组件:Card, DataTable, PageHeader, Pagination, Drawer
116
+ * 使用 compounds 组件:Card, DataTable, PageHeader, Pagination, Drawer, Modal
115
117
  *
116
118
  * @example
117
119
  * <CrudPage crud={userCrud} data={data} permissions={{ create: true, update: true, delete: true }} />
@@ -15,6 +15,36 @@ export interface CrudPermissions {
15
15
  /** 允许删除 */
16
16
  delete?: boolean;
17
17
  }
18
+ /** 新建/编辑表单的展示形式 */
19
+ export type CrudFormVariant = 'drawer' | 'modal';
20
+ /** 列表显示密度 */
21
+ export type CrudDensity = 'normal' | 'compact';
22
+ /** 新建/编辑表单展示配置 */
23
+ export interface CrudFormConfig {
24
+ /** 展示形式:'drawer'(抽屉,默认)或 'modal'(弹出窗口) */
25
+ variant?: CrudFormVariant;
26
+ /** 抽屉尺寸预设(variant='drawer',默认 '2xl') */
27
+ drawerSize?: Size;
28
+ /** 抽屉自定义宽度 CSS 值,优先级高于 drawerSize(variant='drawer') */
29
+ drawerWidth?: string;
30
+ /** 弹窗尺寸预设(variant='modal',默认 '2xl') */
31
+ modalSize?: Size | 'full';
32
+ /** 弹窗自定义宽度 CSS 值(variant='modal') */
33
+ modalWidth?: string;
34
+ /** 弹窗自定义高度 CSS 值(variant='modal') */
35
+ modalHeight?: string;
36
+ }
37
+ /** 分页栏展示配置 */
38
+ export interface CrudPaginationConfig {
39
+ /** 是否显示每页条数选择器(默认 true) */
40
+ showSizeChanger?: boolean;
41
+ /** 每页条数候选项(默认 [10, 20, 50, 100]) */
42
+ pageSizeOptions?: number[];
43
+ /** 是否显示跳页输入(默认 true) */
44
+ showJumper?: boolean;
45
+ /** 是否显示总数(默认 true) */
46
+ showTotal?: boolean;
47
+ }
18
48
  /** CrudPage 初始列表数据(由 +page.server.ts load 返回) */
19
49
  export interface CrudPageData<T = Record<string, unknown>> {
20
50
  items: T[];
@@ -108,8 +138,12 @@ export interface CrudPageProps<T = Record<string, unknown>> {
108
138
  data: CrudPageData<T>;
109
139
  /** 权限控制 */
110
140
  permissions?: CrudPermissions;
111
- /** 抽屉尺寸(默认 '2xl') */
112
- drawerSize?: Size;
141
+ /** 新建/编辑表单展示配置(抽屉或弹窗、尺寸、宽高) */
142
+ form?: CrudFormConfig;
143
+ /** 分页栏展示配置(每页条数选择、跳页、总数) */
144
+ pagination?: CrudPaginationConfig;
145
+ /** 列表显示密度:影响列表行、行内操作、分页与详情/编辑表单;不影响页头与筛选栏 */
146
+ density?: CrudDensity;
113
147
  /** 列表行点击是否打开详情(默认 true) */
114
148
  rowClickDetail?: boolean;
115
149
  /** 列表行操作按钮插槽 */
@@ -1,13 +1,13 @@
1
1
  /**
2
2
  * @h-ai/ui — CRUD 场景组件
3
3
  *
4
- * 提供声明式 CRUD 页面组件,基于 kit.crud.define() 定义自动渲染列表、搜索过滤、分页、详情/编辑抽屉和删除确认。
4
+ * 提供声明式 CRUD 页面组件,基于 kit.crud.define() 定义自动渲染列表、搜索过滤、分页、详情/编辑面板和删除确认。
5
5
  * @module crud
6
6
  */
7
7
  export type * from './crud-types.js';
8
8
  export { default as CrudDeleteConfirm } from './CrudDeleteConfirm.svelte';
9
- export { default as CrudDetailDrawer } from './CrudDetailDrawer.svelte';
10
- export { default as CrudEditDrawer } from './CrudEditDrawer.svelte';
9
+ export { default as CrudDetailPanel } from './CrudDetailPanel.svelte';
10
+ export { default as CrudEditPanel } from './CrudEditPanel.svelte';
11
11
  export { default as CrudFilterBar } from './CrudFilterBar.svelte';
12
12
  export { default as CrudPage } from './CrudPage.svelte';
13
13
  export type { NavAdapter } from './nav-adapter.js';
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * @h-ai/ui — CRUD 场景组件
3
3
  *
4
- * 提供声明式 CRUD 页面组件,基于 kit.crud.define() 定义自动渲染列表、搜索过滤、分页、详情/编辑抽屉和删除确认。
4
+ * 提供声明式 CRUD 页面组件,基于 kit.crud.define() 定义自动渲染列表、搜索过滤、分页、详情/编辑面板和删除确认。
5
5
  * @module crud
6
6
  */
7
7
  export { default as CrudDeleteConfirm } from './CrudDeleteConfirm.svelte';
8
- export { default as CrudDetailDrawer } from './CrudDetailDrawer.svelte';
9
- export { default as CrudEditDrawer } from './CrudEditDrawer.svelte';
8
+ export { default as CrudDetailPanel } from './CrudDetailPanel.svelte';
9
+ export { default as CrudEditPanel } from './CrudEditPanel.svelte';
10
10
  export { default as CrudFilterBar } from './CrudFilterBar.svelte';
11
11
  export { default as CrudPage } from './CrudPage.svelte';
12
12
  export { createBrowserNavAdapter } from './nav-adapter.js';
@@ -156,9 +156,10 @@
156
156
  "feedback_type_feature": "Feature Request",
157
157
  "feedback_type_question": "Question",
158
158
  "feedback_type_other": "Other",
159
- "pagination_total": "Total {count}",
159
+ "pagination_total": "{count} items total",
160
160
  "pagination_jump_to": "Go to",
161
161
  "pagination_page": "page",
162
+ "pagination_page_size": "{size} / page",
162
163
  "severity_critical": "Critical",
163
164
  "severity_high": "High",
164
165
  "severity_medium": "Medium",
@@ -274,7 +275,7 @@
274
275
  "crud_delete_failed": "Delete failed",
275
276
  "crud_network_error": "Network error, please try again later",
276
277
  "crud_filter_all": "All",
277
- "crud_total": "Total {count}",
278
+ "crud_total": "{count} items total",
278
279
  "crud_detail_empty": "-",
279
280
  "crud_field_required": "This field is required"
280
281
  }
@@ -156,9 +156,10 @@
156
156
  "feedback_type_feature": "功能建议",
157
157
  "feedback_type_question": "问题咨询",
158
158
  "feedback_type_other": "其他",
159
- "pagination_total": "共 {count}",
159
+ "pagination_total": "共 {count} 条",
160
160
  "pagination_jump_to": "跳转到",
161
161
  "pagination_page": "页",
162
+ "pagination_page_size": "{size} 条/页",
162
163
  "severity_critical": "严重",
163
164
  "severity_high": "高",
164
165
  "severity_medium": "中",
@@ -274,7 +275,7 @@
274
275
  "crud_delete_failed": "删除失败",
275
276
  "crud_network_error": "网络错误,请稍后重试",
276
277
  "crud_filter_all": "全部",
277
- "crud_total": "共 {count}",
278
+ "crud_total": "共 {count} 条",
278
279
  "crud_detail_empty": "-",
279
280
  "crud_field_required": "此字段为必填项"
280
281
  }
package/dist/types.d.ts CHANGED
@@ -475,6 +475,8 @@ export interface DrawerProps {
475
475
  position?: Position;
476
476
  /** 尺寸 */
477
477
  size?: Size;
478
+ /** 自定义宽度(任意合法 CSS 宽度值,优先级高于 size 预设) */
479
+ width?: string;
478
480
  /** 是否可通过点击遮罩关闭 */
479
481
  closeOnBackdrop?: boolean;
480
482
  /** 是否显示关闭按钮 */
@@ -585,6 +587,10 @@ export interface PaginationProps {
585
587
  showTotal?: boolean;
586
588
  /** 是否显示跳转 */
587
589
  showJumper?: boolean;
590
+ /** 是否显示每页条数选择器 */
591
+ showSizeChanger?: boolean;
592
+ /** 每页条数候选项(配合 showSizeChanger,默认 [10, 20, 50, 100]) */
593
+ pageSizeOptions?: number[];
588
594
  /** i18n 文案配置 */
589
595
  labels?: {
590
596
  /** 总数文案,{count} 会被替换为实际数字 */
@@ -593,11 +599,15 @@ export interface PaginationProps {
593
599
  jumpTo?: string;
594
600
  /** 页 */
595
601
  page?: string;
602
+ /** 每页条数文案,{size} 会被替换为实际数字 */
603
+ pageSize?: string;
596
604
  };
597
605
  /** 自定义类名 */
598
606
  class?: string;
599
607
  /** 页码变化事件 */
600
608
  onchange?: (page: number) => void;
609
+ /** 每页条数变化事件 */
610
+ onpagesizechange?: (pageSize: number) => void;
601
611
  }
602
612
  /**
603
613
  * 面包屑项
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@h-ai/ui",
3
3
  "type": "module",
4
- "version": "0.1.0-alpha.22",
4
+ "version": "0.1.0-alpha.24",
5
5
  "description": "Hai Framework UI component library for Svelte 5 Runes.",
6
6
  "license": "Apache-2.0",
7
7
  "svelte": "./dist/index.js",
@@ -45,7 +45,7 @@
45
45
  "mermaid": "^11.12.0",
46
46
  "shiki": "^4.0.2",
47
47
  "tailwind-merge": "^3.5.0",
48
- "@h-ai/core": "0.1.0-alpha.22"
48
+ "@h-ai/core": "0.1.0-alpha.24"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@sveltejs/package": "^2.5.7",