@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.
- package/README.md +39 -5
- package/auto-import.d.ts +2 -2
- package/auto-import.js +2 -2
- package/dist/components/compounds/Card.svelte +1 -1
- package/dist/components/compounds/DataTable.svelte +32 -7
- package/dist/components/compounds/DataTable.svelte.d.ts +2 -0
- package/dist/components/compounds/Drawer.svelte +7 -2
- package/dist/components/compounds/Modal.svelte +2 -0
- package/dist/components/compounds/Pagination.svelte +57 -16
- package/dist/components/primitives/Input.svelte +23 -1
- package/dist/components/primitives/Select.svelte +2 -2
- package/dist/components/scenes/crud/CrudDetailDrawer.svelte +59 -18
- package/dist/components/scenes/crud/CrudDetailDrawer.svelte.d.ts +8 -2
- package/dist/components/scenes/crud/CrudDetailPanel.svelte +204 -0
- package/dist/components/scenes/crud/CrudDetailPanel.svelte.d.ts +45 -0
- package/dist/components/scenes/crud/CrudEditPanel.svelte +281 -0
- package/dist/components/scenes/crud/{CrudEditDrawer.svelte.d.ts → CrudEditPanel.svelte.d.ts} +13 -6
- package/dist/components/scenes/crud/CrudFilterBar.svelte +22 -18
- package/dist/components/scenes/crud/CrudPage.svelte +105 -60
- package/dist/components/scenes/crud/CrudPage.svelte.d.ts +6 -4
- package/dist/components/scenes/crud/crud-types.d.ts +36 -2
- package/dist/components/scenes/crud/index.d.ts +3 -3
- package/dist/components/scenes/crud/index.js +3 -3
- package/dist/messages/en-US.json +3 -2
- package/dist/messages/zh-CN.json +3 -2
- package/dist/types.d.ts +10 -0
- package/package.json +2 -2
- 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 {
|
|
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
|
|
27
|
-
import
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
256
|
+
panelMode = 'detail'
|
|
227
257
|
}
|
|
228
258
|
|
|
229
259
|
function openCreate() {
|
|
230
260
|
selectedItem = null
|
|
231
261
|
formData = { ...crud.getDefaultValues() }
|
|
232
262
|
formError = ''
|
|
233
|
-
|
|
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
|
-
|
|
270
|
+
panelMode = 'edit'
|
|
241
271
|
}
|
|
242
272
|
|
|
243
|
-
function
|
|
244
|
-
|
|
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 (
|
|
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
|
-
|
|
295
|
+
closePanel()
|
|
266
296
|
onaftersubmit?.(submitted, 'create')
|
|
267
297
|
await nav.refresh?.()
|
|
268
298
|
}
|
|
269
|
-
else if (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
351
|
-
|
|
380
|
+
const panelTitle = $derived(
|
|
381
|
+
panelMode === 'create'
|
|
352
382
|
? `${uiM('crud_create')}${resourceLabel}`
|
|
353
|
-
:
|
|
383
|
+
: panelMode === 'edit'
|
|
354
384
|
? `${uiM('crud_edit')}${resourceLabel}`
|
|
355
385
|
: `${resourceLabel}${uiM('crud_detail')}`,
|
|
356
386
|
)
|
|
357
387
|
|
|
358
|
-
//
|
|
359
|
-
const detailOpen = $derived(
|
|
360
|
-
const editOpen = $derived(
|
|
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='
|
|
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=
|
|
451
|
+
size={actionButtonSize}
|
|
421
452
|
ariaLabel={uiM('crud_detail')}
|
|
422
453
|
onclick={() => openDetail(item)}
|
|
423
454
|
>
|
|
424
|
-
<span class='icon-[tabler--eye]
|
|
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=
|
|
461
|
+
size={actionButtonSize}
|
|
431
462
|
ariaLabel={uiM('crud_edit')}
|
|
432
463
|
onclick={() => openEdit(item)}
|
|
433
464
|
>
|
|
434
|
-
<span class='icon-[tabler--edit]
|
|
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=
|
|
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]
|
|
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
|
-
{
|
|
456
|
-
<
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
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
|
-
<
|
|
503
|
+
<!-- 详情:抽屉或弹窗 -->
|
|
504
|
+
<CrudDetailPanel
|
|
472
505
|
open={detailOpen}
|
|
473
506
|
item={selectedItem}
|
|
474
507
|
fields={detailFields}
|
|
475
|
-
|
|
476
|
-
|
|
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={
|
|
518
|
+
onclose={closePanel}
|
|
480
519
|
{detailExtra}
|
|
481
520
|
/>
|
|
482
521
|
|
|
483
|
-
<!--
|
|
484
|
-
<
|
|
522
|
+
<!-- 编辑/新建:抽屉或弹窗 -->
|
|
523
|
+
<CrudEditPanel
|
|
485
524
|
open={editOpen}
|
|
486
|
-
mode={
|
|
487
|
-
fields={
|
|
525
|
+
mode={panelMode === 'create' ? 'create' : 'edit'}
|
|
526
|
+
fields={panelMode === 'create' ? createFields : editFields}
|
|
527
|
+
{density}
|
|
488
528
|
bind:formData
|
|
489
|
-
title={
|
|
490
|
-
|
|
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={
|
|
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 {
|
|
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
|
-
|
|
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
|
-
/**
|
|
112
|
-
|
|
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
|
|
10
|
-
export { default as
|
|
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
|
|
9
|
-
export { default as
|
|
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';
|
package/dist/messages/en-US.json
CHANGED
|
@@ -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": "
|
|
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": "
|
|
278
|
+
"crud_total": "{count} items total",
|
|
278
279
|
"crud_detail_empty": "-",
|
|
279
280
|
"crud_field_required": "This field is required"
|
|
280
281
|
}
|
package/dist/messages/zh-CN.json
CHANGED
|
@@ -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.
|
|
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.
|
|
48
|
+
"@h-ai/core": "0.1.0-alpha.24"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@sveltejs/package": "^2.5.7",
|