@done-coding/admin-core 0.9.0 → 0.10.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.
Files changed (58) hide show
  1. package/docs/nested-config-paradigm.md +80 -0
  2. package/es/bridge/theme.mjs +41 -38
  3. package/es/components/app-layout/AppTheme.vue.mjs +2 -2
  4. package/es/components/app-layout/AppTheme.vue2.mjs +19 -19
  5. package/es/components/form/FormItemNestForm.vue.mjs +7 -0
  6. package/es/components/form/FormItemNestForm.vue2.mjs +49 -0
  7. package/es/components/form/FormItemNestFormList.vue.mjs +7 -0
  8. package/es/components/form/FormItemNestFormList.vue2.mjs +137 -0
  9. package/es/components/form/FormMain.vue.mjs +5 -140
  10. package/es/components/form/FormMain.vue2.mjs +160 -2
  11. package/es/components/form/FormSearch.vue.mjs +2 -2
  12. package/es/components/form/FormSearch.vue2.mjs +43 -42
  13. package/es/components/form/FormSubmitPanel.vue2.mjs +21 -20
  14. package/es/components/form/nest-form-item-list.mjs +71 -0
  15. package/es/components/form/nest-form-item.mjs +42 -0
  16. package/es/components/form/nest-registry.mjs +7 -0
  17. package/es/components/form/use-nest-form-list.mjs +22 -0
  18. package/es/components/form/use-nest-form.mjs +34 -0
  19. package/es/components/form/use-nest-layout-scale.mjs +14 -0
  20. package/es/components/form/utils.mjs +77 -61
  21. package/es/components/modal/ConfirmModal.vue.mjs +1 -2
  22. package/es/components/modal/ConfirmModal.vue2.mjs +73 -94
  23. package/es/components/modal/DetailModal.vue.mjs +6 -6
  24. package/es/components/panel/PanelItemNestForm.vue.mjs +7 -0
  25. package/es/components/panel/PanelItemNestForm.vue2.mjs +69 -0
  26. package/es/components/panel/PanelItemNestPanel.vue.mjs +34 -0
  27. package/es/components/panel/PanelItemNestPanel.vue2.mjs +4 -0
  28. package/es/components/panel/PanelMain.vue.mjs +2 -2
  29. package/es/components/panel/PanelMain.vue2.mjs +52 -45
  30. package/es/components/panel/nest-panel-form.mjs +53 -0
  31. package/es/components/panel/nest-panel-item.mjs +25 -0
  32. package/es/index.mjs +182 -153
  33. package/es/inject/key.mjs +12 -6
  34. package/es/style.css +1 -1
  35. package/package.json +2 -2
  36. package/types/bridge/index.d.ts +3 -3
  37. package/types/bridge/theme.d.ts +22 -3
  38. package/types/components/form/FormItemNestForm.vue.d.ts +36 -0
  39. package/types/components/form/FormItemNestFormList.vue.d.ts +63 -0
  40. package/types/components/form/FormMain.vue.d.ts +2 -2
  41. package/types/components/form/FormSearch.vue.d.ts +2 -2
  42. package/types/components/form/index.d.ts +9 -1
  43. package/types/components/form/nest-form-item-list.d.ts +63 -0
  44. package/types/components/form/nest-form-item.d.ts +36 -0
  45. package/types/components/form/nest-registry.d.ts +22 -0
  46. package/types/components/form/types.d.ts +2 -0
  47. package/types/components/form/use-nest-form-list.d.ts +20 -0
  48. package/types/components/form/use-nest-form.d.ts +26 -0
  49. package/types/components/form/use-nest-layout-scale.d.ts +17 -0
  50. package/types/components/form/utils.d.ts +26 -1
  51. package/types/components/panel/PanelItemNestForm.vue.d.ts +35 -0
  52. package/types/components/panel/PanelItemNestPanel.vue.d.ts +22 -0
  53. package/types/components/panel/index.d.ts +5 -1
  54. package/types/components/panel/nest-panel-form.d.ts +38 -0
  55. package/types/components/panel/nest-panel-item.d.ts +28 -0
  56. package/types/components/panel/types.d.ts +2 -0
  57. package/types/components/table/TableMain.vue.d.ts +2 -2
  58. package/types/inject/key.d.ts +28 -1
