niuma-ui 1.0.1 → 1.1.0
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/CHANGELOG.md +65 -1
- package/package.json +10 -2
- package/src/__tests__/RsButton.spec.ts +47 -0
- package/src/__tests__/RsCard.spec.ts +160 -1
- package/src/__tests__/RsConfirmDialog.spec.ts +127 -0
- package/src/__tests__/RsContextMenu.spec.ts +12 -0
- package/src/__tests__/RsDatePicker.spec.ts +21 -0
- package/src/__tests__/RsDateTimePicker.spec.ts +11 -0
- package/src/__tests__/RsDescriptions.spec.ts +50 -0
- package/src/__tests__/RsDialog.spec.ts +178 -0
- package/src/__tests__/RsDrawer.spec.ts +96 -3
- package/src/__tests__/RsDynamicTags.spec.ts +52 -0
- package/src/__tests__/RsForm.spec.ts +250 -6
- package/src/__tests__/RsFormItem.spec.ts +478 -0
- package/src/__tests__/RsFormList.spec.ts +109 -0
- package/src/__tests__/RsInput.spec.ts +108 -1
- package/src/__tests__/RsInputNumber.spec.ts +33 -0
- package/src/__tests__/RsMenu.spec.ts +406 -14
- package/src/__tests__/RsPagination.spec.ts +67 -2
- package/src/__tests__/RsSelect.spec.ts +465 -2
- package/src/__tests__/RsSwitch.spec.ts +74 -0
- package/src/__tests__/RsTable.a11y.spec.ts +83 -0
- package/src/__tests__/RsTable.dom-baseline.spec.ts +87 -0
- package/src/__tests__/RsTable.perf.spec.ts +23 -4
- package/src/__tests__/RsTable.spec.ts +63 -8
- package/src/__tests__/RsTable.ssr.spec.ts +71 -0
- package/src/__tests__/RsTable.summary.spec.ts +45 -0
- package/src/__tests__/RsTabs.spec.ts +102 -4
- package/src/__tests__/RsTimePicker.spec.ts +20 -0
- package/src/__tests__/RsTooltip.spec.ts +43 -0
- package/src/__tests__/RsUpload.spec.ts +62 -6
- package/src/__tests__/createRsDialog.spec.ts +145 -0
- package/src/__tests__/css-token.spec.ts +51 -0
- package/src/__tests__/date-picker-utils.spec.ts +49 -0
- package/src/__tests__/dialog-utils.spec.ts +43 -0
- package/src/__tests__/form-path.spec.ts +46 -0
- package/src/__tests__/form-rules.spec.ts +139 -0
- package/src/__tests__/perf-budgets.ts +32 -0
- package/src/__tests__/rs-table-api.spec.ts +206 -0
- package/src/__tests__/rs-table-compat-matrix.spec.ts +108 -0
- package/src/__tests__/rs-table-echarts-adapter.spec.ts +43 -0
- package/src/__tests__/rs-table-grid-nav.spec.ts +63 -0
- package/src/__tests__/rs-table-isolation.spec.ts +158 -0
- package/src/__tests__/split-pane-utils.spec.ts +21 -0
- package/src/__tests__/table-chart-utils.spec.ts +88 -0
- package/src/__tests__/table-summary-utils.spec.ts +62 -0
- package/src/__tests__/table-utils.spec.ts +124 -0
- package/src/__tests__/theme.spec.ts +27 -0
- package/src/__tests__/useRsTableColumnResize.spec.ts +25 -0
- package/src/__tests__/useRsTableCore.perf.spec.ts +170 -0
- package/src/components/RsAlert.vue +212 -0
- package/src/components/RsAvatar.vue +1 -1
- package/src/components/RsBadge.vue +1 -1
- package/src/components/RsBreadcrumb.vue +1 -1
- package/src/components/RsButton.vue +147 -23
- package/src/components/RsCalendarGrid.vue +3 -3
- package/src/components/RsCard.vue +204 -20
- package/src/components/RsCodeBlock.vue +4 -4
- package/src/components/RsCodeEditor.vue +8 -8
- package/src/components/RsConfirmDialog.vue +217 -30
- package/src/components/RsContextMenu.vue +57 -17
- package/src/components/RsDatePicker.vue +316 -39
- package/src/components/RsDateTimePicker.vue +27 -2
- package/src/components/RsDescriptions.vue +186 -0
- package/src/components/RsDescriptionsItem.vue +32 -0
- package/src/components/RsDialog.vue +374 -52
- package/src/components/RsDivider.vue +89 -0
- package/src/components/RsDrawer.vue +559 -34
- package/src/components/RsDropdown.vue +34 -3
- package/src/components/RsDynamicTags.vue +531 -0
- package/src/components/RsEmpty.vue +1 -1
- package/src/components/RsForm.vue +164 -8
- package/src/components/RsFormItem.vue +423 -0
- package/src/components/RsFormItemControl.vue +21 -0
- package/src/components/RsFormList.vue +117 -0
- package/src/components/RsInput.vue +491 -100
- package/src/components/RsInputNumber.vue +77 -27
- package/src/components/RsLabel.vue +20 -5
- package/src/components/RsLink.vue +1 -1
- package/src/components/RsLoadingBar.vue +151 -0
- package/src/components/RsMarkdown.vue +5 -5
- package/src/components/RsMenu.vue +74 -16
- package/src/components/RsMenuItems.vue +147 -9
- package/src/components/RsMonacoEditor.vue +9 -3
- package/src/components/RsPagination.vue +93 -14
- package/src/components/RsProseEditor.vue +3 -3
- package/src/components/RsRadio.vue +81 -0
- package/src/components/RsRadioItem.vue +156 -0
- package/src/components/RsSelect.vue +372 -642
- package/src/components/RsSidebarGroup.vue +1 -1
- package/src/components/RsSplitPane.vue +90 -1
- package/src/components/RsStatCard.vue +2 -2
- package/src/components/RsSteps.vue +2 -2
- package/src/components/RsSwitch.vue +192 -0
- package/src/components/RsTable.vue +653 -2555
- package/src/components/RsTabs.vue +422 -90
- package/src/components/RsTag.vue +191 -0
- package/src/components/RsTerminal.vue +58 -19
- package/src/components/RsTimePicker.vue +72 -9
- package/src/components/RsTimePickerColumns.vue +137 -78
- package/src/components/RsToaster.vue +64 -24
- package/src/components/RsTooltip.vue +10 -1
- package/src/components/RsTooltipProvider.vue +11 -1
- package/src/components/RsTree.vue +45 -27
- package/src/components/RsUpload.vue +147 -14
- package/src/components/RsVNodeHost.vue +20 -0
- package/src/components/button-utils.ts +39 -0
- package/src/components/context-menu-utils.ts +6 -0
- package/src/components/date-picker-utils.ts +195 -4
- package/src/components/descriptions-utils.ts +24 -0
- package/src/components/dialog-utils.ts +182 -0
- package/src/components/dialog-window.ts +74 -9
- package/src/components/drawer-utils.ts +73 -0
- package/src/components/form-item-control.ts +55 -0
- package/src/components/form-path.ts +92 -0
- package/src/components/form-rules.ts +311 -0
- package/src/components/form-utils.ts +145 -3
- package/src/components/menu-utils.ts +11 -0
- package/src/components/overlay-utils.ts +3 -0
- package/src/components/radio-utils.ts +12 -0
- package/src/components/reka.ts +5 -0
- package/src/components/select-utils.ts +285 -6
- package/src/components/split-pane-utils.ts +65 -12
- package/src/components/table/RsTableBody.vue +217 -0
- package/src/components/table/RsTableBodyRow.vue +90 -1
- package/src/components/table/RsTableColGroup.vue +41 -0
- package/src/components/table/RsTableHeader.vue +158 -0
- package/src/components/table/RsTableHeaderFilter.vue +1 -1
- package/src/components/table/RsTableSummaryRow.vue +52 -0
- package/src/components/table/rs-table-api.ts +99 -0
- package/src/components/table/rs-table-compat-matrix.ts +71 -0
- package/src/components/table/rs-table-echarts-adapter.ts +81 -0
- package/src/components/table/rs-table-feature-host.ts +178 -0
- package/src/components/table/rs-table-grid-nav.ts +122 -0
- package/src/components/table/rs-table-header-types.ts +47 -0
- package/src/components/table/rs-table-module-registry.ts +72 -0
- package/src/components/table/rs-table-props.ts +274 -0
- package/src/components/table/rs-table-view-context.ts +258 -0
- package/src/components/table/rs-table.css +85 -7
- package/src/components/table/table-chart-utils.ts +165 -0
- package/src/components/table/table-features.ts +284 -0
- package/src/components/table/table-summary-utils.ts +194 -0
- package/src/components/table-utils.ts +452 -2
- package/src/components/tabs-utils.ts +142 -2
- package/src/components/time-picker-utils.ts +76 -3
- package/src/components/upload-utils.ts +122 -0
- package/src/components/use-rs-select.ts +436 -0
- package/src/components/virtual-list-utils.ts +15 -2
- package/src/composables/assembleRsTableApi.ts +79 -0
- package/src/composables/bindRsTableViewContext.ts +269 -0
- package/src/composables/createRsDialog.ts +357 -0
- package/src/composables/createRsTableEditEmitBridge.ts +38 -0
- package/src/composables/useRsConfig.ts +10 -3
- package/src/composables/useRsI18n.ts +16 -5
- package/src/composables/useRsLoadingBar.ts +36 -0
- package/src/composables/useRsTable.ts +134 -0
- package/src/composables/useRsTableA11y.ts +52 -0
- package/src/composables/useRsTableChartBridge.ts +79 -0
- package/src/composables/useRsTableColumnLayout.ts +320 -0
- package/src/composables/useRsTableColumnResize.ts +244 -0
- package/src/composables/useRsTableColumnVirtual.ts +180 -0
- package/src/composables/useRsTableColumns.ts +200 -0
- package/src/composables/useRsTableContextMenu.ts +257 -0
- package/src/composables/useRsTableCore.ts +256 -0
- package/src/composables/useRsTableEditActions.ts +606 -0
- package/src/composables/useRsTableEditLayer.ts +251 -0
- package/src/composables/useRsTableEngine.ts +357 -0
- package/src/composables/useRsTableGridKeyboard.ts +123 -0
- package/src/composables/useRsTableHeadless.ts +137 -0
- package/src/composables/useRsTableInteraction.ts +433 -0
- package/src/composables/useRsTableScrollHost.ts +75 -0
- package/src/composables/useRsTableScrollLayout.ts +255 -0
- package/src/composables/useRsTableSelectionSource.ts +89 -0
- package/src/composables/useRsTableShell.ts +416 -0
- package/src/composables/useRsTableShellChrome.ts +170 -0
- package/src/composables/useRsTableSummary.ts +113 -0
- package/src/composables/useRsTableViewProvide.ts +263 -0
- package/src/composables/useRsTableVirtual.ts +154 -0
- package/src/composables/useRsTabsNav.ts +4 -0
- package/src/composables/useTableEdit.ts +1 -1
- package/src/index.ts +378 -10
- package/src/locale/interpolate.ts +32 -0
- package/src/locale/messages.ts +40 -0
- package/src/styles.css +365 -56
- package/src/theme/brand.example.css +24 -2
- package/src/theme/css-token.ts +107 -0
- package/src/theme/presets.ts +4 -0
- package/src/theme/types.ts +68 -0
- package/src/components/RsTableColgroup.vue +0 -17
- package/src/components/RsTableHeaderRow.vue +0 -30
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 装配 RsTable 公开 Api(从 SFC 下沉,单一出口)。
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { ComputedRef, Ref } from 'vue'
|
|
6
|
+
import type { RsTableApi } from '../components/table/rs-table-api'
|
|
7
|
+
import type { RsTableRowData, RsTableRowEntry } from '../components/table-utils'
|
|
8
|
+
import type { RsTableAnalyticsSnapshot } from './useRsTableSelectionSource'
|
|
9
|
+
import type { useRsTable } from './useRsTable'
|
|
10
|
+
|
|
11
|
+
type RowEntry<T extends RsTableRowData> = Extract<RsTableRowEntry<T>, { type: 'row' }>
|
|
12
|
+
|
|
13
|
+
export interface AssembleRsTableApiOptions<T extends RsTableRowData> {
|
|
14
|
+
tableSurface: ReturnType<typeof useRsTable<T>>
|
|
15
|
+
dataRows: Ref<RowEntry<T>[]> | ComputedRef<RowEntry<T>[]>
|
|
16
|
+
rowKeyByIndex: Ref<Map<number, string>> | ComputedRef<Map<number, string>>
|
|
17
|
+
viewRows: Ref<T[]> | ComputedRef<T[]>
|
|
18
|
+
selectedRows: Ref<T[]> | ComputedRef<T[]>
|
|
19
|
+
selectedRowKeys: Ref<string[]> | ComputedRef<string[]>
|
|
20
|
+
getAnalyticsSnapshot: () => RsTableAnalyticsSnapshot<T>
|
|
21
|
+
subscribeAnalytics: (listener: (snap: RsTableAnalyticsSnapshot<T>) => void) => () => void
|
|
22
|
+
getRowByKey: (
|
|
23
|
+
rowKey: string,
|
|
24
|
+
dataRows: RowEntry<T>[],
|
|
25
|
+
rowKeyByIndex: Map<number, string>,
|
|
26
|
+
) => T | undefined
|
|
27
|
+
getRowByIndex: (index: number, dataRows: RowEntry<T>[]) => T | undefined
|
|
28
|
+
getColumnValues: (colKey: string, dataRows: RowEntry<T>[]) => unknown[]
|
|
29
|
+
getCellValue: (
|
|
30
|
+
rowKey: string,
|
|
31
|
+
colKey: string,
|
|
32
|
+
dataRows: RowEntry<T>[],
|
|
33
|
+
rowKeyByIndex: Map<number, string>,
|
|
34
|
+
) => unknown
|
|
35
|
+
toApiEditSlice: (ctx: {
|
|
36
|
+
dataRows: Ref<RowEntry<T>[]> | ComputedRef<RowEntry<T>[]>
|
|
37
|
+
rowKeyByIndex: Ref<Map<number, string>> | ComputedRef<Map<number, string>>
|
|
38
|
+
}) => Pick<
|
|
39
|
+
RsTableApi<T>,
|
|
40
|
+
| 'getHighlightedRowKey'
|
|
41
|
+
| 'setHighlightedRowKey'
|
|
42
|
+
| 'cancelCellEdit'
|
|
43
|
+
| 'cancelAllEdits'
|
|
44
|
+
| 'getDirtyCellKeys'
|
|
45
|
+
| 'getCellError'
|
|
46
|
+
| 'setCellError'
|
|
47
|
+
| 'stageCell'
|
|
48
|
+
| 'rejectRowEdit'
|
|
49
|
+
| 'undoEdit'
|
|
50
|
+
| 'redoEdit'
|
|
51
|
+
| 'commitRowEdits'
|
|
52
|
+
| 'rollbackRowEdits'
|
|
53
|
+
>
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 创建并返回 RsTableApi(含 feature 元数据)。
|
|
58
|
+
*/
|
|
59
|
+
export function assembleRsTableApi<T extends RsTableRowData>(
|
|
60
|
+
options: AssembleRsTableApiOptions<T>,
|
|
61
|
+
): RsTableApi<T> {
|
|
62
|
+
const { tableSurface, dataRows, rowKeyByIndex } = options
|
|
63
|
+
return tableSurface.createApi({
|
|
64
|
+
getRowByKey: (rowKey) =>
|
|
65
|
+
options.getRowByKey(rowKey, dataRows.value, rowKeyByIndex.value),
|
|
66
|
+
getRowByIndex: (index) => options.getRowByIndex(index, dataRows.value),
|
|
67
|
+
getColumnValues: (colKey) => options.getColumnValues(colKey, dataRows.value),
|
|
68
|
+
getCellValue: (rowKey, colKey) =>
|
|
69
|
+
options.getCellValue(rowKey, colKey, dataRows.value, rowKeyByIndex.value),
|
|
70
|
+
getViewRows: () => options.viewRows.value,
|
|
71
|
+
getSelectedRows: () => options.selectedRows.value,
|
|
72
|
+
getSelectedRowKeys: () => [...options.selectedRowKeys.value],
|
|
73
|
+
getAnalyticsSnapshot: options.getAnalyticsSnapshot,
|
|
74
|
+
subscribeAnalytics: options.subscribeAnalytics,
|
|
75
|
+
...options.toApiEditSlice({ dataRows, rowKeyByIndex }),
|
|
76
|
+
getToolbarItems: () => tableSurface.getToolbarItems(),
|
|
77
|
+
getOverlayContributions: () => tableSurface.getOverlayContributions(),
|
|
78
|
+
})
|
|
79
|
+
}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 将 Shell / Edit / Chrome 接线捆成 ViewContext provide(削薄 RsTable.vue)。
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { ComputedRef, Ref } from 'vue'
|
|
6
|
+
import type {
|
|
7
|
+
RsTableRowData,
|
|
8
|
+
RsTableRowEntry,
|
|
9
|
+
RsTableRowKey,
|
|
10
|
+
RsTableSelectionType,
|
|
11
|
+
} from '../components/table-utils'
|
|
12
|
+
import type { RsTableCellEditFocusMode, RsTableCellEditTrigger } from '../components/table/table-edit-utils'
|
|
13
|
+
import type { RsTableBodyLabels, RsTableHeaderLabels } from '../components/table/rs-table-view-context'
|
|
14
|
+
import type { useTableEdit } from './useTableEdit'
|
|
15
|
+
import {
|
|
16
|
+
useRsTableViewProvide,
|
|
17
|
+
type RsTableViewProvideHandlers,
|
|
18
|
+
type RsTableViewProvideSources,
|
|
19
|
+
} from './useRsTableViewProvide'
|
|
20
|
+
|
|
21
|
+
type RowEntry<T extends RsTableRowData> = Extract<RsTableRowEntry<T>, { type: 'row' }>
|
|
22
|
+
type TableEditApi = ReturnType<typeof useTableEdit>
|
|
23
|
+
|
|
24
|
+
export interface BindRsTableViewContextDeps<T extends RsTableRowData> {
|
|
25
|
+
props: {
|
|
26
|
+
columnDraggable: () => boolean
|
|
27
|
+
resizable: () => boolean
|
|
28
|
+
multiSort: () => boolean
|
|
29
|
+
loading: () => boolean
|
|
30
|
+
loadingMore: () => boolean
|
|
31
|
+
infinite: () => boolean
|
|
32
|
+
rowKey: () => RsTableRowKey<T> | undefined
|
|
33
|
+
striped: () => boolean
|
|
34
|
+
selectionType: () => RsTableSelectionType
|
|
35
|
+
editable: () => boolean
|
|
36
|
+
editTrigger: () => RsTableCellEditTrigger
|
|
37
|
+
rowCommit: () => boolean
|
|
38
|
+
allowNull: () => boolean
|
|
39
|
+
editFocusMode: () => RsTableCellEditFocusMode
|
|
40
|
+
nullLabel: () => string
|
|
41
|
+
}
|
|
42
|
+
layout: Pick<
|
|
43
|
+
RsTableViewProvideSources<T>,
|
|
44
|
+
| 'useFixedColumnLayout'
|
|
45
|
+
| 'showRowDragHandle'
|
|
46
|
+
| 'detailExpandable'
|
|
47
|
+
| 'showSelectColumn'
|
|
48
|
+
| 'showEditGutterColumn'
|
|
49
|
+
| 'showIndexColumn'
|
|
50
|
+
| 'showRowStatusColumn'
|
|
51
|
+
| 'columnPadLeft'
|
|
52
|
+
| 'columnPadRight'
|
|
53
|
+
| 'visibleDataColumns'
|
|
54
|
+
| 'prefixWidths'
|
|
55
|
+
| 'resolvedGutterWidth'
|
|
56
|
+
| 'resolvedIndexWidth'
|
|
57
|
+
| 'isRadioSelection'
|
|
58
|
+
| 'selectAllState'
|
|
59
|
+
| 'columnFiltersState'
|
|
60
|
+
| 'dragColumnKey'
|
|
61
|
+
| 'dropColumnKey'
|
|
62
|
+
| 'dragLeadHeaderStyle'
|
|
63
|
+
| 'expandLeadHeaderStyle'
|
|
64
|
+
| 'selectLeadHeaderStyle'
|
|
65
|
+
| 'gutterLeadHeaderStyle'
|
|
66
|
+
| 'indexLeadHeaderStyle'
|
|
67
|
+
| 'columnHeaderStyleMap'
|
|
68
|
+
| 'bodyColspan'
|
|
69
|
+
| 'emptyContentStyle'
|
|
70
|
+
| 'virtualScrollEnabled'
|
|
71
|
+
| 'virtualSlice'
|
|
72
|
+
| 'visibleEntries'
|
|
73
|
+
| 'treeMode'
|
|
74
|
+
| 'treeIndentPx'
|
|
75
|
+
| 'treeExpandColumnKey'
|
|
76
|
+
| 'treeLoadingKeySet'
|
|
77
|
+
| 'dragLeadStyle'
|
|
78
|
+
| 'expandLeadStyle'
|
|
79
|
+
| 'selectLeadStyle'
|
|
80
|
+
| 'indexLeadStyle'
|
|
81
|
+
| 'gutterLeadStyle'
|
|
82
|
+
| 'columnTdClassMap'
|
|
83
|
+
| 'columnStyleMap'
|
|
84
|
+
| 'dragRowKeys'
|
|
85
|
+
| 'dropRowTargetKey'
|
|
86
|
+
| 'dropRowPosition'
|
|
87
|
+
>
|
|
88
|
+
chrome: {
|
|
89
|
+
hasData: Ref<boolean> | ComputedRef<boolean>
|
|
90
|
+
headerLabels: Ref<RsTableHeaderLabels> | ComputedRef<RsTableHeaderLabels>
|
|
91
|
+
bodyLabels: Ref<RsTableBodyLabels> | ComputedRef<RsTableBodyLabels>
|
|
92
|
+
hasColumnSlot: (key: string) => boolean
|
|
93
|
+
hasEditSlot: (key: string) => boolean
|
|
94
|
+
}
|
|
95
|
+
edit: {
|
|
96
|
+
tableEdit: TableEditApi
|
|
97
|
+
activeEditCellKey: Ref<string> | ComputedRef<string>
|
|
98
|
+
activeFocusCellKey: Ref<string> | ComputedRef<string>
|
|
99
|
+
activeErrorMapSize: Ref<number> | ComputedRef<number>
|
|
100
|
+
activeValidatingMapSize: Ref<number> | ComputedRef<number>
|
|
101
|
+
cellTooltipEnabled: RsTableViewProvideHandlers<T>['cellTooltipEnabled']
|
|
102
|
+
cellTooltipMode: RsTableViewProvideHandlers<T>['cellTooltipMode']
|
|
103
|
+
cellTooltipText: RsTableViewProvideHandlers<T>['cellTooltipText']
|
|
104
|
+
cellTooltipFallbackTitle: RsTableViewProvideHandlers<T>['cellTooltipFallbackTitle']
|
|
105
|
+
rowEditPending: RsTableViewProvideHandlers<T>['rowEditPending']
|
|
106
|
+
isExternalRowPending: RsTableViewProvideHandlers<T>['isExternalRowPending']
|
|
107
|
+
onCellStartEdit: RsTableViewProvideHandlers<T>['onCellStartEdit']
|
|
108
|
+
onCellCommit: RsTableViewProvideHandlers<T>['onCellCommit']
|
|
109
|
+
onCellCancel: RsTableViewProvideHandlers<T>['onCellCancel']
|
|
110
|
+
onCellUpdateDraft: RsTableViewProvideHandlers<T>['onCellUpdateDraft']
|
|
111
|
+
onCellNavigate: RsTableViewProvideHandlers<T>['onCellNavigate']
|
|
112
|
+
onRowCommit: RsTableViewProvideHandlers<T>['onRowCommit']
|
|
113
|
+
onRowRollback: RsTableViewProvideHandlers<T>['onRowRollback']
|
|
114
|
+
onGutterCommit: RsTableViewProvideHandlers<T>['onGutterCommit']
|
|
115
|
+
onCellClick: RsTableViewProvideHandlers<T>['onCellClick']
|
|
116
|
+
onCellDblclick: RsTableViewProvideHandlers<T>['onCellDblclick']
|
|
117
|
+
}
|
|
118
|
+
interaction: {
|
|
119
|
+
isHighlighted: (key: string) => boolean
|
|
120
|
+
onCellTipOver: (event: PointerEvent) => void
|
|
121
|
+
onCellTipOut: (event: PointerEvent) => void
|
|
122
|
+
} & Pick<
|
|
123
|
+
RsTableViewProvideHandlers<T>,
|
|
124
|
+
| 'resolvedDataColumnWidth'
|
|
125
|
+
| 'columnFilterValue'
|
|
126
|
+
| 'sortOrderFor'
|
|
127
|
+
| 'sortPriorityFor'
|
|
128
|
+
| 'sortIconName'
|
|
129
|
+
| 'onToggleSelectAll'
|
|
130
|
+
| 'onColumnDragOver'
|
|
131
|
+
| 'onColumnDrop'
|
|
132
|
+
| 'onColumnDragStart'
|
|
133
|
+
| 'onColumnDragEnd'
|
|
134
|
+
| 'updateColumnFilter'
|
|
135
|
+
| 'onHeaderClick'
|
|
136
|
+
| 'onResizeStart'
|
|
137
|
+
| 'rowKeyFor'
|
|
138
|
+
| 'isRowSelected'
|
|
139
|
+
| 'isRowIndeterminate'
|
|
140
|
+
| 'isRowExpanded'
|
|
141
|
+
| 'treeDepthOf'
|
|
142
|
+
| 'canExpandRow'
|
|
143
|
+
| 'canSelectRow'
|
|
144
|
+
| 'isRowDragByRow'
|
|
145
|
+
| 'isRowDragging'
|
|
146
|
+
| 'isRowDropTarget'
|
|
147
|
+
| 'onRowClick'
|
|
148
|
+
| 'onRowSelectMouseDown'
|
|
149
|
+
| 'onCellContextmenu'
|
|
150
|
+
| 'onRowDblclick'
|
|
151
|
+
| 'onRowContextmenu'
|
|
152
|
+
| 'onRowDragOver'
|
|
153
|
+
| 'onRowDragLeave'
|
|
154
|
+
| 'onRowDrop'
|
|
155
|
+
| 'onRowDragStart'
|
|
156
|
+
| 'onRowDragEnd'
|
|
157
|
+
| 'onToggleExpand'
|
|
158
|
+
| 'onToggleSelect'
|
|
159
|
+
>
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* 装配并 provide ViewContext。
|
|
164
|
+
*/
|
|
165
|
+
export function bindRsTableViewContext<T extends RsTableRowData>(
|
|
166
|
+
deps: BindRsTableViewContextDeps<T>,
|
|
167
|
+
) {
|
|
168
|
+
const { props, layout, chrome, edit, interaction } = deps
|
|
169
|
+
const { tableEdit } = edit
|
|
170
|
+
|
|
171
|
+
return useRsTableViewProvide<T>(
|
|
172
|
+
{
|
|
173
|
+
...layout,
|
|
174
|
+
columnDraggable: props.columnDraggable,
|
|
175
|
+
resizable: props.resizable,
|
|
176
|
+
multiSort: props.multiSort,
|
|
177
|
+
headerLabels: chrome.headerLabels,
|
|
178
|
+
loading: props.loading,
|
|
179
|
+
hasData: chrome.hasData,
|
|
180
|
+
loadingMore: props.loadingMore,
|
|
181
|
+
infinite: props.infinite,
|
|
182
|
+
rowKey: props.rowKey,
|
|
183
|
+
striped: props.striped,
|
|
184
|
+
selectionType: props.selectionType,
|
|
185
|
+
editable: props.editable,
|
|
186
|
+
editTrigger: props.editTrigger,
|
|
187
|
+
rowCommit: props.rowCommit,
|
|
188
|
+
allowNull: props.allowNull,
|
|
189
|
+
editFocusMode: props.editFocusMode,
|
|
190
|
+
nullLabel: props.nullLabel,
|
|
191
|
+
activeEditCellKey: edit.activeEditCellKey,
|
|
192
|
+
activeFocusCellKey: edit.activeFocusCellKey,
|
|
193
|
+
activeErrorMapSize: edit.activeErrorMapSize,
|
|
194
|
+
activeValidatingMapSize: edit.activeValidatingMapSize,
|
|
195
|
+
stagedMapSize: () => tableEdit.stagedMap.value.size,
|
|
196
|
+
editingDraft: () => tableEdit.editingDraft.value,
|
|
197
|
+
editingCell: () => tableEdit.editingCell.value,
|
|
198
|
+
focusCell: () => tableEdit.focusCell.value,
|
|
199
|
+
bodyLabels: chrome.bodyLabels,
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
resolvedDataColumnWidth: interaction.resolvedDataColumnWidth,
|
|
203
|
+
columnFilterValue: interaction.columnFilterValue,
|
|
204
|
+
sortOrderFor: interaction.sortOrderFor,
|
|
205
|
+
sortPriorityFor: interaction.sortPriorityFor,
|
|
206
|
+
sortIconName: interaction.sortIconName,
|
|
207
|
+
onToggleSelectAll: interaction.onToggleSelectAll,
|
|
208
|
+
onColumnDragOver: interaction.onColumnDragOver,
|
|
209
|
+
onColumnDrop: interaction.onColumnDrop,
|
|
210
|
+
onColumnDragStart: interaction.onColumnDragStart,
|
|
211
|
+
onColumnDragEnd: interaction.onColumnDragEnd,
|
|
212
|
+
updateColumnFilter: interaction.updateColumnFilter,
|
|
213
|
+
onHeaderClick: interaction.onHeaderClick,
|
|
214
|
+
onResizeStart: interaction.onResizeStart,
|
|
215
|
+
onHeaderPointerOver: interaction.onCellTipOver,
|
|
216
|
+
onHeaderPointerOut: interaction.onCellTipOut,
|
|
217
|
+
rowKeyFor: interaction.rowKeyFor,
|
|
218
|
+
isRowSelected: interaction.isRowSelected,
|
|
219
|
+
isRowIndeterminate: interaction.isRowIndeterminate,
|
|
220
|
+
isRowExpanded: interaction.isRowExpanded,
|
|
221
|
+
isHighlighted: interaction.isHighlighted,
|
|
222
|
+
rowEditPending: edit.rowEditPending,
|
|
223
|
+
isExternalRowPending: edit.isExternalRowPending,
|
|
224
|
+
treeDepthOf: interaction.treeDepthOf,
|
|
225
|
+
canExpandRow: interaction.canExpandRow,
|
|
226
|
+
canSelectRow: interaction.canSelectRow,
|
|
227
|
+
isRowDragByRow: interaction.isRowDragByRow,
|
|
228
|
+
isRowDragging: interaction.isRowDragging,
|
|
229
|
+
isRowDropTarget: interaction.isRowDropTarget,
|
|
230
|
+
isRowDirty: tableEdit.isRowDirty,
|
|
231
|
+
hasColumnSlot: chrome.hasColumnSlot,
|
|
232
|
+
hasEditSlot: chrome.hasEditSlot,
|
|
233
|
+
cellTooltipEnabled: edit.cellTooltipEnabled,
|
|
234
|
+
cellTooltipMode: edit.cellTooltipMode,
|
|
235
|
+
cellTooltipText: edit.cellTooltipText,
|
|
236
|
+
cellTooltipFallbackTitle: edit.cellTooltipFallbackTitle,
|
|
237
|
+
getCellDraft: tableEdit.getDraft,
|
|
238
|
+
isCellDirty: tableEdit.isDirty,
|
|
239
|
+
getCellError: tableEdit.getCellError,
|
|
240
|
+
isCellValidating: tableEdit.isValidating,
|
|
241
|
+
onBodyPointerOver: interaction.onCellTipOver,
|
|
242
|
+
onBodyPointerOut: interaction.onCellTipOut,
|
|
243
|
+
onRowClick: interaction.onRowClick,
|
|
244
|
+
onRowSelectMouseDown: interaction.onRowSelectMouseDown,
|
|
245
|
+
onCellClick: edit.onCellClick,
|
|
246
|
+
onCellDblclick: edit.onCellDblclick,
|
|
247
|
+
onCellContextmenu: interaction.onCellContextmenu,
|
|
248
|
+
onRowDblclick: interaction.onRowDblclick,
|
|
249
|
+
onRowContextmenu: interaction.onRowContextmenu,
|
|
250
|
+
onRowDragOver: interaction.onRowDragOver,
|
|
251
|
+
onRowDragLeave: interaction.onRowDragLeave,
|
|
252
|
+
onRowDrop: interaction.onRowDrop,
|
|
253
|
+
onRowDragStart: interaction.onRowDragStart,
|
|
254
|
+
onRowDragEnd: interaction.onRowDragEnd,
|
|
255
|
+
onToggleExpand: interaction.onToggleExpand,
|
|
256
|
+
onToggleSelect: interaction.onToggleSelect,
|
|
257
|
+
onCellStartEdit: edit.onCellStartEdit,
|
|
258
|
+
onCellCommit: edit.onCellCommit,
|
|
259
|
+
onCellCancel: edit.onCellCancel,
|
|
260
|
+
onCellUpdateDraft: edit.onCellUpdateDraft,
|
|
261
|
+
onCellNavigate: edit.onCellNavigate,
|
|
262
|
+
onRowCommit: edit.onRowCommit,
|
|
263
|
+
onRowRollback: edit.onRowRollback,
|
|
264
|
+
onGutterCommit: edit.onGutterCommit,
|
|
265
|
+
},
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export type { RowEntry }
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { createApp, h, ref, type App } from 'vue'
|
|
2
|
+
import RsConfigProvider from '../components/RsConfigProvider.vue'
|
|
3
|
+
import RsConfirmDialog from '../components/RsConfirmDialog.vue'
|
|
4
|
+
import RsDialog from '../components/RsDialog.vue'
|
|
5
|
+
import type { RsConfirmOptions } from '../components/dialog-utils'
|
|
6
|
+
import type { RsDialogBeforeClose, RsDialogCloseReason, RsDialogWidth } from '../components/dialog-utils'
|
|
7
|
+
import type { RsFeedbackTone } from '../components/overlay-utils'
|
|
8
|
+
import { defaultLocale, type RsLocale } from '../locale/types'
|
|
9
|
+
import type { RsThemeMode } from '../theme/types'
|
|
10
|
+
|
|
11
|
+
export type RsConfirmResult = boolean
|
|
12
|
+
|
|
13
|
+
export type RsConfirmInput = RsConfirmOptions | string
|
|
14
|
+
|
|
15
|
+
export interface RsDialogOpenOptions {
|
|
16
|
+
title?: string
|
|
17
|
+
subtitle?: string
|
|
18
|
+
description?: string
|
|
19
|
+
width?: RsDialogWidth
|
|
20
|
+
tone?: RsFeedbackTone
|
|
21
|
+
/**
|
|
22
|
+
* 布局。默认 window(工作窗)。
|
|
23
|
+
* confirm 仅作历史兼容;新代码的确认/提示请用 rsConfirm / RsConfirmDialog。
|
|
24
|
+
*/
|
|
25
|
+
layout?: 'window' | 'confirm'
|
|
26
|
+
showOverlay?: boolean
|
|
27
|
+
/** 遮罩不透明度 0–1 */
|
|
28
|
+
overlayOpacity?: number
|
|
29
|
+
/** 遮罩模糊;number 为 px */
|
|
30
|
+
overlayBlur?: number | string
|
|
31
|
+
showClose?: boolean
|
|
32
|
+
closeOnOverlayClick?: boolean
|
|
33
|
+
closeOnEsc?: boolean
|
|
34
|
+
showFooter?: boolean
|
|
35
|
+
showCancel?: boolean
|
|
36
|
+
showConfirm?: boolean
|
|
37
|
+
cancelText?: string
|
|
38
|
+
confirmText?: string
|
|
39
|
+
confirmVariant?: 'primary' | 'danger'
|
|
40
|
+
autoCloseOnConfirm?: boolean
|
|
41
|
+
beforeClose?: RsDialogBeforeClose
|
|
42
|
+
teleportTo?: string | HTMLElement
|
|
43
|
+
/** 默认插槽对应 #body 的渲染函数 */
|
|
44
|
+
body?: () => unknown
|
|
45
|
+
footer?: () => unknown
|
|
46
|
+
onConfirm?: () => void | Promise<void>
|
|
47
|
+
onCancel?: () => void
|
|
48
|
+
onAfterClose?: (reason: RsDialogCloseReason) => void
|
|
49
|
+
/** 命令式挂载时覆盖主题;默认读 document data-rs-theme */
|
|
50
|
+
theme?: RsThemeMode
|
|
51
|
+
/** 命令式挂载时覆盖语言;默认读 document data-rs-locale */
|
|
52
|
+
locale?: RsLocale
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface RsDialogHandle {
|
|
56
|
+
close: (reason?: RsDialogCloseReason) => Promise<boolean>
|
|
57
|
+
destroy: () => void
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** tone 快捷方法:可传完整选项或纯文案(作为 description) */
|
|
61
|
+
export interface RsConfirmApi {
|
|
62
|
+
(options?: RsConfirmOptions): Promise<RsConfirmResult>
|
|
63
|
+
warning: (options?: RsConfirmInput) => Promise<RsConfirmResult>
|
|
64
|
+
danger: (options?: RsConfirmInput) => Promise<RsConfirmResult>
|
|
65
|
+
info: (options?: RsConfirmInput) => Promise<RsConfirmResult>
|
|
66
|
+
success: (options?: RsConfirmInput) => Promise<RsConfirmResult>
|
|
67
|
+
error: (options?: RsConfirmInput) => Promise<RsConfirmResult>
|
|
68
|
+
confirm: (options?: RsConfirmInput) => Promise<RsConfirmResult>
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function readDomTheme(): RsThemeMode {
|
|
72
|
+
if (typeof document === 'undefined') return 'light'
|
|
73
|
+
return document.documentElement.getAttribute('data-rs-theme') === 'dark' ? 'dark' : 'light'
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function readDomLocale(): RsLocale {
|
|
77
|
+
if (typeof document === 'undefined') return defaultLocale
|
|
78
|
+
const value = document.documentElement.getAttribute('data-rs-locale')
|
|
79
|
+
return value === 'en-US' || value === 'zh-CN' ? value : defaultLocale
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function mountHost(
|
|
83
|
+
render: () => unknown,
|
|
84
|
+
config?: { theme?: RsThemeMode; locale?: RsLocale },
|
|
85
|
+
): { app: App; container: HTMLDivElement; destroy: () => void } {
|
|
86
|
+
const container = document.createElement('div')
|
|
87
|
+
document.body.appendChild(container)
|
|
88
|
+
|
|
89
|
+
// themeScope=local:不覆盖主应用的 document 主题;Portal 仍靠页面已有 data-rs-theme。
|
|
90
|
+
// ConfigProvider 负责 provide locale,使命令式实例的 i18n 默认文案正确。
|
|
91
|
+
const theme = config?.theme ?? readDomTheme()
|
|
92
|
+
const locale = config?.locale ?? readDomLocale()
|
|
93
|
+
|
|
94
|
+
const app = createApp({
|
|
95
|
+
setup() {
|
|
96
|
+
return () =>
|
|
97
|
+
h(
|
|
98
|
+
RsConfigProvider,
|
|
99
|
+
{ theme, locale, themeScope: 'local' },
|
|
100
|
+
{ default: () => render() },
|
|
101
|
+
)
|
|
102
|
+
},
|
|
103
|
+
})
|
|
104
|
+
app.mount(container)
|
|
105
|
+
const destroy = () => {
|
|
106
|
+
app.unmount()
|
|
107
|
+
container.remove()
|
|
108
|
+
}
|
|
109
|
+
return { app, container, destroy }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function normalizeConfirmInput(
|
|
113
|
+
options: RsConfirmInput | undefined,
|
|
114
|
+
defaults: Partial<RsConfirmOptions>,
|
|
115
|
+
): RsConfirmOptions {
|
|
116
|
+
if (typeof options === 'string') {
|
|
117
|
+
return { ...defaults, description: options }
|
|
118
|
+
}
|
|
119
|
+
return { ...defaults, ...(options ?? {}) }
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* 命令式确认框(基于 RsConfirmDialog)。
|
|
124
|
+
* resolve(true) 为确认,resolve(false) 为取消/关闭。
|
|
125
|
+
* 若传入 onConfirm 且返回 Promise,确认期间自动 loading,成功后关闭。
|
|
126
|
+
*/
|
|
127
|
+
function rsConfirmCore(options: RsConfirmOptions = {}): Promise<RsConfirmResult> {
|
|
128
|
+
return new Promise((resolve) => {
|
|
129
|
+
const open = ref(true)
|
|
130
|
+
const loading = ref(options.confirmLoading ?? false)
|
|
131
|
+
let settled = false
|
|
132
|
+
let confirmed = false
|
|
133
|
+
const hasAsyncConfirm = typeof options.onConfirm === 'function'
|
|
134
|
+
|
|
135
|
+
const settle = (value: boolean) => {
|
|
136
|
+
if (settled) return
|
|
137
|
+
settled = true
|
|
138
|
+
open.value = false
|
|
139
|
+
if (!value) options.onCancel?.()
|
|
140
|
+
// 等关闭帧后再销毁,避免动画被硬切
|
|
141
|
+
window.setTimeout(() => destroy(), 200)
|
|
142
|
+
resolve(value)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const { destroy } = mountHost(
|
|
146
|
+
() =>
|
|
147
|
+
h(
|
|
148
|
+
RsConfirmDialog,
|
|
149
|
+
{
|
|
150
|
+
open: open.value,
|
|
151
|
+
'onUpdate:open': (value: boolean) => {
|
|
152
|
+
open.value = value
|
|
153
|
+
if (!value) {
|
|
154
|
+
// 等同 tick 内的 confirm/cancel 事件先落定,避免 Action 关闭抢先 resolve(false)
|
|
155
|
+
queueMicrotask(() => settle(confirmed))
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
title: options.title,
|
|
159
|
+
subtitle: options.subtitle,
|
|
160
|
+
description: options.description,
|
|
161
|
+
tone: options.tone,
|
|
162
|
+
icon: options.icon,
|
|
163
|
+
width: options.width,
|
|
164
|
+
confirmText: options.confirmText,
|
|
165
|
+
cancelText: options.cancelText,
|
|
166
|
+
confirmVariant: options.confirmVariant,
|
|
167
|
+
showCancel: options.showCancel,
|
|
168
|
+
confirmLoading: loading.value,
|
|
169
|
+
beforeClose: options.beforeClose,
|
|
170
|
+
// 有异步 onConfirm 时由我们在结束后关闭,避免提前关掉
|
|
171
|
+
autoCloseOnConfirm: !hasAsyncConfirm,
|
|
172
|
+
showOverlay: options.showOverlay ?? true,
|
|
173
|
+
overlayOpacity: options.overlayOpacity,
|
|
174
|
+
overlayBlur: options.overlayBlur,
|
|
175
|
+
teleportTo: options.teleportTo === false ? false : options.teleportTo,
|
|
176
|
+
onConfirm: () => {
|
|
177
|
+
if (!hasAsyncConfirm) {
|
|
178
|
+
confirmed = true
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
loading.value = true
|
|
182
|
+
void Promise.resolve()
|
|
183
|
+
.then(() => options.onConfirm?.())
|
|
184
|
+
.then(() => {
|
|
185
|
+
confirmed = true
|
|
186
|
+
settle(true)
|
|
187
|
+
})
|
|
188
|
+
.catch(() => {
|
|
189
|
+
loading.value = false
|
|
190
|
+
})
|
|
191
|
+
},
|
|
192
|
+
onCancel: () => {
|
|
193
|
+
confirmed = false
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
options.extra
|
|
197
|
+
? {
|
|
198
|
+
extra: () => options.extra?.(),
|
|
199
|
+
}
|
|
200
|
+
: undefined,
|
|
201
|
+
),
|
|
202
|
+
{ theme: options.theme, locale: options.locale },
|
|
203
|
+
)
|
|
204
|
+
})
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* 命令式确认 / 提示 API。
|
|
209
|
+
* - rsConfirm(options) 基础调用
|
|
210
|
+
* - rsConfirm.warning / .danger / .confirm 双按钮确认
|
|
211
|
+
* - rsConfirm.info / .success / .error 默认单按钮提示(showCancel: false)
|
|
212
|
+
*/
|
|
213
|
+
export const rsConfirm: RsConfirmApi = Object.assign(rsConfirmCore, {
|
|
214
|
+
warning: (options?: RsConfirmInput) =>
|
|
215
|
+
rsConfirmCore(
|
|
216
|
+
normalizeConfirmInput(options, {
|
|
217
|
+
tone: 'danger',
|
|
218
|
+
confirmVariant: 'danger',
|
|
219
|
+
showOverlay: true,
|
|
220
|
+
}),
|
|
221
|
+
),
|
|
222
|
+
danger: (options?: RsConfirmInput) =>
|
|
223
|
+
rsConfirmCore(
|
|
224
|
+
normalizeConfirmInput(options, {
|
|
225
|
+
tone: 'danger',
|
|
226
|
+
confirmVariant: 'danger',
|
|
227
|
+
showOverlay: true,
|
|
228
|
+
}),
|
|
229
|
+
),
|
|
230
|
+
info: (options?: RsConfirmInput) =>
|
|
231
|
+
rsConfirmCore(
|
|
232
|
+
normalizeConfirmInput(options, {
|
|
233
|
+
tone: 'info',
|
|
234
|
+
confirmVariant: 'primary',
|
|
235
|
+
showCancel: false,
|
|
236
|
+
showOverlay: true,
|
|
237
|
+
}),
|
|
238
|
+
),
|
|
239
|
+
success: (options?: RsConfirmInput) =>
|
|
240
|
+
rsConfirmCore(
|
|
241
|
+
normalizeConfirmInput(options, {
|
|
242
|
+
tone: 'success',
|
|
243
|
+
confirmVariant: 'primary',
|
|
244
|
+
showCancel: false,
|
|
245
|
+
showOverlay: true,
|
|
246
|
+
}),
|
|
247
|
+
),
|
|
248
|
+
error: (options?: RsConfirmInput) =>
|
|
249
|
+
rsConfirmCore(
|
|
250
|
+
normalizeConfirmInput(options, {
|
|
251
|
+
tone: 'danger',
|
|
252
|
+
confirmVariant: 'danger',
|
|
253
|
+
showCancel: false,
|
|
254
|
+
showOverlay: true,
|
|
255
|
+
}),
|
|
256
|
+
),
|
|
257
|
+
confirm: (options?: RsConfirmInput) =>
|
|
258
|
+
rsConfirmCore(
|
|
259
|
+
normalizeConfirmInput(options, {
|
|
260
|
+
tone: 'warning',
|
|
261
|
+
confirmVariant: 'primary',
|
|
262
|
+
showOverlay: true,
|
|
263
|
+
}),
|
|
264
|
+
),
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* 命令式打开 RsDialog;适合临时表单/说明层。
|
|
269
|
+
* 确认/危险提示请用 rsConfirm,不要传 layout: 'confirm'。
|
|
270
|
+
* 复杂长期状态仍建议声明式使用组件。
|
|
271
|
+
*/
|
|
272
|
+
export function openRsDialog(options: RsDialogOpenOptions = {}): RsDialogHandle {
|
|
273
|
+
const open = ref(true)
|
|
274
|
+
let destroyed = false
|
|
275
|
+
let dialogExpose: { close?: (reason?: RsDialogCloseReason) => Promise<boolean> } | null = null
|
|
276
|
+
const layout = options.layout ?? 'window'
|
|
277
|
+
|
|
278
|
+
if (import.meta.env.DEV && layout === 'confirm') {
|
|
279
|
+
console.warn(
|
|
280
|
+
'[openRsDialog] layout:"confirm" 已弃用。确认/提示请使用 rsConfirm / RsConfirmDialog;本 API 仅用于工作窗/表单。',
|
|
281
|
+
)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const { destroy: unmount } = mountHost(
|
|
285
|
+
() =>
|
|
286
|
+
h(
|
|
287
|
+
RsDialog,
|
|
288
|
+
{
|
|
289
|
+
ref: (instance: unknown) => {
|
|
290
|
+
dialogExpose = instance as typeof dialogExpose
|
|
291
|
+
},
|
|
292
|
+
open: open.value,
|
|
293
|
+
'onUpdate:open': (value: boolean) => {
|
|
294
|
+
open.value = value
|
|
295
|
+
if (!value && !destroyed) {
|
|
296
|
+
window.setTimeout(() => destroy(), 200)
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
title: options.title,
|
|
300
|
+
description:
|
|
301
|
+
[options.subtitle, options.description].filter(Boolean).join('\n\n') ||
|
|
302
|
+
options.description,
|
|
303
|
+
width: options.width ?? 'md',
|
|
304
|
+
tone: options.tone,
|
|
305
|
+
layout,
|
|
306
|
+
resizable: layout === 'window',
|
|
307
|
+
fullscreenable: layout === 'window',
|
|
308
|
+
showOverlay: options.showOverlay ?? true,
|
|
309
|
+
overlayOpacity: options.overlayOpacity,
|
|
310
|
+
overlayBlur: options.overlayBlur,
|
|
311
|
+
showClose: options.showClose,
|
|
312
|
+
closeOnOverlayClick: options.closeOnOverlayClick,
|
|
313
|
+
closeOnEsc: options.closeOnEsc,
|
|
314
|
+
showFooter: options.showFooter ?? true,
|
|
315
|
+
showCancel: options.showCancel,
|
|
316
|
+
showConfirm: options.showConfirm,
|
|
317
|
+
cancelText: options.cancelText,
|
|
318
|
+
confirmText: options.confirmText,
|
|
319
|
+
confirmVariant: options.confirmVariant,
|
|
320
|
+
autoCloseOnConfirm: options.autoCloseOnConfirm ?? true,
|
|
321
|
+
beforeClose: options.beforeClose,
|
|
322
|
+
teleportTo: options.teleportTo,
|
|
323
|
+
deferBodyMount: false,
|
|
324
|
+
onConfirm: () => {
|
|
325
|
+
void options.onConfirm?.()
|
|
326
|
+
},
|
|
327
|
+
onCancel: () => {
|
|
328
|
+
options.onCancel?.()
|
|
329
|
+
},
|
|
330
|
+
onAfterClose: (reason: RsDialogCloseReason) => {
|
|
331
|
+
options.onAfterClose?.(reason)
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
body: options.body,
|
|
336
|
+
footer: options.footer,
|
|
337
|
+
},
|
|
338
|
+
),
|
|
339
|
+
{ theme: options.theme, locale: options.locale },
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
function destroy(): void {
|
|
343
|
+
if (destroyed) return
|
|
344
|
+
destroyed = true
|
|
345
|
+
unmount()
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return {
|
|
349
|
+
async close(reason: RsDialogCloseReason = 'programmatic') {
|
|
350
|
+
if (destroyed) return false
|
|
351
|
+
if (dialogExpose?.close) return dialogExpose.close(reason)
|
|
352
|
+
open.value = false
|
|
353
|
+
return true
|
|
354
|
+
},
|
|
355
|
+
destroy,
|
|
356
|
+
}
|
|
357
|
+
}
|