@aithe/aithe-ui 26.3.1 → 26.3.2

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 (171) hide show
  1. package/README.md +8 -5
  2. package/dist/apps/api/i18n/de-DE.d.ts.map +1 -1
  3. package/dist/apps/api/i18n/de-DE.js +1 -0
  4. package/dist/apps/api/i18n/en-US.d.ts.map +1 -1
  5. package/dist/apps/api/i18n/en-US.js +1 -0
  6. package/dist/apps/api/i18n/es-ES.d.ts.map +1 -1
  7. package/dist/apps/api/i18n/es-ES.js +1 -0
  8. package/dist/apps/api/i18n/fr-FR.d.ts.map +1 -1
  9. package/dist/apps/api/i18n/fr-FR.js +1 -0
  10. package/dist/apps/api/i18n/ja-JP.d.ts.map +1 -1
  11. package/dist/apps/api/i18n/ja-JP.js +1 -0
  12. package/dist/apps/api/i18n/ko-KR.d.ts.map +1 -1
  13. package/dist/apps/api/i18n/ko-KR.js +1 -0
  14. package/dist/apps/api/i18n/pt-BR.d.ts.map +1 -1
  15. package/dist/apps/api/i18n/pt-BR.js +1 -0
  16. package/dist/apps/api/i18n/zh-CN.d.ts.map +1 -1
  17. package/dist/apps/api/i18n/zh-CN.js +1 -0
  18. package/dist/apps/api/i18n/zh-HK.d.ts.map +1 -1
  19. package/dist/apps/api/i18n/zh-HK.js +1 -0
  20. package/dist/apps/api/i18n/zh-TW.d.ts.map +1 -1
  21. package/dist/apps/api/i18n/zh-TW.js +1 -0
  22. package/dist/apps/api/pages/docs.d.ts.map +1 -1
  23. package/dist/apps/api/pages/docs.js +2 -0
  24. package/dist/apps/demo/app.d.ts.map +1 -1
  25. package/dist/apps/demo/app.js +2 -0
  26. package/dist/apps/demo/i18n/de-DE.d.ts.map +1 -1
  27. package/dist/apps/demo/i18n/de-DE.js +20 -0
  28. package/dist/apps/demo/i18n/en-US.d.ts.map +1 -1
  29. package/dist/apps/demo/i18n/en-US.js +20 -0
  30. package/dist/apps/demo/i18n/es-ES.d.ts.map +1 -1
  31. package/dist/apps/demo/i18n/es-ES.js +20 -0
  32. package/dist/apps/demo/i18n/fr-FR.d.ts.map +1 -1
  33. package/dist/apps/demo/i18n/fr-FR.js +20 -0
  34. package/dist/apps/demo/i18n/ja-JP.d.ts.map +1 -1
  35. package/dist/apps/demo/i18n/ja-JP.js +20 -0
  36. package/dist/apps/demo/i18n/ko-KR.d.ts.map +1 -1
  37. package/dist/apps/demo/i18n/ko-KR.js +20 -0
  38. package/dist/apps/demo/i18n/pt-BR.d.ts.map +1 -1
  39. package/dist/apps/demo/i18n/pt-BR.js +20 -0
  40. package/dist/apps/demo/i18n/zh-CN.d.ts.map +1 -1
  41. package/dist/apps/demo/i18n/zh-CN.js +20 -0
  42. package/dist/apps/demo/i18n/zh-HK.d.ts.map +1 -1
  43. package/dist/apps/demo/i18n/zh-HK.js +20 -0
  44. package/dist/apps/demo/i18n/zh-TW.d.ts.map +1 -1
  45. package/dist/apps/demo/i18n/zh-TW.js +20 -0
  46. package/dist/apps/demo/pages/autoform.d.ts.map +1 -1
  47. package/dist/apps/demo/pages/autoform.js +10 -0
  48. package/dist/apps/demo/pages/autoview.d.ts +3 -0
  49. package/dist/apps/demo/pages/autoview.d.ts.map +1 -0
  50. package/dist/apps/demo/pages/autoview.js +310 -0
  51. package/dist/apps/demo/pages/form.d.ts.map +1 -1
  52. package/dist/apps/demo/pages/form.js +20 -0
  53. package/dist/components/data/tree-menu.js +1 -1
  54. package/dist/components/display/autoview.d.ts +139 -0
  55. package/dist/components/display/autoview.d.ts.map +1 -0
  56. package/dist/components/display/autoview.js +460 -0
  57. package/dist/components/display/desc.d.ts +4 -0
  58. package/dist/components/display/desc.d.ts.map +1 -1
  59. package/dist/components/display/desc.js +45 -3
  60. package/dist/components/form/autoform-item.d.ts +6 -0
  61. package/dist/components/form/autoform-item.d.ts.map +1 -1
  62. package/dist/components/form/autoform-item.js +34 -4
  63. package/dist/components/form/combobox.d.ts +4 -0
  64. package/dist/components/form/combobox.d.ts.map +1 -1
  65. package/dist/components/form/combobox.js +56 -13
  66. package/dist/components/form/select.d.ts +4 -0
  67. package/dist/components/form/select.d.ts.map +1 -1
  68. package/dist/components/form/select.js +84 -40
  69. package/dist/components/navigation/sub-menu.d.ts.map +1 -1
  70. package/dist/components/navigation/sub-menu.js +0 -1
  71. package/dist/core/autoform/autoview.d.ts +86 -0
  72. package/dist/core/autoform/autoview.d.ts.map +1 -0
  73. package/dist/core/autoform/autoview.js +37 -0
  74. package/dist/core/autoform/index.d.ts +2 -0
  75. package/dist/core/autoform/index.d.ts.map +1 -1
  76. package/dist/core/autoform/index.js +1 -0
  77. package/dist/core/datahub/__tests__/force-options.test.d.ts +8 -0
  78. package/dist/core/datahub/__tests__/force-options.test.d.ts.map +1 -0
  79. package/dist/core/datahub/__tests__/force-options.test.js +161 -0
  80. package/dist/core/datahub/core/api-styles.d.ts.map +1 -1
  81. package/dist/core/datahub/core/api-styles.js +5 -0
  82. package/dist/core/datahub/core/datahub-core.d.ts +50 -0
  83. package/dist/core/datahub/core/datahub-core.d.ts.map +1 -1
  84. package/dist/core/datahub/core/datahub-core.js +160 -81
  85. package/dist/core/datahub/types.d.ts +18 -0
  86. package/dist/core/datahub/types.d.ts.map +1 -1
  87. package/dist/core/markdown/plugins.d.ts +2 -1
  88. package/dist/core/markdown/plugins.d.ts.map +1 -1
  89. package/dist/core/markdown/plugins.js +168 -21
  90. package/dist/core/types.d.ts +2 -0
  91. package/dist/core/types.d.ts.map +1 -1
  92. package/dist/index.d.ts +1 -0
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +1267 -753
  95. package/dist/index.js.map +1 -1
  96. package/dist/index.umd.js +282 -138
  97. package/dist/index.umd.js.map +1 -1
  98. package/dist/styles/i18n/locales/de-DE.d.ts.map +1 -1
  99. package/dist/styles/i18n/locales/de-DE.js +3 -0
  100. package/dist/styles/i18n/locales/en-US.d.ts.map +1 -1
  101. package/dist/styles/i18n/locales/en-US.js +3 -0
  102. package/dist/styles/i18n/locales/es-ES.d.ts.map +1 -1
  103. package/dist/styles/i18n/locales/es-ES.js +3 -0
  104. package/dist/styles/i18n/locales/fr-FR.d.ts.map +1 -1
  105. package/dist/styles/i18n/locales/fr-FR.js +3 -0
  106. package/dist/styles/i18n/locales/ja-JP.d.ts.map +1 -1
  107. package/dist/styles/i18n/locales/ja-JP.js +3 -0
  108. package/dist/styles/i18n/locales/ko-KR.d.ts.map +1 -1
  109. package/dist/styles/i18n/locales/ko-KR.js +3 -0
  110. package/dist/styles/i18n/locales/pt-BR.d.ts.map +1 -1
  111. package/dist/styles/i18n/locales/pt-BR.js +3 -0
  112. package/dist/styles/i18n/locales/zh-CN.d.ts.map +1 -1
  113. package/dist/styles/i18n/locales/zh-CN.js +3 -0
  114. package/dist/styles/i18n/locales/zh-HK.d.ts.map +1 -1
  115. package/dist/styles/i18n/locales/zh-HK.js +3 -0
  116. package/dist/styles/i18n/locales/zh-TW.d.ts.map +1 -1
  117. package/dist/styles/i18n/locales/zh-TW.js +3 -0
  118. package/docs/api/display/autoview.md +277 -0
  119. package/docs/api/display/desc.md +56 -14
  120. package/docs/api/form/autoform-item.md +16 -1
  121. package/docs/api/form/autoform.md +3 -2
  122. package/docs/api/form/combobox.md +27 -7
  123. package/docs/api/form/select.md +30 -8
  124. package/docs/api/summary.md +1 -0
  125. package/docs/autoform.md +1 -32
  126. package/docs/changelog/CHANGELOG.md +76 -1
  127. package/docs/changelog/VERSION_26.3.1.md +5 -5
  128. package/docs/changelog/VERSION_26.3.2.md +852 -0
  129. package/docs/datahub.md +3 -0
  130. package/docs/framework-integration.md +1 -1
  131. package/docs/guide.md +7 -6
  132. package/docs/i18n.md +1 -3
  133. package/docs/issue/26.3.2/issue_26.3.2.1.md +46 -0
  134. package/docs/issue/26.3.2/issue_26.3.2.2.md +82 -0
  135. package/docs/issue/26.3.2/issue_26.3.2.3.md +57 -0
  136. package/docs/issue/26.3.2/issue_26.3.2.4.md +43 -0
  137. package/docs/issue/AGENTS.md +24 -3
  138. package/docs/markdown.md +2 -2
  139. package/docs/quickstart.md +3 -3
  140. package/docs/theming.md +5 -4
  141. package/package.json +1 -1
  142. package/dist/components/navigation/dropdown.d.ts +0 -56
  143. package/dist/components/navigation/dropdown.d.ts.map +0 -1
  144. /package/docs/issue/{issue_26.2.2.1.md → 26.2.2/issue_26.2.2.1.md} +0 -0
  145. /package/docs/issue/{issue_26.2.2.2.md → 26.2.2/issue_26.2.2.2.md} +0 -0
  146. /package/docs/issue/{issue_26.2.2.3.md → 26.2.2/issue_26.2.2.3.md} +0 -0
  147. /package/docs/issue/{issue_26.2.2.4.md → 26.2.2/issue_26.2.2.4.md} +0 -0
  148. /package/docs/issue/{issue_26.2.3.1.md → 26.2.3/issue_26.2.3.1.md} +0 -0
  149. /package/docs/issue/{issue_26.2.3.10.md → 26.2.3/issue_26.2.3.10.md} +0 -0
  150. /package/docs/issue/{issue_26.2.3.11.md → 26.2.3/issue_26.2.3.11.md} +0 -0
  151. /package/docs/issue/{issue_26.2.3.12.md → 26.2.3/issue_26.2.3.12.md} +0 -0
  152. /package/docs/issue/{issue_26.2.3.13.md → 26.2.3/issue_26.2.3.13.md} +0 -0
  153. /package/docs/issue/{issue_26.2.3.14.md → 26.2.3/issue_26.2.3.14.md} +0 -0
  154. /package/docs/issue/{issue_26.2.3.15.md → 26.2.3/issue_26.2.3.15.md} +0 -0
  155. /package/docs/issue/{issue_26.2.3.16.md → 26.2.3/issue_26.2.3.16.md} +0 -0
  156. /package/docs/issue/{issue_26.2.3.2.md → 26.2.3/issue_26.2.3.2.md} +0 -0
  157. /package/docs/issue/{issue_26.2.3.3.md → 26.2.3/issue_26.2.3.3.md} +0 -0
  158. /package/docs/issue/{issue_26.2.3.4.md → 26.2.3/issue_26.2.3.4.md} +0 -0
  159. /package/docs/issue/{issue_26.2.3.5.md → 26.2.3/issue_26.2.3.5.md} +0 -0
  160. /package/docs/issue/{issue_26.2.3.6.md → 26.2.3/issue_26.2.3.6.md} +0 -0
  161. /package/docs/issue/{issue_26.2.3.7.md → 26.2.3/issue_26.2.3.7.md} +0 -0
  162. /package/docs/issue/{issue_26.2.3.8.md → 26.2.3/issue_26.2.3.8.md} +0 -0
  163. /package/docs/issue/{issue_26.2.3.9.md → 26.2.3/issue_26.2.3.9.md} +0 -0
  164. /package/docs/issue/{issue_26.3.1.0.md → 26.3.1/issue_26.3.1.0.md} +0 -0
  165. /package/docs/issue/{issue_26.3.1.1.md → 26.3.1/issue_26.3.1.1.md} +0 -0
  166. /package/docs/issue/{issue_26.3.1.2.md → 26.3.1/issue_26.3.1.2.md} +0 -0
  167. /package/docs/issue/{issue_26.3.1.3.md → 26.3.1/issue_26.3.1.3.md} +0 -0
  168. /package/docs/issue/{issue_26.3.1.4.md → 26.3.1/issue_26.3.1.4.md} +0 -0
  169. /package/docs/issue/{issue_26.3.1.5.md → 26.3.1/issue_26.3.1.5.md} +0 -0
  170. /package/docs/issue/{issue_26.3.1.6.md → 26.3.1/issue_26.3.1.6.md} +0 -0
  171. /package/docs/issue/{issue_26.3.1.7.md → 26.3.1/issue_26.3.1.7.md} +0 -0