package/es/style.css CHANGED
@@ -1 +1 @@
1
- .confirm-dialog .content[data-v-0e89245a]{overflow-x:hidden;overflow-y:auto;max-height:calc(100vh - 200px)}.confirm-dialog .btn[data-v-0e89245a]{width:150px;height:40px;border-radius:4px}.confirm-dialog .main[data-v-0e89245a]{position:relative;text-align:center}.confirm-dialog .main .close-box[data-v-0e89245a]{position:absolute;top:0;right:0;cursor:pointer;z-index:2}.confirm-dialog .main .shim[data-v-0e89245a]{position:relative;z-index:1}.confirm-dialog .main .shim .title[data-v-0e89245a]{font-size:18px;font-weight:500}.confirm-dialog .main .shim .content[data-v-0e89245a]{font-size:16px;margin-top:15px}.confirm-dialog .main .shim .footer[data-v-0e89245a]{display:flex;justify-content:center;align-items:center;padding-top:5px}.confirm-dialog .main .shim .footer>.btn[data-v-0e89245a]:not(:last-child){margin-right:30px}.confirm-dialog .main .shim .footer[reverse=true][data-v-0e89245a]{flex-direction:row-reverse}.confirm-dialog .main .shim .footer[reverse=true]>.btn[data-v-0e89245a]:not(:last-child){margin-right:0;margin-left:30px}.confirm-dialog .el-dialog__header,.confirm-dialog .el-dialog__body{padding:0;background-color:transparent}.action-confirm__title[data-v-88119b35]{font-weight:600;margin-bottom:6px}.action-confirm__content[data-v-88119b35]{margin-bottom:12px;color:var(--el-text-color-regular)}.action-confirm__actions[data-v-88119b35]{display:flex;justify-content:flex-end;gap:8px}.form-item-tip[data-v-8b508d64]{text-align:left;line-height:1.5;font-size:12px}.form-item-label-hide[data-v-8b508d64] .el-form-item__label-wrap{display:none}.form-submit-panel[data-v-93bc9096]{display:flex;flex-direction:column}.form-submit-panel .form-submit-panel-form[data-v-93bc9096]{order:1}.form-submit-panel .form-submit-panel-operation[data-v-93bc9096]{order:2}.form-submit-panel .form-submit-panel-operation-inner[data-v-93bc9096]{display:flex;align-items:center;gap:8px;padding:10px 12px}.form-submit-panel .el-affix--fixed .form-submit-panel-operation-inner[data-v-93bc9096]{background-color:var(--admin-core-body-color)}.form-submit-panel_bottom-center .form-submit-panel-operation-inner[data-v-93bc9096],.form-submit-panel_bottom-right .form-submit-panel-operation-inner[data-v-93bc9096]{border-top:1px solid var(--el-border-color-light);border-bottom-left-radius:var(--admin-core-radius, var(--el-border-radius-base));border-bottom-right-radius:var(--admin-core-radius, var(--el-border-radius-base))}.form-submit-panel_bottom-center .form-submit-panel-operation-inner[data-v-93bc9096]{justify-content:center}.form-submit-panel_bottom-right .form-submit-panel-operation-inner[data-v-93bc9096]{justify-content:flex-end}.form-submit-panel_top-right .form-submit-panel-operation[data-v-93bc9096]{order:0}.form-submit-panel_top-right .form-submit-panel-operation-inner[data-v-93bc9096]{justify-content:flex-end;border-bottom:1px solid var(--el-border-color-light);border-top-left-radius:var(--admin-core-radius, var(--el-border-radius-base));border-top-right-radius:var(--admin-core-radius, var(--el-border-radius-base))}.form-submit-panel_no-divider .form-submit-panel-operation-inner[data-v-93bc9096]{border:none;border-radius:0}.form-submit-panel_bare .form-submit-panel-operation-inner[data-v-93bc9096]{padding:0}.panel-edit-switch[data-v-65f056ab]{position:relative}.panel-edit-switch:hover .panel-edit-switch-edit-btn[data-v-65f056ab]{display:block}.panel-edit-switch-edit-btn[data-v-65f056ab]{position:absolute;top:0;right:0;z-index:1;display:none}.panel-edit-switch-actions[data-v-65f056ab]{display:flex;justify-content:flex-end;gap:8px;margin-top:8px}.form-search_show[data-v-72f1475d]{margin-bottom:10px}.form-search .btn-box[data-v-72f1475d]{display:flex;align-items:center;gap:8px;justify-content:flex-end}.form-search .btn-box-expand-icon[data-v-72f1475d]{margin-right:2px}.form-search[data-v-72f1475d] .el-col{padding-left:14px}.form-verify-image[data-v-669b7ad9] .el-input__suffix-inner *{margin:0}.form-verify-image-suffix[data-v-669b7ad9]{position:absolute;height:100%;border-radius:var(--el-input-border-radius, var(--admin-core-radius, var(--el-border-radius-base)));top:50%;transform:translateY(-50%);overflow:hidden;cursor:pointer}.form-verify-image-suffix-main[data-v-669b7ad9]{position:absolute;left:0;top:0;width:100%;height:100%;background-color:#f4f4f4}.tabs-main-bar[data-v-3faa57f5]{position:relative;display:flex;align-items:center}.tabs-main-bar-item[data-v-3faa57f5]{border:none;background:transparent;cursor:pointer;color:var(--el-text-color-regular);transition:background .2s,color .2s,box-shadow .2s}.tabs-main-bar-indicator[data-v-3faa57f5]{position:absolute;left:0;background:var(--admin-core-primary-color);transition:transform .2s,width .2s}.tabs-main-bar--l1 .tabs-main-bar-item[data-v-3faa57f5]{font-size:16px}.tabs-main-bar--l2 .tabs-main-bar-item[data-v-3faa57f5]{font-size:14px}.tabs-main-bar--l3 .tabs-main-bar-item[data-v-3faa57f5],.tabs-main-bar--l4 .tabs-main-bar-item[data-v-3faa57f5]{font-size:12px}.tabs-main-bar--variant-card[data-v-3faa57f5]{position:relative;overflow:hidden;gap:2px}.tabs-main-bar--variant-card .tabs-main-bar-item[data-v-3faa57f5]{position:relative;padding:8px 20px;line-height:1.4;border:1px solid transparent;border-bottom:0;border-radius:6px 6px 0 0}.tabs-main-bar--variant-card .tabs-main-bar-item[data-v-3faa57f5]:hover:not(.tabs-main-bar-item_active){color:var(--admin-core-primary-color)}.tabs-main-bar--variant-card .tabs-main-bar-item_active[data-v-3faa57f5]{color:var(--admin-core-primary-color);border-color:var(--el-border-color-light)}.tabs-main-bar--variant-card .tabs-main-bar-item_active[data-v-3faa57f5]:before,.tabs-main-bar--variant-card .tabs-main-bar-item_active[data-v-3faa57f5]:after{content:"";position:absolute;bottom:0;width:100vw;height:1px;background:var(--el-border-color-light)}.tabs-main-bar--variant-card .tabs-main-bar-item_active[data-v-3faa57f5]:before{right:100%}.tabs-main-bar--variant-card .tabs-main-bar-item_active[data-v-3faa57f5]:after{left:100%}.tabs-main-bar--variant-indicator .tabs-main-bar-item[data-v-3faa57f5]{padding:8px 16px}.tabs-main-bar--variant-indicator .tabs-main-bar-item_active[data-v-3faa57f5]{color:var(--admin-core-primary-color)}.tabs-main-bar--variant-indicator .tabs-main-bar-indicator[data-v-3faa57f5]{bottom:0;height:2px}.tabs-main-bar--variant-indicator-compact .tabs-main-bar-item[data-v-3faa57f5]{padding:6px 10px}.tabs-main-bar--variant-indicator-compact .tabs-main-bar-item_active[data-v-3faa57f5]{color:var(--admin-core-primary-color)}.tabs-main-bar--variant-indicator-compact .tabs-main-bar-indicator[data-v-3faa57f5]{bottom:0;height:1px}.tabs-main-bar--variant-plain .tabs-main-bar-item[data-v-3faa57f5]{padding:4px 8px}.tabs-main-bar--variant-plain .tabs-main-bar-item_active[data-v-3faa57f5]{color:var(--admin-core-primary-color);font-weight:600}.app-breadcrumb[data-v-9bbe0b05]{display:flex;align-items:center;justify-content:flex-start}.app-body[data-v-ae442089]{transition-duration:.3s;transition-property:padding;transition-timing-function:linear;min-height:100vh}.app-body-shim[data-v-ae442089]{width:100%;--app-viewport-max-height: var(--ae6fc168)}.app-footer[data-v-bba5d0e4]{transition-duration:.3s;transition-property:height;transition-timing-function:linear;overflow:hidden;width:100%;box-shadow:-5px 0 5px #0000001a}.app-footer-shim[data-v-bba5d0e4]{width:100%;height:100%;padding:0 20px}.app-theme[data-v-2607ca39]{display:inline-flex;align-items:center;gap:12px;margin-right:12px}.app-theme__style-select[data-v-2607ca39]{width:120px}.app-header[data-v-b47543cd]{transition-duration:.3s;transition-property:height;transition-timing-function:linear;overflow:hidden;position:fixed;left:var(--ae6f6fe0);top:var(--v4782742c);right:var(--v70971b33);box-shadow:5px 0 5px #0000001a;z-index:1}.app-header-module[data-v-b47543cd]{display:flex;flex:1;height:100%;overflow-x:auto}.app-header-module-item[data-v-b47543cd]{display:flex;justify-content:center;align-items:center;padding:0 20px;white-space:nowrap;height:100%;color:var(--fcf1a792)}.app-header-module-item[data-v-b47543cd]:hover,.app-header-module-item_active[data-v-b47543cd]{color:var(--d3910988)}.app-header-module-item_active[data-v-b47543cd]{position:relative}.app-header-module-item_active[data-v-b47543cd]:before{content:"";position:absolute;left:50%;top:0;width:100%;height:3px;background-color:var(--d3910988);transform:translate(-50%)}.app-header-shim[data-v-b47543cd]{width:100%;height:100%;display:flex;align-items:center;justify-content:space-between;padding:0 20px;font-size:18px;font-weight:700}.app-header-module-item__icon[data-v-b47543cd]{margin-right:8px}.app-header-userInfo[data-v-b47543cd]{padding-left:80px}.app-sidebar[data-v-2499f12e]{transition-duration:.3s;transition-property:width;transition-timing-function:linear;position:fixed;left:var(--f2149ac0);top:var(--v6fb5779c);bottom:var(--e0532af8);box-shadow:0 5px 5px #0000001a;overflow:visible;z-index:var(--v36eef49e)}.app-sidebar-top[data-v-2499f12e]{position:absolute;left:0;right:0;top:0;overflow:hidden}.app-sidebar-bottom[data-v-2499f12e]{position:absolute;left:0;right:0;bottom:0;overflow:hidden}.app-sidebar-shim[data-v-2499f12e]{position:absolute;left:0;right:0;top:var(--v7a209d86);bottom:var(--v0a70f74c);overflow-x:hidden;overflow-y:auto;--el-menu-border-color: transparent;-webkit-user-select:none;user-select:none}.app-sidebar-toggle[data-v-2499f12e]{position:absolute;left:100%;top:50%;transform:translate(-50%,-50%);cursor:pointer;width:22px;height:22px;border-radius:50%;background-color:var(--v1ffafb76);color:var(--v738d1dcc);border:1px solid var(--v738d1dcc);box-shadow:0 1px 2px #0000000f;display:flex;align-items:center;justify-content:center;font-size:12px;z-index:1;isolation:isolate;transition:color .3s,border-color .3s,box-shadow .3s}.app-sidebar-toggle[data-v-2499f12e]:before{content:"";position:absolute;top:-3px;right:-3px;bottom:-3px;left:-3px;border-radius:50%;background-color:var(--v738d1dcc);opacity:.18;z-index:-1;pointer-events:none;transition:opacity .3s,inset .3s}.app-sidebar-toggle[data-v-2499f12e]:active,.app-sidebar-toggle[data-v-2499f12e]:focus,.app-sidebar-toggle[data-v-2499f12e]:hover{box-shadow:0 2px 6px #0000001f}.app-sidebar-toggle[data-v-2499f12e]:active:before,.app-sidebar-toggle[data-v-2499f12e]:focus:before,.app-sidebar-toggle[data-v-2499f12e]:hover:before{opacity:.32;top:-5px;right:-5px;bottom:-5px;left:-5px}.app-sidebar-toggle-icon[data-v-2499f12e]{transition:transform .3s}.app-layout[data-v-7aeee1b9]{position:relative}.app-layout_noLogin[data-v-7aeee1b9] .app-body,.app-layout_noLogin[data-v-7aeee1b9] .app-sidebar,.app-layout_noLogin[data-v-7aeee1b9] .app-header,.app-layout_noLogin[data-v-7aeee1b9] .app-footer{transition:none!important}.app-page-shim[data-v-fda19616]{--app-viewport-max-height: var(--v54888f0e)}[data-v-64f355fe] .auto-refresh-label{display:flex;font-size:13px;color:var(--el-text-color-regular);margin-bottom:8px}.auto-refresh-group-icon--rotating[data-v-e608ff06]{animation:auto-refresh-rotating-e608ff06 1s linear infinite}@keyframes auto-refresh-rotating-e608ff06{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.table-toolbar[data-v-6f2937e1]{display:flex;justify-content:space-between;align-items:center;padding-bottom:8px;gap:20px}.table-toolbar-left[data-v-6f2937e1],.table-toolbar-right[data-v-6f2937e1]{display:flex;align-items:center;gap:10px}.table-toolbar-switch-view[data-v-6f2937e1]{--el-switch-off-color: var(--admin-core-primary-color);--el-switch-on-color: var(--admin-core-warning-color)}.data-list-view[data-v-708af83f]{width:100%}.data-list-view-empty[data-v-708af83f]{display:flex;justify-content:center;align-items:center;width:100%;min-height:60px}.table-main-pagination[data-v-132febbc]{margin-top:10px;display:flex;justify-content:flex-end}.list-page[data-v-fc41e3d4]{min-height:var(--c6e708aa)}.list-page-header[data-v-fc41e3d4],.list-page-operation[data-v-fc41e3d4]{margin-bottom:10px}.list-page[data-v-fc41e3d4] .el-loading-mask{left:-10px;top:-10px;right:-10px;bottom:-10px}.panel-main-item-col:not(:last-of-type) .panel-main-item-col-wrap_card[data-v-5cf5e2e7]{margin-bottom:var(--v5f184251)}
1
+ .confirm-modal[data-v-26598cb2] .el-dialog__header{margin-right:0;padding:16px 20px;border-bottom:1px solid var(--el-border-color-lighter)}.confirm-modal__title[data-v-26598cb2]{font-size:16px;font-weight:600;line-height:24px;color:var(--el-text-color-primary);text-align:left}.confirm-modal[data-v-26598cb2] .el-dialog__body{padding:20px}.confirm-modal__content[data-v-26598cb2]{overflow-x:hidden;overflow-y:auto;max-height:calc(100vh - 200px);font-size:14px;line-height:22px;color:var(--el-text-color-regular);text-align:left;word-break:break-word}.confirm-modal[data-v-26598cb2] .el-dialog__footer{padding:12px 20px;border-top:1px solid var(--el-border-color-lighter)}.confirm-modal__footer[data-v-26598cb2]{display:flex;justify-content:flex-end;align-items:center;gap:8px}.confirm-modal__footer[data-v-26598cb2] .el-button{min-width:72px}.confirm-modal__footer[reverse=true][data-v-26598cb2]{flex-direction:row-reverse}.action-confirm__title[data-v-88119b35]{font-weight:600;margin-bottom:6px}.action-confirm__content[data-v-88119b35]{margin-bottom:12px;color:var(--el-text-color-regular)}.action-confirm__actions[data-v-88119b35]{display:flex;justify-content:flex-end;gap:8px}.form-item-tip[data-v-8b508d64]{text-align:left;line-height:1.5;font-size:12px}.form-item-label-hide[data-v-8b508d64] .el-form-item__label-wrap{display:none}[data-v-8ad14c45] .el-row>.el-col>.el-form-item{margin-bottom:18px}.form-submit-panel[data-v-93bc9096]{display:flex;flex-direction:column}.form-submit-panel .form-submit-panel-form[data-v-93bc9096]{order:1}.form-submit-panel .form-submit-panel-operation[data-v-93bc9096]{order:2}.form-submit-panel .form-submit-panel-operation-inner[data-v-93bc9096]{display:flex;align-items:center;gap:8px;padding:10px 12px}.form-submit-panel .el-affix--fixed .form-submit-panel-operation-inner[data-v-93bc9096]{background-color:var(--admin-core-body-color)}.form-submit-panel_bottom-center .form-submit-panel-operation-inner[data-v-93bc9096],.form-submit-panel_bottom-right .form-submit-panel-operation-inner[data-v-93bc9096]{border-top:1px solid var(--el-border-color-light);border-bottom-left-radius:var(--admin-core-radius, var(--el-border-radius-base));border-bottom-right-radius:var(--admin-core-radius, var(--el-border-radius-base))}.form-submit-panel_bottom-center .form-submit-panel-operation-inner[data-v-93bc9096]{justify-content:center}.form-submit-panel_bottom-right .form-submit-panel-operation-inner[data-v-93bc9096]{justify-content:flex-end}.form-submit-panel_top-right .form-submit-panel-operation[data-v-93bc9096]{order:0}.form-submit-panel_top-right .form-submit-panel-operation-inner[data-v-93bc9096]{justify-content:flex-end;border-bottom:1px solid var(--el-border-color-light);border-top-left-radius:var(--admin-core-radius, var(--el-border-radius-base));border-top-right-radius:var(--admin-core-radius, var(--el-border-radius-base))}.form-submit-panel_no-divider .form-submit-panel-operation-inner[data-v-93bc9096]{border:none;border-radius:0}.form-submit-panel_bare .form-submit-panel-operation-inner[data-v-93bc9096]{padding:0}.panel-edit-switch[data-v-65f056ab]{position:relative}.panel-edit-switch:hover .panel-edit-switch-edit-btn[data-v-65f056ab]{display:block}.panel-edit-switch-edit-btn[data-v-65f056ab]{position:absolute;top:0;right:0;z-index:1;display:none}.panel-edit-switch-actions[data-v-65f056ab]{display:flex;justify-content:flex-end;gap:8px;margin-top:8px}.panel-main-item-col:not(:last-of-type) .panel-main-item-col-wrap_card[data-v-9c14b584]{margin-bottom:var(--v5b714e11)}.form-search_show[data-v-9a9f48af]{margin-bottom:10px}.form-search .btn-box[data-v-9a9f48af]{display:flex;align-items:center;gap:8px;justify-content:flex-end}.form-search .btn-box-expand-icon[data-v-9a9f48af]{margin-right:2px}.form-verify-image[data-v-669b7ad9] .el-input__suffix-inner *{margin:0}.form-verify-image-suffix[data-v-669b7ad9]{position:absolute;height:100%;border-radius:var(--el-input-border-radius, var(--admin-core-radius, var(--el-border-radius-base)));top:50%;transform:translateY(-50%);overflow:hidden;cursor:pointer}.form-verify-image-suffix-main[data-v-669b7ad9]{position:absolute;left:0;top:0;width:100%;height:100%;background-color:#f4f4f4}.tabs-main-bar[data-v-3faa57f5]{position:relative;display:flex;align-items:center}.tabs-main-bar-item[data-v-3faa57f5]{border:none;background:transparent;cursor:pointer;color:var(--el-text-color-regular);transition:background .2s,color .2s,box-shadow .2s}.tabs-main-bar-indicator[data-v-3faa57f5]{position:absolute;left:0;background:var(--admin-core-primary-color);transition:transform .2s,width .2s}.tabs-main-bar--l1 .tabs-main-bar-item[data-v-3faa57f5]{font-size:16px}.tabs-main-bar--l2 .tabs-main-bar-item[data-v-3faa57f5]{font-size:14px}.tabs-main-bar--l3 .tabs-main-bar-item[data-v-3faa57f5],.tabs-main-bar--l4 .tabs-main-bar-item[data-v-3faa57f5]{font-size:12px}.tabs-main-bar--variant-card[data-v-3faa57f5]{position:relative;overflow:hidden;gap:2px}.tabs-main-bar--variant-card .tabs-main-bar-item[data-v-3faa57f5]{position:relative;padding:8px 20px;line-height:1.4;border:1px solid transparent;border-bottom:0;border-radius:6px 6px 0 0}.tabs-main-bar--variant-card .tabs-main-bar-item[data-v-3faa57f5]:hover:not(.tabs-main-bar-item_active){color:var(--admin-core-primary-color)}.tabs-main-bar--variant-card .tabs-main-bar-item_active[data-v-3faa57f5]{color:var(--admin-core-primary-color);border-color:var(--el-border-color-light)}.tabs-main-bar--variant-card .tabs-main-bar-item_active[data-v-3faa57f5]:before,.tabs-main-bar--variant-card .tabs-main-bar-item_active[data-v-3faa57f5]:after{content:"";position:absolute;bottom:0;width:100vw;height:1px;background:var(--el-border-color-light)}.tabs-main-bar--variant-card .tabs-main-bar-item_active[data-v-3faa57f5]:before{right:100%}.tabs-main-bar--variant-card .tabs-main-bar-item_active[data-v-3faa57f5]:after{left:100%}.tabs-main-bar--variant-indicator .tabs-main-bar-item[data-v-3faa57f5]{padding:8px 16px}.tabs-main-bar--variant-indicator .tabs-main-bar-item_active[data-v-3faa57f5]{color:var(--admin-core-primary-color)}.tabs-main-bar--variant-indicator .tabs-main-bar-indicator[data-v-3faa57f5]{bottom:0;height:2px}.tabs-main-bar--variant-indicator-compact .tabs-main-bar-item[data-v-3faa57f5]{padding:6px 10px}.tabs-main-bar--variant-indicator-compact .tabs-main-bar-item_active[data-v-3faa57f5]{color:var(--admin-core-primary-color)}.tabs-main-bar--variant-indicator-compact .tabs-main-bar-indicator[data-v-3faa57f5]{bottom:0;height:1px}.tabs-main-bar--variant-plain .tabs-main-bar-item[data-v-3faa57f5]{padding:4px 8px}.tabs-main-bar--variant-plain .tabs-main-bar-item_active[data-v-3faa57f5]{color:var(--admin-core-primary-color);font-weight:600}.app-breadcrumb[data-v-9bbe0b05]{display:flex;align-items:center;justify-content:flex-start}.app-body[data-v-ae442089]{transition-duration:.3s;transition-property:padding;transition-timing-function:linear;min-height:100vh}.app-body-shim[data-v-ae442089]{width:100%;--app-viewport-max-height: var(--ae6fc168)}.app-footer[data-v-bba5d0e4]{transition-duration:.3s;transition-property:height;transition-timing-function:linear;overflow:hidden;width:100%;box-shadow:-5px 0 5px #0000001a}.app-footer-shim[data-v-bba5d0e4]{width:100%;height:100%;padding:0 20px}.app-theme[data-v-1f068b22]{display:inline-flex;align-items:center;gap:12px;margin-right:12px}.app-theme__style-select[data-v-1f068b22]{width:120px}.app-header[data-v-b47543cd]{transition-duration:.3s;transition-property:height;transition-timing-function:linear;overflow:hidden;position:fixed;left:var(--ae6f6fe0);top:var(--v4782742c);right:var(--v70971b33);box-shadow:5px 0 5px #0000001a;z-index:1}.app-header-module[data-v-b47543cd]{display:flex;flex:1;height:100%;overflow-x:auto}.app-header-module-item[data-v-b47543cd]{display:flex;justify-content:center;align-items:center;padding:0 20px;white-space:nowrap;height:100%;color:var(--fcf1a792)}.app-header-module-item[data-v-b47543cd]:hover,.app-header-module-item_active[data-v-b47543cd]{color:var(--d3910988)}.app-header-module-item_active[data-v-b47543cd]{position:relative}.app-header-module-item_active[data-v-b47543cd]:before{content:"";position:absolute;left:50%;top:0;width:100%;height:3px;background-color:var(--d3910988);transform:translate(-50%)}.app-header-shim[data-v-b47543cd]{width:100%;height:100%;display:flex;align-items:center;justify-content:space-between;padding:0 20px;font-size:18px;font-weight:700}.app-header-module-item__icon[data-v-b47543cd]{margin-right:8px}.app-header-userInfo[data-v-b47543cd]{padding-left:80px}.app-sidebar[data-v-2499f12e]{transition-duration:.3s;transition-property:width;transition-timing-function:linear;position:fixed;left:var(--f2149ac0);top:var(--v6fb5779c);bottom:var(--e0532af8);box-shadow:0 5px 5px #0000001a;overflow:visible;z-index:var(--v36eef49e)}.app-sidebar-top[data-v-2499f12e]{position:absolute;left:0;right:0;top:0;overflow:hidden}.app-sidebar-bottom[data-v-2499f12e]{position:absolute;left:0;right:0;bottom:0;overflow:hidden}.app-sidebar-shim[data-v-2499f12e]{position:absolute;left:0;right:0;top:var(--v7a209d86);bottom:var(--v0a70f74c);overflow-x:hidden;overflow-y:auto;--el-menu-border-color: transparent;-webkit-user-select:none;user-select:none}.app-sidebar-toggle[data-v-2499f12e]{position:absolute;left:100%;top:50%;transform:translate(-50%,-50%);cursor:pointer;width:22px;height:22px;border-radius:50%;background-color:var(--v1ffafb76);color:var(--v738d1dcc);border:1px solid var(--v738d1dcc);box-shadow:0 1px 2px #0000000f;display:flex;align-items:center;justify-content:center;font-size:12px;z-index:1;isolation:isolate;transition:color .3s,border-color .3s,box-shadow .3s}.app-sidebar-toggle[data-v-2499f12e]:before{content:"";position:absolute;top:-3px;right:-3px;bottom:-3px;left:-3px;border-radius:50%;background-color:var(--v738d1dcc);opacity:.18;z-index:-1;pointer-events:none;transition:opacity .3s,inset .3s}.app-sidebar-toggle[data-v-2499f12e]:active,.app-sidebar-toggle[data-v-2499f12e]:focus,.app-sidebar-toggle[data-v-2499f12e]:hover{box-shadow:0 2px 6px #0000001f}.app-sidebar-toggle[data-v-2499f12e]:active:before,.app-sidebar-toggle[data-v-2499f12e]:focus:before,.app-sidebar-toggle[data-v-2499f12e]:hover:before{opacity:.32;top:-5px;right:-5px;bottom:-5px;left:-5px}.app-sidebar-toggle-icon[data-v-2499f12e]{transition:transform .3s}.app-layout[data-v-7aeee1b9]{position:relative}.app-layout_noLogin[data-v-7aeee1b9] .app-body,.app-layout_noLogin[data-v-7aeee1b9] .app-sidebar,.app-layout_noLogin[data-v-7aeee1b9] .app-header,.app-layout_noLogin[data-v-7aeee1b9] .app-footer{transition:none!important}.app-page-shim[data-v-fda19616]{--app-viewport-max-height: var(--v54888f0e)}[data-v-64f355fe] .auto-refresh-label{display:flex;font-size:13px;color:var(--el-text-color-regular);margin-bottom:8px}.auto-refresh-group-icon--rotating[data-v-e608ff06]{animation:auto-refresh-rotating-e608ff06 1s linear infinite}@keyframes auto-refresh-rotating-e608ff06{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.form-item-nest-form[data-v-9c251e76],.form-item-nest-form-list[data-v-f424fc36]{padding:16px;border:1px solid var(--admin-core-border-color);border-radius:8px;box-shadow:var(--admin-core-shadow)}.form-item-nest-form-list-row[data-v-f424fc36]{display:flex;align-items:flex-start;gap:8px;margin-bottom:12px}.form-item-nest-form-list-row-body[data-v-f424fc36]{flex:1;min-width:0;padding:12px 16px;border:1px solid var(--el-border-color-lighter);border-radius:6px;box-shadow:var(--el-box-shadow-lighter)}.table-toolbar[data-v-6f2937e1]{display:flex;justify-content:space-between;align-items:center;padding-bottom:8px;gap:20px}.table-toolbar-left[data-v-6f2937e1],.table-toolbar-right[data-v-6f2937e1]{display:flex;align-items:center;gap:10px}.table-toolbar-switch-view[data-v-6f2937e1]{--el-switch-off-color: var(--admin-core-primary-color);--el-switch-on-color: var(--admin-core-warning-color)}.data-list-view[data-v-708af83f]{width:100%}.data-list-view-empty[data-v-708af83f]{display:flex;justify-content:center;align-items:center;width:100%;min-height:60px}.table-main-pagination[data-v-132febbc]{margin-top:10px;display:flex;justify-content:flex-end}.list-page[data-v-fc41e3d4]{min-height:var(--c6e708aa)}.list-page-header[data-v-fc41e3d4],.list-page-operation[data-v-fc41e3d4]{margin-bottom:10px}.list-page[data-v-fc41e3d4] .el-loading-mask{left:-10px;top:-10px;right:-10px;bottom:-10px}.panel-item-nest-form-actions[data-v-3af1d77a]{display:flex;justify-content:flex-end;gap:8px;margin-top:8px}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@done-coding/admin-core",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "后台管理核心",
5
5
  "private": false,
6
6
  "main": "lib/index.cjs",
@@ -79,5 +79,5 @@
79
79
  "node": ">=18.0.0",
80
80
  "pnpm": ">=9.0.0"
81
81
  },
82
- "gitHead": "13c617a9392202dffa804eff704fbd2919bd097f"
82
+ "gitHead": "a178e085b87b9c2fd6ddbbea5065bf2a338c9931"
83
83
  }
@@ -442,9 +442,9 @@ export interface AdminBridge<UserInfo = unknown, LoginParams = unknown> {
442
442
  /**
443
443
  * 主题模块(架构反转:core/bridge 主导主题切换)。
444
444
  *
445
- * `theme.{add,remove,setStyle,setDark,list}`——风格 map 注册/注销 + 切换。
446
- * 插件 install 经 `bridge.theme.add(name, config)` 注册风格;切换真相在 bridge,
447
- * appStore / AppTheme.vue 转发 `setStyle` / `setDark`([MUST NOT] bridge 反向监测 store)。
445
+ * `theme.{add,remove,setStyle,setDark,list,labelOf}`——风格 map 注册/注销 + 切换 + 展示名。
446
+ * 插件 install 经 `bridge.theme.add(name, preset)` 注册风格(preset = {config,label?});切换真相在
447
+ * bridge,appStore / AppTheme.vue 转发 `setStyle` / `setDark`([MUST NOT] bridge 反向监测 store)。
448
448
  */
449
449
  readonly theme: AdminThemeModule;
450
450
  /** 当前风格名(响应式只读真相源;[MUST NOT] 解构/快照取值,⚠️ 切换后定格) */
@@ -12,16 +12,33 @@ import { AppThemeConfig, StorageLike } from './index';
12
12
  * 灌进 bridge 响应式 APP_THEME_CONFIG(故 init 后响应式 APP_THEME_CONFIG 随切换变,
13
13
  * 不再恒等于初始值);用注入的 `storage` 持久化 `{themeStyle,themeIsDark}` 并 init 恢复。
14
14
  */
15
+ /**
16
+ * 主题注册项(`bridge.theme.add` 第 2 参)——core 侧主题「preset」结构。
17
+ *
18
+ * core 不依赖 plugin,故自定义此最小注册形;plugin-theme 的 `AdminThemePreset`
19
+ * (含 id/label/description/config)是其结构超集,可整坨直接透传:
20
+ * `bridge.theme.add(preset.id, preset)`(多出的 id/description 作 excess 字段被忽略)。
21
+ */
22
+ export interface AdminThemeEntry {
23
+ /**
24
+ * 风格色值(light/dark 两套 `AppThemeColor`)。
25
+ *
26
+ * 内部做浅快照(`{light:{...},dark:{...}}`)——与调用方对象解耦,且与 bridge
27
+ * 响应式 APP_THEME_CONFIG 的 proxy target 解耦(避免切走后反写注册值)。
28
+ */
29
+ config: AppThemeConfig;
30
+ /** 展示名(供 `AppTheme.vue` 下拉显示,如中文「柔光悬浮」);缺省回退注册 name 自身。 */
31
+ label?: string;
32
+ }
15
33
  /** 主题模块对外能力。 */
16
34
  export interface AdminThemeModule {
17
35
  /**
18
36
  * 注册/覆盖一个风格(插件 install 经 `bridge.theme.add` 调;同名覆盖)。
19
37
  *
20
- * config 内部做浅快照(`{light:{...},dark:{...}}`)——与调用方对象解耦,且与 bridge
21
- * 响应式 APP_THEME_CONFIG 的 proxy target 解耦(避免切走后反写注册值)。
38
+ * 2 参收 {@link AdminThemeEntry}(`{config,label?}`);config 内部浅快照解耦。
22
39
  * 若新注册 name 命中持久化恢复的目标风格(init 时尚未注册),自动 `setStyle(name)`。
23
40
  */
24
- add: (name: string, config: AppThemeConfig) => void;
41
+ add: (name: string, preset: AdminThemeEntry) => void;
25
42
  /** 注销一个风格(`'default'` 不可注销;注销当前风格则回退 `'default'`)。 */
26
43
  remove: (name: string) => void;
27
44
  /** 切换风格(未注册回退 `'default'`):同步 APP_THEME_CONFIG + 持久化。 */
@@ -30,6 +47,8 @@ export interface AdminThemeModule {
30
47
  setDark: (isDark: boolean) => void;
31
48
  /** 响应式风格名列表(只读,供 `AppTheme.vue` 下拉;`length>1` 才显示选择)。 */
32
49
  list: DeepReadonly<Ref<string[]>>;
50
+ /** 取风格展示名(`add` 注册的 label;缺省回退 name 自身)。 */
51
+ labelOf: (name: string) => string;
33
52
  }
34
53
  /** 主题 hook 对外契约:模块 + 两个顶层响应式只读真相源。 */
35
54
  export interface BridgeThemeHook {
@@ -0,0 +1,36 @@
1
+ import { FormItemConfigList } from './types';
2
+ import { ColProps } from 'element-plus';
3
+ type __VLS_Props = {
4
+ /** 所属父 item key(注册到父 FormMain exposeMap 的索引) */
5
+ nestKey: string;
6
+ /** 子表单配置列表 */
7
+ list: FormItemConfigList;
8
+ layout?: Partial<ColProps>;
9
+ rowGutter?: number;
10
+ /** 联结组件外环阴影颜色;缺省走 CSS 变量主题自适配(亮/暗),仅显式传时内联覆盖 */
11
+ shadowColor?: string;
12
+ /** 父 item 代表 span(P3 rebase 算因子用;helper 经 resolveLayoutSpan(layout) 传入) */
13
+ parentSpan?: number;
14
+ /** 是否叠本层嵌套布局 rebase(缺省 true;false = 逆向逃生口,layout 原样直透) */
15
+ rebase?: boolean;
16
+ };
17
+ type __VLS_PublicProps = {
18
+ modelValue?: Record<string, any>;
19
+ } & __VLS_Props;
20
+ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
21
+ "update:modelValue": (value: Record<string, any>) => any;
22
+ }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
23
+ "onUpdate:modelValue"?: ((value: Record<string, any>) => any) | undefined;
24
+ }>, {
25
+ rebase: boolean;
26
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
27
+ childRef: {
28
+ validate: () => Promise<void>;
29
+ resetFields: () => void;
30
+ clearValidate: (key?: string) => void;
31
+ generate: () => Record<string, any>;
32
+ parse: (stringifyData: import('./types').ExcludeNeverProperties<import('./types').ExtractFormStringifyRawFromObject<Record<string, any>, Record<string, any>>>) => Record<string, any>;
33
+ stringify: () => import('./types').ExcludeNeverProperties<import('./types').ExtractFormStringifyRawFromObject<Record<string, any>, Record<string, any>>>;
34
+ } | null;
35
+ }, any>;
36
+ export default _default;
@@ -0,0 +1,63 @@
1
+ import { VNodeChild } from 'vue';
2
+ import { ColProps } from 'element-plus';
3
+ import { FormItemConfigList } from './types';
4
+ import { ActionBtnConfirmConfig } from '../display';
5
+ declare const _default: <T extends Record<string, any>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
6
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
7
+ readonly "onUpdate:modelValue"?: ((value: T[]) => any) | undefined;
8
+ } & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, never>, "onUpdate:modelValue"> & ({
9
+ modelValue?: T[];
10
+ } & {
11
+ /** 所属父 item key(注册到父 FormMain exposeMap 的索引) */
12
+ nestKey: string;
13
+ /** 每行子表单配置列表 */
14
+ list: FormItemConfigList;
15
+ /** 行稳定标识字段(指向 T 内稳定 id);缺省走内部自增 rowId */
16
+ rowKey?: string;
17
+ /** 新增行工厂;缺省 generateFormData(list) 产子默认对象 */
18
+ itemFactory?: () => T;
19
+ /** 最少行数(删到 min 禁删;硬约束走父 item rules 长度校验) */
20
+ min?: number;
21
+ /** 最多行数(达上限禁新增;硬约束走父 item rules 长度校验) */
22
+ max?: number;
23
+ layout?: Partial<ColProps>;
24
+ rowGutter?: number;
25
+ addText?: string;
26
+ removeText?: string;
27
+ /** 顶部自定义渲染(render-fn prop,替代 template slot;label 由父 FormItem 渲染) */
28
+ headerRender?: (scope: {
29
+ count: number;
30
+ max: number;
31
+ }) => VNodeChild;
32
+ /** 底部自定义渲染;缺省 = 内置「新增」按钮 */
33
+ footerRender?: (scope: {
34
+ count: number;
35
+ max: number;
36
+ canAdd: boolean;
37
+ add: () => void;
38
+ }) => VNodeChild;
39
+ /** 联结组件外环 + 每行分割阴影颜色 */
40
+ shadowColor?: string;
41
+ /** 父 item 代表 span(P3 rebase 算因子用;helper 经 resolveLayoutSpan(layout) 传入) */
42
+ parentSpan?: number;
43
+ /** 是否叠本层嵌套布局 rebase(缺省 true;false = 逆向逃生口,layout 原样直透) */
44
+ rebase?: boolean;
45
+ /**
46
+ * 行删除二次确认(破坏性操作防误删):
47
+ * - `true`(默认)→ 默认 popconfirm「确认删除该项?」(danger)
48
+ * - `false` → 不弹确认,直删(回旧行为)
49
+ * - 对象 → 自定义 ActionBtnConfirmConfig
50
+ */
51
+ removeConfirm?: boolean | ActionBtnConfirmConfig;
52
+ }) & Partial<{}>> & import('vue').PublicProps;
53
+ expose(exposed: import('vue').ShallowUnwrapRef<{}>): void;
54
+ attrs: any;
55
+ slots: {};
56
+ emit: (evt: "update:modelValue", value: T[]) => void;
57
+ }>) => import('vue').VNode & {
58
+ __ctx?: Awaited<typeof __VLS_setup>;
59
+ };
60
+ export default _default;
61
+ type __VLS_PrettifyLocal<T> = {
62
+ [K in keyof T]: T[K];
63
+ } & {};
@@ -3,9 +3,9 @@ import { ColProps } from 'element-plus';
3
3
  declare const _default: <PO extends Record<string, any>, SO extends Record<string, any>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