@@ -97,6 +97,8 @@ let AitheAutoformItem = class AitheAutoformItem extends AitheElement {
97
97
  this._ruleDisabled = false;
98
98
  /** Options computed by dependency rules. 依赖规则计算的选项。 */
99
99
  this._ruleOptions = null;
100
+ /** Whether the password is visible (only for inputType="password"). 密码是否明文显示(仅 inputType="password" 时生效)。 */
101
+ this._passwordVisible = false;
100
102
  this.pendingClear = false;
101
103
  /** Handles input/textarea/number change events. 处理 input/textarea/number 的变更事件。 */
102
104
  this.handleInputChange = (ev) => {
@@ -107,6 +109,10 @@ let AitheAutoformItem = class AitheAutoformItem extends AitheElement {
107
109
  this.validate();
108
110
  }
109
111
  };
112
+ /** Toggles password visibility (only for inputType="password"). 切换密码明文显示(仅 inputType="password" 时生效)。 */
113
+ this.togglePasswordVisible = () => {
114
+ this._passwordVisible = !this._passwordVisible;
115
+ };
110
116
  /** Handles switch toggle change. 处理开关组件的切换事件。 */
111
117
  this.handleSwitchChange = (ev) => {
112
118
  const target = ev.target;
@@ -369,7 +375,9 @@ let AitheAutoformItem = class AitheAutoformItem extends AitheElement {
369
375
  if (this.required && !String(val).trim()) {
370
376
  this.errorMsg =
371
377
  this.message ||
372
- t('form.formItem.required', '{label} is required', { label: this.label || this.name || t('form.formItem.requiredField') });
378
+ t('form.formItem.required', '{label} is required', {
379
+ label: this.label || this.name || t('form.formItem.requiredField'),
380
+ });
373
381
  return false;
374
382
  }
375
383
  if (this.pattern && String(val).trim()) {
@@ -414,6 +422,10 @@ let AitheAutoformItem = class AitheAutoformItem extends AitheElement {
414
422
  }
415
423
  return this.value;
416
424
  }
425
+ /** Resolves the effective input type for password fields based on visibility state. 根据可见状态解析密码字段的有效输入类型。 */
426
+ resolvePasswordType() {
427
+ return this._passwordVisible ? 'text' : 'password';
428
+ }
417
429
  /** Renders the appropriate form control based on type. Falls back to input for unknown types. 根据控件类型渲染对应的表单控件,未知类型回退为 input。 */
418
430
  renderControl() {
419
431
  const ph = this.placeholder || '';
@@ -447,17 +459,32 @@ let AitheAutoformItem = class AitheAutoformItem extends AitheElement {
447
459
  });
448
460
  }
449
461
  switch (this.type) {
450
- case 'input':
462
+ case 'input': {
463
+ const isPassword = this.inputType === 'password';
464
+ const effectiveType = isPassword ? this.resolvePasswordType() : this.inputType || 'text';
465
+ const passwordIconName = this._passwordVisible ? 'eyeOff' : 'eye';
451
466
  return html `
452
467
  <aithe-input
453
- .type=${this.inputType || 'text'}
468
+ .type=${effectiveType}
454
469
  .placeholder=${ph}
455
470
  .value=${this.value}
456
471
  ?disabled=${dis}
457
472
  name=${this.name}
458
473
  @aithe-change=${this.handleInputChange}
459
- ></aithe-input>
474
+ >
475
+ ${isPassword
476
+ ? html `
477
+ <aithe-icon
478
+ slot="suffix"
479
+ name=${passwordIconName}
480
+ size="sm"
481
+ @click=${this.togglePasswordVisible}
482
+ ></aithe-icon>
483
+ `
484
+ : nothing}
485
+ </aithe-input>
460
486
  `;
487
+ }
461
488
  case 'textarea':
462
489
  return html `
463
490
  <aithe-textarea
@@ -755,6 +782,9 @@ __decorate([
755
782
  __decorate([
756
783
  state()
757
784
  ], AitheAutoformItem.prototype, "_ruleOptions", void 0);
785
+ __decorate([
786
+ state()
787
+ ], AitheAutoformItem.prototype, "_passwordVisible", void 0);
758
788
  AitheAutoformItem = __decorate([
759
789
  customElement('aithe-autoform-item')
760
790
  ], AitheAutoformItem);
@@ -41,5 +41,9 @@ export declare class AitheCombobox extends AitheElement {
41
41
  private selectOption;
42
42
  render(): import("lit-html").TemplateResult<1>;
43
43
  private renderOptionList;
44
+ /** Renders a single option button. 渲染单个选项按钮。 */
45
+ private renderOption;
46
+ /** Groups options by their `group` field. 按 group 字段对选项聚合。 */
47
+ private groupedOptions;
44
48
  }
45
49
  //# sourceMappingURL=combobox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../../../src/components/form/combobox.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAYnD;;;;;;;;;;;;;;;GAeG;AACH,qBACa,aAAc,SAAQ,YAAY;IAC7C,kCAAkC;IACN,KAAK,SAAM;IACvC,2EAA2E;IAC/C,KAAK,SAAM;IACvC,2DAA2D;IAC/B,IAAI,SAAM;IACtC,wDAAwD;IAC5B,OAAO,SAAQ;IAC3C,8DAA8D;IACjC,UAAU,UAAQ;IAC/C,iDAAiD;IACL,QAAQ,UAAS;IAC7D,gDAAgD;IACpB,WAAW,SAAM;IAEpC,OAAO,CAAC,IAAI,CAAS;IAE9B,MAAM,CAAC,QAAQ,CAAC,MAAM,0DAoHpB;IAEF,iBAAiB,IAAI,IAAI;IAKzB,oBAAoB,IAAI,IAAI;IAK5B,OAAO,KAAK,aAAa,GAOxB;IAED,OAAO,KAAK,eAAe,GAQ1B;IAED,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAIpC;IAEF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAK1B;IAEF,OAAO,CAAC,YAAY;IAMpB,MAAM;IA0BN,OAAO,CAAC,gBAAgB;CAwBzB"}
1
+ {"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../../../src/components/form/combobox.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAcnD;;;;;;;;;;;;;;;GAeG;AACH,qBACa,aAAc,SAAQ,YAAY;IAC7C,kCAAkC;IACN,KAAK,SAAM;IACvC,2EAA2E;IAC/C,KAAK,SAAM;IACvC,2DAA2D;IAC/B,IAAI,SAAM;IACtC,wDAAwD;IAC5B,OAAO,SAAQ;IAC3C,8DAA8D;IACjC,UAAU,UAAQ;IAC/C,iDAAiD;IACL,QAAQ,UAAS;IAC7D,gDAAgD;IACpB,WAAW,SAAM;IAEpC,OAAO,CAAC,IAAI,CAAS;IAE9B,MAAM,CAAC,QAAQ,CAAC,MAAM,0DAgIpB;IAEF,iBAAiB,IAAI,IAAI;IAKzB,oBAAoB,IAAI,IAAI;IAK5B,OAAO,KAAK,aAAa,GAOxB;IAED,OAAO,KAAK,eAAe,GAQ1B;IAED,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAIpC;IAEF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAK1B;IAEF,OAAO,CAAC,YAAY;IAMpB,MAAM;IA8BN,OAAO,CAAC,gBAAgB;IAyBxB,gDAAgD;IAChD,OAAO,CAAC,YAAY;IAgBpB,8DAA8D;IAC9D,OAAO,CAAC,cAAc;CAevB"}
@@ -171,6 +171,18 @@ let AitheCombobox = class AitheCombobox extends AitheElement {
171
171
  padding: var(--aithe-space-3);
172
172
  color: var(--aithe-color-text-subtle);
173
173
  }
174
+
175
+ .group-header {
176
+ padding: var(--aithe-space-2) var(--aithe-space-3);
177
+ font-size: var(--aithe-font-size-xs);
178
+ font-weight: var(--aithe-font-weight-medium);
179
+ color: var(--aithe-color-text-muted);
180
+ user-select: none;
181
+ }
182
+
183
+ .group .item {
184
+ padding-left: var(--aithe-space-6);
185
+ }
174
186
  `,
175
187
  ]; }
176
188
  connectedCallback() {
@@ -209,8 +221,8 @@ let AitheCombobox = class AitheCombobox extends AitheElement {
209
221
  <label class=${classMap({ control: true, disabled: this.disabled })} title=${this.title}>
210
222
  ${this.icon
211
223
  ? html `
212
- <aithe-icon class="value-icon" name=${this.icon} size="16"></aithe-icon>
213
- `
224
+ <aithe-icon class="value-icon" name=${this.icon} size="16"></aithe-icon>
225
+ `
214
226
  : nothing}
215
227
  <input
216
228
  .value=${this.value}
@@ -222,8 +234,8 @@ let AitheCombobox = class AitheCombobox extends AitheElement {
222
234
  </label>
223
235
  ${this.open
224
236
  ? html `
225
- <div class="panel">${this.renderOptionList(options)}</div>
226
- `
237
+ <div class="panel">${this.renderOptionList(options)}</div>
238
+ `
227
239
  : null}
228
240
  `;
229
241
  }
@@ -235,22 +247,53 @@ let AitheCombobox = class AitheCombobox extends AitheElement {
235
247
  `,
236
248
  ];
237
249
  }
238
- return options.map((option) => {
239
- const intentClass = option.variant && option.variant !== 'default' ? option.variant : '';
240
- const optionIcon = option.icon
250
+ const hasGroup = options.some((o) => o.group);
251
+ if (!hasGroup) {
252
+ return options.map((option) => this.renderOption(option));
253
+ }
254
+ return this.groupedOptions(options).map((group) => {
255
+ const header = group.label
241
256
  ? html `
242
- <aithe-icon class="option-icon" name=${option.icon} size="16"></aithe-icon>
257
+ <div class="group-header" role="presentation">${group.label}</div>
243
258
  `
244
259
  : nothing;
260
+ const items = group.options.map((option) => this.renderOption(option));
245
261
  return html `
246
- <button class="item ${intentClass}" type="button" @click=${() => this.selectOption(option)}>
247
- <span style="display:inline-flex;align-items:center;gap:var(--aithe-space-2);">
248
- ${optionIcon}${option.label}
249
- </span>
250
- </button>
262
+ <div class="group">${header}${items}</div>
251
263
  `;
252
264
  });
253
265
  }
266
+ /** Renders a single option button. 渲染单个选项按钮。 */
267
+ renderOption(option) {
268
+ const intentClass = option.variant && option.variant !== 'default' ? option.variant : '';
269
+ const optionIcon = option.icon
270
+ ? html `
271
+ <aithe-icon class="option-icon" name=${option.icon} size="16"></aithe-icon>
272
+ `
273
+ : nothing;
274
+ return html `
275
+ <button class="item ${intentClass}" type="button" @click=${() => this.selectOption(option)}>
276
+ <span style="display:inline-flex;align-items:center;gap:var(--aithe-space-2);">
277
+ ${optionIcon}${option.label}
278
+ </span>
279
+ </button>
280
+ `;
281
+ }
282
+ /** Groups options by their `group` field. 按 group 字段对选项聚合。 */
283
+ groupedOptions(options) {
284
+ const map = new Map();
285
+ for (const opt of options) {
286
+ const g = opt.group ?? '';
287
+ if (!map.has(g))
288
+ map.set(g, []);
289
+ map.get(g).push(opt);
290
+ }
291
+ const groups = [];
292
+ for (const [label, opts] of map) {
293
+ groups.push({ label: label || undefined, options: opts });
294
+ }
295
+ return groups;
296
+ }
254
297
  };
255
298
  __decorate([
256
299
  property({ type: String })
@@ -70,5 +70,9 @@ export declare class AitheSelect extends AitheAnchoredOverlayElement {
70
70
  private readonly handleTriggerKeydown;
71
71
  render(): import("lit-html").TemplateResult<1>;
72
72
  private renderOptionList;
73
+ /** Renders a single option button. 渲染单个选项按钮。 */
74
+ private renderOption;
75
+ /** Groups filtered options by their `group` field. 按 group 字段对过滤后的选项聚合。 */
76
+ private get groupedOptions();
73
77
  }
74
78
  //# sourceMappingURL=select.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/components/form/select.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAK1C,OAAO,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrD;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,WAAY,SAAQ,2BAA2B;IAC1D,mDAAmD;IACD,WAAW,SAAM;IACnE,8CAA8C;IACd,OAAO,EAAE,iBAAiB,EAAE,CAAM;IAClE,wCAAwC;IACZ,KAAK,SAAM;IACvC,0EAA0E;IAC9C,KAAK,SAAM;IACvC,oEAAoE;IACxC,IAAI,SAAM;IACtC,oEAAoE;IACxC,WAAW,SAAM;IAC7C,2DAA2D;IAC9B,UAAU,UAAS;IAChD,4DAA4D;IAC/B,SAAS,UAAS;IAC/C,4CAA4C;IACA,QAAQ,UAAS;IAC7D,wCAAwC;IACZ,SAAS,EAAE,cAAc,GAAG,WAAW,CAAkB;IAElE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAc;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAc;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAmB;IAE/D,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,WAAW,CAAM;IAElC,uGAAuG;IACvG,SAAS,CAAC,UAAU,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAUzD,MAAM,CAAC,QAAQ,CAAC,MAAM,0DAoJpB;IAEF,SAAS,KAAK,YAAY,IAAI,WAAW,GAAG,IAAI,CAE/C;IAED,SAAS,KAAK,aAAa,IAAI,WAAW,CAEzC;IAED,iBAAiB,IAAI,IAAI;IAMzB,oBAAoB,IAAI,IAAI;IAM5B,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAwBtD,2EAA2E;IAC3E,OAAO,KAAK,cAAc,GAEzB;IAED,4DAA4D;IAC5D,OAAO,KAAK,eAAe,GAW1B;IAED,6DAA6D;IAC7D,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAInC;IAEF,sDAAsD;IACtD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAIpC;IAEF,kDAAkD;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAMzB;IAEF,qFAAqF;IACrF,OAAO,CAAC,YAAY;IAWpB,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAUzB;IAEF,wEAAwE;IACxE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAiCnC;IAEF,MAAM;IAyEN,OAAO,CAAC,gBAAgB;CA0CzB"}
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/components/form/select.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAK1C,OAAO,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrD;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,WAAY,SAAQ,2BAA2B;IAC1D,mDAAmD;IACD,WAAW,SAAM;IACnE,8CAA8C;IACd,OAAO,EAAE,iBAAiB,EAAE,CAAM;IAClE,wCAAwC;IACZ,KAAK,SAAM;IACvC,0EAA0E;IAC9C,KAAK,SAAM;IACvC,oEAAoE;IACxC,IAAI,SAAM;IACtC,oEAAoE;IACxC,WAAW,SAAM;IAC7C,2DAA2D;IAC9B,UAAU,UAAS;IAChD,4DAA4D;IAC/B,SAAS,UAAS;IAC/C,4CAA4C;IACA,QAAQ,UAAS;IAC7D,wCAAwC;IACZ,SAAS,EAAE,cAAc,GAAG,WAAW,CAAkB;IAElE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAc;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAc;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAmB;IAE/D,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,WAAW,CAAM;IAElC,uGAAuG;IACvG,SAAS,CAAC,UAAU,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAUzD,MAAM,CAAC,QAAQ,CAAC,MAAM,0DAgKpB;IAEF,SAAS,KAAK,YAAY,IAAI,WAAW,GAAG,IAAI,CAE/C;IAED,SAAS,KAAK,aAAa,IAAI,WAAW,CAEzC;IAED,iBAAiB,IAAI,IAAI;IAMzB,oBAAoB,IAAI,IAAI;IAM5B,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI;IAwBtD,2EAA2E;IAC3E,OAAO,KAAK,cAAc,GAEzB;IAED,4DAA4D;IAC5D,OAAO,KAAK,eAAe,GAW1B;IAED,6DAA6D;IAC7D,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAInC;IAEF,sDAAsD;IACtD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAIpC;IAEF,kDAAkD;IAClD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAMzB;IAEF,qFAAqF;IACrF,OAAO,CAAC,YAAY;IAWpB,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAUzB;IAEF,wEAAwE;IACxE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAiCnC;IAEF,MAAM;IA+EN,OAAO,CAAC,gBAAgB;IA0BxB,gDAAgD;IAChD,OAAO,CAAC,YAAY;IAoCpB,2EAA2E;IAC3E,OAAO,KAAK,cAAc,GAYzB;CACF"}
@@ -271,6 +271,18 @@ let AitheSelect = class AitheSelect extends AitheAnchoredOverlayElement {
271
271
  color: var(--aithe-color-text-muted);
272
272
  text-align: center;
273
273
  }
274
+
275
+ .group-header {
276
+ padding: var(--aithe-space-2) var(--aithe-space-3);
277
+ font-size: var(--aithe-font-size-xs);
278
+ font-weight: var(--aithe-font-weight-medium);
279
+ color: var(--aithe-color-text-muted);
280
+ user-select: none;
281
+ }
282
+
283
+ .group .option {
284
+ padding-left: var(--aithe-space-6);
285
+ }
274
286
  `,
275
287
  ]; }
276
288
  get panelElement() {
@@ -373,31 +385,31 @@ let AitheSelect = class AitheSelect extends AitheAnchoredOverlayElement {
373
385
  <div class="value">
374
386
  ${this.icon
375
387
  ? html `
376
- <aithe-icon class="value-icon" name=${this.icon} size="16"></aithe-icon>
377
- `
388
+ <aithe-icon class="value-icon" name=${this.icon} size="16"></aithe-icon>
389
+ `
378
390
  : nothing}
379
391
  ${valueContent}
380
392
  </div>
381
393
  <span class="actions">
382
394
  ${this.clearable && this.value
383
395
  ? html `
384
- <button
385
- class="action"
386
- type="button"
387
- aria-label=${t('form.select.clearAriaLabel')}
388
- @click=${this.clearValue}
389
- >
390
- ×
391
- </button>
392
- `
396
+ <button
397
+ class="action"
398
+ type="button"
399
+ aria-label=${t('form.select.clearAriaLabel')}
400
+ @click=${this.clearValue}
401
+ >
402
+ ×
403
+ </button>
404
+ `
393
405
  : null}
394
406
  <span aria-hidden="true">${this.open ? '▴' : '▾'}</span>
395
407
  </span>
396
408
  </div>
397
409
  ${this.open
398
410
  ? html `
399
- <div class="panel" role="listbox">${this.renderOptionList()}</div>
400
- `
411
+ <div class="panel" role="listbox">${this.renderOptionList()}</div>
412
+ `
401
413
  : null}
402
414
  `;
403
415
  }
@@ -409,40 +421,72 @@ let AitheSelect = class AitheSelect extends AitheAnchoredOverlayElement {
409
421
  `,
410
422
  ];
411
423
  }