4
4
  props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
5
5
  readonly onSubmit?: ((type: FormItemSubmitType) => any) | undefined;
6
- readonly onLoadingChange?: ((status: boolean) => any) | undefined;
7
6
  readonly onVisibleChange?: ((status: boolean) => any) | undefined;
8
- } & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, never>, "onSubmit" | "onLoadingChange" | "onVisibleChange"> & FormMainProps<PO, SO> & Partial<{}>> & import('vue').PublicProps;
7
+ readonly onLoadingChange?: ((status: boolean) => any) | undefined;
8
+ } & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, never>, "onSubmit" | "onVisibleChange" | "onLoadingChange"> & FormMainProps<PO, SO> & Partial<{}>> & import('vue').PublicProps;
9
9
  expose(exposed: import('vue').ShallowUnwrapRef<FormMainInstance<PO, SO>>): void;
10
10
  attrs: any;
11
11
  slots: Partial<Record<NonNullable<Extract<keyof PO, string>>, (_: {
@@ -2,9 +2,9 @@ import { FormSearchInstance, FormSearchProps, FormSearchSearchType } from './typ
2
2
  declare const _default: <PO extends Record<string, any>, SO extends Record<string, any>, SQ extends Record<string, any>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
3
3
  props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
4
4
  readonly onSearch?: ((data: import('./types').ExcludeNeverProperties<import('./types').ExtractFormStringifyRawFromObject<PO, SO>> & SQ, type: FormSearchSearchType) => any) | undefined;
5
- readonly onVisibleChange?: ((status: boolean) => any) | undefined;
6
5
  readonly onHeightChange?: ((height: number) => any) | undefined;
7
- } & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, never>, "onVisibleChange" | "onHeightChange" | "onSearch"> & FormSearchProps<PO, SO, SQ> & Partial<{}>> & import('vue').PublicProps;
6
+ readonly onVisibleChange?: ((status: boolean) => any) | undefined;
7
+ } & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps, never>, "onHeightChange" | "onSearch" | "onVisibleChange"> & FormSearchProps<PO, SO, SQ> & Partial<{}>> & import('vue').PublicProps;
8
8
  expose(exposed: import('vue').ShallowUnwrapRef<FormSearchInstance<PO, SO>>): void;