412
- return this.filteredOptions.map((option, index) => {
413
- const intentClass = option.variant && option.variant !== 'default' ? option.variant : '';
414
- const optionIcon = option.icon
424
+ const hasGroup = this.filteredOptions.some((o) => o.group);
425
+ if (!hasGroup) {
426
+ return this.filteredOptions.map((option, index) => this.renderOption(option, index));
427
+ }
428
+ let flatIndex = 0;
429
+ return this.groupedOptions.map((group) => {
430
+ const header = group.label
415
431
  ? html `
416
- <aithe-icon class="option-icon" name=${option.icon} size="20"></aithe-icon>
432
+ <div class="group-header" role="presentation">${group.label}</div>
417
433
  `
418
434
  : nothing;
435
+ const items = group.options.map((option) => this.renderOption(option, flatIndex++));
419
436
  return html `
420
- <button
421
- class=${classMap({
422
- option: true,
423
- active: index === this.activeIndex,
424
- [intentClass]: Boolean(intentClass),
425
- })}
426
- ?disabled=${option.disabled}
427
- type="button"
428
- @click=${() => this.selectOption(option)}
429
- @mouseenter=${() => (this.activeIndex = index)}
430
- >
431
- ${optionIcon}
432
- <span style="display:grid;gap:2px;flex:1;min-width:0;">
433
- <span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">
434
- ${option.label}
435
- </span>
436
- ${option.description
437
- ? html `
438
- <span class="desc">${option.description}</span>
439
- `
440
- : null}
441
- </span>
442
- </button>
437
+ <div class="group">${header}${items}</div>
443
438
  `;
444
439
  });
445
440
  }
441
+ /** Renders a single option button. 渲染单个选项按钮。 */
442
+ renderOption(option, index) {
443
+ const intentClass = option.variant && option.variant !== 'default' ? option.variant : '';
444
+ const optionIcon = option.icon
445
+ ? html `
446
+ <aithe-icon class="option-icon" name=${option.icon} size="20"></aithe-icon>
447
+ `
448
+ : nothing;
449
+ return html `
450
+ <button
451
+ class=${classMap({
452
+ option: true,
453
+ active: index === this.activeIndex,
454
+ [intentClass]: Boolean(intentClass),
455
+ })}
456
+ ?disabled=${option.disabled}
457
+ type="button"
458
+ @click=${() => this.selectOption(option)}
459
+ @mouseenter=${() => (this.activeIndex = index)}
460
+ >
461
+ ${optionIcon}
462
+ <span style="display:grid;gap:2px;flex:1;min-width:0;">
463
+ <span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">
464
+ ${option.label}
465
+ </span>
466
+ ${option.description
467
+ ? html `
468
+ <span class="desc">${option.description}</span>
469
+ `
470
+ : null}
471
+ </span>
472
+ </button>
473
+ `;
474
+ }
475
+ /** Groups filtered options by their `group` field. 按 group 字段对过滤后的选项聚合。 */
476
+ get groupedOptions() {
477
+ const map = new Map();
478
+ for (const opt of this.filteredOptions) {
479
+ const g = opt.group ?? '';
480
+ if (!map.has(g))
481
+ map.set(g, []);
482
+ map.get(g).push(opt);
483
+ }
484
+ const groups = [];
485
+ for (const [label, opts] of map) {
486
+ groups.push({ label: label || undefined, options: opts });
487
+ }
488
+ return groups;
489
+ }
446
490
  };