9
9
  attrs: any;
10
10
  slots: Partial<Record<NonNullable<Extract<keyof PO, string>>, (_: any) => any>>;
@@ -7,6 +7,14 @@ import { default as FormSubmitBtn } from './FormSubmitBtn.vue';
7
7
  import { default as FormSubmitPanel } from './FormSubmitPanel.vue';
8
8
  import { default as FormVerifyImage } from './FormVerifyImage.vue';
9
9
  import { default as FormVerifyCode } from './FormVerifyCode.vue';
10
+ import { default as FormItemNestForm } from './FormItemNestForm.vue';
11
+ import { default as FormItemNestFormList } from './FormItemNestFormList.vue';
10
12
  export * from './types';
11
13
  export * from './utils';
12
- export { FormMain, FormSelect, FormSearch, FormSubmitBtn, FormSubmitPanel, FormRadioGroup, FormTree, FormVerifyImage, FormVerifyCode, };
14
+ export * from './nest-registry';
15
+ export * from './use-nest-form';
16
+ export * from './nest-form-item';
17
+ export * from './use-nest-form-list';
18
+ export * from './nest-form-item-list';
19
+ export * from './use-nest-layout-scale';
20
+ export { FormMain, FormSelect, FormSearch, FormSubmitBtn, FormSubmitPanel, FormRadioGroup, FormTree, FormVerifyImage, FormVerifyCode, FormItemNestForm, FormItemNestFormList, };
@@ -0,0 +1,63 @@
1
+ import { VNodeChild } from 'vue';
2
+ import { ColProps } from 'element-plus';
3
+ import { FormItemConfig, FormItemConfigList } from './types';
4
+ import { ActionBtnConfirmConfig } from '../display';
5
+ export interface NestFormItemListOptions {
6
+ /** 父 item key */
7
+ key: string;
8
+ /** 父 item label */
9
+ label: string;
10
+ /** 每行子表单配置列表 */
11
+ list: FormItemConfigList;
12
+ /** 行稳定标识字段(指向行对象内稳定 id);缺省走内部自增 rowId */
13
+ rowKey?: string;
14
+ /** 新增行工厂;缺省 generateFormData(list) */
15
+ itemFactory?: () => Record<string, any>;
16
+ /** 最少行数 */
17
+ min?: number;
18
+ /** 最多行数 */
19
+ max?: number;
20
+ /** 父 item 栅格布局 */
21
+ layout?: Partial<ColProps>;
22
+ /** 每行子表单行间距 */
23
+ rowGutter?: number;
24
+ /** 新增 / 删除按钮文案 */
25
+ addText?: string;
26
+ removeText?: string;
27
+ /** 顶部自定义渲染(render-fn;label 由父 FormItem 渲染,本组件不出 title) */
28
+ headerRender?: (scope: {
29
+ count: number;
30
+ max: number;
31
+ }) => VNodeChild;
32
+ /** 底部自定义渲染;缺省 = 内置「新增」按钮 */
33
+ footerRender?: (scope: {
34
+ count: number;
35
+ max: number;
36
+ canAdd: boolean;
37
+ add: () => void;
38
+ }) => VNodeChild;
39
+ /** 联结组件外环 + 每行分割阴影颜色 */
40
+ shadowColor?: string;
41
+ /** 业务校验规则;与自动织入的 min/max 长度规则合并(长度规则在前) */
42
+ rules?: FormItemConfig["rules"];
43
+ /** 覆盖默认 init(缺省 = 空数组 [],[MUST NOT] 改初始值补 min;min/max 走校验) */
44
+ init?: FormItemConfig["init"];
45
+ /** 覆盖默认 stringify(缺省 = 数组逐项 `stringifyFormData(t, list)`) */
46
+ stringify?: FormItemConfig["stringify"];
47
+ /** 覆盖默认 parse(缺省 = 数组逐项 `parseFormData(t, list)`) */
48
+ parse?: FormItemConfig["parse"];
49
+ /** 是否叠本层嵌套布局 rebase(P3,缺省 true;false = 逆向逃生口,子层 layout 原样直透) */
50
+ rebase?: boolean;
51
+ /** 行删除二次确认(缺省 true=默认 popconfirm「确认删除该项?」;false=直删;对象=自定义) */
52
+ removeConfirm?: boolean | ActionBtnConfirmConfig;
53
+ }
54
+ /**
55
+ * 生成「父 item 内嵌数组子表单(N 行 FormMain)」的 FormItemConfig(C4 配套 helper)
56
+ * ----
57
+ * render 出口挂 FormItemNestFormList(值贯通数组 in-place + 增删 + 聚合校验穿透自动接线)。
58
+ * ----
59
+ * **序列化 pack(ADR-6,对齐 §34)**:自动织入 init/stringify/parse —— 父 FormMain 的
60
+ * generate()/stringify()/parse() 逐项命中即对数组逐项递归(行内若再嵌 nestFormItem /
61
+ * nestFormItemList → 逐层组合)。业务传 init/stringify/parse 则以业务为准。
62
+ */
63
+ export declare function nestFormItemList(options: NestFormItemListOptions): FormItemConfig;
@@ -0,0 +1,36 @@
1
+ import { ColProps } from 'element-plus';
2
+ import { FormItemConfig, FormItemConfigList } from './types';
3
+ export interface NestFormItemOptions {
4
+ /** 父 item key */
5
+ key: string;
6
+ /** 父 item label */
7
+ label: string;
8
+ /** 子表单配置列表 */
9
+ list: FormItemConfigList;
10
+ /** 父 item 栅格布局 */
11
+ layout?: Partial<ColProps>;
12
+ /** 子表单行间距 */
13
+ rowGutter?: number;
14
+ /** 联结组件外环阴影颜色 */
15
+ shadowColor?: string;
16
+ /** 覆盖默认 init(缺省 = `generateFormData(list)`,产子默认对象) */
17
+ init?: FormItemConfig["init"];
18
+ /** 覆盖默认 stringify(缺省 = 递归 `stringifyFormData(value, list)`) */
19
+ stringify?: FormItemConfig["stringify"];
20
+ /** 覆盖默认 parse(缺省 = 递归 `parseFormData(value, list)`) */
21
+ parse?: FormItemConfig["parse"];
22
+ /** 是否叠本层嵌套布局 rebase(P3,缺省 true;false = 逆向逃生口,子层 layout 原样直透) */
23
+ rebase?: boolean;
24
+ }
25
+ /**
26
+ * 生成「父 item 内嵌子 FormMain」的 FormItemConfig(C1 配套 helper)
27
+ * ----
28
+ * 降低业务方手写 h(FormItemNestForm) 噪音:传 key/label/子 list 即得一个满足 FormItemConfig
29
+ * 的配置项,渲染出口挂 FormItemNestForm(值贯通 + 校验级联自动接线)。
30
+ * ----
31
+ * **stringify/parse/init 自动 pack**:FormItemConfig 的 per-item `init`/`stringify`/`parse`
32
+ * 钩子 + 纯 list 驱动 util(generate/stringify/parseFormData)→ 自动织入「递归进子 list」,
33
+ * 父 FormMain 的 `generate()`/`stringify()`/`parse()` 逐项命中即递归序列化/回显嵌套子表单,
34
+ * 多层自然组合(孙 nestFormItem 的钩子同理逐层)。业务传 init/stringify/parse 则以业务为准。
35
+ */
36
+ export declare function nestFormItem(options: NestFormItemOptions): FormItemConfig;
@@ -0,0 +1,22 @@
1
+ import { FormMainInstance } from './types';
2
+ /**
3
+ * 嵌套子 FormMain 级联 expose 子集
4
+ * ----
5
+ * 联结组件(FormItemNestForm)把所持子 FormMain 的级联方法注册进父 FormMain 的 exposeMap,
6
+ * 使父顶层 validate/clearValidate/resetFields 可级联到子。
7
+ */
8
+ export interface NestFormExpose {
9
+ validate: FormMainInstance["validate"];
10
+ clearValidate: FormMainInstance["clearValidate"];
11
+ resetFields: FormMainInstance["resetFields"];
12
+ }
13
+ /**
14
+ * 嵌套子表单 exposeMap
15
+ * ----
16
+ * key = 联结组件所属父 item 的 key(天然唯一,供父 FormMain 对齐 hideKeyList:隐藏 item 不级联 validate)。
17
+ * 用 `shallowReactive`:顶层 key 增删响应式(注册/摘除可被响应式消费),value(expose 对象)保持 raw
18
+ * 不深代理——既规避 expose 引用循环,又留响应式消费口。每个 FormMain 经工厂在闭包内 new 一份,零模块级单例。
19
+ */
20
+ export type NestFormExposeMap = Record<string, NestFormExpose>;
21
+ /** 创建一个嵌套子表单 exposeMap(shallowReactive) */
22
+ export declare function createNestFormExposeMap(): NestFormExposeMap;
@@ -161,6 +161,8 @@ export interface FormMainProps<PO extends Record<string, any>, SO extends Record
161
161
  data: PO;
162
162
  layout?: Partial<ColProps>;
163
163
  rowGutter?: number;
164
+ /** P3 嵌套 rebase 累乘因子(缺省 1 = 顶级行为不变,向后兼容)。由联结薄壳算出后传子 FormMain */
165
+ layoutScale?: number;
164
166
  }
165
167
  /** FormSearch props */
166
168
  export interface FormSearchProps<PO extends Record<string, any>, SO extends Record<string, any>, SQ extends Record<string, any>> extends FormMainProps<PO, SO> {
@@ -0,0 +1,20 @@
1
+ import { MaybeRefOrGetter } from 'vue';
2
+ import { FormMainInstance } from './types';
3
+ export interface UseNestFormListOptions {
4
+ /** 当前存活行子 FormMain 实例(getter,每次取最新存活集合) */
5
+ rowInstances: () => FormMainInstance[];
6
+ /**
7
+ * 父 item key——注册到父 FormMain exposeMap 的索引(C4 必传);
8
+ * 无父 FormMain registry(脱离嵌套上下文)时 inject 返回 null → 跳过注册。
9
+ */
10
+ key?: MaybeRefOrGetter<string | undefined>;
11
+ }
12
+ /**
13
+ * 数组子表单聚合注册 composable(C4 配套,ADR-1/2)
14
+ * ----
15
+ * 向最近祖先 FormMain registry 注册【1 个聚合 expose】(key = 本 item key),方法体
16
+ * fan-out 遍历当前存活 N 行子 FormMain:validate=Promise.all、clearValidate/resetFields=forEach。
17
+ * → 父 registry 仍「1 item 1 entry」,父 validate 的 hideKeyList 过滤按 item key 命中(守 ADR-8)。
18
+ * 职责收窄:仅聚合注册 + 摘除,[MUST NOT] 碰值贯通 / 增删(组件自管)。
19
+ */
20
+ export declare function useNestFormList(options: UseNestFormListOptions): void;
@@ -0,0 +1,26 @@
1
+ import { MaybeRefOrGetter, Ref } from 'vue';
2
+ import { FormMainInstance } from './types';
3
+ export interface UseNestFormOptions {
4
+ /** 子 FormMain 实例 ref(联结组件内 FormMain 的 defineExpose) */
5
+ childRef: Ref<FormMainInstance | undefined>;
6
+ /**
7
+ * 所属父 item key——注册到父 FormMain exposeMap 时必传(C1 form 族,作 map 索引);
8
+ * panel 上下文(C3)无父 FormMain exposeMap,可省(inject 返回 null → 跳过注册)。
9
+ * 接受 ref/getter,挂载/摘除时经 toValue 取值(避免 setup 根作用域读 props 失响应式)。
10
+ */
11
+ key?: MaybeRefOrGetter<string | undefined>;
12
+ }
13
+ /**
14
+ * 嵌套联结组件子表单接线 composable
15
+ * ----
16
+ * 职责(ADR-7,刻意收窄):
17
+ * 1. 代理子 FormMain 的 validate / clearValidate / resetFields;
18
+ * 2. context 自适应注册——inject 到最近祖先 FormMain 的 exposeMap 则按 key 写入(onMounted)+
19
+ * 删除(onBeforeUnmount);无(panel 上下文)则跳过。
20
+ * [MUST NOT] 在此处理值贯通——值语义 form/panel 两族不同(ADR-5),由各联结组件自管。
21
+ */
22
+ export declare function useNestForm(options: UseNestFormOptions): {
23
+ validateChild: () => Promise<void>;
24
+ clearChild: (k?: string) => void;
25
+ resetChild: () => void;
26
+ };
@@ -0,0 +1,17 @@
1
+ import { MaybeRefOrGetter, ComputedRef } from 'vue';
2
+ /**
3
+ * 联结薄壳计算子 Form/PanelMain 的嵌套布局 rebase 因子(P3,4 薄壳共用)。
4
+ * ----
5
+ * `childScale = parentScale × (24 / parentSpan)`:
6
+ * - parentScale 经 inject 从最近祖先 Form/PanelMain 取(顶级 / 未嵌套 → 缺省 1);
7
+ * - parentSpan = 父 item 实际分配的代表 span(薄壳由 helper 经 props 传入,缺省 24 = 本层不缩);
8
+ * - `rebase === false`(逆向逃生口)→ 不叠本层因子(= parentScale),layout 原样直透子层。
9
+ * ----
10
+ * 返回 ComputedRef,薄壳作 `layoutScale` 传子 FormMain/PanelMain(其再 resolveFormLayout 取整到档集)。
11
+ */
12
+ export declare function useNestLayoutScale(options: {
13
+ /** 父 item 代表 span(来自 helper 的 resolveLayoutSpan(layout)) */
14
+ parentSpan: MaybeRefOrGetter<number | undefined>;
15
+ /** 是否叠本层 rebase 因子(缺省 true;false = 逆向逃生口) */
16
+ rebase: MaybeRefOrGetter<boolean | undefined>;
17
+ }): ComputedRef<number>;
@@ -1,11 +1,36 @@
1
1
  import { DatePickerShortcut, FormItemConfig, FormItemConfigList, ExtractFormStringifyFromObject, FormItemConfigSwiftOptions } from './types';
2
2
  import { ColProps } from 'element-plus';
3
+ /**
4
+ * 嵌套布局 rebase 的栅格档集(P3)。
5
+ * ---
6
+ * FormMain/PanelMain 配置化 `span` 约定用 24 的约数 {6,8,12,24}(admin 常用档);
7
+ * 子层 rebase(×scale)后 ceil 到这组档,避免非约数(18/16/7)致行铺不满 ragged。
8
+ */
9
+ export declare const NEST_LAYOUT_TIERS: readonly [6, 8, 12, 24];
10
+ /**
11
+ * 把数值 ceil 到档集中 ≥ value 的最近一档(偏宽取向)。
12
+ * ---
13
+ * - value ≤ 下限 → 取下限;value ≥ 上限 → 封顶上限。
14
+ * - 落档间 → 抬到上一档(如 16 → 24,非更近的 12),合「容器窄字段更宽」意图。
15
+ */
16
+ export declare const ceilToTier: (value: number, tiers?: readonly number[]) => number;
17
+ /**
18
+ * 从 layout 解析父 item 实际分配的代表 span(P3 rebase 算因子用)。
19
+ * ---
20
+ * span 优先;无 span 时取 lg→md→sm→xl→xs 首个数值断点代表;都无 → 24(本层不缩)。
21
+ */
22
+ export declare const resolveLayoutSpan: (layout?: Partial<ColProps>) => number;
3
23
  /**
4
24
  * 将 layout 解析为各屏幕尺寸的显式值:
5
25
  * - 配置 span: xxx 时,xs/sm/md/lg/xl 默认全部视为 xxx
6
26
  * - 单独设置某个尺寸则该尺寸覆盖 span 推导值
27
+ * ---
28
+ * **P3 嵌套 rebase**:可选第 2 参 `scale`(嵌套累乘因子,缺省 1)。
29
+ * - `scale === 1` → 现状行为不变(非档值原样透传,[MUST NOT] ceil,向后兼容关键)。
30
+ * - `scale !== 1` → span 及各断点数值 `× scale` 后经 `ceilToTier` 取整到档集,
31
+ * 维持子层字段绝对宽与顶级一致(容器变窄 → span 变大)。
7
32
  */
8
- export declare const resolveFormLayout: (layout?: Partial<ColProps>) => Partial<ColProps>;
33
+ export declare const resolveFormLayout: (layout?: Partial<ColProps>, scale?: number) => Partial<ColProps>;
9
34
  /**
10
35
  * 生成 ElDatePicker 原生 `shortcuts` 的默认时间段快捷值:今日、昨日、近7日。
11
36
  * 直接用于 `<ElDatePicker :shortcuts="getDatePickerShortcuts()">`——
@@ -0,0 +1,35 @@
1
+ import { ColProps } from 'element-plus';
2
+ import { FormItemConfigList } from '../form';
3
+ type __VLS_Props = {
4
+ /** 子 FormMain 数据(= 父 item 草稿的嵌套对象,子 in-place 改草稿) */
5
+ data: Record<string, any>;
6
+ /** 子表单配置列表 */
7
+ list: FormItemConfigList;
8
+ layout?: Partial<ColProps>;
9
+ rowGutter?: number;
10
+ submitText?: string;
11
+ cancelText?: string;
12
+ /** 校验通过后的业务提交(helper 内 wire submitFn(草稿) → closeEdit);返回 Promise 自动 loading */
13
+ submit?: () => Promise<unknown> | unknown;
14
+ /** 取消编辑(helper 内 wire closeEdit) */
15
+ cancel?: () => void;
16
+ /** 父 item 代表 span(P3 rebase 算因子用;helper 经 resolveLayoutSpan(layout) 传入) */
17
+ parentSpan?: number;
18
+ /** 是否叠本层嵌套布局 rebase(缺省 true;false = 逆向逃生口,layout 原样直透) */
19
+ rebase?: boolean;
20
+ };
21
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
22
+ submitText: string;
23
+ cancelText: string;
24
+ rebase: boolean;
25
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
26
+ childRef: {
27
+ validate: () => Promise<void>;
28
+ resetFields: () => void;
29
+ clearValidate: (key?: string) => void;
30
+ generate: () => Record<string, any>;
31
+ parse: (stringifyData: import('../form').ExcludeNeverProperties<import('../form').ExtractFormStringifyRawFromObject<Record<string, any>, Record<string, any>>>) => Record<string, any>;
32
+ stringify: () => import('../form').ExcludeNeverProperties<import('../form').ExtractFormStringifyRawFromObject<Record<string, any>, Record<string, any>>>;
33
+ } | null;
34
+ }, any>;
35
+ export default _default;
@@ -0,0 +1,22 @@
1
+ import { PanelItemConfigList } from './types';
2
+ import { ColProps, CardProps } from 'element-plus';
3
+ type __VLS_Props = {
4
+ /** 子 PanelMain 数据(= 父 item value,嵌套对象) */
5
+ data: Record<string, any>;
6
+ /** 子 PanelMain 配置列表 */
7
+ list: PanelItemConfigList;
8
+ /** 子项是否包 Card,缺省继承 PanelMain 默认 */
9
+ itemCard?: boolean | Partial<CardProps & {
10
+ lastMarginBottom?: string;
11
+ }>;
12
+ layout?: Partial<ColProps>;
13
+ rowGutter?: number;
14
+ /** 父 item 代表 span(P3 rebase 算因子用;helper 经 resolveLayoutSpan(layout) 传入) */
15
+ parentSpan?: number;
16
+ /** 是否叠本层嵌套布局 rebase(缺省 true;false = 逆向逃生口,layout 原样直透) */
17
+ rebase?: boolean;
18
+ };
19
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
20
+ rebase: boolean;
21
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
22
+ export default _default;
@@ -1,5 +1,9 @@
1
1
  import { default as PanelMain } from './PanelMain.vue';
2
2
  import { default as PanelItem } from './PanelItem.vue';
3
3
  import { default as PanelEditSwitch } from './PanelEditSwitch.vue';
4
+ import { default as PanelItemNestPanel } from './PanelItemNestPanel.vue';
5
+ import { default as PanelItemNestForm } from './PanelItemNestForm.vue';
4
6
  export * from './types';
5
- export { PanelMain, PanelItem, PanelEditSwitch };
7
+ export * from './nest-panel-item';
8
+ export * from './nest-panel-form';
9
+ export { PanelMain, PanelItem, PanelEditSwitch, PanelItemNestPanel, PanelItemNestForm, };