447
491
  __decorate([
448
492
  property({ type: String, attribute: 'options' })
@@ -1 +1 @@
1
- {"version":3,"file":"sub-menu.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/sub-menu.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,YAAa,SAAQ,YAAY;IAC5C,sDAAsD;IAC1B,IAAI,SAAM;IACtC,2DAA2D;IAC/B,KAAK,SAAM;IACvC,0DAA0D;IAC9B,IAAI,SAAM;IACtC,iDAAiD;IACL,QAAQ,UAAS;IAC7D,0DAA0D;IACd,IAAI,UAAS;IACzD,6DAA6D;IAC7B,MAAM,UAAS;IAC/C,4EAA4E;IAC5C,QAAQ,EAAE,YAAY,GAAG,UAAU,CAAc;IACjF,wMAAwM;IACxK,SAAS,UAAS;IAElD,MAAM,CAAC,QAAQ,CAAC,MAAM,0DA4FpB;IAEF,iBAAiB,IAAI,IAAI;IAIzB,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAuBtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAMrB;IAEF,MAAM;CAqDP"}
1
+ {"version":3,"file":"sub-menu.d.ts","sourceRoot":"","sources":["../../../src/components/navigation/sub-menu.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,YAAa,SAAQ,YAAY;IAC5C,sDAAsD;IAC1B,IAAI,SAAM;IACtC,2DAA2D;IAC/B,KAAK,SAAM;IACvC,0DAA0D;IAC9B,IAAI,SAAM;IACtC,iDAAiD;IACL,QAAQ,UAAS;IAC7D,0DAA0D;IACd,IAAI,UAAS;IACzD,6DAA6D;IAC7B,MAAM,UAAS;IAC/C,4EAA4E;IAC5C,QAAQ,EAAE,YAAY,GAAG,UAAU,CAAc;IACjF,wMAAwM;IACxK,SAAS,UAAS;IAElD,MAAM,CAAC,QAAQ,CAAC,MAAM,0DA2FpB;IAEF,iBAAiB,IAAI,IAAI;IAIzB,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAuBtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAMrB;IAEF,MAAM;CAqDP"}
@@ -96,7 +96,6 @@ let AitheSubMenu = class AitheSubMenu extends AitheElement {
96
96
 
97
97
  .toggle.active {
98
98
  color: var(--aithe-color-text);
99
- background: var(--aithe-color-surface-muted);
100
99
  }
101
100
 
102
101
  .toggle.active .toggle-icon {
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @file Auto-view registry & renderer types / 只读视图注册表与渲染器类型
3
+ * @description Defines the extension point for custom read-only field renderers.
4
+ * Zero Lit dependency — pure types and a static registry, mirroring FormRegistry.
5
+ * 定义自定义只读字段渲染器的扩展点。
6
+ * 零 Lit 依赖 — 仅类型与静态注册表,与 FormRegistry 对称。
7
+ */
8
+ import type { TemplateResult } from 'lit';
9
+ import type { FormFieldConfig, FormItemOption } from './types';
10
+ /**
11
+ * Extended field configuration for read-only views.
12
+ * 只读视图的扩展字段配置。
13
+ * @description Extends FormFieldConfig with optional display-only properties.
14
+ * All extra fields are optional, so a plain FormFieldConfig can be used directly.
15
+ * 在 FormFieldConfig 基础上追加可选的展示属性,
16
+ * 全部可选,因此可直接传入纯 FormFieldConfig。
17
+ */
18
+ export interface ViewFieldConfig extends FormFieldConfig {
19
+ /** Filter expression for formatting the value, e.g. "amount" / "date yyyy-MM-dd" / "empty". 值过滤器表达式。 */
20
+ filter?: string;
21
+ /** Placeholder text for empty values; falls back to the component's empty-text. 空值占位文本,回退到组件的全局 empty-text。 */
22
+ emptyText?: string;
23
+ /** Column span in the grid layout. Default 1. 网格中占用的列数,默认 1。 */
24
+ span?: number;
25
+ /** Row span in the grid layout. Default 1. 网格中占用的行数,默认 1。 */
26
+ rowspan?: number;
27
+ /** Content text alignment. 内容文本对齐方式。 */
28
+ align?: 'left' | 'center' | 'right';
29
+ /** Whether to hide the label cell. 是否隐藏标签单元格。 */
30
+ hideLabel?: boolean;
31
+ }
32
+ /**
33
+ * Context passed to a read-only view renderer.
34
+ * 传递给只读视图渲染器的上下文。
35
+ */
36
+ export interface ViewRenderContext {
37
+ /** Transformed value (boolean for switch, number for number, string[] for checkbox, etc.). 转换后的值。 */
38
+ value: unknown;
39
+ /** Raw string value as stored in data. 原始字符串值。 */
40
+ rawValue: string;
41
+ /** Options for select/radio/checkbox controls. 选择类控件的选项。 */
42
+ options: FormItemOption[];
43
+ /** Full field configuration. 完整字段配置。 */
44
+ field: ViewFieldConfig;
45
+ /** Resolved empty placeholder text. 解析后的空值占位文本。 */
46
+ emptyText: string;
47
+ }
48
+ /**
49
+ * Read-only view renderer function. Returns a TemplateResult to be injected into a desc-item slot.
50
+ * 只读视图渲染函数,返回 TemplateResult 注入 desc-item 的 slot。
51
+ */
52
+ export type ViewRenderer = (ctx: ViewRenderContext) => TemplateResult;
53
+ /**
54
+ * Read-only view control type definition.
55
+ * 只读视图控件类型定义。
56
+ */
57
+ export interface ViewControlDefinition {
58
+ /** Control type matching the `type` field in ViewFieldConfig. 匹配 ViewFieldConfig 中 type 字段的控件类型。 */
59
+ type: string;
60
+ /** Renderer function. 渲染函数。 */
61
+ render: ViewRenderer;
62
+ }
63
+ /**
64
+ * Read-only view control type registry. Allows registering custom renderers
65
+ * to extend autoview with arbitrary display logic for specific field types.
66
+ * 只读视图控件类型注册表。允许注册自定义渲染器,
67
+ * 以特定字段类型的任意展示逻辑扩展 autoview。
68
+ */
69
+ export declare class ViewRegistry {
70
+ private static readonly _views;
71
+ /**
72
+ * Register a custom read-only renderer.
73
+ * 注册自定义只读渲染器。
74
+ * @throws Error if the type is already registered. 类型已注册时抛错。
75
+ */
76
+ static register(definition: ViewControlDefinition): void;
77
+ /** Unregister a view type. Returns whether the type existed. 注销视图类型,返回类型是否存在。 */
78
+ static unregister(type: string): boolean;
79
+ /** Get a view definition by type. 按 type 获取视图定义。 */
80
+ static get(type: string): ViewControlDefinition | undefined;
81
+ /** Check whether a view type is registered. 检查视图类型是否已注册。 */
82
+ static has(type: string): boolean;
83
+ /** List all registered view type names. 列出所有已注册的视图类型名。 */
84
+ static types(): string[];
85
+ }
86
+ //# sourceMappingURL=autoview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoview.d.ts","sourceRoot":"","sources":["../../../src/core/autoform/autoview.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;;;GAOG;AACH,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,wGAAwG;IACxG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+GAA+G;IAC/G,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IACpC,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,qGAAqG;IACrG,KAAK,EAAE,OAAO,CAAC;IACf,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,wCAAwC;IACxC,KAAK,EAAE,eAAe,CAAC;IACvB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,iBAAiB,KAAK,cAAc,CAAC;AAEtE;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,oGAAoG;IACpG,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;;;;GAKG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAA4C;IAE1E;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,qBAAqB,GAAG,IAAI;IAUxD,iFAAiF;IACjF,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIxC,oDAAoD;IACpD,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;IAI3D,4DAA4D;IAC5D,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC,0DAA0D;IAC1D,MAAM,CAAC,KAAK,IAAI,MAAM,EAAE;CAGzB"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Read-only view control type registry. Allows registering custom renderers
3
+ * to extend autoview with arbitrary display logic for specific field types.
4
+ * 只读视图控件类型注册表。允许注册自定义渲染器,
5
+ * 以特定字段类型的任意展示逻辑扩展 autoview。
6
+ */
7
+ export class ViewRegistry {
8
+ static { this._views = new Map(); }
9
+ /**
10
+ * Register a custom read-only renderer.
11
+ * 注册自定义只读渲染器。
12
+ * @throws Error if the type is already registered. 类型已注册时抛错。
13
+ */
14
+ static register(definition) {
15
+ if (ViewRegistry._views.has(definition.type)) {
16
+ throw new Error(`[ViewRegistry] View type "${definition.type}" is already registered. ` +
17
+ `Call ViewRegistry.unregister() first if you want to replace it.`);
18
+ }
19
+ ViewRegistry._views.set(definition.type, definition);
20
+ }
21
+ /** Unregister a view type. Returns whether the type existed. 注销视图类型,返回类型是否存在。 */
22
+ static unregister(type) {
23
+ return ViewRegistry._views.delete(type);
24
+ }
25
+ /** Get a view definition by type. 按 type 获取视图定义。 */
26
+ static get(type) {
27
+ return ViewRegistry._views.get(type);
28
+ }
29
+ /** Check whether a view type is registered. 检查视图类型是否已注册。 */
30
+ static has(type) {
31
+ return ViewRegistry._views.has(type);
32
+ }
33
+ /** List all registered view type names. 列出所有已注册的视图类型名。 */
34
+ static types() {
35
+ return Array.from(ViewRegistry._views.keys());
36
+ }
37
+ }
@@ -8,4 +8,6 @@ export { FormRuleEngine, FormRegistry } from './autoform';
8
8
  export type { FormDependencyState, FormControlRenderer, FormControlContext, FormControlDefinition, } from './autoform';
9
9
  export { FormCondition } from './condition';
10
10
  export type { FormRule, FormRuleType, FormFieldConfig, FormItemOption } from './types';
11
+ export { ViewRegistry } from './autoview';
12
+ export type { ViewFieldConfig, ViewRenderContext, ViewRenderer, ViewControlDefinition, } from './autoview';
11
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/autoform/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1D,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/autoform/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1D,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEvF,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
@@ -6,3 +6,4 @@
6
6
  */
7
7
  export { FormRuleEngine, FormRegistry } from './autoform';
8
8
  export { FormCondition } from './condition';
9
+ export { ViewRegistry } from './autoview';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @file DataHubCore forceDedup / forceCache 选项测试
3
+ * @description 验证当 URL 不以 query/list/get 结尾时,
4
+ * forceDedup 和 forceCache 选项能强制启用去重和缓存,
5
+ * 且不会被幂等守卫拦截。
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=force-options.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"force-options.test.d.ts","sourceRoot":"","sources":["../../../../src/core/datahub/__tests__/force-options.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}