@xihan-ui/web-components 1.0.0-alpha.0 → 1.0.0-alpha.1

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/dist/define.js CHANGED
@@ -1,9 +1,9 @@
1
- import { a as discoverParts, i as containsPart, o as wcNormalize, r as createSpreader, t as MachineController } from "./machine-controller-Bnr5jbhz.js";
1
+ import { a as containsPart, i as PART_ATTR, o as discoverParts, r as createSpreader, s as wcNormalize, t as MachineController } from "./machine-controller-Cq9t_cfJ.js";
2
2
  import { t as defineElement } from "./registry-DR6I2_zF.js";
3
- import { n as version, t as XhReactiveElement } from "./element-xjYY5Oe2.js";
3
+ import { n as version, t as XhReactiveElement } from "./element-BxtVEMuI.js";
4
4
  import { DIAGNOSTIC_CODES, createCounterIdGenerator, createRuntimeConfig, createScope, getDiagnostics, reportDiagnostic } from "@xihan-ui/kernel";
5
5
  import { ITEM_VALUE_ATTR, declaredItemDisabled, isItemDisabled } from "@xihan-ui/behavior";
6
- import { accordionAnatomy, accordionMachine, accordionMeta, affixAnatomy, affixMachine, affixMeta, alertAnatomy, alertMachine, alertMeta, anchorAnatomy, anchorMachine, anchorMeta, avatarAnatomy, avatarGroupAnatomy, avatarGroupMeta, avatarMachine, avatarMeta, backTopAnatomy, backTopMachine, backTopMeta, badgeAnatomy, badgeMeta, breadcrumbAnatomy, breadcrumbMeta, buttonAnatomy, buttonGroupAnatomy, buttonGroupMeta, buttonMeta, calendarAnatomy, calendarMachine, calendarMeta, cardAnatomy, cardMeta, carouselAnatomy, carouselMachine, carouselMeta, cascaderAnatomy, cascaderMachine, cascaderMeta, checkboxAnatomy, checkboxGroupAnatomy, checkboxGroupMachine, checkboxGroupMeta, checkboxMachine, checkboxMeta, clipboardAnatomy, clipboardMachine, clipboardMeta, codeBlockAnatomy, codeBlockMeta, collapsibleAnatomy, collapsibleMachine, collapsibleMeta, colorPickerAnatomy, colorPickerMachine, colorPickerMeta, colorPickerToChannel, colorPickerToInputChannel, comboboxAnatomy, comboboxMachine, comboboxMeta, composerAnatomy, composerMachine, composerMeta, connectAccordion, connectAffix, connectAlert, connectAnchor, connectAvatar, connectAvatarGroup, connectBackTop, connectBadge, connectBreadcrumb, connectButton, connectButtonGroup, connectCalendar, connectCard, connectCarousel, connectCascader, connectCheckbox, connectCheckboxGroup, connectClipboard, connectCodeBlock, connectCollapsible, connectColorPicker, connectCombobox, connectComposer, connectContextMenu, connectCountdown, connectDateField, connectDatePicker, connectDescriptions, connectDialog, connectDrawer, connectDynamicInput, connectEditable, connectEllipsis, connectEmptyState, connectField, connectFileUpload, connectFlex, connectFloatButton, connectForm, connectGradientText, connectGrid, connectHighlight, connectHoverCard, connectIcon, connectIconWrapper, connectImage, connectInfiniteScroll, connectLayout, connectList, connectListbox, connectLoadingBar, connectLog, connectMarquee, connectMention, connectMenu, connectMenubar, connectNavigationMenu, connectNumberAnimation, connectNumberField, connectPageHeader, connectPagination, connectPinInput, connectPopconfirm, connectPopover, connectPopselect, connectProgress, connectQrCode, connectRadioGroup, connectRating, connectResult, connectScrollArea, connectSelect, connectSeparator, connectSkeleton, connectSlider, connectSpinner, connectSplitter, connectStatistic, connectSteps, connectSwitch, connectTable, connectTabs, connectTagsInput, connectTextField, connectThread, connectTime, connectTimeField, connectTimePicker, connectTimeline, connectToast, connectToaster, connectToggle, connectToggleGroup, connectToolbar, connectTooltip, connectTour, connectTransfer, connectTree, connectTreeSelect, connectTypography, connectVirtualizer, connectWatermark, contextMenuAnatomy, contextMenuMachine, contextMenuMeta, countdownAnatomy, countdownMachine, countdownMeta, dateFieldAnatomy, dateFieldMachine, dateFieldMeta, datePickerAnatomy, datePickerCalendarProps, datePickerFieldEndProps, datePickerFieldProps, datePickerMachine, datePickerMeta, descriptionsAnatomy, descriptionsMeta, dialogAnatomy, dialogMachine, dialogMeta, drawerAnatomy, drawerMachine, drawerMeta, dynamicInputAnatomy, dynamicInputMachine, dynamicInputMeta, editableAnatomy, editableMachine, editableMeta, ellipsisAnatomy, ellipsisMachine, ellipsisMeta, emptyStateAnatomy, emptyStateMeta, fieldAnatomy, fieldMeta, fileUploadAnatomy, fileUploadMachine, fileUploadMeta, flexAnatomy, flexMeta, floatButtonAnatomy, floatButtonMeta, formAnatomy, formMachine, formMeta, gradientTextAnatomy, gradientTextMeta, gridAnatomy, gridMeta, highlightAnatomy, highlightMeta, hoverCardAnatomy, hoverCardMachine, hoverCardMeta, iconAnatomy, iconMeta, iconWrapperAnatomy, iconWrapperMeta, imageAnatomy, imageMachine, imageMeta, infiniteScrollAnatomy, infiniteScrollMachine, infiniteScrollMeta, layoutAnatomy, layoutMachine, layoutMeta, listAnatomy, listMeta, listboxAnatomy, listboxMachine, listboxMeta, loadingBarAnatomy, loadingBarMachine, loadingBarMeta, logAnatomy, logMeta, marqueeAnatomy, marqueeMeta, mentionAnatomy, mentionMachine, mentionMeta, menuAnatomy, menuMachine, menuMeta, menubarAnatomy, menubarMachine, menubarMeta, navigationMenuAnatomy, navigationMenuMachine, navigationMenuMeta, numberAnimationAnatomy, numberAnimationMachine, numberAnimationMeta, numberFieldAnatomy, numberFieldMachine, numberFieldMeta, pageHeaderAnatomy, pageHeaderMeta, paginationAnatomy, paginationMachine, paginationMeta, pinInputAnatomy, pinInputMachine, pinInputMeta, popconfirmAnatomy, popconfirmMeta, popoverAnatomy, popoverMachine, popoverMeta, popselectAnatomy, popselectMeta, progressAnatomy, progressMeta, qrCodeAnatomy, qrCodeMeta, radioGroupAnatomy, radioGroupMachine, radioGroupMeta, ratingAnatomy, ratingMachine, ratingMeta, resultAnatomy, resultMeta, scrollAreaAnatomy, scrollAreaMachine, scrollAreaMeta, selectAnatomy, selectMachine, selectMeta, separatorAnatomy, separatorMeta, skeletonAnatomy, skeletonMeta, sliderAnatomy, sliderMachine, sliderMeta, spinnerAnatomy, spinnerMeta, splitterAnatomy, splitterMachine, splitterMeta, statisticAnatomy, statisticMeta, stepsAnatomy, stepsMachine, stepsMeta, switchAnatomy, switchMachine, switchMeta, tableAnatomy, tableMachine, tableMeta, tabsAnatomy, tabsMachine, tabsMeta, tagsInputAnatomy, tagsInputMachine, tagsInputMeta, textFieldAnatomy, textFieldMachine, textFieldMeta, threadAnatomy, threadMachine, threadMeta, timeAnatomy, timeFieldAnatomy, timeFieldMachine, timeFieldMeta, timeMeta, timePickerAnatomy, timePickerMachine, timePickerMeta, timelineAnatomy, timelineMeta, toastAnatomy, toastMachine, toastMeta, toasterAnatomy, toasterMachine, toasterMeta, toggleAnatomy, toggleGroupAnatomy, toggleGroupMachine, toggleGroupMeta, toggleMachine, toggleMeta, toolbarAnatomy, toolbarMachine, toolbarMeta, tooltipAnatomy, tooltipMachine, tooltipMeta, tourAnatomy, tourMachine, tourMeta, transferAnatomy, transferFocusKey, transferMachine, transferMeta, treeAnatomy, treeMachine, treeMeta, treeSelectAnatomy, treeSelectMachine, treeSelectMeta, typographyAnatomy, typographyMeta, virtualizerAnatomy, virtualizerMachine, virtualizerMeta, watermarkAnatomy, watermarkMeta } from "@xihan-ui/headless";
6
+ import { accordionAnatomy, accordionMachine, accordionMeta, affixAnatomy, affixMachine, affixMeta, alertAnatomy, alertMachine, alertMeta, anchorAnatomy, anchorMachine, anchorMeta, autoSizeTextarea, avatarAnatomy, avatarGroupAnatomy, avatarGroupMeta, avatarMachine, avatarMeta, backTopAnatomy, backTopMachine, backTopMeta, badgeAnatomy, badgeMeta, breadcrumbAnatomy, breadcrumbMeta, buttonAnatomy, buttonGroupAnatomy, buttonGroupMeta, buttonMeta, calendarAnatomy, calendarMachine, calendarMeta, cardAnatomy, cardMeta, carouselAnatomy, carouselMachine, carouselMeta, cascaderAnatomy, cascaderMachine, cascaderMeta, checkboxAnatomy, checkboxGroupAnatomy, checkboxGroupMachine, checkboxGroupMeta, checkboxMachine, checkboxMeta, clipboardAnatomy, clipboardMachine, clipboardMeta, codeBlockAnatomy, codeBlockMeta, collapsibleAnatomy, collapsibleMachine, collapsibleMeta, colorPickerAnatomy, colorPickerMachine, colorPickerMeta, colorPickerToChannel, colorPickerToInputChannel, comboboxAnatomy, comboboxMachine, comboboxMeta, composerAnatomy, composerMachine, composerMeta, connectAccordion, connectAffix, connectAlert, connectAnchor, connectAvatar, connectAvatarGroup, connectBackTop, connectBadge, connectBreadcrumb, connectButton, connectButtonGroup, connectCalendar, connectCard, connectCarousel, connectCascader, connectCheckbox, connectCheckboxGroup, connectClipboard, connectCodeBlock, connectCollapsible, connectColorPicker, connectCombobox, connectComposer, connectContextMenu, connectCountdown, connectDateField, connectDatePicker, connectDescriptions, connectDialog, connectDrawer, connectDynamicInput, connectEditable, connectEllipsis, connectEmptyState, connectField, connectFileUpload, connectFlex, connectFloatButton, connectForm, connectGradientText, connectGrid, connectHighlight, connectHoverCard, connectIcon, connectIconWrapper, connectImage, connectImageViewer, connectInfiniteScroll, connectLayout, connectList, connectListbox, connectLoadingBar, connectLog, connectMarquee, connectMention, connectMenu, connectMenubar, connectNavigationMenu, connectNumberAnimation, connectNumberField, connectPageHeader, connectPagination, connectPinInput, connectPopconfirm, connectPopover, connectPopselect, connectProgress, connectQrCode, connectRadioGroup, connectRating, connectResult, connectScrollArea, connectSelect, connectSeparator, connectSideNav, connectSkeleton, connectSlider, connectSpinner, connectSplitter, connectStatistic, connectSteps, connectSwitch, connectTable, connectTabs, connectTagsInput, connectTextField, connectThread, connectTime, connectTimeField, connectTimePicker, connectTimeline, connectToast, connectToaster, connectToggle, connectToggleGroup, connectToolbar, connectTooltip, connectTour, connectTransfer, connectTree, connectTreeSelect, connectTypography, connectVirtualizer, connectWatermark, contextMenuAnatomy, contextMenuMachine, contextMenuMeta, countdownAnatomy, countdownMachine, countdownMeta, dateFieldAnatomy, dateFieldMachine, dateFieldMeta, datePickerAnatomy, datePickerCalendarProps, datePickerFieldEndProps, datePickerFieldProps, datePickerMachine, datePickerMeta, descriptionsAnatomy, descriptionsMeta, dialogAnatomy, dialogMachine, dialogMeta, drawerAnatomy, drawerMachine, drawerMeta, dynamicInputAnatomy, dynamicInputMachine, dynamicInputMeta, editableAnatomy, editableMachine, editableMeta, ellipsisAnatomy, ellipsisMachine, ellipsisMeta, emptyStateAnatomy, emptyStateMeta, fieldAnatomy, fieldMeta, fileUploadAnatomy, fileUploadMachine, fileUploadMeta, flexAnatomy, flexMeta, floatButtonAnatomy, floatButtonMeta, formAnatomy, formMachine, formMeta, gradientTextAnatomy, gradientTextMeta, gridAnatomy, gridMeta, highlightAnatomy, highlightMeta, hoverCardAnatomy, hoverCardMachine, hoverCardMeta, iconAnatomy, iconMeta, iconWrapperAnatomy, iconWrapperMeta, imageAnatomy, imageMachine, imageMeta, imageViewerAnatomy, imageViewerCounterText, imageViewerMachine, imageViewerMeta, infiniteScrollAnatomy, infiniteScrollMachine, infiniteScrollMeta, layoutAnatomy, layoutMachine, layoutMeta, listAnatomy, listMeta, listboxAnatomy, listboxMachine, listboxMeta, loadingBarAnatomy, loadingBarMachine, loadingBarMeta, logAnatomy, logMeta, marqueeAnatomy, marqueeMeta, mentionAnatomy, mentionMachine, mentionMeta, menuAnatomy, menuMachine, menuMeta, menubarAnatomy, menubarMachine, menubarMeta, navigationMenuAnatomy, navigationMenuMachine, navigationMenuMeta, numberAnimationAnatomy, numberAnimationMachine, numberAnimationMeta, numberFieldAnatomy, numberFieldMachine, numberFieldMeta, pageHeaderAnatomy, pageHeaderMeta, paginationAnatomy, paginationMachine, paginationMeta, pinInputAnatomy, pinInputMachine, pinInputMeta, popconfirmAnatomy, popconfirmMeta, popoverAnatomy, popoverMachine, popoverMeta, popselectAnatomy, popselectInitialFocus, popselectMeta, progressAnatomy, progressMeta, qrCodeAnatomy, qrCodeMeta, radioGroupAnatomy, radioGroupMachine, radioGroupMeta, ratingAnatomy, ratingMachine, ratingMeta, resultAnatomy, resultMeta, scrollAreaAnatomy, scrollAreaMachine, scrollAreaMeta, selectAnatomy, selectMachine, selectMeta, separatorAnatomy, separatorMeta, sideNavAnatomy, sideNavMachine, sideNavMeta, skeletonAnatomy, skeletonMeta, sliderAnatomy, sliderMachine, sliderMeta, spinnerAnatomy, spinnerMeta, splitterAnatomy, splitterMachine, splitterMeta, statisticAnatomy, statisticMeta, stepsAnatomy, stepsMachine, stepsMeta, switchAnatomy, switchMachine, switchMeta, tableAnatomy, tableMachine, tableMeta, tabsAnatomy, tabsMachine, tabsMeta, tagsInputAnatomy, tagsInputMachine, tagsInputMeta, textFieldAnatomy, textFieldMachine, textFieldMeta, threadAnatomy, threadMachine, threadMeta, timeAnatomy, timeFieldAnatomy, timeFieldMachine, timeFieldMeta, timeMeta, timePickerAnatomy, timePickerMachine, timePickerMeta, timelineAnatomy, timelineMeta, toastAnatomy, toastMachine, toastMeta, toasterAnatomy, toasterMachine, toasterMeta, toggleAnatomy, toggleGroupAnatomy, toggleGroupMachine, toggleGroupMeta, toggleMachine, toggleMeta, toolbarAnatomy, toolbarMachine, toolbarMeta, tooltipAnatomy, tooltipMachine, tooltipMeta, tourAnatomy, tourMachine, tourMeta, transferAnatomy, transferFocusKey, transferMachine, transferMeta, treeAnatomy, treeMachine, treeMeta, treeSelectAnatomy, treeSelectMachine, treeSelectMeta, typographyAnatomy, typographyMeta, virtualizerAnatomy, virtualizerMachine, virtualizerMeta, watermarkAnatomy, watermarkMeta } from "@xihan-ui/headless";
7
7
  import { createPositionEngine } from "@xihan-ui/position";
8
8
  import { createHighlighter } from "@xihan-ui/code-highlight";
9
9
  //#region src/dom/part-contract.ts
@@ -302,7 +302,7 @@ var XhAccordionElement = class extends XhElement {
302
302
  };
303
303
  //#endregion
304
304
  //#region src/elements/affix.ts
305
- const NUMBER_CONVERTER$49 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
305
+ const NUMBER_CONVERTER$50 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
306
306
  /**
307
307
  * `<xh-affix>` —— 吸附行为宿主:滚过判定线就把 content 钉在滚动容器可视区的边上。
308
308
  *
@@ -325,11 +325,11 @@ var XhAffixElement = class extends XhElement {
325
325
  };
326
326
  static properties = {
327
327
  topOffset: {
328
- converter: NUMBER_CONVERTER$49,
328
+ converter: NUMBER_CONVERTER$50,
329
329
  attribute: "offset-top"
330
330
  },
331
331
  bottomOffset: {
332
- converter: NUMBER_CONVERTER$49,
332
+ converter: NUMBER_CONVERTER$50,
333
333
  attribute: "offset-bottom"
334
334
  },
335
335
  target: { attribute: false }
@@ -430,9 +430,9 @@ var XhAlertElement = class extends XhElement {
430
430
  };
431
431
  //#endregion
432
432
  //#region src/elements/anchor.ts
433
- const STRING_CONVERTER$79 = { fromAttribute: (v) => v ?? void 0 };
434
- const NUMBER_CONVERTER$48 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
435
- const BOOLEAN_CONVERTER$50 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
433
+ const STRING_CONVERTER$80 = { fromAttribute: (v) => v ?? void 0 };
434
+ const NUMBER_CONVERTER$49 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
435
+ const BOOLEAN_CONVERTER$52 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
436
436
  /**
437
437
  * `<xh-anchor>` —— 锚点导航行为宿主,激活项由机器的滚动观察器结算,
438
438
  * 目标区块按 link 上的 value 属性(或 targets 清单)里的 id 现查。
@@ -463,20 +463,20 @@ var XhAnchorElement = class extends XhElement {
463
463
  meta: anchorMeta
464
464
  };
465
465
  static properties = {
466
- value: { converter: STRING_CONVERTER$79 },
466
+ value: { converter: STRING_CONVERTER$80 },
467
467
  defaultValue: {
468
- converter: STRING_CONVERTER$79,
468
+ converter: STRING_CONVERTER$80,
469
469
  attribute: "default-value"
470
470
  },
471
- offset: { converter: NUMBER_CONVERTER$48 },
472
- smooth: { converter: BOOLEAN_CONVERTER$50 },
473
- orientation: { converter: STRING_CONVERTER$79 },
471
+ offset: { converter: NUMBER_CONVERTER$49 },
472
+ smooth: { converter: BOOLEAN_CONVERTER$52 },
473
+ orientation: { converter: STRING_CONVERTER$80 },
474
474
  direction: {
475
- converter: STRING_CONVERTER$79,
475
+ converter: STRING_CONVERTER$80,
476
476
  attribute: "dir"
477
477
  },
478
- tone: { converter: STRING_CONVERTER$79 },
479
- size: { converter: STRING_CONVERTER$79 },
478
+ tone: { converter: STRING_CONVERTER$80 },
479
+ size: { converter: STRING_CONVERTER$80 },
480
480
  targets: { attribute: false },
481
481
  translations: { attribute: false },
482
482
  scrollElement: { attribute: false }
@@ -531,7 +531,7 @@ var XhAnchorElement = class extends XhElement {
531
531
  };
532
532
  //#endregion
533
533
  //#region src/elements/avatar.ts
534
- const STRING_CONVERTER$78 = { fromAttribute: (v) => v ?? void 0 };
534
+ const STRING_CONVERTER$79 = { fromAttribute: (v) => v ?? void 0 };
535
535
  /**
536
536
  * `<xh-avatar>` —— 头像行为宿主,src/alt 写进 image 节点,加载成败回送机器,image 与 fallback 互斥显隐。
537
537
  *
@@ -550,9 +550,9 @@ var XhAvatarElement = class extends XhElement {
550
550
  meta: avatarMeta
551
551
  };
552
552
  static properties = {
553
- src: { converter: STRING_CONVERTER$78 },
554
- alt: { converter: STRING_CONVERTER$78 },
555
- size: { converter: STRING_CONVERTER$78 }
553
+ src: { converter: STRING_CONVERTER$79 },
554
+ alt: { converter: STRING_CONVERTER$79 },
555
+ size: { converter: STRING_CONVERTER$79 }
556
556
  };
557
557
  notify = (details) => {
558
558
  this.dispatchEvent(new CustomEvent("status-change", {
@@ -631,8 +631,8 @@ var XhAvatarGroupElement = class extends XhElement {
631
631
  };
632
632
  //#endregion
633
633
  //#region src/elements/back-top.ts
634
- const STRING_CONVERTER$77 = { fromAttribute: (v) => v ?? void 0 };
635
- const NUMBER_CONVERTER$47 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
634
+ const STRING_CONVERTER$78 = { fromAttribute: (v) => v ?? void 0 };
635
+ const NUMBER_CONVERTER$48 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
636
636
  /**
637
637
  * `<xh-back-top>` —— 回到顶部行为宿主:滚动量过线时露出按钮,点它滚回顶部。
638
638
  *
@@ -656,12 +656,12 @@ var XhBackTopElement = class extends XhElement {
656
656
  };
657
657
  static properties = {
658
658
  visibilityHeight: {
659
- converter: NUMBER_CONVERTER$47,
659
+ converter: NUMBER_CONVERTER$48,
660
660
  attribute: "visibility-height"
661
661
  },
662
- behavior: { converter: STRING_CONVERTER$77 },
663
- tone: { converter: STRING_CONVERTER$77 },
664
- size: { converter: STRING_CONVERTER$77 },
662
+ behavior: { converter: STRING_CONVERTER$78 },
663
+ tone: { converter: STRING_CONVERTER$78 },
664
+ size: { converter: STRING_CONVERTER$78 },
665
665
  translations: { attribute: false },
666
666
  target: { attribute: false }
667
667
  };
@@ -732,7 +732,7 @@ var XhBadgeElement = class extends XhElement {
732
732
  };
733
733
  //#endregion
734
734
  //#region src/elements/breadcrumb.ts
735
- const STRING_CONVERTER$76 = { fromAttribute: (v) => v ?? void 0 };
735
+ const STRING_CONVERTER$77 = { fromAttribute: (v) => v ?? void 0 };
736
736
  /** 读作者写在角色节点上的布尔声明:属性缺席或 ="false" 为假,其余为真。 */
737
737
  function authorFlag$1(el, name) {
738
738
  const raw = el.getAttribute(name);
@@ -762,11 +762,11 @@ var XhBreadcrumbElement = class extends XhElement {
762
762
  };
763
763
  static properties = {
764
764
  direction: {
765
- converter: STRING_CONVERTER$76,
765
+ converter: STRING_CONVERTER$77,
766
766
  attribute: "dir"
767
767
  },
768
- tone: { converter: STRING_CONVERTER$76 },
769
- size: { converter: STRING_CONVERTER$76 },
768
+ tone: { converter: STRING_CONVERTER$77 },
769
+ size: { converter: STRING_CONVERTER$77 },
770
770
  translations: { attribute: false }
771
771
  };
772
772
  wire() {
@@ -872,7 +872,7 @@ var XhButtonGroupElement = class extends XhElement {
872
872
  };
873
873
  //#endregion
874
874
  //#region src/elements/calendar.ts
875
- const STRING_CONVERTER$75 = { fromAttribute: (v) => v ?? void 0 };
875
+ const STRING_CONVERTER$76 = { fromAttribute: (v) => v ?? void 0 };
876
876
  /**
877
877
  * `<xh-calendar>` —— 日历行为宿主。
878
878
  *
@@ -916,32 +916,32 @@ var XhCalendarElement = class extends XhElement {
916
916
  meta: calendarMeta
917
917
  };
918
918
  static properties = {
919
- value: { converter: STRING_CONVERTER$75 },
919
+ value: { converter: STRING_CONVERTER$76 },
920
920
  defaultValue: {
921
- converter: STRING_CONVERTER$75,
921
+ converter: STRING_CONVERTER$76,
922
922
  attribute: "default-value"
923
923
  },
924
924
  selectionMode: {
925
- converter: STRING_CONVERTER$75,
925
+ converter: STRING_CONVERTER$76,
926
926
  attribute: "selection-mode"
927
927
  },
928
928
  focusedValue: {
929
- converter: STRING_CONVERTER$75,
929
+ converter: STRING_CONVERTER$76,
930
930
  attribute: "focused-value"
931
931
  },
932
932
  defaultFocusedValue: {
933
- converter: STRING_CONVERTER$75,
933
+ converter: STRING_CONVERTER$76,
934
934
  attribute: "default-focused-value"
935
935
  },
936
- min: { converter: STRING_CONVERTER$75 },
937
- max: { converter: STRING_CONVERTER$75 },
938
- locale: { converter: STRING_CONVERTER$75 },
936
+ min: { converter: STRING_CONVERTER$76 },
937
+ max: { converter: STRING_CONVERTER$76 },
938
+ locale: { converter: STRING_CONVERTER$76 },
939
939
  timeZone: {
940
- converter: STRING_CONVERTER$75,
940
+ converter: STRING_CONVERTER$76,
941
941
  attribute: "time-zone"
942
942
  },
943
943
  weekdayFormat: {
944
- converter: STRING_CONVERTER$75,
944
+ converter: STRING_CONVERTER$76,
945
945
  attribute: "weekday-format"
946
946
  },
947
947
  disabled: { type: Boolean },
@@ -1089,9 +1089,9 @@ var XhCardElement = class extends XhElement {
1089
1089
  };
1090
1090
  //#endregion
1091
1091
  //#region src/elements/carousel.ts
1092
- const STRING_CONVERTER$74 = { fromAttribute: (v) => v ?? void 0 };
1093
- const NUMBER_CONVERTER$46 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
1094
- const BOOLEAN_CONVERTER$49 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
1092
+ const STRING_CONVERTER$75 = { fromAttribute: (v) => v ?? void 0 };
1093
+ const NUMBER_CONVERTER$47 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
1094
+ const BOOLEAN_CONVERTER$51 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
1095
1095
  /**
1096
1096
  * autoplay 布尔或毫秒两用:缺席 = undefined,`autoplay` / `autoplay="true"` = 默认间隔,
1097
1097
  * `autoplay="false"` = 关,`autoplay="3000"` = 3 秒一张,念不成数的串按开着处理。
@@ -1145,35 +1145,35 @@ var XhCarouselElement = class extends XhElement {
1145
1145
  meta: carouselMeta
1146
1146
  };
1147
1147
  static properties = {
1148
- page: { converter: NUMBER_CONVERTER$46 },
1148
+ page: { converter: NUMBER_CONVERTER$47 },
1149
1149
  defaultPage: {
1150
- converter: NUMBER_CONVERTER$46,
1150
+ converter: NUMBER_CONVERTER$47,
1151
1151
  attribute: "default-page"
1152
1152
  },
1153
1153
  slideCount: {
1154
- converter: NUMBER_CONVERTER$46,
1154
+ converter: NUMBER_CONVERTER$47,
1155
1155
  attribute: "slide-count"
1156
1156
  },
1157
1157
  slidesPerPage: {
1158
- converter: NUMBER_CONVERTER$46,
1158
+ converter: NUMBER_CONVERTER$47,
1159
1159
  attribute: "slides-per-page"
1160
1160
  },
1161
1161
  slidesPerMove: {
1162
- converter: NUMBER_CONVERTER$46,
1162
+ converter: NUMBER_CONVERTER$47,
1163
1163
  attribute: "slides-per-move"
1164
1164
  },
1165
- orientation: { converter: STRING_CONVERTER$74 },
1165
+ orientation: { converter: STRING_CONVERTER$75 },
1166
1166
  direction: {
1167
- converter: STRING_CONVERTER$74,
1167
+ converter: STRING_CONVERTER$75,
1168
1168
  attribute: "dir"
1169
1169
  },
1170
- loop: { converter: BOOLEAN_CONVERTER$49 },
1170
+ loop: { converter: BOOLEAN_CONVERTER$51 },
1171
1171
  autoplay: { converter: AUTOPLAY_CONVERTER },
1172
1172
  allowPointerDrag: {
1173
- converter: BOOLEAN_CONVERTER$49,
1173
+ converter: BOOLEAN_CONVERTER$51,
1174
1174
  attribute: "allow-pointer-drag"
1175
1175
  },
1176
- spacing: { converter: STRING_CONVERTER$74 },
1176
+ spacing: { converter: STRING_CONVERTER$75 },
1177
1177
  translations: { attribute: false }
1178
1178
  };
1179
1179
  notify = (details) => {
@@ -1223,9 +1223,9 @@ var XhCarouselElement = class extends XhElement {
1223
1223
  };
1224
1224
  //#endregion
1225
1225
  //#region src/elements/cascader.ts
1226
- const STRING_CONVERTER$73 = { fromAttribute: (v) => v ?? void 0 };
1227
- const NUMBER_CONVERTER$45 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
1228
- const BOOLEAN_CONVERTER$48 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
1226
+ const STRING_CONVERTER$74 = { fromAttribute: (v) => v ?? void 0 };
1227
+ const NUMBER_CONVERTER$46 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
1228
+ const BOOLEAN_CONVERTER$50 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
1229
1229
  /** 条目一系的归属容器:文本与勾选标记向上找最近的那个条目。 */
1230
1230
  const ITEM_SELECTOR$4 = "[data-xh-part=\"item\"]";
1231
1231
  /**
@@ -1251,6 +1251,9 @@ const ITEM_SELECTOR$4 = "[data-xh-part=\"item\"]";
1251
1251
  * @attr {'click'|'hover'} expand-trigger - 子列由点还是悬停展开,默认 click
1252
1252
  * @attr {boolean} change-on-select - 中间层(分支)也能落值
1253
1253
  * @attr {boolean} multiple - 多选:选中后浮层不收起,焦点留在列里
1254
+ * @attr {boolean} searchable - 开启搜索:input 部件可用,输入后整条路径连缀过滤、候选替换列视图
1255
+ * @attr {boolean} cascade - 多选下父子级联勾选(整枝传导/半选/禁用冻结),默认 false
1256
+ * @attr {string} checked-strategy - 级联下对外值的收敛策略:child(默认)/ parent / all
1254
1257
  * @attr {boolean} disabled - 整个控件禁用:trigger 用原生 disabled,浮层展不开
1255
1258
  * @attr {boolean} read-only - 只读:浮层照常展开、列照常浏览,但选中值改不动、也清不掉
1256
1259
  * @attr {boolean} invalid - 校验失败标注
@@ -1272,7 +1275,11 @@ const ITEM_SELECTOR$4 = "[data-xh-part=\"item\"]";
1272
1275
  * @csspart indicator - 展开指示符(aria-hidden,data-state 随开合)
1273
1276
  * @csspart clear-trigger - 清空按钮,须是原生 button;不占 Tab 位且对读屏隐藏
1274
1277
  * @csspart positioner - 浮层定位容器,坐标由引擎写成内联样式
1275
- * @csspart content - 浮层壳(焦点域与消解层的根节点),键盘在此收口,收起时带 hidden
1278
+ * @csspart content - 浮层壳(焦点域与消解层的根节点),键盘在此收口,收起时带 hidden;根列没有条目时带 data-empty
1279
+ * @csspart input - 搜索框(content 顶部);没开 searchable 时带 hidden。上下键走候选、Enter 选中、Escape 先清词
1280
+ * @csspart search-list - 候选列表容器;不在搜索视图时带 hidden,无候选时带 data-empty
1281
+ * @csspart search-item - 一条候选,须用 value 属性写整条路径的 JSON 数组串(如 value='["a","b"]');词换了不匹配的带 hidden
1282
+ * @csspart empty - 空态占位:搜索无候选或 collection 为空时露面,其余时候带 hidden。标记里没写就由元素在 content 末尾补一个并填缺省文案;写了就用作者那份,文案也归作者
1276
1283
  * @csspart column - role=listbox 的一列,须自带 level 属性标识它是第几列;砍掉时带 hidden
1277
1284
  * @csspart item - role=option 的条目,须自带 value 属性标识身份;不在当前列里时带 hidden
1278
1285
  * @csspart item-text - 条目文本
@@ -1287,36 +1294,43 @@ var XhCascaderElement = class extends XhElement {
1287
1294
  collection: { attribute: false },
1288
1295
  value: { attribute: false },
1289
1296
  defaultValue: { attribute: false },
1290
- open: { converter: BOOLEAN_CONVERTER$48 },
1297
+ open: { converter: BOOLEAN_CONVERTER$50 },
1291
1298
  defaultOpen: {
1292
1299
  type: Boolean,
1293
1300
  attribute: "default-open"
1294
1301
  },
1295
1302
  expandTrigger: {
1296
- converter: STRING_CONVERTER$73,
1303
+ converter: STRING_CONVERTER$74,
1297
1304
  attribute: "expand-trigger"
1298
1305
  },
1299
1306
  changeOnSelect: {
1300
- converter: BOOLEAN_CONVERTER$48,
1307
+ converter: BOOLEAN_CONVERTER$50,
1301
1308
  attribute: "change-on-select"
1302
1309
  },
1303
1310
  multiple: { type: Boolean },
1311
+ searchable: { type: Boolean },
1312
+ cascade: { type: Boolean },
1313
+ checkedStrategy: {
1314
+ converter: STRING_CONVERTER$74,
1315
+ attribute: "checked-strategy"
1316
+ },
1304
1317
  disabled: { type: Boolean },
1305
1318
  readOnly: {
1306
- converter: BOOLEAN_CONVERTER$48,
1319
+ converter: BOOLEAN_CONVERTER$50,
1307
1320
  attribute: "read-only"
1308
1321
  },
1309
- invalid: { converter: BOOLEAN_CONVERTER$48 },
1310
- variant: { converter: STRING_CONVERTER$73 },
1311
- tone: { converter: STRING_CONVERTER$73 },
1312
- size: { converter: STRING_CONVERTER$73 },
1313
- placeholder: { converter: STRING_CONVERTER$73 },
1314
- separator: { converter: STRING_CONVERTER$73 },
1315
- placement: { converter: STRING_CONVERTER$73 },
1316
- offset: { converter: NUMBER_CONVERTER$45 },
1317
- loop: { converter: BOOLEAN_CONVERTER$48 },
1322
+ invalid: { converter: BOOLEAN_CONVERTER$50 },
1323
+ variant: { converter: STRING_CONVERTER$74 },
1324
+ tone: { converter: STRING_CONVERTER$74 },
1325
+ size: { converter: STRING_CONVERTER$74 },
1326
+ placeholder: { converter: STRING_CONVERTER$74 },
1327
+ separator: { converter: STRING_CONVERTER$74 },
1328
+ translations: { attribute: false },
1329
+ placement: { converter: STRING_CONVERTER$74 },
1330
+ offset: { converter: NUMBER_CONVERTER$46 },
1331
+ loop: { converter: BOOLEAN_CONVERTER$50 },
1318
1332
  direction: {
1319
- converter: STRING_CONVERTER$73,
1333
+ converter: STRING_CONVERTER$74,
1320
1334
  attribute: "dir"
1321
1335
  }
1322
1336
  };
@@ -1326,6 +1340,8 @@ var XhCascaderElement = class extends XhElement {
1326
1340
  config = null;
1327
1341
  /** value-text 是否归元素填:首次见到该节点时定,之后不再回读(回读到的会是自己写的字)。 */
1328
1342
  ownsValueText = /* @__PURE__ */ new WeakMap();
1343
+ /** 空态占位的文案是否归元素填,判定同 ownsValueText。 */
1344
+ ownsEmptyText = /* @__PURE__ */ new WeakMap();
1329
1345
  notifyValue = (details) => {
1330
1346
  this.dispatchEvent(new CustomEvent("value-change", {
1331
1347
  detail: details,
@@ -1354,6 +1370,9 @@ var XhCascaderElement = class extends XhElement {
1354
1370
  expandTrigger: this.expandTrigger,
1355
1371
  changeOnSelect: this.changeOnSelect ?? false,
1356
1372
  multiple: this.multiple ?? false,
1373
+ searchable: this.searchable ?? false,
1374
+ cascade: this.cascade,
1375
+ checkedStrategy: this.checkedStrategy,
1357
1376
  disabled: this.disabled ?? false,
1358
1377
  readOnly: this.readOnly ?? false,
1359
1378
  invalid: this.invalid ?? false,
@@ -1366,6 +1385,7 @@ var XhCascaderElement = class extends XhElement {
1366
1385
  offset: this.offset,
1367
1386
  loop: this.loop,
1368
1387
  dir: this.direction,
1388
+ translations: this.translations,
1369
1389
  onValueChange: this.notifyValue,
1370
1390
  onOpenChange: this.notifyOpen
1371
1391
  };
@@ -1434,16 +1454,30 @@ var XhCascaderElement = class extends XhElement {
1434
1454
  stripNativeDisabled(el) {
1435
1455
  if (el.hasAttribute("disabled")) el.removeAttribute("disabled");
1436
1456
  }
1437
- /** 把整条路径的文字填进 value-text;首次见到该节点时若已有内容则判为归作者,之后一概不碰。 */
1438
- fillValueText(el, text) {
1439
- let owned = this.ownsValueText.get(el);
1457
+ /** 把文字填进角色节点;首次见到该节点时若已有内容则判为归作者,之后一概不碰。 */
1458
+ fillOwnedText(owns, el, text) {
1459
+ let owned = owns.get(el);
1440
1460
  if (owned === void 0) {
1441
1461
  owned = (el.textContent ?? "").trim() === "";
1442
- this.ownsValueText.set(el, owned);
1462
+ owns.set(el, owned);
1443
1463
  }
1444
1464
  if (!owned || el.textContent === text) return;
1445
1465
  el.textContent = text;
1446
1466
  }
1467
+ /**
1468
+ * 取空态占位;标记里没写就在 content 末尾补一个,位置与 Vue 侧一致。
1469
+ * 作者写了就用作者那份,只接线不新建。补出来的节点下一轮由 discoverParts 收进 partMap。
1470
+ */
1471
+ ensureEmpty() {
1472
+ const existing = this.getPart("empty");
1473
+ if (existing) return existing;
1474
+ const content = this.getPart("content");
1475
+ if (!content) return null;
1476
+ const el = this.ownerDocument.createElement("div");
1477
+ el.setAttribute(PART_ATTR, "empty");
1478
+ content.append(el);
1479
+ return el;
1480
+ }
1447
1481
  wire() {
1448
1482
  const api = connectCascader(this.ctrl.service, wcNormalize);
1449
1483
  const put = (name, props) => {
@@ -1457,10 +1491,28 @@ var XhCascaderElement = class extends XhElement {
1457
1491
  put("clear-trigger", api.getClearTriggerProps());
1458
1492
  put("positioner", api.getPositionerProps());
1459
1493
  put("content", api.getContentProps());
1494
+ put("input", api.getInputProps());
1495
+ put("search-list", api.getSearchListProps());
1496
+ const empty = this.ensureEmpty();
1497
+ if (empty) {
1498
+ this.spreader.spread(empty, api.getEmptyProps());
1499
+ this.fillOwnedText(this.ownsEmptyText, empty, api.searching ? api.translations.noMatch : api.translations.empty);
1500
+ }
1501
+ for (const el of this.getParts("search-item")) {
1502
+ const raw = el.getAttribute("value") ?? "[]";
1503
+ let path = [];
1504
+ try {
1505
+ const parsed = JSON.parse(raw);
1506
+ if (Array.isArray(parsed)) path = parsed.map(String);
1507
+ } catch {
1508
+ path = [];
1509
+ }
1510
+ this.spreader.spread(el, api.getSearchItemProps({ path }));
1511
+ }
1460
1512
  const valueText = this.getPart("value-text");
1461
1513
  if (valueText) {
1462
1514
  this.spreader.spread(valueText, api.getValueTextProps());
1463
- this.fillValueText(valueText, api.displayText);
1515
+ this.fillOwnedText(this.ownsValueText, valueText, api.displayText);
1464
1516
  }
1465
1517
  this.getParts("column").forEach((el, position) => {
1466
1518
  this.spreader.spread(el, api.getColumnProps({ level: this.levelOf(el, position) }));
@@ -1496,6 +1548,8 @@ var XhCascaderElement = class extends XhElement {
1496
1548
  * @fires checked-change - checked 状态变化;detail 为 `{ checked: boolean }`
1497
1549
  * @csspart root - role=checkbox 的按钮(承载 aria-checked / data-state)
1498
1550
  * @csspart indicator - 选中标记
1551
+ * @attr {string} name - 表单字段名;给了 hidden-input 才参与提交
1552
+ * @csspart hidden-input - type=hidden 的表单出口,省略该节点即不参与表单
1499
1553
  */
1500
1554
  var XhCheckboxElement = class extends XhElement {
1501
1555
  static partContract = {
@@ -1509,6 +1563,8 @@ var XhCheckboxElement = class extends XhElement {
1509
1563
  converter: { fromAttribute: (v) => v === null ? void 0 : v === "indeterminate" ? "indeterminate" : v !== "false" }
1510
1564
  },
1511
1565
  disabled: { type: Boolean },
1566
+ name: { converter: { fromAttribute: (v) => v ?? void 0 } },
1567
+ value: { converter: { fromAttribute: (v) => v ?? void 0 } },
1512
1568
  tone: {},
1513
1569
  size: {}
1514
1570
  };
@@ -1527,6 +1583,8 @@ var XhCheckboxElement = class extends XhElement {
1527
1583
  disabled: this.disabled ?? false,
1528
1584
  tone: this.tone,
1529
1585
  size: this.size,
1586
+ name: this.name,
1587
+ value: this.value,
1530
1588
  onCheckedChange: this.notify
1531
1589
  };
1532
1590
  }
@@ -1536,6 +1594,8 @@ var XhCheckboxElement = class extends XhElement {
1536
1594
  if (root) this.spreader.spread(root, api.getRootProps());
1537
1595
  const indicator = this.getPart("indicator");
1538
1596
  if (indicator) this.spreader.spread(indicator, api.getIndicatorProps());
1597
+ const hidden = this.getPart("hidden-input");
1598
+ if (hidden) this.spreader.spread(hidden, api.getHiddenInputProps());
1539
1599
  }
1540
1600
  };
1541
1601
  //#endregion
@@ -1555,12 +1615,12 @@ function createDeclaredDisabled() {
1555
1615
  }
1556
1616
  //#endregion
1557
1617
  //#region src/elements/checkbox-group.ts
1558
- const STRING_CONVERTER$72 = { fromAttribute: (v) => v ?? void 0 };
1559
- const BOOLEAN_CONVERTER$47 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
1618
+ const STRING_CONVERTER$73 = { fromAttribute: (v) => v ?? void 0 };
1619
+ const BOOLEAN_CONVERTER$49 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
1560
1620
  const LIST_CONVERTER = { fromAttribute: (v) => v === null ? void 0 : v.split(",").map((s) => s.trim()).filter(Boolean) };
1561
1621
  /**
1562
1622
  * `<xh-checkbox-group>` —— Light-DOM 行为宿主:作者写 root/label 与若干 item 角色节点,
1563
- * 每个 item 内自带 item-hidden-input/item-control/item-text,元素跑 checkbox-group 机器
1623
+ * 每个 item 内自带 hidden-input/indicator/item-text,元素跑 checkbox-group 机器
1564
1624
  * 并把 connect 产出打上去。条目身份取自条目节点上的 value 属性。
1565
1625
  *
1566
1626
  * 不做 roving tabindex:组内每一项都是独立的 Tab 停靠点(禁用项也保留),容器自己不占位。
@@ -1578,9 +1638,9 @@ const LIST_CONVERTER = { fromAttribute: (v) => v === null ? void 0 : v.split(","
1578
1638
  * @csspart root - role=group 容器
1579
1639
  * @csspart label - 组标题(aria-labelledby 目标)
1580
1640
  * @csspart item - role=checkbox 条目,作者用 value 属性声明身份
1581
- * @csspart item-control - 条目的视觉方框(对读屏隐藏)
1641
+ * @csspart indicator - 条目的视觉方框(对读屏隐藏)
1582
1642
  * @csspart item-text - 条目文本,条目的可及名来源
1583
- * @csspart item-hidden-input - 条目的表单影子输入(必须是原生 input)
1643
+ * @csspart hidden-input - 条目的表单影子输入(必须是原生 input)
1584
1644
  * @csspart trigger - 全选/半选的父复选框,须写在 root 之内
1585
1645
  */
1586
1646
  var XhCheckboxGroupElement = class extends XhElement {
@@ -1599,14 +1659,14 @@ var XhCheckboxGroupElement = class extends XhElement {
1599
1659
  converter: LIST_CONVERTER,
1600
1660
  attribute: "item-values"
1601
1661
  },
1602
- disabled: { converter: BOOLEAN_CONVERTER$47 },
1662
+ disabled: { converter: BOOLEAN_CONVERTER$49 },
1603
1663
  readOnly: {
1604
- converter: BOOLEAN_CONVERTER$47,
1664
+ converter: BOOLEAN_CONVERTER$49,
1605
1665
  attribute: "read-only"
1606
1666
  },
1607
- invalid: { converter: BOOLEAN_CONVERTER$47 },
1608
- orientation: { converter: STRING_CONVERTER$72 },
1609
- name: { converter: STRING_CONVERTER$72 }
1667
+ invalid: { converter: BOOLEAN_CONVERTER$49 },
1668
+ orientation: { converter: STRING_CONVERTER$73 },
1669
+ name: { converter: STRING_CONVERTER$73 }
1610
1670
  };
1611
1671
  /** 条目自身 disabled 声明的快照,整组禁用期间 DOM 上的 aria-disabled 不可信。 */
1612
1672
  declaredDisabled = /* @__PURE__ */ new WeakMap();
@@ -1685,8 +1745,8 @@ var XhCheckboxGroupElement = class extends XhElement {
1685
1745
  for (const el of this.getParts("item")) {
1686
1746
  const item = this.itemProps(el);
1687
1747
  this.spreader.spread(el, api.getItemProps(item));
1688
- for (const input of this.partsIn(el, "item-hidden-input")) this.spreadHiddenInput(input, api.getItemHiddenInputProps(item));
1689
- for (const control of this.partsIn(el, "item-control")) this.spreader.spread(control, api.getItemControlProps(item));
1748
+ for (const input of this.partsIn(el, "hidden-input")) this.spreadHiddenInput(input, api.getHiddenInputProps(item));
1749
+ for (const control of this.partsIn(el, "indicator")) this.spreader.spread(control, api.getIndicatorProps(item));
1690
1750
  for (const text of this.partsIn(el, "item-text")) this.spreader.spread(text, api.getItemTextProps(item));
1691
1751
  }
1692
1752
  this.wasGroupDisabled = !!this.disabled;
@@ -1694,8 +1754,8 @@ var XhCheckboxGroupElement = class extends XhElement {
1694
1754
  };
1695
1755
  //#endregion
1696
1756
  //#region src/elements/clipboard.ts
1697
- const STRING_CONVERTER$71 = { fromAttribute: (v) => v ?? void 0 };
1698
- const NUMBER_CONVERTER$44 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
1757
+ const STRING_CONVERTER$72 = { fromAttribute: (v) => v ?? void 0 };
1758
+ const NUMBER_CONVERTER$45 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
1699
1759
  /**
1700
1760
  * `<xh-clipboard>` —— Light-DOM 行为宿主,跑 clipboard 机器并把 connect 产出打到角色节点上。
1701
1761
  *
@@ -1722,8 +1782,8 @@ var XhClipboardElement = class extends XhElement {
1722
1782
  meta: clipboardMeta
1723
1783
  };
1724
1784
  static properties = {
1725
- value: { converter: STRING_CONVERTER$71 },
1726
- timeout: { converter: NUMBER_CONVERTER$44 }
1785
+ value: { converter: STRING_CONVERTER$72 },
1786
+ timeout: { converter: NUMBER_CONVERTER$45 }
1727
1787
  };
1728
1788
  notifyStatus = (details) => {
1729
1789
  this.dispatchEvent(new CustomEvent("status-change", {
@@ -1770,8 +1830,8 @@ var XhClipboardElement = class extends XhElement {
1770
1830
  //#region src/elements/code-block.ts
1771
1831
  /** 默认着色实现全元素共用一份:它无状态,没必要每个块建一个。 */
1772
1832
  const defaultHighlighter = createHighlighter();
1773
- const STRING_CONVERTER$70 = { fromAttribute: (v) => v ?? void 0 };
1774
- const BOOLEAN_CONVERTER$46 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
1833
+ const STRING_CONVERTER$71 = { fromAttribute: (v) => v ?? void 0 };
1834
+ const BOOLEAN_CONVERTER$48 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
1775
1835
  /**
1776
1836
  * `<xh-code-block>` —— Light-DOM 行为宿主,无状态机:wire 时算出 connectCodeBlock 的产出,
1777
1837
  * 打到四类角色节点上。显示的代码文本由作者写在 code 角色节点里,元素不改其子节点。
@@ -1793,14 +1853,14 @@ var XhCodeBlockElement = class extends XhElement {
1793
1853
  meta: codeBlockMeta
1794
1854
  };
1795
1855
  static properties = {
1796
- code: { converter: STRING_CONVERTER$70 },
1856
+ code: { converter: STRING_CONVERTER$71 },
1797
1857
  codeLang: {
1798
- converter: STRING_CONVERTER$70,
1858
+ converter: STRING_CONVERTER$71,
1799
1859
  attribute: "code-lang"
1800
1860
  },
1801
- complete: { converter: BOOLEAN_CONVERTER$46 },
1861
+ complete: { converter: BOOLEAN_CONVERTER$48 },
1802
1862
  highlightWhileStreaming: {
1803
- converter: BOOLEAN_CONVERTER$46,
1863
+ converter: BOOLEAN_CONVERTER$48,
1804
1864
  attribute: "highlight-while-streaming"
1805
1865
  }
1806
1866
  };
@@ -1915,9 +1975,9 @@ var XhCollapsibleElement = class extends XhElement {
1915
1975
  };
1916
1976
  //#endregion
1917
1977
  //#region src/elements/color-picker.ts
1918
- const STRING_CONVERTER$69 = { fromAttribute: (v) => v ?? void 0 };
1919
- const NUMBER_CONVERTER$43 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
1920
- const BOOLEAN_CONVERTER$45 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
1978
+ const STRING_CONVERTER$70 = { fromAttribute: (v) => v ?? void 0 };
1979
+ const NUMBER_CONVERTER$44 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
1980
+ const BOOLEAN_CONVERTER$47 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
1921
1981
  /** 预设色板写成逗号分隔(swatches="#ff0000,#00ff00"),空串当没写。 */
1922
1982
  const STRING_LIST_CONVERTER = { fromAttribute: (v) => {
1923
1983
  if (v == null || v.trim() === "") return void 0;
@@ -1949,6 +2009,7 @@ const STRING_LIST_CONVERTER = { fromAttribute: (v) => {
1949
2009
  * @attr {'ltr'|'rtl'} dir - 文字方向,只改写横轴上左右两键与指针的语义,默认 ltr
1950
2010
  * @attr {string} placement - 首选放置位,默认 bottom-start;避让后的实际位写在 data-placement 上
1951
2011
  * @attr {number} offset - 浮层与锚点的间距(px)
2012
+ * @attr {string} name - 表单字段名;给了 hidden-input 才带 name 并参与提交
1952
2013
  * @fires value-change - 颜色变化;detail 为 `{ value: string }`
1953
2014
  * @fires open-change - open 状态变化;detail 为 `{ open: boolean }`
1954
2015
  * @csspart root - 组件根容器(承载 data-state/data-disabled/data-readonly)
@@ -1967,6 +2028,7 @@ const STRING_LIST_CONVERTER = { fromAttribute: (v) => {
1967
2028
  * @csspart eye-dropper-trigger - 屏幕取色按钮,须是原生 button;环境不支持时自动禁用
1968
2029
  * @csspart swatch-group - role=group 的预设色板容器
1969
2030
  * @csspart swatch-item - 预设色板一格,须是原生 button 且自带 value 属性
2031
+ * @csspart hidden-input - type=hidden 的表单出口,值是当前颜色串;作者不写这个部件就不参与提交
1970
2032
  */
1971
2033
  var XhColorPickerElement = class extends XhElement {
1972
2034
  static partContract = {
@@ -1974,30 +2036,31 @@ var XhColorPickerElement = class extends XhElement {
1974
2036
  meta: colorPickerMeta
1975
2037
  };
1976
2038
  static properties = {
1977
- value: { converter: STRING_CONVERTER$69 },
2039
+ value: { converter: STRING_CONVERTER$70 },
1978
2040
  defaultValue: {
1979
- converter: STRING_CONVERTER$69,
2041
+ converter: STRING_CONVERTER$70,
1980
2042
  attribute: "default-value"
1981
2043
  },
1982
- format: { converter: STRING_CONVERTER$69 },
1983
- open: { converter: BOOLEAN_CONVERTER$45 },
2044
+ format: { converter: STRING_CONVERTER$70 },
2045
+ open: { converter: BOOLEAN_CONVERTER$47 },
1984
2046
  defaultOpen: {
1985
2047
  type: Boolean,
1986
2048
  attribute: "default-open"
1987
2049
  },
1988
- disabled: { converter: BOOLEAN_CONVERTER$45 },
2050
+ disabled: { converter: BOOLEAN_CONVERTER$47 },
1989
2051
  readOnly: {
1990
- converter: BOOLEAN_CONVERTER$45,
2052
+ converter: BOOLEAN_CONVERTER$47,
1991
2053
  attribute: "read-only"
1992
2054
  },
1993
- alpha: { converter: BOOLEAN_CONVERTER$45 },
2055
+ alpha: { converter: BOOLEAN_CONVERTER$47 },
1994
2056
  swatches: { converter: STRING_LIST_CONVERTER },
2057
+ name: { converter: STRING_CONVERTER$70 },
1995
2058
  direction: {
1996
- converter: STRING_CONVERTER$69,
2059
+ converter: STRING_CONVERTER$70,
1997
2060
  attribute: "dir"
1998
2061
  },
1999
- placement: { converter: STRING_CONVERTER$69 },
2000
- offset: { converter: NUMBER_CONVERTER$43 },
2062
+ placement: { converter: STRING_CONVERTER$70 },
2063
+ offset: { converter: NUMBER_CONVERTER$44 },
2001
2064
  translations: { attribute: false }
2002
2065
  };
2003
2066
  idGen = createCounterIdGenerator();
@@ -2033,6 +2096,7 @@ var XhColorPickerElement = class extends XhElement {
2033
2096
  readOnly: this.readOnly ?? false,
2034
2097
  alpha: this.alpha ?? false,
2035
2098
  swatches: this.swatches,
2099
+ name: this.name,
2036
2100
  dir: this.direction,
2037
2101
  placement: this.placement,
2038
2102
  offset: this.offset,
@@ -2111,6 +2175,7 @@ var XhColorPickerElement = class extends XhElement {
2111
2175
  put("area-thumb", api.getAreaThumbProps());
2112
2176
  put("eye-dropper-trigger", api.getEyeDropperTriggerProps());
2113
2177
  put("swatch-group", api.getSwatchGroupProps());
2178
+ put("hidden-input", api.getHiddenInputProps());
2114
2179
  const valueText = this.getPart("value-text");
2115
2180
  if (valueText) {
2116
2181
  this.spreader.spread(valueText, api.getValueTextProps());
@@ -2136,9 +2201,9 @@ var XhColorPickerElement = class extends XhElement {
2136
2201
  };
2137
2202
  //#endregion
2138
2203
  //#region src/elements/combobox.ts
2139
- const STRING_CONVERTER$68 = { fromAttribute: (v) => v ?? void 0 };
2140
- const NUMBER_CONVERTER$42 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
2141
- const BOOLEAN_CONVERTER$44 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
2204
+ const STRING_CONVERTER$69 = { fromAttribute: (v) => v ?? void 0 };
2205
+ const NUMBER_CONVERTER$43 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
2206
+ const BOOLEAN_CONVERTER$46 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
2142
2207
  /**
2143
2208
  * `<xh-combobox>` —— Light-DOM 行为宿主:作者写 root/label/control/input/trigger/positioner/content/item/...
2144
2209
  * 角色节点,元素跑 combobox 机器并把 connect 产出打上去。浮层定位引擎在本元素里建好、经 refs 注入机器,
@@ -2186,6 +2251,8 @@ const BOOLEAN_CONVERTER$44 = { fromAttribute: (v) => v === null ? void 0 : v !==
2186
2251
  * @csspart item-indicator - 候选选中标记(aria-hidden)
2187
2252
  * @csspart item-group - role=group 分组容器,须自带 value 属性标识身份
2188
2253
  * @csspart item-group-label - 分组标题(本组 aria-labelledby 的目标)
2254
+ * @attr {string} name - 表单字段名;给了 hidden-input 才参与提交(多选按逗号拼成一串)
2255
+ * @csspart hidden-input - type=hidden 的表单出口,省略该节点即不参与表单
2189
2256
  * @csspart empty - 无匹配项提示;须放在 positioner 里当 content 的兄弟(列表内只允许 option 与 group)
2190
2257
  */
2191
2258
  var XhComboboxElement = class extends XhElement {
@@ -2195,20 +2262,21 @@ var XhComboboxElement = class extends XhElement {
2195
2262
  };
2196
2263
  static properties = {
2197
2264
  collection: { attribute: false },
2198
- value: { converter: STRING_CONVERTER$68 },
2265
+ name: { converter: STRING_CONVERTER$69 },
2266
+ value: { converter: STRING_CONVERTER$69 },
2199
2267
  defaultValue: {
2200
- converter: STRING_CONVERTER$68,
2268
+ converter: STRING_CONVERTER$69,
2201
2269
  attribute: "default-value"
2202
2270
  },
2203
2271
  inputValue: {
2204
- converter: STRING_CONVERTER$68,
2272
+ converter: STRING_CONVERTER$69,
2205
2273
  attribute: "input-value"
2206
2274
  },
2207
2275
  defaultInputValue: {
2208
- converter: STRING_CONVERTER$68,
2276
+ converter: STRING_CONVERTER$69,
2209
2277
  attribute: "default-input-value"
2210
2278
  },
2211
- open: { converter: BOOLEAN_CONVERTER$44 },
2279
+ open: { converter: BOOLEAN_CONVERTER$46 },
2212
2280
  defaultOpen: {
2213
2281
  type: Boolean,
2214
2282
  attribute: "default-open"
@@ -2216,12 +2284,12 @@ var XhComboboxElement = class extends XhElement {
2216
2284
  multiple: { type: Boolean },
2217
2285
  disabled: { type: Boolean },
2218
2286
  readOnly: {
2219
- converter: BOOLEAN_CONVERTER$44,
2287
+ converter: BOOLEAN_CONVERTER$46,
2220
2288
  attribute: "read-only"
2221
2289
  },
2222
- invalid: { converter: BOOLEAN_CONVERTER$44 },
2223
- loop: { converter: BOOLEAN_CONVERTER$44 },
2224
- placeholder: { converter: STRING_CONVERTER$68 },
2290
+ invalid: { converter: BOOLEAN_CONVERTER$46 },
2291
+ loop: { converter: BOOLEAN_CONVERTER$46 },
2292
+ placeholder: { converter: STRING_CONVERTER$69 },
2225
2293
  allowCustomValue: {
2226
2294
  type: Boolean,
2227
2295
  attribute: "allow-custom-value"
@@ -2231,14 +2299,14 @@ var XhComboboxElement = class extends XhElement {
2231
2299
  attribute: "open-on-click"
2232
2300
  },
2233
2301
  inputBehavior: {
2234
- converter: STRING_CONVERTER$68,
2302
+ converter: STRING_CONVERTER$69,
2235
2303
  attribute: "input-behavior"
2236
2304
  },
2237
- placement: { converter: STRING_CONVERTER$68 },
2238
- offset: { converter: NUMBER_CONVERTER$42 },
2239
- variant: { converter: STRING_CONVERTER$68 },
2240
- tone: { converter: STRING_CONVERTER$68 },
2241
- size: { converter: STRING_CONVERTER$68 }
2305
+ placement: { converter: STRING_CONVERTER$69 },
2306
+ offset: { converter: NUMBER_CONVERTER$43 },
2307
+ variant: { converter: STRING_CONVERTER$69 },
2308
+ tone: { converter: STRING_CONVERTER$69 },
2309
+ size: { converter: STRING_CONVERTER$69 }
2242
2310
  };
2243
2311
  idGen = createCounterIdGenerator();
2244
2312
  comboboxScope = createScope(null, this.idGen);
@@ -2285,6 +2353,7 @@ var XhComboboxElement = class extends XhElement {
2285
2353
  readOnly: this.readOnly ?? false,
2286
2354
  invalid: this.invalid ?? false,
2287
2355
  loop: this.loop,
2356
+ name: this.name,
2288
2357
  placeholder: this.placeholder,
2289
2358
  allowCustomValue: this.allowCustomValue ?? false,
2290
2359
  openOnClick: this.openOnClick ?? false,
@@ -2354,6 +2423,7 @@ var XhComboboxElement = class extends XhElement {
2354
2423
  put("positioner", api.getPositionerProps());
2355
2424
  put("content", api.getContentProps());
2356
2425
  put("empty", api.getEmptyProps());
2426
+ put("hidden-input", api.getHiddenInputProps());
2357
2427
  for (const el of this.getParts("item-group")) {
2358
2428
  const group = { value: el.getAttribute("value") ?? "" };
2359
2429
  this.spreader.spread(el, api.getItemGroupProps(group));
@@ -2379,8 +2449,8 @@ var XhComboboxElement = class extends XhElement {
2379
2449
  };
2380
2450
  //#endregion
2381
2451
  //#region src/elements/composer.ts
2382
- const STRING_CONVERTER$67 = { fromAttribute: (v) => v ?? void 0 };
2383
- const BOOLEAN_CONVERTER$43 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
2452
+ const STRING_CONVERTER$68 = { fromAttribute: (v) => v ?? void 0 };
2453
+ const BOOLEAN_CONVERTER$45 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
2384
2454
  /**
2385
2455
  * `<xh-composer>` —— Light-DOM 行为宿主:跑 composer 机器,把 connect 产出打到作者写的
2386
2456
  * root/input/submit-trigger 三类角色节点上。input 须是原生 `<textarea>`,值经 property 写、
@@ -2406,18 +2476,18 @@ var XhComposerElement = class extends XhElement {
2406
2476
  meta: composerMeta
2407
2477
  };
2408
2478
  static properties = {
2409
- value: { converter: STRING_CONVERTER$67 },
2479
+ value: { converter: STRING_CONVERTER$68 },
2410
2480
  defaultValue: {
2411
- converter: STRING_CONVERTER$67,
2481
+ converter: STRING_CONVERTER$68,
2412
2482
  attribute: "default-value"
2413
2483
  },
2414
- disabled: { converter: BOOLEAN_CONVERTER$43 },
2484
+ disabled: { converter: BOOLEAN_CONVERTER$45 },
2415
2485
  runStatus: {
2416
- converter: STRING_CONVERTER$67,
2486
+ converter: STRING_CONVERTER$68,
2417
2487
  attribute: "run-status"
2418
2488
  },
2419
2489
  submitOnEnter: {
2420
- converter: BOOLEAN_CONVERTER$43,
2490
+ converter: BOOLEAN_CONVERTER$45,
2421
2491
  attribute: "submit-on-enter"
2422
2492
  },
2423
2493
  translations: { attribute: false }
@@ -2459,9 +2529,9 @@ var XhComposerElement = class extends XhElement {
2459
2529
  };
2460
2530
  //#endregion
2461
2531
  //#region src/elements/context-menu.ts
2462
- const STRING_CONVERTER$66 = { fromAttribute: (v) => v ?? void 0 };
2463
- const NUMBER_CONVERTER$41 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
2464
- const BOOLEAN_CONVERTER$42 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
2532
+ const STRING_CONVERTER$67 = { fromAttribute: (v) => v ?? void 0 };
2533
+ const NUMBER_CONVERTER$42 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
2534
+ const BOOLEAN_CONVERTER$44 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
2465
2535
  /**
2466
2536
  * `<xh-context-menu>` —— Light-DOM 行为宿主:作者写 root/trigger/positioner/content 与若干
2467
2537
  * item / group / separator 角色节点,元素跑 context-menu 机器并把 connect 产出打上去。
@@ -2504,25 +2574,26 @@ var XhContextMenuElement = class extends XhElement {
2504
2574
  };
2505
2575
  static properties = {
2506
2576
  collection: { attribute: false },
2507
- open: { converter: BOOLEAN_CONVERTER$42 },
2577
+ open: { converter: BOOLEAN_CONVERTER$44 },
2508
2578
  defaultOpen: {
2509
2579
  type: Boolean,
2510
2580
  attribute: "default-open"
2511
2581
  },
2512
- placement: { converter: STRING_CONVERTER$66 },
2513
- offset: { converter: NUMBER_CONVERTER$41 },
2514
- loop: { converter: BOOLEAN_CONVERTER$42 },
2515
- typeahead: { converter: BOOLEAN_CONVERTER$42 },
2582
+ placement: { converter: STRING_CONVERTER$67 },
2583
+ offset: { converter: NUMBER_CONVERTER$42 },
2584
+ loop: { converter: BOOLEAN_CONVERTER$44 },
2585
+ typeahead: { converter: BOOLEAN_CONVERTER$44 },
2586
+ translations: { attribute: false },
2516
2587
  direction: {
2517
- converter: STRING_CONVERTER$66,
2588
+ converter: STRING_CONVERTER$67,
2518
2589
  attribute: "dir"
2519
2590
  },
2520
2591
  longPressDelay: {
2521
- converter: NUMBER_CONVERTER$41,
2592
+ converter: NUMBER_CONVERTER$42,
2522
2593
  attribute: "long-press-delay"
2523
2594
  },
2524
- tone: { converter: STRING_CONVERTER$66 },
2525
- size: { converter: STRING_CONVERTER$66 }
2595
+ tone: { converter: STRING_CONVERTER$67 },
2596
+ size: { converter: STRING_CONVERTER$67 }
2526
2597
  };
2527
2598
  idGen = createCounterIdGenerator();
2528
2599
  menuScope = createScope(null, this.idGen);
@@ -2557,6 +2628,7 @@ var XhContextMenuElement = class extends XhElement {
2557
2628
  offset: this.offset,
2558
2629
  loop: this.loop,
2559
2630
  typeahead: this.typeahead,
2631
+ translations: this.translations,
2560
2632
  dir: this.direction,
2561
2633
  longPressDelay: this.longPressDelay,
2562
2634
  tone: this.tone,
@@ -2589,6 +2661,7 @@ var XhContextMenuElement = class extends XhElement {
2589
2661
  svc.refs.set("registerLayer", this.registerLayer);
2590
2662
  svc.refs.set("position", this.positionEngine);
2591
2663
  svc.refs.set("getFloatingEl", () => this.getPart("positioner"));
2664
+ svc.refs.set("getTriggerEl", () => this.getPart("trigger"));
2592
2665
  svc.refs.set("getContentEl", () => this.getPart("content"));
2593
2666
  }
2594
2667
  /**
@@ -2652,9 +2725,9 @@ var XhContextMenuElement = class extends XhElement {
2652
2725
  };
2653
2726
  //#endregion
2654
2727
  //#region src/elements/countdown.ts
2655
- const STRING_CONVERTER$65 = { fromAttribute: (v) => v ?? void 0 };
2656
- const NUMBER_CONVERTER$40 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
2657
- const BOOLEAN_CONVERTER$41 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
2728
+ const STRING_CONVERTER$66 = { fromAttribute: (v) => v ?? void 0 };
2729
+ const NUMBER_CONVERTER$41 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
2730
+ const BOOLEAN_CONVERTER$43 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
2658
2731
  /**
2659
2732
  * `<xh-countdown>` —— Light-DOM 行为宿主:作者写一个 root 角色节点,
2660
2733
  * 元素跑 countdown 机器,逐帧把剩余毫秒按模板铺成时分秒写进那个节点。
@@ -2684,11 +2757,11 @@ var XhCountdownElement = class extends XhElement {
2684
2757
  meta: countdownMeta
2685
2758
  };
2686
2759
  static properties = {
2687
- value: { converter: NUMBER_CONVERTER$40 },
2688
- format: { converter: STRING_CONVERTER$65 },
2689
- active: { converter: BOOLEAN_CONVERTER$41 },
2690
- precision: { converter: NUMBER_CONVERTER$40 },
2691
- live: { converter: STRING_CONVERTER$65 }
2760
+ value: { converter: NUMBER_CONVERTER$41 },
2761
+ format: { converter: STRING_CONVERTER$66 },
2762
+ active: { converter: BOOLEAN_CONVERTER$43 },
2763
+ precision: { converter: NUMBER_CONVERTER$41 },
2764
+ live: { converter: STRING_CONVERTER$66 }
2692
2765
  };
2693
2766
  notify = (details) => {
2694
2767
  this.dispatchEvent(new CustomEvent("finish", {
@@ -2718,8 +2791,8 @@ var XhCountdownElement = class extends XhElement {
2718
2791
  };
2719
2792
  //#endregion
2720
2793
  //#region src/elements/date-field.ts
2721
- const STRING_CONVERTER$64 = { fromAttribute: (v) => v ?? void 0 };
2722
- const BOOLEAN_CONVERTER$40 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
2794
+ const STRING_CONVERTER$65 = { fromAttribute: (v) => v ?? void 0 };
2795
+ const BOOLEAN_CONVERTER$42 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
2723
2796
  /** 作者写在段位上的下标。缺席或写坏了就退回文档序——手写 HTML 时把段位按顺序排下来本身就是声明。 */
2724
2797
  function declaredIndex$4(el, position) {
2725
2798
  const raw = el.getAttribute("index");
@@ -2770,32 +2843,32 @@ var XhDateFieldElement = class extends XhElement {
2770
2843
  meta: dateFieldMeta
2771
2844
  };
2772
2845
  static properties = {
2773
- value: { converter: STRING_CONVERTER$64 },
2846
+ value: { converter: STRING_CONVERTER$65 },
2774
2847
  defaultValue: {
2775
- converter: STRING_CONVERTER$64,
2848
+ converter: STRING_CONVERTER$65,
2776
2849
  attribute: "default-value"
2777
2850
  },
2778
- min: { converter: STRING_CONVERTER$64 },
2779
- max: { converter: STRING_CONVERTER$64 },
2780
- locale: { converter: STRING_CONVERTER$64 },
2851
+ min: { converter: STRING_CONVERTER$65 },
2852
+ max: { converter: STRING_CONVERTER$65 },
2853
+ locale: { converter: STRING_CONVERTER$65 },
2781
2854
  timeZone: {
2782
- converter: STRING_CONVERTER$64,
2855
+ converter: STRING_CONVERTER$65,
2783
2856
  attribute: "time-zone"
2784
2857
  },
2785
- granularity: { converter: STRING_CONVERTER$64 },
2786
- disabled: { converter: BOOLEAN_CONVERTER$40 },
2858
+ granularity: { converter: STRING_CONVERTER$65 },
2859
+ disabled: { converter: BOOLEAN_CONVERTER$42 },
2787
2860
  readOnly: {
2788
- converter: BOOLEAN_CONVERTER$40,
2861
+ converter: BOOLEAN_CONVERTER$42,
2789
2862
  attribute: "read-only"
2790
2863
  },
2791
- invalid: { converter: BOOLEAN_CONVERTER$40 },
2792
- required: { converter: BOOLEAN_CONVERTER$40 },
2793
- name: { converter: STRING_CONVERTER$64 },
2864
+ invalid: { converter: BOOLEAN_CONVERTER$42 },
2865
+ required: { converter: BOOLEAN_CONVERTER$42 },
2866
+ name: { converter: STRING_CONVERTER$65 },
2794
2867
  placeholder: { attribute: false },
2795
2868
  translations: { attribute: false },
2796
- variant: { converter: STRING_CONVERTER$64 },
2797
- tone: { converter: STRING_CONVERTER$64 },
2798
- size: { converter: STRING_CONVERTER$64 }
2869
+ variant: { converter: STRING_CONVERTER$65 },
2870
+ tone: { converter: STRING_CONVERTER$65 },
2871
+ size: { converter: STRING_CONVERTER$65 }
2799
2872
  };
2800
2873
  notifyChange = (details) => {
2801
2874
  this.dispatchEvent(new CustomEvent("value-change", {
@@ -2849,9 +2922,9 @@ var XhDateFieldElement = class extends XhElement {
2849
2922
  };
2850
2923
  //#endregion
2851
2924
  //#region src/elements/date-picker.ts
2852
- const STRING_CONVERTER$63 = { fromAttribute: (v) => v ?? void 0 };
2853
- const NUMBER_CONVERTER$39 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
2854
- const BOOLEAN_CONVERTER$39 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
2925
+ const STRING_CONVERTER$64 = { fromAttribute: (v) => v ?? void 0 };
2926
+ const NUMBER_CONVERTER$40 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
2927
+ const BOOLEAN_CONVERTER$41 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
2855
2928
  /** 取作者写在段位上的 index,缺席或写坏了退回组内文档序。 */
2856
2929
  function declaredIndex$3(el, position) {
2857
2930
  const raw = el.getAttribute("index");
@@ -2909,6 +2982,9 @@ function declaredIndex$3(el, position) {
2909
2982
  * @csspart positioner - 浮层定位容器,坐标由引擎写成内联样式
2910
2983
  * @csspart content - role=dialog 浮层(消解层的根节点),收起时带 hidden
2911
2984
  * @csspart calendar - 内嵌日历的挂载点,同时充当日历的根节点
2985
+ * @csspart time-column - showTime 的时间列,须自带 unit 属性(hour/minute/second);没开时带 hidden
2986
+ * @csspart time-item - 时间选项,须自带 value 属性(两位补零串);点按把该单位写进值
2987
+ * @csspart confirm-trigger - showTime 的收口按钮;没开时带 hidden
2912
2988
  * @csspart header - 日历标题栏外壳(data-scope="calendar")
2913
2989
  * @csspart prev-trigger - 上一月;越过 min 时转原生 disabled
2914
2990
  * @csspart next-trigger - 下一月;越过 max 时转原生 disabled
@@ -2929,46 +3005,54 @@ var XhDatePickerElement = class extends XhElement {
2929
3005
  delegates: [dateFieldAnatomy, calendarAnatomy]
2930
3006
  };
2931
3007
  static properties = {
2932
- value: { converter: STRING_CONVERTER$63 },
3008
+ value: { converter: STRING_CONVERTER$64 },
2933
3009
  defaultValue: {
2934
- converter: STRING_CONVERTER$63,
3010
+ converter: STRING_CONVERTER$64,
2935
3011
  attribute: "default-value"
2936
3012
  },
2937
- open: { converter: BOOLEAN_CONVERTER$39 },
3013
+ open: { converter: BOOLEAN_CONVERTER$41 },
2938
3014
  defaultOpen: {
2939
3015
  type: Boolean,
2940
3016
  attribute: "default-open"
2941
3017
  },
2942
- min: { converter: STRING_CONVERTER$63 },
2943
- max: { converter: STRING_CONVERTER$63 },
2944
- locale: { converter: STRING_CONVERTER$63 },
3018
+ min: { converter: STRING_CONVERTER$64 },
3019
+ max: { converter: STRING_CONVERTER$64 },
3020
+ locale: { converter: STRING_CONVERTER$64 },
2945
3021
  timeZone: {
2946
- converter: STRING_CONVERTER$63,
3022
+ converter: STRING_CONVERTER$64,
2947
3023
  attribute: "time-zone"
2948
3024
  },
2949
3025
  selectionMode: {
2950
- converter: STRING_CONVERTER$63,
3026
+ converter: STRING_CONVERTER$64,
2951
3027
  attribute: "selection-mode"
2952
3028
  },
2953
- disabled: { converter: BOOLEAN_CONVERTER$39 },
3029
+ disabled: { converter: BOOLEAN_CONVERTER$41 },
2954
3030
  readOnly: {
2955
- converter: BOOLEAN_CONVERTER$39,
3031
+ converter: BOOLEAN_CONVERTER$41,
2956
3032
  attribute: "read-only"
2957
3033
  },
2958
- invalid: { converter: BOOLEAN_CONVERTER$39 },
2959
- required: { converter: BOOLEAN_CONVERTER$39 },
2960
- name: { converter: STRING_CONVERTER$63 },
3034
+ invalid: { converter: BOOLEAN_CONVERTER$41 },
3035
+ required: { converter: BOOLEAN_CONVERTER$41 },
3036
+ name: { converter: STRING_CONVERTER$64 },
2961
3037
  endName: {
2962
- converter: STRING_CONVERTER$63,
3038
+ converter: STRING_CONVERTER$64,
2963
3039
  attribute: "end-name"
2964
3040
  },
2965
3041
  translations: { attribute: false },
2966
- placement: { converter: STRING_CONVERTER$63 },
2967
- offset: { converter: NUMBER_CONVERTER$39 },
3042
+ placement: { converter: STRING_CONVERTER$64 },
3043
+ offset: { converter: NUMBER_CONVERTER$40 },
2968
3044
  closeOnSelect: {
2969
- converter: BOOLEAN_CONVERTER$39,
3045
+ converter: BOOLEAN_CONVERTER$41,
2970
3046
  attribute: "close-on-select"
2971
3047
  },
3048
+ showTime: {
3049
+ converter: BOOLEAN_CONVERTER$41,
3050
+ attribute: "show-time"
3051
+ },
3052
+ timeGranularity: {
3053
+ converter: STRING_CONVERTER$64,
3054
+ attribute: "time-granularity"
3055
+ },
2972
3056
  isDateUnavailable: { attribute: false }
2973
3057
  };
2974
3058
  idGen = createCounterIdGenerator();
@@ -3038,6 +3122,8 @@ var XhDatePickerElement = class extends XhElement {
3038
3122
  placement: this.placement,
3039
3123
  offset: this.offset,
3040
3124
  closeOnSelect: this.closeOnSelect,
3125
+ showTime: this.showTime,
3126
+ timeGranularity: this.timeGranularity,
3041
3127
  onValueChange: this.notifyValue,
3042
3128
  onOpenChange: this.notifyOpen,
3043
3129
  onFocusedValueChange: this.notifyFocus
@@ -3128,6 +3214,12 @@ var XhDatePickerElement = class extends XhElement {
3128
3214
  put("positioner", api.getPositionerProps());
3129
3215
  put("content", api.getContentProps());
3130
3216
  put("calendar", api.getCalendarProps());
3217
+ put("confirm-trigger", api.getConfirmTriggerProps());
3218
+ for (const el of this.getParts("time-column")) this.spreader.spread(el, api.getTimeColumnProps({ unit: el.getAttribute("unit") ?? "hour" }));
3219
+ for (const el of this.getParts("time-item")) this.spreader.spread(el, api.getTimeItemProps({
3220
+ unit: el.closest("[data-xh-part=\"time-column\"]")?.getAttribute("unit") ?? "hour",
3221
+ value: el.getAttribute("value") ?? ""
3222
+ }));
3131
3223
  const inputs = this.getParts("input");
3132
3224
  const owners = [inputs[0] ?? this, inputs[1]];
3133
3225
  const hiddenInputs = this.hiddenInputGroups(inputs);
@@ -3167,7 +3259,7 @@ var XhDatePickerElement = class extends XhElement {
3167
3259
  };
3168
3260
  //#endregion
3169
3261
  //#region src/elements/descriptions.ts
3170
- const STRING_CONVERTER$62 = { fromAttribute: (v) => v ?? void 0 };
3262
+ const STRING_CONVERTER$63 = { fromAttribute: (v) => v ?? void 0 };
3171
3263
  /**
3172
3264
  * `<xh-descriptions>` —— Light-DOM 行为宿主,无状态机,把 connectDescriptions 产出打到各角色节点。
3173
3265
  * 排版走 CSS Grid,columns 落成列数。
@@ -3193,8 +3285,8 @@ var XhDescriptionsElement = class extends XhElement {
3193
3285
  static properties = {
3194
3286
  columns: { type: Number },
3195
3287
  bordered: { type: Boolean },
3196
- placement: { converter: STRING_CONVERTER$62 },
3197
- size: { converter: STRING_CONVERTER$62 }
3288
+ placement: { converter: STRING_CONVERTER$63 },
3289
+ size: { converter: STRING_CONVERTER$63 }
3198
3290
  };
3199
3291
  wire() {
3200
3292
  const api = connectDescriptions({
@@ -3215,8 +3307,8 @@ var XhDescriptionsElement = class extends XhElement {
3215
3307
  };
3216
3308
  //#endregion
3217
3309
  //#region src/elements/dialog.ts
3218
- const BOOLEAN_CONVERTER$38 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
3219
- const STRING_CONVERTER$61 = { fromAttribute: (v) => v ?? void 0 };
3310
+ const BOOLEAN_CONVERTER$40 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
3311
+ const STRING_CONVERTER$62 = { fromAttribute: (v) => v ?? void 0 };
3220
3312
  /**
3221
3313
  * `<xh-dialog>` —— Light-DOM 行为宿主,跑 dialog 机器并把 connect 产出打到角色节点上,
3222
3314
  * 关闭时用内联 style.display 隐藏浮层子树。
@@ -3244,21 +3336,21 @@ var XhDialogElement = class extends XhElement {
3244
3336
  meta: dialogMeta
3245
3337
  };
3246
3338
  static properties = {
3247
- open: { converter: BOOLEAN_CONVERTER$38 },
3339
+ open: { converter: BOOLEAN_CONVERTER$40 },
3248
3340
  defaultOpen: {
3249
3341
  type: Boolean,
3250
3342
  attribute: "default-open"
3251
3343
  },
3252
- modal: { converter: BOOLEAN_CONVERTER$38 },
3344
+ modal: { converter: BOOLEAN_CONVERTER$40 },
3253
3345
  closeOnEscape: {
3254
- converter: BOOLEAN_CONVERTER$38,
3346
+ converter: BOOLEAN_CONVERTER$40,
3255
3347
  attribute: "close-on-escape"
3256
3348
  },
3257
3349
  restoreFocus: {
3258
- converter: BOOLEAN_CONVERTER$38,
3350
+ converter: BOOLEAN_CONVERTER$40,
3259
3351
  attribute: "restore-focus"
3260
3352
  },
3261
- size: { converter: STRING_CONVERTER$61 }
3353
+ size: { converter: STRING_CONVERTER$62 }
3262
3354
  };
3263
3355
  idGen = createCounterIdGenerator();
3264
3356
  dialogScope = createScope(null, this.idGen);
@@ -3344,8 +3436,8 @@ var XhDialogElement = class extends XhElement {
3344
3436
  };
3345
3437
  //#endregion
3346
3438
  //#region src/elements/drawer.ts
3347
- const BOOLEAN_CONVERTER$37 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
3348
- const STRING_CONVERTER$60 = { fromAttribute: (v) => v ?? void 0 };
3439
+ const BOOLEAN_CONVERTER$39 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
3440
+ const STRING_CONVERTER$61 = { fromAttribute: (v) => v ?? void 0 };
3349
3441
  /**
3350
3442
  * `<xh-drawer>` —— Light-DOM 行为宿主,跑 drawer 机器并把 connect 产出打到角色节点上,
3351
3443
  * 关闭时用内联 style.display 隐藏浮层子树。
@@ -3378,26 +3470,26 @@ var XhDrawerElement = class extends XhElement {
3378
3470
  meta: drawerMeta
3379
3471
  };
3380
3472
  static properties = {
3381
- open: { converter: BOOLEAN_CONVERTER$37 },
3473
+ open: { converter: BOOLEAN_CONVERTER$39 },
3382
3474
  defaultOpen: {
3383
3475
  type: Boolean,
3384
3476
  attribute: "default-open"
3385
3477
  },
3386
- modal: { converter: BOOLEAN_CONVERTER$37 },
3387
- side: { converter: STRING_CONVERTER$60 },
3478
+ modal: { converter: BOOLEAN_CONVERTER$39 },
3479
+ side: { converter: STRING_CONVERTER$61 },
3388
3480
  closeOnEscape: {
3389
- converter: BOOLEAN_CONVERTER$37,
3481
+ converter: BOOLEAN_CONVERTER$39,
3390
3482
  attribute: "close-on-escape"
3391
3483
  },
3392
3484
  closeOnInteractOutside: {
3393
- converter: BOOLEAN_CONVERTER$37,
3485
+ converter: BOOLEAN_CONVERTER$39,
3394
3486
  attribute: "close-on-interact-outside"
3395
3487
  },
3396
3488
  restoreFocus: {
3397
- converter: BOOLEAN_CONVERTER$37,
3489
+ converter: BOOLEAN_CONVERTER$39,
3398
3490
  attribute: "restore-focus"
3399
3491
  },
3400
- size: { converter: STRING_CONVERTER$60 },
3492
+ size: { converter: STRING_CONVERTER$61 },
3401
3493
  translations: { attribute: false }
3402
3494
  };
3403
3495
  idGen = createCounterIdGenerator();
@@ -3488,8 +3580,8 @@ var XhDrawerElement = class extends XhElement {
3488
3580
  };
3489
3581
  //#endregion
3490
3582
  //#region src/elements/dynamic-input.ts
3491
- const NUMBER_CONVERTER$38 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
3492
- const BOOLEAN_CONVERTER$36 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
3583
+ const NUMBER_CONVERTER$39 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
3584
+ const BOOLEAN_CONVERTER$38 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
3493
3585
  /** 作者写在行上的下标。缺席或写坏了就退回文档序——把行按顺序排下来本身就是声明。 */
3494
3586
  function declaredIndex$2(el, position) {
3495
3587
  const raw = el.getAttribute("index");
@@ -3531,11 +3623,11 @@ var XhDynamicInputElement = class extends XhElement {
3531
3623
  static properties = {
3532
3624
  value: { attribute: false },
3533
3625
  defaultValue: { attribute: false },
3534
- min: { converter: NUMBER_CONVERTER$38 },
3535
- max: { converter: NUMBER_CONVERTER$38 },
3626
+ min: { converter: NUMBER_CONVERTER$39 },
3627
+ max: { converter: NUMBER_CONVERTER$39 },
3536
3628
  createItem: { attribute: false },
3537
- movable: { converter: BOOLEAN_CONVERTER$36 },
3538
- disabled: { converter: BOOLEAN_CONVERTER$36 },
3629
+ movable: { converter: BOOLEAN_CONVERTER$38 },
3630
+ disabled: { converter: BOOLEAN_CONVERTER$38 },
3539
3631
  translations: { attribute: false }
3540
3632
  };
3541
3633
  notifyValue = (details) => {
@@ -3589,9 +3681,9 @@ var XhDynamicInputElement = class extends XhElement {
3589
3681
  };
3590
3682
  //#endregion
3591
3683
  //#region src/elements/editable.ts
3592
- const STRING_CONVERTER$59 = { fromAttribute: (v) => v ?? void 0 };
3593
- const NUMBER_CONVERTER$37 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
3594
- const BOOLEAN_CONVERTER$35 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
3684
+ const STRING_CONVERTER$60 = { fromAttribute: (v) => v ?? void 0 };
3685
+ const NUMBER_CONVERTER$38 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
3686
+ const BOOLEAN_CONVERTER$37 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
3595
3687
  /**
3596
3688
  * `<xh-editable>` —— Light-DOM 行为宿主:作者写 root/label/area/preview/input/control
3597
3689
  * 与三颗按钮的角色节点,元素跑 editable 机器并把 connect 产出打上去。
@@ -3640,42 +3732,42 @@ var XhEditableElement = class extends XhElement {
3640
3732
  meta: editableMeta
3641
3733
  };
3642
3734
  static properties = {
3643
- value: { converter: STRING_CONVERTER$59 },
3735
+ value: { converter: STRING_CONVERTER$60 },
3644
3736
  defaultValue: {
3645
- converter: STRING_CONVERTER$59,
3737
+ converter: STRING_CONVERTER$60,
3646
3738
  attribute: "default-value"
3647
3739
  },
3648
- edit: { converter: BOOLEAN_CONVERTER$35 },
3740
+ edit: { converter: BOOLEAN_CONVERTER$37 },
3649
3741
  defaultEdit: {
3650
- converter: BOOLEAN_CONVERTER$35,
3742
+ converter: BOOLEAN_CONVERTER$37,
3651
3743
  attribute: "default-edit"
3652
3744
  },
3653
- placeholder: { converter: STRING_CONVERTER$59 },
3654
- disabled: { converter: BOOLEAN_CONVERTER$35 },
3745
+ placeholder: { converter: STRING_CONVERTER$60 },
3746
+ disabled: { converter: BOOLEAN_CONVERTER$37 },
3655
3747
  readOnly: {
3656
- converter: BOOLEAN_CONVERTER$35,
3748
+ converter: BOOLEAN_CONVERTER$37,
3657
3749
  attribute: "read-only"
3658
3750
  },
3659
- invalid: { converter: BOOLEAN_CONVERTER$35 },
3751
+ invalid: { converter: BOOLEAN_CONVERTER$37 },
3660
3752
  maxLength: {
3661
- converter: NUMBER_CONVERTER$37,
3753
+ converter: NUMBER_CONVERTER$38,
3662
3754
  attribute: "max-length"
3663
3755
  },
3664
- name: { converter: STRING_CONVERTER$59 },
3756
+ name: { converter: STRING_CONVERTER$60 },
3665
3757
  submitMode: {
3666
- converter: STRING_CONVERTER$59,
3758
+ converter: STRING_CONVERTER$60,
3667
3759
  attribute: "submit-mode"
3668
3760
  },
3669
3761
  activationMode: {
3670
- converter: STRING_CONVERTER$59,
3762
+ converter: STRING_CONVERTER$60,
3671
3763
  attribute: "activation-mode"
3672
3764
  },
3673
3765
  selectOnFocus: {
3674
- converter: BOOLEAN_CONVERTER$35,
3766
+ converter: BOOLEAN_CONVERTER$37,
3675
3767
  attribute: "select-on-focus"
3676
3768
  },
3677
3769
  autoResize: {
3678
- converter: BOOLEAN_CONVERTER$35,
3770
+ converter: BOOLEAN_CONVERTER$37,
3679
3771
  attribute: "auto-resize"
3680
3772
  }
3681
3773
  };
@@ -3784,7 +3876,7 @@ var XhEditableElement = class extends XhElement {
3784
3876
  };
3785
3877
  //#endregion
3786
3878
  //#region src/elements/ellipsis.ts
3787
- const NUMBER_CONVERTER$36 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
3879
+ const NUMBER_CONVERTER$37 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
3788
3880
  const TRISTATE_CONVERTER$1 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
3789
3881
  /**
3790
3882
  * `<xh-ellipsis>` —— 省略行为宿主:把一段文字夹在给定行数内,并如实报出它有没有被裁掉。
@@ -3812,7 +3904,7 @@ var XhEllipsisElement = class extends XhElement {
3812
3904
  meta: ellipsisMeta
3813
3905
  };
3814
3906
  static properties = {
3815
- lines: { converter: NUMBER_CONVERTER$36 },
3907
+ lines: { converter: NUMBER_CONVERTER$37 },
3816
3908
  expandable: { type: Boolean },
3817
3909
  expanded: { converter: TRISTATE_CONVERTER$1 },
3818
3910
  defaultExpanded: {
@@ -3858,7 +3950,7 @@ var XhEllipsisElement = class extends XhElement {
3858
3950
  };
3859
3951
  //#endregion
3860
3952
  //#region src/elements/empty-state.ts
3861
- const STRING_CONVERTER$58 = { fromAttribute: (v) => v ?? void 0 };
3953
+ const STRING_CONVERTER$59 = { fromAttribute: (v) => v ?? void 0 };
3862
3954
  /**
3863
3955
  * `<xh-empty-state>` —— 空状态行为宿主,无状态机,把 connectEmptyState 产出的属性打到角色节点上。
3864
3956
  *
@@ -3880,8 +3972,8 @@ var XhEmptyStateElement = class extends XhElement {
3880
3972
  meta: emptyStateMeta
3881
3973
  };
3882
3974
  static properties = {
3883
- size: { converter: STRING_CONVERTER$58 },
3884
- live: { converter: STRING_CONVERTER$58 }
3975
+ size: { converter: STRING_CONVERTER$59 },
3976
+ live: { converter: STRING_CONVERTER$59 }
3885
3977
  };
3886
3978
  wire() {
3887
3979
  const api = connectEmptyState({
@@ -3901,7 +3993,7 @@ var XhEmptyStateElement = class extends XhElement {
3901
3993
  };
3902
3994
  //#endregion
3903
3995
  //#region src/elements/field.ts
3904
- const STRING_CONVERTER$57 = { fromAttribute: (v) => v ?? void 0 };
3996
+ const STRING_CONVERTER$58 = { fromAttribute: (v) => v ?? void 0 };
3905
3997
  /**
3906
3998
  * `<xh-field>` —— Light-DOM 行为宿主,无状态机,把 connectField 产出的 id 与 aria-* 打到
3907
3999
  * label/control/description/error-text 角色节点上,自动对齐 `for` 与描述链。控件本身由作者渲染。
@@ -3931,7 +4023,7 @@ var XhFieldElement = class extends XhElement {
3931
4023
  required: { type: Boolean },
3932
4024
  disabled: { type: Boolean },
3933
4025
  controlId: {
3934
- converter: STRING_CONVERTER$57,
4026
+ converter: STRING_CONVERTER$58,
3935
4027
  attribute: "control-id"
3936
4028
  }
3937
4029
  };
@@ -3957,9 +4049,9 @@ var XhFieldElement = class extends XhElement {
3957
4049
  };
3958
4050
  //#endregion
3959
4051
  //#region src/elements/file-upload.ts
3960
- const STRING_CONVERTER$56 = { fromAttribute: (v) => v ?? void 0 };
3961
- const NUMBER_CONVERTER$35 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
3962
- const BOOLEAN_CONVERTER$34 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
4052
+ const STRING_CONVERTER$57 = { fromAttribute: (v) => v ?? void 0 };
4053
+ const NUMBER_CONVERTER$36 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
4054
+ const BOOLEAN_CONVERTER$36 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
3963
4055
  /** 取作者写在条目上的 index,缺席或写坏了退回文档序。 */
3964
4056
  function declaredIndex$1(el, position) {
3965
4057
  const raw = el.getAttribute("index");
@@ -3991,7 +4083,11 @@ function declaredIndex$1(el, position) {
3991
4083
  * @attr {boolean} allow-drop - 是否接受拖拽投放,默认 true;写 allow-drop="false" 关掉
3992
4084
  * @attr {boolean} directory - 选目录而不是选文件(隐藏输入带 webkitdirectory)
3993
4085
  * @attr {'user'|'environment'} capture - 移动端直接调用摄像头/麦克风采集
4086
+ * @attr {boolean} auto-upload - 收下即自动开传(须配 upload 实现),默认 true;写 auto-upload="false" 关掉
3994
4087
  * @fires files-change - 列表变化;detail 为 `{ files: File[] }`
4088
+ * @fires remote-files-change - 远程附件列表变化;detail 为 `{ files: FileUploadRemoteFile[] }`
4089
+ * @fires upload-complete - 单个文件传完;detail 为 `{ file, url? }`
4090
+ * @fires upload-error - 单个文件传败;detail 为 `{ file, error }`
3995
4091
  * @fires file-accept - 本次收下了哪些;detail 为 `{ files: File[] }`
3996
4092
  * @fires file-reject - 本次拒了哪些、各自为什么;detail 为 `{ files: { file, reasons }[] }`
3997
4093
  * @csspart root - 组件根容器,承载 data-dragging / data-disabled / data-invalid / data-empty
@@ -4015,28 +4111,35 @@ var XhFileUploadElement = class XhFileUploadElement extends XhElement {
4015
4111
  static properties = {
4016
4112
  files: { attribute: false },
4017
4113
  defaultFiles: { attribute: false },
4018
- accept: { converter: STRING_CONVERTER$56 },
4114
+ remoteFiles: { attribute: false },
4115
+ defaultRemoteFiles: { attribute: false },
4116
+ upload: { attribute: false },
4117
+ autoUpload: {
4118
+ converter: BOOLEAN_CONVERTER$36,
4119
+ attribute: "auto-upload"
4120
+ },
4121
+ accept: { converter: STRING_CONVERTER$57 },
4019
4122
  maxFiles: {
4020
- converter: NUMBER_CONVERTER$35,
4123
+ converter: NUMBER_CONVERTER$36,
4021
4124
  attribute: "max-files"
4022
4125
  },
4023
4126
  maxFileSize: {
4024
- converter: NUMBER_CONVERTER$35,
4127
+ converter: NUMBER_CONVERTER$36,
4025
4128
  attribute: "max-file-size"
4026
4129
  },
4027
4130
  minFileSize: {
4028
- converter: NUMBER_CONVERTER$35,
4131
+ converter: NUMBER_CONVERTER$36,
4029
4132
  attribute: "min-file-size"
4030
4133
  },
4031
4134
  disabled: { type: Boolean },
4032
4135
  invalid: { type: Boolean },
4033
- name: { converter: STRING_CONVERTER$56 },
4136
+ name: { converter: STRING_CONVERTER$57 },
4034
4137
  allowDrop: {
4035
- converter: BOOLEAN_CONVERTER$34,
4138
+ converter: BOOLEAN_CONVERTER$36,
4036
4139
  attribute: "allow-drop"
4037
4140
  },
4038
4141
  directory: { type: Boolean },
4039
- capture: { converter: STRING_CONVERTER$56 },
4142
+ capture: { converter: STRING_CONVERTER$57 },
4040
4143
  translations: { attribute: false }
4041
4144
  };
4042
4145
  uploadScope = createScope(this, createCounterIdGenerator());
@@ -4061,11 +4164,36 @@ var XhFileUploadElement = class XhFileUploadElement extends XhElement {
4061
4164
  composed: true
4062
4165
  }));
4063
4166
  };
4167
+ notifyRemoteChange = (details) => {
4168
+ this.dispatchEvent(new CustomEvent("remote-files-change", {
4169
+ detail: details,
4170
+ bubbles: true,
4171
+ composed: true
4172
+ }));
4173
+ };
4174
+ notifyUploadComplete = (details) => {
4175
+ this.dispatchEvent(new CustomEvent("upload-complete", {
4176
+ detail: details,
4177
+ bubbles: true,
4178
+ composed: true
4179
+ }));
4180
+ };
4181
+ notifyUploadError = (details) => {
4182
+ this.dispatchEvent(new CustomEvent("upload-error", {
4183
+ detail: details,
4184
+ bubbles: true,
4185
+ composed: true
4186
+ }));
4187
+ };
4064
4188
  ctrl = new MachineController(this, fileUploadMachine, () => this.machineProps(), { scope: this.uploadScope });
4065
4189
  machineProps() {
4066
4190
  return {
4067
4191
  files: this.files,
4068
4192
  defaultFiles: this.defaultFiles,
4193
+ remoteFiles: this.remoteFiles,
4194
+ defaultRemoteFiles: this.defaultRemoteFiles,
4195
+ upload: this.upload,
4196
+ autoUpload: this.autoUpload,
4069
4197
  accept: this.accept,
4070
4198
  maxFiles: this.maxFiles,
4071
4199
  maxFileSize: this.maxFileSize,
@@ -4078,6 +4206,9 @@ var XhFileUploadElement = class XhFileUploadElement extends XhElement {
4078
4206
  capture: this.capture,
4079
4207
  translations: this.translations,
4080
4208
  onFilesChange: this.notifyChange,
4209
+ onRemoteFilesChange: this.notifyRemoteChange,
4210
+ onUploadComplete: this.notifyUploadComplete,
4211
+ onUploadError: this.notifyUploadError,
4081
4212
  onFileAccept: this.notifyAccept,
4082
4213
  onFileReject: this.notifyReject
4083
4214
  };
@@ -4222,8 +4353,8 @@ var XhFlexElement = class extends XhElement {
4222
4353
  };
4223
4354
  //#endregion
4224
4355
  //#region src/elements/float-button.ts
4225
- const STRING_CONVERTER$55 = { fromAttribute: (v) => v ?? void 0 };
4226
- const NUMBER_CONVERTER$34 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
4356
+ const STRING_CONVERTER$56 = { fromAttribute: (v) => v ?? void 0 };
4357
+ const NUMBER_CONVERTER$35 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
4227
4358
  const TRISTATE_CONVERTER = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
4228
4359
  /**
4229
4360
  * `<xh-float-button>` —— 悬浮按钮行为宿主:一颗钉在视口一角的触发器,展开一组动作。
@@ -4261,11 +4392,11 @@ var XhFloatButtonElement = class extends XhElement {
4261
4392
  attribute: "default-open"
4262
4393
  },
4263
4394
  disabled: { type: Boolean },
4264
- placement: { converter: STRING_CONVERTER$55 },
4265
- offset: { converter: NUMBER_CONVERTER$34 },
4266
- shape: { converter: STRING_CONVERTER$55 },
4395
+ placement: { converter: STRING_CONVERTER$56 },
4396
+ offset: { converter: NUMBER_CONVERTER$35 },
4397
+ shape: { converter: STRING_CONVERTER$56 },
4267
4398
  expandTrigger: {
4268
- converter: STRING_CONVERTER$55,
4399
+ converter: STRING_CONVERTER$56,
4269
4400
  attribute: "expand-trigger"
4270
4401
  },
4271
4402
  translations: { attribute: false }
@@ -4313,8 +4444,8 @@ var XhFloatButtonElement = class extends XhElement {
4313
4444
  };
4314
4445
  //#endregion
4315
4446
  //#region src/elements/form.ts
4316
- const STRING_CONVERTER$54 = { fromAttribute: (v) => v ?? void 0 };
4317
- const BOOLEAN_CONVERTER$33 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
4447
+ const STRING_CONVERTER$55 = { fromAttribute: (v) => v ?? void 0 };
4448
+ const BOOLEAN_CONVERTER$35 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
4318
4449
  /**
4319
4450
  * 字段容器与摘要条目自报的字段名,取作者写的 `value` 属性。
4320
4451
  *
@@ -4344,6 +4475,9 @@ function fieldNameOf(el) {
4344
4475
  *
4345
4476
  * @customElement xh-form
4346
4477
  * @attr {string} validate-on - 校验时机:submit(默认)/ blur / change
4478
+ * @attr {string} layout - 排布:vertical(默认)/ horizontal(标签左置两列)/ inline(横排一行流)
4479
+ * @attr {string} label-width - horizontal 下标签列宽(CSS 长度),整表统一对齐
4480
+ * @attr {string} label-align - horizontal 下标签对齐缘:end(默认,贴控件)/ start
4347
4481
  * @attr {boolean} disabled - 整个表单禁用:提交、重置、写值一概不发生,两颗按钮带原生 disabled
4348
4482
  * @attr {boolean} read-only - 只读:写值与重置不发生,但仍可提交
4349
4483
  * @fires values-change - 值表变化;detail 为 `{ values }`
@@ -4351,7 +4485,8 @@ function fieldNameOf(el) {
4351
4485
  * @fires submit - 校验通过才派发;detail 为 `{ values }`
4352
4486
  * @fires invalid - 校验不通过时派发;detail 为 `{ errors, values }`
4353
4487
  * @csspart root - 表单根容器,必须是原生 `<form>`(承载 data-state/data-disabled/data-readonly/data-invalid)
4354
- * @csspart field-group - 单个字段的容器,须自带 value 属性标识字段名;带 id 供摘要链接指向
4488
+ * @csspart field-group - 单个字段的容器,须自带 value 属性标识字段名;带 id 供摘要链接指向。
4489
+ * 组里的 `<xh-field>` 由表单驱动 invalid/required/disabled,作者显式设的会被顶掉
4355
4490
  * @csspart error-summary - role=alert 的错误汇总,提交失败且仍有错误时才显形
4356
4491
  * @csspart error-summary-item - 摘要里的一条,须是原生 `<a>` 且自带 value 属性标识字段名;无对应错误时带 hidden
4357
4492
  * @csspart submit-trigger - 提交键,须是原生 button(连接层写成 type=submit)
@@ -4368,13 +4503,24 @@ var XhFormElement = class extends XhElement {
4368
4503
  errors: { attribute: false },
4369
4504
  defaultErrors: { attribute: false },
4370
4505
  validate: { attribute: false },
4506
+ rules: { attribute: false },
4507
+ validateMessages: { attribute: false },
4371
4508
  validateOn: {
4372
- converter: STRING_CONVERTER$54,
4509
+ converter: STRING_CONVERTER$55,
4373
4510
  attribute: "validate-on"
4374
4511
  },
4375
- disabled: { converter: BOOLEAN_CONVERTER$33 },
4512
+ layout: { converter: STRING_CONVERTER$55 },
4513
+ labelWidth: {
4514
+ converter: STRING_CONVERTER$55,
4515
+ attribute: "label-width"
4516
+ },
4517
+ labelAlign: {
4518
+ converter: STRING_CONVERTER$55,
4519
+ attribute: "label-align"
4520
+ },
4521
+ disabled: { converter: BOOLEAN_CONVERTER$35 },
4376
4522
  readOnly: {
4377
- converter: BOOLEAN_CONVERTER$33,
4523
+ converter: BOOLEAN_CONVERTER$35,
4378
4524
  attribute: "read-only"
4379
4525
  }
4380
4526
  };
@@ -4414,7 +4560,12 @@ var XhFormElement = class extends XhElement {
4414
4560
  errors: this.errors,
4415
4561
  defaultErrors: this.defaultErrors,
4416
4562
  validate: this.validate,
4563
+ rules: this.rules,
4564
+ validateMessages: this.validateMessages,
4417
4565
  validateOn: this.validateOn,
4566
+ layout: this.layout,
4567
+ labelWidth: this.labelWidth,
4568
+ labelAlign: this.labelAlign,
4418
4569
  disabled: this.disabled ?? false,
4419
4570
  readOnly: this.readOnly ?? false,
4420
4571
  onValuesChange: this.notifyValues,
@@ -4486,7 +4637,15 @@ var XhFormElement = class extends XhElement {
4486
4637
  put("error-summary", api.getErrorSummaryProps());
4487
4638
  put("submit-trigger", api.getSubmitTriggerProps());
4488
4639
  put("reset-trigger", api.getResetTriggerProps());
4489
- for (const el of this.getParts("field-group")) this.spreader.spread(el, api.getFieldGroupProps({ name: fieldNameOf(el) }));
4640
+ for (const el of this.getParts("field-group")) {
4641
+ const name = fieldNameOf(el);
4642
+ this.spreader.spread(el, api.getFieldGroupProps({ name }));
4643
+ for (const field of el.querySelectorAll("xh-field")) {
4644
+ field.invalid = api.isFieldInvalid(name);
4645
+ field.required = api.isFieldRequired(name) || void 0;
4646
+ field.disabled = api.disabled || void 0;
4647
+ }
4648
+ }
4490
4649
  for (const el of this.getParts("error-summary-item")) {
4491
4650
  this.spreader.spread(el, api.getErrorSummaryItemProps({ name: fieldNameOf(el) }));
4492
4651
  this.setPartHidden(el, api.getFieldError(fieldNameOf(el)) === void 0);
@@ -4496,7 +4655,7 @@ var XhFormElement = class extends XhElement {
4496
4655
  };
4497
4656
  //#endregion
4498
4657
  //#region src/elements/gradient-text.ts
4499
- const STRING_CONVERTER$53 = { fromAttribute: (v) => v ?? void 0 };
4658
+ const STRING_CONVERTER$54 = { fromAttribute: (v) => v ?? void 0 };
4500
4659
  /**
4501
4660
  * `<xh-gradient-text>` —— Light-DOM 行为宿主,无状态机,把 connectGradientText 产出打到 root 角色节点。
4502
4661
  *
@@ -4517,9 +4676,9 @@ var XhGradientTextElement = class extends XhElement {
4517
4676
  meta: gradientTextMeta
4518
4677
  };
4519
4678
  static properties = {
4520
- from: { converter: STRING_CONVERTER$53 },
4521
- to: { converter: STRING_CONVERTER$53 },
4522
- direction: { converter: STRING_CONVERTER$53 }
4679
+ from: { converter: STRING_CONVERTER$54 },
4680
+ to: { converter: STRING_CONVERTER$54 },
4681
+ direction: { converter: STRING_CONVERTER$54 }
4523
4682
  };
4524
4683
  wire() {
4525
4684
  const api = connectGradientText({
@@ -4533,7 +4692,7 @@ var XhGradientTextElement = class extends XhElement {
4533
4692
  };
4534
4693
  //#endregion
4535
4694
  //#region src/elements/grid.ts
4536
- const STRING_CONVERTER$52 = { fromAttribute: (v) => v ?? void 0 };
4695
+ const STRING_CONVERTER$53 = { fromAttribute: (v) => v ?? void 0 };
4537
4696
  /**
4538
4697
  * 列数写整数就是各档同一个列数(`cols="3"`),写 JSON 对象就是逐档的列数
4539
4698
  * (`cols='{"base":1,"md":3}'`)。解析不出对象时当没写:落一个半截对象进去,
@@ -4582,9 +4741,9 @@ var XhGridElement = class extends XhElement {
4582
4741
  };
4583
4742
  static properties = {
4584
4743
  cols: { converter: COLS_CONVERTER },
4585
- gap: { converter: STRING_CONVERTER$52 },
4586
- align: { converter: STRING_CONVERTER$52 },
4587
- justify: { converter: STRING_CONVERTER$52 }
4744
+ gap: { converter: STRING_CONVERTER$53 },
4745
+ align: { converter: STRING_CONVERTER$53 },
4746
+ justify: { converter: STRING_CONVERTER$53 }
4588
4747
  };
4589
4748
  wire() {
4590
4749
  const api = connectGrid({
@@ -4606,7 +4765,7 @@ var XhGridElement = class extends XhElement {
4606
4765
  };
4607
4766
  //#endregion
4608
4767
  //#region src/elements/highlight.ts
4609
- const STRING_CONVERTER$51 = { fromAttribute: (v) => v ?? void 0 };
4768
+ const STRING_CONVERTER$52 = { fromAttribute: (v) => v ?? void 0 };
4610
4769
  /**
4611
4770
  * `<xh-highlight>` —— Light-DOM 行为宿主,无状态机,把 text 按 keyword 切段铺进 root。
4612
4771
  *
@@ -4632,8 +4791,8 @@ var XhHighlightElement = class extends XhElement {
4632
4791
  meta: highlightMeta
4633
4792
  };
4634
4793
  static properties = {
4635
- text: { converter: STRING_CONVERTER$51 },
4636
- keyword: { converter: STRING_CONVERTER$51 },
4794
+ text: { converter: STRING_CONVERTER$52 },
4795
+ keyword: { converter: STRING_CONVERTER$52 },
4637
4796
  caseSensitive: {
4638
4797
  type: Boolean,
4639
4798
  attribute: "case-sensitive"
@@ -4681,13 +4840,13 @@ var XhHighlightElement = class extends XhElement {
4681
4840
  };
4682
4841
  //#endregion
4683
4842
  //#region src/elements/hover-card.ts
4684
- const STRING_CONVERTER$50 = { fromAttribute: (v) => v ?? void 0 };
4685
- const NUMBER_CONVERTER$33 = { fromAttribute: (v) => {
4843
+ const STRING_CONVERTER$51 = { fromAttribute: (v) => v ?? void 0 };
4844
+ const NUMBER_CONVERTER$34 = { fromAttribute: (v) => {
4686
4845
  if (v === null) return void 0;
4687
4846
  const n = Number(v);
4688
4847
  return Number.isFinite(n) ? n : void 0;
4689
4848
  } };
4690
- const BOOLEAN_CONVERTER$32 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
4849
+ const BOOLEAN_CONVERTER$34 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
4691
4850
  /**
4692
4851
  * `<xh-hover-card>` —— Light-DOM 行为宿主:作者写 root/trigger/positioner/content/arrow 角色节点,
4693
4852
  * 元素跑 hover-card 机器并把 connect 产出打上去。
@@ -4720,27 +4879,27 @@ var XhHoverCardElement = class extends XhElement {
4720
4879
  meta: hoverCardMeta
4721
4880
  };
4722
4881
  static properties = {
4723
- open: { converter: BOOLEAN_CONVERTER$32 },
4882
+ open: { converter: BOOLEAN_CONVERTER$34 },
4724
4883
  defaultOpen: {
4725
4884
  type: Boolean,
4726
4885
  attribute: "default-open"
4727
4886
  },
4728
- placement: { converter: STRING_CONVERTER$50 },
4729
- offset: { converter: NUMBER_CONVERTER$33 },
4887
+ placement: { converter: STRING_CONVERTER$51 },
4888
+ offset: { converter: NUMBER_CONVERTER$34 },
4730
4889
  openDelay: {
4731
- converter: NUMBER_CONVERTER$33,
4890
+ converter: NUMBER_CONVERTER$34,
4732
4891
  attribute: "open-delay"
4733
4892
  },
4734
4893
  closeDelay: {
4735
- converter: NUMBER_CONVERTER$33,
4894
+ converter: NUMBER_CONVERTER$34,
4736
4895
  attribute: "close-delay"
4737
4896
  },
4738
4897
  direction: {
4739
- converter: STRING_CONVERTER$50,
4898
+ converter: STRING_CONVERTER$51,
4740
4899
  attribute: "dir"
4741
4900
  },
4742
4901
  disabled: { type: Boolean },
4743
- size: { converter: STRING_CONVERTER$50 }
4902
+ size: { converter: STRING_CONVERTER$51 }
4744
4903
  };
4745
4904
  idGen = createCounterIdGenerator();
4746
4905
  hoverCardScope = createScope(null, this.idGen);
@@ -4828,7 +4987,7 @@ var XhHoverCardElement = class extends XhElement {
4828
4987
  };
4829
4988
  //#endregion
4830
4989
  //#region src/elements/icon.ts
4831
- const STRING_CONVERTER$49 = { fromAttribute: (v) => v ?? void 0 };
4990
+ const STRING_CONVERTER$50 = { fromAttribute: (v) => v ?? void 0 };
4832
4991
  const SVG_NS$1 = "http://www.w3.org/2000/svg";
4833
4992
  /** 自带可及名字的控件;图标落在它们里面时名字该写在控件上。 */
4834
4993
  const NAMED_CONTROLS = "button, a[href], [role=\"button\"], [role=\"link\"], [role=\"menuitem\"], [role=\"tab\"], [role=\"option\"]";
@@ -4869,10 +5028,10 @@ var XhIconElement = class extends XhElement {
4869
5028
  }
4870
5029
  };
4871
5030
  static properties = {
4872
- label: { converter: STRING_CONVERTER$49 },
4873
- size: { converter: STRING_CONVERTER$49 },
4874
- weight: { converter: STRING_CONVERTER$49 },
4875
- tone: { converter: STRING_CONVERTER$49 },
5031
+ label: { converter: STRING_CONVERTER$50 },
5032
+ size: { converter: STRING_CONVERTER$50 },
5033
+ weight: { converter: STRING_CONVERTER$50 },
5034
+ tone: { converter: STRING_CONVERTER$50 },
4876
5035
  icon: { attribute: false }
4877
5036
  };
4878
5037
  /** 一个 glyph 节点归谁,首次见到时定死。 */
@@ -4995,8 +5154,8 @@ var XhIconWrapperElement = class extends XhElement {
4995
5154
  };
4996
5155
  //#endregion
4997
5156
  //#region src/elements/image.ts
4998
- const STRING_CONVERTER$48 = { fromAttribute: (v) => v ?? void 0 };
4999
- const NUMBER_CONVERTER$32 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
5157
+ const STRING_CONVERTER$49 = { fromAttribute: (v) => v ?? void 0 };
5158
+ const NUMBER_CONVERTER$33 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
5000
5159
  /**
5001
5160
  * `<xh-image>` —— Light-DOM 行为宿主:作者写 root/image/fallback 角色节点,
5002
5161
  * 元素跑 image 机器并把 connect 产出打上去。图片来源由宿主的 src/alt 写进 image 节点,
@@ -5020,10 +5179,10 @@ var XhImageElement = class extends XhElement {
5020
5179
  meta: imageMeta
5021
5180
  };
5022
5181
  static properties = {
5023
- src: { converter: STRING_CONVERTER$48 },
5024
- alt: { converter: STRING_CONVERTER$48 },
5182
+ src: { converter: STRING_CONVERTER$49 },
5183
+ alt: { converter: STRING_CONVERTER$49 },
5025
5184
  fallbackDelay: {
5026
- converter: NUMBER_CONVERTER$32,
5185
+ converter: NUMBER_CONVERTER$33,
5027
5186
  attribute: "fallback-delay"
5028
5187
  }
5029
5188
  };
@@ -5078,9 +5237,208 @@ var XhImageElement = class extends XhElement {
5078
5237
  }
5079
5238
  };
5080
5239
  //#endregion
5240
+ //#region src/elements/image-viewer.ts
5241
+ const BOOLEAN_CONVERTER$33 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
5242
+ const NUMBER_CONVERTER$32 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
5243
+ /**
5244
+ * `<xh-image-viewer>` —— Light-DOM 行为宿主,跑 image-viewer 机器:
5245
+ * 模态看片浮层,滚轮缩放、拖拽平移、旋转翻转与多图翻页。
5246
+ *
5247
+ * @customElement xh-image-viewer
5248
+ * @attr {boolean} open - 受控开合;缺省该属性即非受控
5249
+ * @attr {boolean} default-open - 非受控初始为打开
5250
+ * @attr {number} index - 受控下标(0 起)
5251
+ * @attr {number} default-index - 非受控初始下标,默认 0
5252
+ * @attr {boolean} loop - 前后翻页到头回绕,默认 true;写 loop="false" 关掉
5253
+ * @attr {number} zoom-step - 缩放步长(加法),默认 0.5
5254
+ * @attr {number} min-scale - 缩放下限,默认 0.25
5255
+ * @attr {number} max-scale - 缩放上限,默认 8
5256
+ * @attr {boolean} close-on-escape - Esc 关闭,默认 true
5257
+ * @attr {boolean} close-on-interact-outside - 点遮罩关闭,默认 true
5258
+ * @attr {boolean} restore-focus - 关闭后把焦点归还触发元素,默认 true
5259
+ * @fires open-change - open 状态变化;detail 为 `{ open: boolean }`
5260
+ * @fires index-change - 下标变化;detail 为 `{ index: number }`
5261
+ * @csspart trigger - 触发按钮
5262
+ * @csspart backdrop - 遮罩层
5263
+ * @csspart positioner - 浮层定位容器
5264
+ * @csspart content - 看片容器(role=dialog + aria-modal;方向键翻页在这里)
5265
+ * @csspart viewport - 手势视口(滚轮缩放、拖拽平移)
5266
+ * @csspart image - 当前那张图(src/alt/transform 由元素代填)
5267
+ * @csspart toolbar - 工具条容器
5268
+ * @csspart zoom-in-trigger - 放大
5269
+ * @csspart zoom-out-trigger - 缩小
5270
+ * @csspart rotate-left-trigger - 左转 90°
5271
+ * @csspart rotate-right-trigger - 右转 90°
5272
+ * @csspart flip-horizontal-trigger - 水平翻转
5273
+ * @csspart flip-vertical-trigger - 垂直翻转
5274
+ * @csspart reset-trigger - 变换归零
5275
+ * @csspart prev-trigger - 上一张
5276
+ * @csspart next-trigger - 下一张
5277
+ * @csspart counter - 「第 n / 共 m」计数(元素代填)
5278
+ * @csspart close-trigger - 关闭
5279
+ */
5280
+ var XhImageViewerElement = class extends XhElement {
5281
+ static partContract = {
5282
+ anatomy: imageViewerAnatomy,
5283
+ meta: imageViewerMeta
5284
+ };
5285
+ static properties = {
5286
+ open: { converter: BOOLEAN_CONVERTER$33 },
5287
+ defaultOpen: {
5288
+ type: Boolean,
5289
+ attribute: "default-open"
5290
+ },
5291
+ index: { converter: NUMBER_CONVERTER$32 },
5292
+ defaultIndex: {
5293
+ converter: NUMBER_CONVERTER$32,
5294
+ attribute: "default-index"
5295
+ },
5296
+ loop: { converter: BOOLEAN_CONVERTER$33 },
5297
+ zoomStep: {
5298
+ converter: NUMBER_CONVERTER$32,
5299
+ attribute: "zoom-step"
5300
+ },
5301
+ minScale: {
5302
+ converter: NUMBER_CONVERTER$32,
5303
+ attribute: "min-scale"
5304
+ },
5305
+ maxScale: {
5306
+ converter: NUMBER_CONVERTER$32,
5307
+ attribute: "max-scale"
5308
+ },
5309
+ closeOnEscape: {
5310
+ converter: BOOLEAN_CONVERTER$33,
5311
+ attribute: "close-on-escape"
5312
+ },
5313
+ closeOnInteractOutside: {
5314
+ converter: BOOLEAN_CONVERTER$33,
5315
+ attribute: "close-on-interact-outside"
5316
+ },
5317
+ restoreFocus: {
5318
+ converter: BOOLEAN_CONVERTER$33,
5319
+ attribute: "restore-focus"
5320
+ },
5321
+ items: { attribute: false },
5322
+ translations: { attribute: false }
5323
+ };
5324
+ idGen = createCounterIdGenerator();
5325
+ viewerScope = createScope(null, this.idGen);
5326
+ config = null;
5327
+ contentNode = null;
5328
+ backdropNode = null;
5329
+ /** counter 的文本归属:首帧为空才代填,作者写过内容就不碰。 */
5330
+ counterOwned = null;
5331
+ notifyOpen = (details) => {
5332
+ this.dispatchEvent(new CustomEvent("open-change", {
5333
+ detail: details,
5334
+ bubbles: true,
5335
+ composed: true
5336
+ }));
5337
+ };
5338
+ notifyIndex = (details) => {
5339
+ this.dispatchEvent(new CustomEvent("index-change", {
5340
+ detail: details,
5341
+ bubbles: true,
5342
+ composed: true
5343
+ }));
5344
+ };
5345
+ ctrl = new MachineController(this, imageViewerMachine, () => this.machineProps(), {
5346
+ scope: this.viewerScope,
5347
+ onBuilt: (svc) => this.injectRefs(svc)
5348
+ });
5349
+ machineProps() {
5350
+ return {
5351
+ items: this.items,
5352
+ open: this.open,
5353
+ defaultOpen: this.defaultOpen ?? false,
5354
+ index: this.index,
5355
+ defaultIndex: this.defaultIndex,
5356
+ loop: this.loop,
5357
+ zoomStep: this.zoomStep,
5358
+ minScale: this.minScale,
5359
+ maxScale: this.maxScale,
5360
+ closeOnEscape: this.closeOnEscape,
5361
+ closeOnInteractOutside: this.closeOnInteractOutside,
5362
+ restoreFocus: this.restoreFocus,
5363
+ translations: this.translations,
5364
+ onOpenChange: this.notifyOpen,
5365
+ onIndexChange: this.notifyIndex
5366
+ };
5367
+ }
5368
+ ensureConfig() {
5369
+ if (this.config) return;
5370
+ this.config = createRuntimeConfig({
5371
+ scope: this.viewerScope,
5372
+ idGenerator: this.idGen
5373
+ });
5374
+ }
5375
+ registerLayer = () => {
5376
+ this.ensureConfig();
5377
+ return this.config.layerRegistry.register({
5378
+ kind: "modal",
5379
+ node: () => this.contentNode,
5380
+ branches: () => [],
5381
+ isModal: () => true,
5382
+ setModal: () => {},
5383
+ surfaces: () => [this.backdropNode].filter(Boolean)
5384
+ });
5385
+ };
5386
+ injectRefs(svc) {
5387
+ this.ensureConfig();
5388
+ svc.refs.set("config", this.config);
5389
+ svc.refs.set("registerLayer", this.registerLayer);
5390
+ svc.refs.set("getContentEl", () => this.contentNode);
5391
+ }
5392
+ wire() {
5393
+ const svc = this.ctrl.service;
5394
+ const api = connectImageViewer(svc, wcNormalize);
5395
+ const open = svc.state.get() === "open";
5396
+ this.contentNode = this.getPart("content");
5397
+ this.backdropNode = this.getPart("backdrop");
5398
+ const put = (name, props) => {
5399
+ const el = this.getPart(name);
5400
+ if (el) this.spreader.spread(el, props);
5401
+ };
5402
+ put("trigger", api.getTriggerProps());
5403
+ put("backdrop", api.getBackdropProps());
5404
+ put("positioner", api.getPositionerProps());
5405
+ put("content", api.getContentProps());
5406
+ put("viewport", api.getViewportProps());
5407
+ put("image", api.getImageProps());
5408
+ put("toolbar", api.getToolbarProps());
5409
+ put("zoom-in-trigger", api.getZoomInTriggerProps());
5410
+ put("zoom-out-trigger", api.getZoomOutTriggerProps());
5411
+ put("rotate-left-trigger", api.getRotateLeftTriggerProps());
5412
+ put("rotate-right-trigger", api.getRotateRightTriggerProps());
5413
+ put("flip-horizontal-trigger", api.getFlipHorizontalTriggerProps());
5414
+ put("flip-vertical-trigger", api.getFlipVerticalTriggerProps());
5415
+ put("reset-trigger", api.getResetTriggerProps());
5416
+ put("prev-trigger", api.getPrevTriggerProps());
5417
+ put("next-trigger", api.getNextTriggerProps());
5418
+ put("counter", api.getCounterProps());
5419
+ put("close-trigger", api.getCloseTriggerProps());
5420
+ const counter = this.getPart("counter");
5421
+ if (counter) {
5422
+ if (this.counterOwned === null) this.counterOwned = (counter.textContent ?? "").trim() === "";
5423
+ if (this.counterOwned) {
5424
+ const text = imageViewerCounterText(this.translations, api.index, api.count);
5425
+ if (counter.textContent !== text) counter.textContent = text;
5426
+ }
5427
+ }
5428
+ const positioner = this.getPart("positioner");
5429
+ if (positioner) this.setPartHidden(positioner, !open);
5430
+ if (this.backdropNode) this.setPartHidden(this.backdropNode, !open);
5431
+ this.setPartHidden(this.contentNode, !open);
5432
+ }
5433
+ disconnectedCallback() {
5434
+ super.disconnectedCallback();
5435
+ this.config = null;
5436
+ }
5437
+ };
5438
+ //#endregion
5081
5439
  //#region src/elements/infinite-scroll.ts
5082
5440
  const NUMBER_CONVERTER$31 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
5083
- const BOOLEAN_CONVERTER$31 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
5441
+ const BOOLEAN_CONVERTER$32 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
5084
5442
  /**
5085
5443
  * `<xh-infinite-scroll>` —— 无限滚动行为宿主:摆在列表末尾的哨兵一进可视区就报「该取下一页了」。
5086
5444
  *
@@ -5104,8 +5462,8 @@ var XhInfiniteScrollElement = class extends XhElement {
5104
5462
  };
5105
5463
  static properties = {
5106
5464
  distance: { converter: NUMBER_CONVERTER$31 },
5107
- disabled: { converter: BOOLEAN_CONVERTER$31 },
5108
- loading: { converter: BOOLEAN_CONVERTER$31 },
5465
+ disabled: { converter: BOOLEAN_CONVERTER$32 },
5466
+ loading: { converter: BOOLEAN_CONVERTER$32 },
5109
5467
  target: { attribute: false }
5110
5468
  };
5111
5469
  notify = () => {
@@ -5139,7 +5497,7 @@ var XhInfiniteScrollElement = class extends XhElement {
5139
5497
  };
5140
5498
  //#endregion
5141
5499
  //#region src/elements/layout.ts
5142
- const STRING_CONVERTER$47 = { fromAttribute: (v) => v ?? void 0 };
5500
+ const STRING_CONVERTER$48 = { fromAttribute: (v) => v ?? void 0 };
5143
5501
  /**
5144
5502
  * `<xh-layout>` —— 页面骨架的 Light-DOM 行为宿主,跑 layout 机器并把 connect 产出打到
5145
5503
  * root/header/sider/content/footer/sider-trigger 角色节点。
@@ -5185,15 +5543,15 @@ var XhLayoutElement = class extends XhElement {
5185
5543
  },
5186
5544
  siderWidth: {
5187
5545
  attribute: "sider-width",
5188
- converter: STRING_CONVERTER$47
5546
+ converter: STRING_CONVERTER$48
5189
5547
  },
5190
5548
  siderCollapsedWidth: {
5191
5549
  attribute: "sider-collapsed-width",
5192
- converter: STRING_CONVERTER$47
5550
+ converter: STRING_CONVERTER$48
5193
5551
  },
5194
5552
  siderPlacement: {
5195
5553
  attribute: "sider-placement",
5196
- converter: STRING_CONVERTER$47
5554
+ converter: STRING_CONVERTER$48
5197
5555
  },
5198
5556
  headerFixed: {
5199
5557
  type: Boolean,
@@ -5242,7 +5600,7 @@ var XhLayoutElement = class extends XhElement {
5242
5600
  };
5243
5601
  //#endregion
5244
5602
  //#region src/elements/list.ts
5245
- const STRING_CONVERTER$46 = { fromAttribute: (v) => v ?? void 0 };
5603
+ const STRING_CONVERTER$47 = { fromAttribute: (v) => v ?? void 0 };
5246
5604
  /**
5247
5605
  * `<xh-list>` —— Light-DOM 行为宿主,无状态机,把 connectList 产出打到各角色节点。
5248
5606
  * 除 root 外的部件全部可缺省:空列表、只有一行标题的条目都是合法形态。
@@ -5272,7 +5630,7 @@ var XhListElement = class extends XhElement {
5272
5630
  bordered: { type: Boolean },
5273
5631
  hoverable: { type: Boolean },
5274
5632
  split: { type: Boolean },
5275
- size: { converter: STRING_CONVERTER$46 }
5633
+ size: { converter: STRING_CONVERTER$47 }
5276
5634
  };
5277
5635
  wire() {
5278
5636
  const api = connectList({
@@ -5296,8 +5654,8 @@ var XhListElement = class extends XhElement {
5296
5654
  };
5297
5655
  //#endregion
5298
5656
  //#region src/elements/listbox.ts
5299
- const STRING_CONVERTER$45 = { fromAttribute: (v) => v ?? void 0 };
5300
- const BOOLEAN_CONVERTER$30 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
5657
+ const STRING_CONVERTER$46 = { fromAttribute: (v) => v ?? void 0 };
5658
+ const BOOLEAN_CONVERTER$31 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
5301
5659
  /**
5302
5660
  * `<xh-listbox>` —— Light-DOM 行为宿主:作者写 root/label/content 与若干 item 角色节点,
5303
5661
  * 元素跑 listbox 机器并把 connect 产出打上去。条目身份取自条目节点上的 value 属性,
@@ -5339,24 +5697,24 @@ var XhListboxElement = class extends XhElement {
5339
5697
  };
5340
5698
  static properties = {
5341
5699
  collection: { attribute: false },
5342
- value: { converter: STRING_CONVERTER$45 },
5700
+ value: { converter: STRING_CONVERTER$46 },
5343
5701
  defaultValue: {
5344
- converter: STRING_CONVERTER$45,
5702
+ converter: STRING_CONVERTER$46,
5345
5703
  attribute: "default-value"
5346
5704
  },
5347
5705
  multiple: { type: Boolean },
5348
5706
  selectionMode: {
5349
- converter: STRING_CONVERTER$45,
5707
+ converter: STRING_CONVERTER$46,
5350
5708
  attribute: "selection-mode"
5351
5709
  },
5352
5710
  disabled: { type: Boolean },
5353
- loop: { converter: BOOLEAN_CONVERTER$30 },
5711
+ loop: { converter: BOOLEAN_CONVERTER$31 },
5354
5712
  direction: {
5355
- converter: STRING_CONVERTER$45,
5713
+ converter: STRING_CONVERTER$46,
5356
5714
  attribute: "dir"
5357
5715
  },
5358
- orientation: { converter: STRING_CONVERTER$45 },
5359
- typeahead: { converter: BOOLEAN_CONVERTER$30 }
5716
+ orientation: { converter: STRING_CONVERTER$46 },
5717
+ typeahead: { converter: BOOLEAN_CONVERTER$31 }
5360
5718
  };
5361
5719
  declaredDisabled = /* @__PURE__ */ new WeakMap();
5362
5720
  /** 上一帧是否整列禁用:解禁当帧 DOM 上还留着机器写回的 aria-disabled,读不得。 */
@@ -5454,9 +5812,9 @@ var XhListboxElement = class extends XhElement {
5454
5812
  };
5455
5813
  //#endregion
5456
5814
  //#region src/elements/loading-bar.ts
5457
- const STRING_CONVERTER$44 = { fromAttribute: (v) => v ?? void 0 };
5815
+ const STRING_CONVERTER$45 = { fromAttribute: (v) => v ?? void 0 };
5458
5816
  const NUMBER_CONVERTER$30 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
5459
- const BOOLEAN_CONVERTER$29 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
5817
+ const BOOLEAN_CONVERTER$30 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
5460
5818
  const HEIGHT_CONVERTER = { fromAttribute: (v) => {
5461
5819
  if (v == null || v === "") return void 0;
5462
5820
  const px = Number(v);
@@ -5500,11 +5858,11 @@ var XhLoadingBarElement = class extends XhElement {
5500
5858
  converter: NUMBER_CONVERTER$30,
5501
5859
  attribute: "default-value"
5502
5860
  },
5503
- loading: { converter: BOOLEAN_CONVERTER$29 },
5861
+ loading: { converter: BOOLEAN_CONVERTER$30 },
5504
5862
  height: { converter: HEIGHT_CONVERTER },
5505
- color: { converter: STRING_CONVERTER$44 },
5506
- tone: { converter: STRING_CONVERTER$44 },
5507
- trickle: { converter: BOOLEAN_CONVERTER$29 },
5863
+ color: { converter: STRING_CONVERTER$45 },
5864
+ tone: { converter: STRING_CONVERTER$45 },
5865
+ trickle: { converter: BOOLEAN_CONVERTER$30 },
5508
5866
  trickleSpeed: {
5509
5867
  converter: NUMBER_CONVERTER$30,
5510
5868
  attribute: "trickle-speed"
@@ -5640,7 +5998,7 @@ var XhLogElement = class extends XhElement {
5640
5998
  };
5641
5999
  //#endregion
5642
6000
  //#region src/elements/marquee.ts
5643
- const STRING_CONVERTER$43 = { fromAttribute: (v) => v ?? void 0 };
6001
+ const STRING_CONVERTER$44 = { fromAttribute: (v) => v ?? void 0 };
5644
6002
  const NUMBER_CONVERTER$28 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
5645
6003
  /**
5646
6004
  * `<xh-marquee>` —— Light-DOM 行为宿主,无状态机,把 connectMarquee 产出打到 root 与 content 上。
@@ -5668,7 +6026,7 @@ var XhMarqueeElement = class extends XhElement {
5668
6026
  meta: marqueeMeta
5669
6027
  };
5670
6028
  static properties = {
5671
- direction: { converter: STRING_CONVERTER$43 },
6029
+ direction: { converter: STRING_CONVERTER$44 },
5672
6030
  speed: { converter: NUMBER_CONVERTER$28 },
5673
6031
  pauseOnHover: {
5674
6032
  type: Boolean,
@@ -5696,9 +6054,9 @@ var XhMarqueeElement = class extends XhElement {
5696
6054
  };
5697
6055
  //#endregion
5698
6056
  //#region src/elements/mention.ts
5699
- const STRING_CONVERTER$42 = { fromAttribute: (v) => v ?? void 0 };
6057
+ const STRING_CONVERTER$43 = { fromAttribute: (v) => v ?? void 0 };
5700
6058
  const NUMBER_CONVERTER$27 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
5701
- const BOOLEAN_CONVERTER$28 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
6059
+ const BOOLEAN_CONVERTER$29 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
5702
6060
  /**
5703
6061
  * `<xh-mention>` —— Light-DOM 行为宿主:作者写 root/input/positioner/content/item 角色节点,
5704
6062
  * 元素跑 mention 机器并把 connect 产出打上去。浮层定位引擎在本元素里建好、经 refs 注入机器,
@@ -5747,22 +6105,22 @@ var XhMentionElement = class extends XhElement {
5747
6105
  collection: { attribute: false },
5748
6106
  translations: { attribute: false },
5749
6107
  triggerPrefix: {
5750
- converter: STRING_CONVERTER$42,
6108
+ converter: STRING_CONVERTER$43,
5751
6109
  attribute: "prefix"
5752
6110
  },
5753
- value: { converter: STRING_CONVERTER$42 },
6111
+ value: { converter: STRING_CONVERTER$43 },
5754
6112
  defaultValue: {
5755
- converter: STRING_CONVERTER$42,
6113
+ converter: STRING_CONVERTER$43,
5756
6114
  attribute: "default-value"
5757
6115
  },
5758
6116
  disabled: { type: Boolean },
5759
- placeholder: { converter: STRING_CONVERTER$42 },
5760
- loop: { converter: BOOLEAN_CONVERTER$28 },
5761
- placement: { converter: STRING_CONVERTER$42 },
6117
+ placeholder: { converter: STRING_CONVERTER$43 },
6118
+ loop: { converter: BOOLEAN_CONVERTER$29 },
6119
+ placement: { converter: STRING_CONVERTER$43 },
5762
6120
  offset: { converter: NUMBER_CONVERTER$27 },
5763
- variant: { converter: STRING_CONVERTER$42 },
5764
- tone: { converter: STRING_CONVERTER$42 },
5765
- size: { converter: STRING_CONVERTER$42 }
6121
+ variant: { converter: STRING_CONVERTER$43 },
6122
+ tone: { converter: STRING_CONVERTER$43 },
6123
+ size: { converter: STRING_CONVERTER$43 }
5766
6124
  };
5767
6125
  idGen = createCounterIdGenerator();
5768
6126
  mentionScope = createScope(null, this.idGen);
@@ -5890,9 +6248,9 @@ var XhMentionElement = class extends XhElement {
5890
6248
  };
5891
6249
  //#endregion
5892
6250
  //#region src/elements/menu.ts
5893
- const STRING_CONVERTER$41 = { fromAttribute: (v) => v ?? void 0 };
6251
+ const STRING_CONVERTER$42 = { fromAttribute: (v) => v ?? void 0 };
5894
6252
  const NUMBER_CONVERTER$26 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
5895
- const BOOLEAN_CONVERTER$27 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
6253
+ const BOOLEAN_CONVERTER$28 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
5896
6254
  /**
5897
6255
  * `<xh-menu>` —— Light-DOM 行为宿主:用户写 trigger/positioner/content/item/... 角色节点,
5898
6256
  * 元素跑 menu 机器并把 connect 产出打上去。浮层定位引擎在本元素里建好、经 refs 注入机器,
@@ -5924,20 +6282,33 @@ var XhMenuElement = class extends XhElement {
5924
6282
  };
5925
6283
  static properties = {
5926
6284
  collection: { attribute: false },
5927
- open: { converter: BOOLEAN_CONVERTER$27 },
6285
+ open: { converter: BOOLEAN_CONVERTER$28 },
5928
6286
  defaultOpen: {
5929
6287
  type: Boolean,
5930
6288
  attribute: "default-open"
5931
6289
  },
5932
- placement: { converter: STRING_CONVERTER$41 },
6290
+ placement: { converter: STRING_CONVERTER$42 },
5933
6291
  offset: { converter: NUMBER_CONVERTER$26 },
5934
- loop: { converter: BOOLEAN_CONVERTER$27 },
6292
+ loop: { converter: BOOLEAN_CONVERTER$28 },
5935
6293
  direction: {
5936
- converter: STRING_CONVERTER$41,
6294
+ converter: STRING_CONVERTER$42,
5937
6295
  attribute: "dir"
5938
6296
  },
5939
- tone: { converter: STRING_CONVERTER$41 },
5940
- size: { converter: STRING_CONVERTER$41 }
6297
+ tone: { converter: STRING_CONVERTER$42 },
6298
+ size: { converter: STRING_CONVERTER$42 },
6299
+ submenu: { converter: BOOLEAN_CONVERTER$28 },
6300
+ openOnHover: {
6301
+ converter: BOOLEAN_CONVERTER$28,
6302
+ attribute: "open-on-hover"
6303
+ },
6304
+ hoverOpenDelay: {
6305
+ converter: NUMBER_CONVERTER$26,
6306
+ attribute: "hover-open-delay"
6307
+ },
6308
+ hoverCloseDelay: {
6309
+ converter: NUMBER_CONVERTER$26,
6310
+ attribute: "hover-close-delay"
6311
+ }
5941
6312
  };
5942
6313
  idGen = createCounterIdGenerator();
5943
6314
  menuScope = createScope(null, this.idGen);
@@ -5974,6 +6345,10 @@ var XhMenuElement = class extends XhElement {
5974
6345
  dir: this.direction,
5975
6346
  tone: this.tone,
5976
6347
  size: this.size,
6348
+ submenu: this.submenu,
6349
+ openOnHover: this.openOnHover,
6350
+ hoverOpenDelay: this.hoverOpenDelay,
6351
+ hoverCloseDelay: this.hoverCloseDelay,
5977
6352
  onOpenChange: this.notifyOpen,
5978
6353
  onSelect: this.notifySelect
5979
6354
  };
@@ -6033,7 +6408,9 @@ var XhMenuElement = class extends XhElement {
6033
6408
  const el = this.getPart(name);
6034
6409
  if (el) this.spreader.spread(el, props);
6035
6410
  };
6036
- put("trigger", api.getTriggerProps());
6411
+ const triggerEl = this.getPart("trigger");
6412
+ if (this.submenu && triggerEl) this.spreader.spread(triggerEl, api.getSubmenuTriggerProps({ value: triggerEl.getAttribute("value") ?? "" }));
6413
+ else put("trigger", api.getTriggerProps());
6037
6414
  put("positioner", api.getPositionerProps());
6038
6415
  put("content", api.getContentProps());
6039
6416
  put("arrow", api.getArrowProps());
@@ -6055,9 +6432,9 @@ var XhMenuElement = class extends XhElement {
6055
6432
  };
6056
6433
  //#endregion
6057
6434
  //#region src/elements/menubar.ts
6058
- const STRING_CONVERTER$40 = { fromAttribute: (v) => v ?? void 0 };
6435
+ const STRING_CONVERTER$41 = { fromAttribute: (v) => v ?? void 0 };
6059
6436
  const NUMBER_CONVERTER$25 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
6060
- const BOOLEAN_CONVERTER$26 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
6437
+ const BOOLEAN_CONVERTER$27 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
6061
6438
  /** 读角色节点的禁用声明,并摘掉作者写的原生 disabled,禁用态归一到 aria-disabled。 */
6062
6439
  function authorDisabled$1(el) {
6063
6440
  const disabled = isItemDisabled(el);
@@ -6107,23 +6484,23 @@ var XhMenubarElement = class extends XhElement {
6107
6484
  };
6108
6485
  static properties = {
6109
6486
  collection: { attribute: false },
6110
- value: { converter: STRING_CONVERTER$40 },
6487
+ value: { converter: STRING_CONVERTER$41 },
6111
6488
  defaultValue: {
6112
- converter: STRING_CONVERTER$40,
6489
+ converter: STRING_CONVERTER$41,
6113
6490
  attribute: "default-value"
6114
6491
  },
6115
- orientation: { converter: STRING_CONVERTER$40 },
6116
- loop: { converter: BOOLEAN_CONVERTER$26 },
6492
+ orientation: { converter: STRING_CONVERTER$41 },
6493
+ loop: { converter: BOOLEAN_CONVERTER$27 },
6117
6494
  direction: {
6118
- converter: STRING_CONVERTER$40,
6495
+ converter: STRING_CONVERTER$41,
6119
6496
  attribute: "dir"
6120
6497
  },
6121
- disabled: { converter: BOOLEAN_CONVERTER$26 },
6122
- typeahead: { converter: BOOLEAN_CONVERTER$26 },
6123
- placement: { converter: STRING_CONVERTER$40 },
6498
+ disabled: { converter: BOOLEAN_CONVERTER$27 },
6499
+ typeahead: { converter: BOOLEAN_CONVERTER$27 },
6500
+ placement: { converter: STRING_CONVERTER$41 },
6124
6501
  offset: { converter: NUMBER_CONVERTER$25 },
6125
- tone: { converter: STRING_CONVERTER$40 },
6126
- size: { converter: STRING_CONVERTER$40 }
6502
+ tone: { converter: STRING_CONVERTER$41 },
6503
+ size: { converter: STRING_CONVERTER$41 }
6127
6504
  };
6128
6505
  idGen = createCounterIdGenerator();
6129
6506
  barScope = createScope(null, this.idGen);
@@ -6257,9 +6634,9 @@ var XhMenubarElement = class extends XhElement {
6257
6634
  };
6258
6635
  //#endregion
6259
6636
  //#region src/elements/navigation-menu.ts
6260
- const STRING_CONVERTER$39 = { fromAttribute: (v) => v ?? void 0 };
6637
+ const STRING_CONVERTER$40 = { fromAttribute: (v) => v ?? void 0 };
6261
6638
  const NUMBER_CONVERTER$24 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
6262
- const BOOLEAN_CONVERTER$25 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
6639
+ const BOOLEAN_CONVERTER$26 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
6263
6640
  /**
6264
6641
  * 作者写在角色节点上的布尔声明,三态读法:属性缺席 = false,="false" = false,其余 = true。
6265
6642
  */
@@ -6319,12 +6696,12 @@ var XhNavigationMenuElement = class extends XhElement {
6319
6696
  };
6320
6697
  static properties = {
6321
6698
  collection: { attribute: false },
6322
- value: { converter: STRING_CONVERTER$39 },
6699
+ value: { converter: STRING_CONVERTER$40 },
6323
6700
  defaultValue: {
6324
- converter: STRING_CONVERTER$39,
6701
+ converter: STRING_CONVERTER$40,
6325
6702
  attribute: "default-value"
6326
6703
  },
6327
- orientation: { converter: STRING_CONVERTER$39 },
6704
+ orientation: { converter: STRING_CONVERTER$40 },
6328
6705
  delayDuration: {
6329
6706
  converter: NUMBER_CONVERTER$24,
6330
6707
  attribute: "delay-duration"
@@ -6334,12 +6711,12 @@ var XhNavigationMenuElement = class extends XhElement {
6334
6711
  attribute: "skip-delay-duration"
6335
6712
  },
6336
6713
  direction: {
6337
- converter: STRING_CONVERTER$39,
6714
+ converter: STRING_CONVERTER$40,
6338
6715
  attribute: "dir"
6339
6716
  },
6340
- loop: { converter: BOOLEAN_CONVERTER$25 },
6341
- tone: { converter: STRING_CONVERTER$39 },
6342
- size: { converter: STRING_CONVERTER$39 },
6717
+ loop: { converter: BOOLEAN_CONVERTER$26 },
6718
+ tone: { converter: STRING_CONVERTER$40 },
6719
+ size: { converter: STRING_CONVERTER$40 },
6343
6720
  translations: { attribute: false }
6344
6721
  };
6345
6722
  idGen = createCounterIdGenerator();
@@ -6412,9 +6789,9 @@ var XhNavigationMenuElement = class extends XhElement {
6412
6789
  };
6413
6790
  //#endregion
6414
6791
  //#region src/elements/number-animation.ts
6415
- const STRING_CONVERTER$38 = { fromAttribute: (v) => v ?? void 0 };
6792
+ const STRING_CONVERTER$39 = { fromAttribute: (v) => v ?? void 0 };
6416
6793
  const NUMBER_CONVERTER$23 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
6417
- const BOOLEAN_CONVERTER$24 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
6794
+ const BOOLEAN_CONVERTER$25 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
6418
6795
  /**
6419
6796
  * `<xh-number-animation>` —— Light-DOM 行为宿主:作者写一个 root 角色节点,
6420
6797
  * 元素跑 number-animation 机器,逐帧把补间算出的数字格式化后写进那个节点。
@@ -6449,13 +6826,13 @@ var XhNumberAnimationElement = class extends XhElement {
6449
6826
  from: { converter: NUMBER_CONVERTER$23 },
6450
6827
  to: { converter: NUMBER_CONVERTER$23 },
6451
6828
  duration: { converter: NUMBER_CONVERTER$23 },
6452
- easing: { converter: STRING_CONVERTER$38 },
6829
+ easing: { converter: STRING_CONVERTER$39 },
6453
6830
  precision: { converter: NUMBER_CONVERTER$23 },
6454
- separator: { converter: STRING_CONVERTER$38 },
6455
- active: { converter: BOOLEAN_CONVERTER$24 },
6456
- size: { converter: STRING_CONVERTER$38 },
6457
- tone: { converter: STRING_CONVERTER$38 },
6458
- live: { converter: STRING_CONVERTER$38 }
6831
+ separator: { converter: STRING_CONVERTER$39 },
6832
+ active: { converter: BOOLEAN_CONVERTER$25 },
6833
+ size: { converter: STRING_CONVERTER$39 },
6834
+ tone: { converter: STRING_CONVERTER$39 },
6835
+ live: { converter: STRING_CONVERTER$39 }
6459
6836
  };
6460
6837
  notify = (details) => {
6461
6838
  this.dispatchEvent(new CustomEvent("finish", {
@@ -6490,7 +6867,7 @@ var XhNumberAnimationElement = class extends XhElement {
6490
6867
  };
6491
6868
  //#endregion
6492
6869
  //#region src/elements/number-field.ts
6493
- const STRING_CONVERTER$37 = { fromAttribute: (v) => v ?? void 0 };
6870
+ const STRING_CONVERTER$38 = { fromAttribute: (v) => v ?? void 0 };
6494
6871
  const NUMBER_CONVERTER$22 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
6495
6872
  /**
6496
6873
  * `<xh-number-field>` —— Light-DOM 行为宿主:作者写 root/label/input/加减按钮四类角色节点,
@@ -6529,9 +6906,9 @@ var XhNumberFieldElement = class extends XhElement {
6529
6906
  meta: numberFieldMeta
6530
6907
  };
6531
6908
  static properties = {
6532
- value: { converter: STRING_CONVERTER$37 },
6909
+ value: { converter: STRING_CONVERTER$38 },
6533
6910
  defaultValue: {
6534
- converter: STRING_CONVERTER$37,
6911
+ converter: STRING_CONVERTER$38,
6535
6912
  attribute: "default-value"
6536
6913
  },
6537
6914
  min: { converter: NUMBER_CONVERTER$22 },
@@ -6548,7 +6925,7 @@ var XhNumberFieldElement = class extends XhElement {
6548
6925
  },
6549
6926
  required: { type: Boolean },
6550
6927
  invalid: { type: Boolean },
6551
- name: { converter: STRING_CONVERTER$37 },
6928
+ name: { converter: STRING_CONVERTER$38 },
6552
6929
  changeDelay: {
6553
6930
  converter: NUMBER_CONVERTER$22,
6554
6931
  attribute: "change-delay"
@@ -6557,9 +6934,9 @@ var XhNumberFieldElement = class extends XhElement {
6557
6934
  converter: NUMBER_CONVERTER$22,
6558
6935
  attribute: "change-interval"
6559
6936
  },
6560
- variant: { converter: STRING_CONVERTER$37 },
6561
- tone: { converter: STRING_CONVERTER$37 },
6562
- size: { converter: STRING_CONVERTER$37 }
6937
+ variant: { converter: STRING_CONVERTER$38 },
6938
+ tone: { converter: STRING_CONVERTER$38 },
6939
+ size: { converter: STRING_CONVERTER$38 }
6563
6940
  };
6564
6941
  notify = (details) => {
6565
6942
  this.dispatchEvent(new CustomEvent("value-change", {
@@ -6605,7 +6982,7 @@ var XhNumberFieldElement = class extends XhElement {
6605
6982
  };
6606
6983
  //#endregion
6607
6984
  //#region src/elements/page-header.ts
6608
- const STRING_CONVERTER$36 = { fromAttribute: (v) => v ?? void 0 };
6985
+ const STRING_CONVERTER$37 = { fromAttribute: (v) => v ?? void 0 };
6609
6986
  /**
6610
6987
  * `<xh-page-header>` —— Light-DOM 行为宿主,无状态机,把 connectPageHeader 产出打到各角色节点。
6611
6988
  * 除 root 外的部件全部可缺省:返回位、标题、副标题、操作、页脚按需摆。
@@ -6629,7 +7006,7 @@ var XhPageHeaderElement = class extends XhElement {
6629
7006
  meta: pageHeaderMeta
6630
7007
  };
6631
7008
  static properties = {
6632
- size: { converter: STRING_CONVERTER$36 },
7009
+ size: { converter: STRING_CONVERTER$37 },
6633
7010
  bordered: { type: Boolean }
6634
7011
  };
6635
7012
  wire() {
@@ -6652,7 +7029,7 @@ var XhPageHeaderElement = class extends XhElement {
6652
7029
  //#endregion
6653
7030
  //#region src/elements/pagination.ts
6654
7031
  const NUMBER_CONVERTER$21 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
6655
- const STRING_CONVERTER$35 = { fromAttribute: (v) => v ?? void 0 };
7032
+ const STRING_CONVERTER$36 = { fromAttribute: (v) => v ?? void 0 };
6656
7033
  /** 页码按钮自报的页数;缺失或空串一律给 NaN(见 wire 里的说明)。 */
6657
7034
  function itemPage(el) {
6658
7035
  const raw = el.getAttribute("value");
@@ -6705,11 +7082,11 @@ var XhPaginationElement = class extends XhElement {
6705
7082
  attribute: "sibling-count"
6706
7083
  },
6707
7084
  direction: {
6708
- converter: STRING_CONVERTER$35,
7085
+ converter: STRING_CONVERTER$36,
6709
7086
  attribute: "dir"
6710
7087
  },
6711
- tone: { converter: STRING_CONVERTER$35 },
6712
- size: { converter: STRING_CONVERTER$35 },
7088
+ tone: { converter: STRING_CONVERTER$36 },
7089
+ size: { converter: STRING_CONVERTER$36 },
6713
7090
  translations: { attribute: false }
6714
7091
  };
6715
7092
  notify = (details) => {
@@ -6752,7 +7129,7 @@ var XhPaginationElement = class extends XhElement {
6752
7129
  };
6753
7130
  //#endregion
6754
7131
  //#region src/elements/pin-input.ts
6755
- const STRING_CONVERTER$34 = { fromAttribute: (v) => v ?? void 0 };
7132
+ const STRING_CONVERTER$35 = { fromAttribute: (v) => v ?? void 0 };
6756
7133
  const NUMBER_CONVERTER$20 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
6757
7134
  const ARRAY_CONVERTER$1 = { fromAttribute: (v) => v == null ? void 0 : [...v] };
6758
7135
  /** 作者写在格子上的下标。缺席或写坏了就退回文档序——手写 HTML 时把格子按顺序排下来本身就是声明。 */
@@ -6804,20 +7181,20 @@ var XhPinInputElement = class extends XhElement {
6804
7181
  attribute: "default-value"
6805
7182
  },
6806
7183
  length: { converter: NUMBER_CONVERTER$20 },
6807
- type: { converter: STRING_CONVERTER$34 },
7184
+ type: { converter: STRING_CONVERTER$35 },
6808
7185
  mask: { type: Boolean },
6809
7186
  otp: { type: Boolean },
6810
- placeholder: { converter: STRING_CONVERTER$34 },
7187
+ placeholder: { converter: STRING_CONVERTER$35 },
6811
7188
  disabled: { type: Boolean },
6812
7189
  invalid: { type: Boolean },
6813
7190
  blurOnComplete: {
6814
7191
  type: Boolean,
6815
7192
  attribute: "blur-on-complete"
6816
7193
  },
6817
- name: { converter: STRING_CONVERTER$34 },
6818
- variant: { converter: STRING_CONVERTER$34 },
6819
- tone: { converter: STRING_CONVERTER$34 },
6820
- size: { converter: STRING_CONVERTER$34 },
7194
+ name: { converter: STRING_CONVERTER$35 },
7195
+ variant: { converter: STRING_CONVERTER$35 },
7196
+ tone: { converter: STRING_CONVERTER$35 },
7197
+ size: { converter: STRING_CONVERTER$35 },
6821
7198
  translations: { attribute: false }
6822
7199
  };
6823
7200
  notifyChange = (details) => {
@@ -6873,9 +7250,9 @@ var XhPinInputElement = class extends XhElement {
6873
7250
  };
6874
7251
  //#endregion
6875
7252
  //#region src/elements/popconfirm.ts
6876
- const STRING_CONVERTER$33 = { fromAttribute: (v) => v ?? void 0 };
7253
+ const STRING_CONVERTER$34 = { fromAttribute: (v) => v ?? void 0 };
6877
7254
  const NUMBER_CONVERTER$19 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
6878
- const BOOLEAN_CONVERTER$23 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
7255
+ const BOOLEAN_CONVERTER$24 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
6879
7256
  /**
6880
7257
  * `<xh-popconfirm>` —— Light-DOM 行为宿主:用户写 root/trigger/positioner/content/... 角色节点,
6881
7258
  * 元素跑 popover 机器(开合、定位、消解层、焦点域都在那里)并把 connectPopconfirm 产出打上去。
@@ -6893,7 +7270,9 @@ const BOOLEAN_CONVERTER$23 = { fromAttribute: (v) => v === null ? void 0 : v !==
6893
7270
  * @attr {boolean} close-on-interact-outside - 层外交互关闭,默认 true;写 "false" 关掉
6894
7271
  * @attr {'sm'|'md'|'lg'} size - 尺寸
6895
7272
  * @fires open-change - open 状态变化;detail 为 `{ open: boolean }`
6896
- * @fires confirm - 点了确认按钮;随后浮层收起
7273
+ * @fires confirm - 点了确认按钮;随后浮层收起。异步门走 confirmAction 属性:
7274
+ * 事件拿不到监听函数的返回值,给元素赋 `confirmAction = () => Promise` 即挂起确认门
7275
+ * (浮层等兑现才收、确认按钮转圈,落空留在原地),confirm 事件照发只作通知
6897
7276
  * @fires cancel - 点了取消按钮;随后浮层收起
6898
7277
  * @csspart root - 框住触发器的根容器,承载 data-state
6899
7278
  * @csspart trigger - 触发按钮(aria-haspopup/aria-expanded/aria-controls 所在),同时是定位锚点
@@ -6910,22 +7289,22 @@ var XhPopconfirmElement = class extends XhElement {
6910
7289
  meta: popconfirmMeta
6911
7290
  };
6912
7291
  static properties = {
6913
- open: { converter: BOOLEAN_CONVERTER$23 },
7292
+ open: { converter: BOOLEAN_CONVERTER$24 },
6914
7293
  defaultOpen: {
6915
7294
  type: Boolean,
6916
7295
  attribute: "default-open"
6917
7296
  },
6918
- placement: { converter: STRING_CONVERTER$33 },
7297
+ placement: { converter: STRING_CONVERTER$34 },
6919
7298
  offset: { converter: NUMBER_CONVERTER$19 },
6920
7299
  closeOnEscape: {
6921
- converter: BOOLEAN_CONVERTER$23,
7300
+ converter: BOOLEAN_CONVERTER$24,
6922
7301
  attribute: "close-on-escape"
6923
7302
  },
6924
7303
  closeOnInteractOutside: {
6925
- converter: BOOLEAN_CONVERTER$23,
7304
+ converter: BOOLEAN_CONVERTER$24,
6926
7305
  attribute: "close-on-interact-outside"
6927
7306
  },
6928
- size: { converter: STRING_CONVERTER$33 }
7307
+ size: { converter: STRING_CONVERTER$34 }
6929
7308
  };
6930
7309
  idGen = createCounterIdGenerator();
6931
7310
  popconfirmScope = createScope(null, this.idGen);
@@ -6938,18 +7317,25 @@ var XhPopconfirmElement = class extends XhElement {
6938
7317
  composed: true
6939
7318
  }));
6940
7319
  };
7320
+ /** 异步确认的挂起布尔;变化时重打属性。 */
7321
+ pendingState = false;
6941
7322
  intents = {
6942
7323
  onConfirm: () => {
6943
7324
  this.dispatchEvent(new CustomEvent("confirm", {
6944
7325
  bubbles: true,
6945
7326
  composed: true
6946
7327
  }));
7328
+ return this.confirmAction?.();
6947
7329
  },
6948
7330
  onCancel: () => {
6949
7331
  this.dispatchEvent(new CustomEvent("cancel", {
6950
7332
  bubbles: true,
6951
7333
  composed: true
6952
7334
  }));
7335
+ },
7336
+ onPendingChange: (next) => {
7337
+ this.pendingState = next;
7338
+ this.requestUpdate();
6953
7339
  }
6954
7340
  };
6955
7341
  ctrl = new MachineController(this, popoverMachine, () => this.machineProps(), {
@@ -7005,7 +7391,10 @@ var XhPopconfirmElement = class extends XhElement {
7005
7391
  super.connectedCallback();
7006
7392
  }
7007
7393
  wire() {
7008
- const api = connectPopconfirm(this.ctrl.service, this.intents, wcNormalize);
7394
+ const api = connectPopconfirm(this.ctrl.service, {
7395
+ ...this.intents,
7396
+ pending: this.pendingState
7397
+ }, wcNormalize);
7009
7398
  const put = (name, props) => {
7010
7399
  const el = this.getPart(name);
7011
7400
  if (el) this.spreader.spread(el, props);
@@ -7028,9 +7417,9 @@ var XhPopconfirmElement = class extends XhElement {
7028
7417
  };
7029
7418
  //#endregion
7030
7419
  //#region src/elements/popover.ts
7031
- const STRING_CONVERTER$32 = { fromAttribute: (v) => v ?? void 0 };
7420
+ const STRING_CONVERTER$33 = { fromAttribute: (v) => v ?? void 0 };
7032
7421
  const NUMBER_CONVERTER$18 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
7033
- const BOOLEAN_CONVERTER$22 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
7422
+ const BOOLEAN_CONVERTER$23 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
7034
7423
  /**
7035
7424
  * `<xh-popover>` —— Light-DOM 行为宿主:用户写 trigger/positioner/content/... 角色节点,
7036
7425
  * 元素跑 popover 机器并把 connect 产出打上去。浮层定位引擎在本元素里建好、经 refs 注入机器,
@@ -7060,23 +7449,23 @@ var XhPopoverElement = class extends XhElement {
7060
7449
  meta: popoverMeta
7061
7450
  };
7062
7451
  static properties = {
7063
- open: { converter: BOOLEAN_CONVERTER$22 },
7452
+ open: { converter: BOOLEAN_CONVERTER$23 },
7064
7453
  defaultOpen: {
7065
7454
  type: Boolean,
7066
7455
  attribute: "default-open"
7067
7456
  },
7068
- placement: { converter: STRING_CONVERTER$32 },
7457
+ placement: { converter: STRING_CONVERTER$33 },
7069
7458
  offset: { converter: NUMBER_CONVERTER$18 },
7070
- modal: { converter: BOOLEAN_CONVERTER$22 },
7459
+ modal: { converter: BOOLEAN_CONVERTER$23 },
7071
7460
  closeOnEscape: {
7072
- converter: BOOLEAN_CONVERTER$22,
7461
+ converter: BOOLEAN_CONVERTER$23,
7073
7462
  attribute: "close-on-escape"
7074
7463
  },
7075
7464
  closeOnInteractOutside: {
7076
- converter: BOOLEAN_CONVERTER$22,
7465
+ converter: BOOLEAN_CONVERTER$23,
7077
7466
  attribute: "close-on-interact-outside"
7078
7467
  },
7079
- size: { converter: STRING_CONVERTER$32 },
7468
+ size: { converter: STRING_CONVERTER$33 },
7080
7469
  translations: { attribute: false }
7081
7470
  };
7082
7471
  idGen = createCounterIdGenerator();
@@ -7168,9 +7557,9 @@ var XhPopoverElement = class extends XhElement {
7168
7557
  };
7169
7558
  //#endregion
7170
7559
  //#region src/elements/popselect.ts
7171
- const STRING_CONVERTER$31 = { fromAttribute: (v) => v ?? void 0 };
7560
+ const STRING_CONVERTER$32 = { fromAttribute: (v) => v ?? void 0 };
7172
7561
  const NUMBER_CONVERTER$17 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
7173
- const BOOLEAN_CONVERTER$21 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
7562
+ const BOOLEAN_CONVERTER$22 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
7174
7563
  /**
7175
7564
  * `<xh-popselect>` —— Light-DOM 行为宿主:作者写 root/trigger/positioner/content/item 角色节点,
7176
7565
  * 元素同时跑两台机器——浮层开合、定位、消解层与焦点域归 popover,选中集合与焦点锚点归 listbox——
@@ -7217,37 +7606,37 @@ var XhPopselectElement = class extends XhElement {
7217
7606
  };
7218
7607
  static properties = {
7219
7608
  collection: { attribute: false },
7220
- value: { converter: STRING_CONVERTER$31 },
7609
+ value: { converter: STRING_CONVERTER$32 },
7221
7610
  defaultValue: {
7222
- converter: STRING_CONVERTER$31,
7611
+ converter: STRING_CONVERTER$32,
7223
7612
  attribute: "default-value"
7224
7613
  },
7225
7614
  multiple: { type: Boolean },
7226
7615
  disabled: { type: Boolean },
7227
- loop: { converter: BOOLEAN_CONVERTER$21 },
7228
- typeahead: { converter: BOOLEAN_CONVERTER$21 },
7616
+ loop: { converter: BOOLEAN_CONVERTER$22 },
7617
+ typeahead: { converter: BOOLEAN_CONVERTER$22 },
7229
7618
  direction: {
7230
- converter: STRING_CONVERTER$31,
7619
+ converter: STRING_CONVERTER$32,
7231
7620
  attribute: "dir"
7232
7621
  },
7233
- open: { converter: BOOLEAN_CONVERTER$21 },
7622
+ open: { converter: BOOLEAN_CONVERTER$22 },
7234
7623
  defaultOpen: {
7235
7624
  type: Boolean,
7236
7625
  attribute: "default-open"
7237
7626
  },
7238
- placement: { converter: STRING_CONVERTER$31 },
7627
+ placement: { converter: STRING_CONVERTER$32 },
7239
7628
  offset: { converter: NUMBER_CONVERTER$17 },
7240
7629
  closeOnEscape: {
7241
- converter: BOOLEAN_CONVERTER$21,
7630
+ converter: BOOLEAN_CONVERTER$22,
7242
7631
  attribute: "close-on-escape"
7243
7632
  },
7244
7633
  closeOnInteractOutside: {
7245
- converter: BOOLEAN_CONVERTER$21,
7634
+ converter: BOOLEAN_CONVERTER$22,
7246
7635
  attribute: "close-on-interact-outside"
7247
7636
  },
7248
- variant: { converter: STRING_CONVERTER$31 },
7249
- tone: { converter: STRING_CONVERTER$31 },
7250
- size: { converter: STRING_CONVERTER$31 }
7637
+ variant: { converter: STRING_CONVERTER$32 },
7638
+ tone: { converter: STRING_CONVERTER$32 },
7639
+ size: { converter: STRING_CONVERTER$32 }
7251
7640
  };
7252
7641
  idGen = createCounterIdGenerator();
7253
7642
  popselectScope = createScope(null, this.idGen);
@@ -7325,6 +7714,7 @@ var XhPopselectElement = class extends XhElement {
7325
7714
  svc.refs.set("getAnchorEl", () => this.getPart("trigger"));
7326
7715
  svc.refs.set("getFloatingEl", () => this.getPart("positioner"));
7327
7716
  svc.refs.set("getContentEl", () => this.getPart("content"));
7717
+ svc.refs.set("getInitialFocusEl", () => popselectInitialFocus(this.listboxCtrl.service, this.getPart("content")));
7328
7718
  }
7329
7719
  /**
7330
7720
  * 角色节点提前发现一次:default-open 时 popover 机器在 hostConnected 当场进入 open,
@@ -7392,16 +7782,35 @@ var XhPopselectElement = class extends XhElement {
7392
7782
  //#endregion
7393
7783
  //#region src/elements/progress.ts
7394
7784
  /**
7395
- * `<xh-progress>` —— Light-DOM 行为宿主,无状态机,把 connectProgress 产出打到 root/track/range 角色节点。
7785
+ * `<xh-progress>` —— Light-DOM 行为宿主,无状态机,把 connectProgress 产出打到各角色节点。
7786
+ *
7787
+ * 线形写三层 div(root > track > range);环形要把 track 与 range 写成 `<circle>`、
7788
+ * 外面套一层 `<svg>` 当 canvas,环心的文字放进 label:
7789
+ *
7790
+ * ```html
7791
+ * <xh-progress variant="circle" value="60">
7792
+ * <div data-part="root">
7793
+ * <svg data-part="canvas"><circle data-part="track" /><circle data-part="range" /></svg>
7794
+ * <div data-part="label">60%</div>
7795
+ * </div>
7796
+ * </xh-progress>
7797
+ * ```
7396
7798
  *
7397
7799
  * @customElement xh-progress
7398
7800
  * @attr {number} value - 当前进度值,越界会被夹到 [0, max],默认 0
7399
7801
  * @attr {number} max - 满值上限,默认 100
7802
+ * @attr {'line'|'circle'|'dashboard'} variant - 形态,默认 line
7803
+ * @attr {number} stroke-width - 环的线宽(viewBox 单位),默认 6;只对 circle / dashboard 生效
7804
+ * @attr {number} gap-degree - 缺口角度,默认 75;只对 dashboard 生效
7805
+ * @attr {'top'|'right'|'bottom'|'left'} gap-position - 缺口朝向,默认 bottom;只对 dashboard 生效
7806
+ * @attr {string} value-text - 读屏播报的文字,覆盖默认的数值播报
7400
7807
  * @attr {'brand'|'neutral'|'success'|'warning'|'danger'|'info'} tone - 语气
7401
- * @attr {'sm'|'md'|'lg'} size - 尺寸
7808
+ * @attr {'sm'|'md'|'lg'} size - 尺寸:线形改厚度,环形改直径
7402
7809
  * @csspart root - role=progressbar 的容器(承载 aria-valuenow/aria-valuemax/data-state)
7403
- * @csspart track - 进度轨道(满长背景)
7404
- * @csspart range - 已完成区段,长度按百分比写成内联 inline-size
7810
+ * @csspart canvas - 承载环的 svg(线形不用)
7811
+ * @csspart track - 进度轨道:线形是满长背景,环形是整段弧
7812
+ * @csspart range - 已完成区段:线形写内联 inline-size,环形写 stroke-dashoffset
7813
+ * @csspart label - 环心那一块,写什么由使用者决定(线形不用)
7405
7814
  */
7406
7815
  var XhProgressElement = class extends XhElement {
7407
7816
  static partContract = {
@@ -7411,6 +7820,17 @@ var XhProgressElement = class extends XhElement {
7411
7820
  static properties = {
7412
7821
  value: { type: Number },
7413
7822
  max: { type: Number },
7823
+ variant: {},
7824
+ strokeWidth: {
7825
+ type: Number,
7826
+ attribute: "stroke-width"
7827
+ },
7828
+ gapDegree: {
7829
+ type: Number,
7830
+ attribute: "gap-degree"
7831
+ },
7832
+ gapPosition: { attribute: "gap-position" },
7833
+ valueText: { attribute: "value-text" },
7414
7834
  tone: {},
7415
7835
  size: {}
7416
7836
  };
@@ -7418,23 +7838,28 @@ var XhProgressElement = class extends XhElement {
7418
7838
  const api = connectProgress({
7419
7839
  value: this.value,
7420
7840
  max: this.max,
7841
+ variant: this.variant,
7842
+ strokeWidth: this.strokeWidth,
7843
+ gapDegree: this.gapDegree,
7844
+ gapPosition: this.gapPosition,
7845
+ valueText: this.valueText,
7421
7846
  tone: this.tone,
7422
7847
  size: this.size
7423
7848
  }, wcNormalize);
7424
- const root = this.getPart("root");
7425
- if (root) this.spreader.spread(root, api.getRootProps());
7426
- const track = this.getPart("track");
7427
- if (track) this.spreader.spread(track, api.getTrackProps());
7428
- const range = this.getPart("range");
7429
- if (!range) return;
7430
- const { style, ...attrs } = api.getRangeProps();
7431
- this.spreader.spread(range, attrs);
7432
- range.style.inlineSize = style?.inlineSize ?? "";
7849
+ const put = (name, props) => {
7850
+ const el = this.getPart(name);
7851
+ if (el) this.spreader.spread(el, props);
7852
+ };
7853
+ put("root", api.getRootProps());
7854
+ put("canvas", api.getCanvasProps());
7855
+ put("track", api.getTrackProps());
7856
+ put("range", api.getRangeProps());
7857
+ put("label", api.getLabelProps());
7433
7858
  }
7434
7859
  };
7435
7860
  //#endregion
7436
7861
  //#region src/elements/qr-code.ts
7437
- const STRING_CONVERTER$30 = { fromAttribute: (v) => v ?? void 0 };
7862
+ const STRING_CONVERTER$31 = { fromAttribute: (v) => v ?? void 0 };
7438
7863
  const SVG_NS = "http://www.w3.org/2000/svg";
7439
7864
  /** 本元素生成的几何节点的标记:作者写的节点不带它,重画时只清掉自己生成的那几个。 */
7440
7865
  const GEOM_ATTR = "data-xh-geom";
@@ -7461,7 +7886,7 @@ function makeGeom(doc, tag, name) {
7461
7886
  * @customElement xh-qr-code
7462
7887
  * @attr {string} value - 要编码的内容,按 UTF-8 取字节走字节模式
7463
7888
  * @attr {'L'|'M'|'Q'|'H'} level - 纠错级别,缺省 M
7464
- * @attr {number} size - 像素边长,缺省 160
7889
+ * @attr {number} pixel-size - 像素边长,缺省 160
7465
7890
  * @attr {number} margin - 静区宽度(模块数),缺省 4
7466
7891
  * @attr {string} label - 可及名字,缺省用 value
7467
7892
  * @attr {'square'|'dot'|'rounded'} module-shape - 码点形状,缺省 square
@@ -7479,17 +7904,20 @@ var XhQrCodeElement = class extends XhElement {
7479
7904
  }
7480
7905
  };
7481
7906
  static properties = {
7482
- value: { converter: STRING_CONVERTER$30 },
7483
- level: { converter: STRING_CONVERTER$30 },
7484
- label: { converter: STRING_CONVERTER$30 },
7485
- size: { type: Number },
7907
+ value: { converter: STRING_CONVERTER$31 },
7908
+ level: { converter: STRING_CONVERTER$31 },
7909
+ label: { converter: STRING_CONVERTER$31 },
7910
+ pixelSize: {
7911
+ type: Number,
7912
+ attribute: "pixel-size"
7913
+ },
7486
7914
  margin: { type: Number },
7487
7915
  moduleShape: {
7488
- converter: STRING_CONVERTER$30,
7916
+ converter: STRING_CONVERTER$31,
7489
7917
  attribute: "module-shape"
7490
7918
  },
7491
7919
  eyeShape: {
7492
- converter: STRING_CONVERTER$30,
7920
+ converter: STRING_CONVERTER$31,
7493
7921
  attribute: "eye-shape"
7494
7922
  }
7495
7923
  };
@@ -7502,7 +7930,7 @@ var XhQrCodeElement = class extends XhElement {
7502
7930
  const api = connectQrCode({
7503
7931
  value: this.value,
7504
7932
  level: this.level,
7505
- size: this.size,
7933
+ pixelSize: this.pixelSize,
7506
7934
  margin: this.margin,
7507
7935
  label: this.label,
7508
7936
  moduleShape: this.moduleShape,
@@ -7690,9 +8118,9 @@ var XhRadioGroupElement = class extends XhElement {
7690
8118
  };
7691
8119
  //#endregion
7692
8120
  //#region src/elements/rating.ts
7693
- const STRING_CONVERTER$29 = { fromAttribute: (v) => v ?? void 0 };
8121
+ const STRING_CONVERTER$30 = { fromAttribute: (v) => v ?? void 0 };
7694
8122
  const NUMBER_CONVERTER$16 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
7695
- const BOOLEAN_CONVERTER$20 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
8123
+ const BOOLEAN_CONVERTER$21 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
7696
8124
  /**
7697
8125
  * `<xh-rating>` —— Light-DOM 行为宿主:作者写 root/label/control 与若干 item 角色节点
7698
8126
  * (可选再写一个 hidden-input 参与表单提交),元素跑 rating 机器并把 connect 产出打上去。
@@ -7705,6 +8133,7 @@ const BOOLEAN_CONVERTER$20 = { fromAttribute: (v) => v === null ? void 0 : v !==
7705
8133
  * @attr {number} default-value - 非受控初值,缺省 0(还没评)
7706
8134
  * @attr {number} count - 星星颗数,默认 5
7707
8135
  * @attr {boolean} allow-half - 允许半颗星:档位从 1 变成 0.5
8136
+ * @attr {boolean} allow-clear - 再点当前档位清零,键盘最低档再往下也清;默认开,写 "false" 关
7708
8137
  * @attr {boolean} disabled - 整个不可交互:整条带子退出 Tab 序列,指针与键盘都不认
7709
8138
  * @attr {boolean} read-only - 只读:仍可聚焦与朗读,但改不动,也没有悬停预览
7710
8139
  * @attr {boolean} required - 必填标注;表单影子据此参与原生校验
@@ -7734,22 +8163,26 @@ var XhRatingElement = class extends XhElement {
7734
8163
  },
7735
8164
  count: { converter: NUMBER_CONVERTER$16 },
7736
8165
  allowHalf: {
7737
- converter: BOOLEAN_CONVERTER$20,
8166
+ converter: BOOLEAN_CONVERTER$21,
7738
8167
  attribute: "allow-half"
7739
8168
  },
7740
- disabled: { converter: BOOLEAN_CONVERTER$20 },
8169
+ allowClear: {
8170
+ converter: BOOLEAN_CONVERTER$21,
8171
+ attribute: "allow-clear"
8172
+ },
8173
+ disabled: { converter: BOOLEAN_CONVERTER$21 },
7741
8174
  readOnly: {
7742
- converter: BOOLEAN_CONVERTER$20,
8175
+ converter: BOOLEAN_CONVERTER$21,
7743
8176
  attribute: "read-only"
7744
8177
  },
7745
- required: { converter: BOOLEAN_CONVERTER$20 },
7746
- name: { converter: STRING_CONVERTER$29 },
8178
+ required: { converter: BOOLEAN_CONVERTER$21 },
8179
+ name: { converter: STRING_CONVERTER$30 },
7747
8180
  direction: {
7748
- converter: STRING_CONVERTER$29,
8181
+ converter: STRING_CONVERTER$30,
7749
8182
  attribute: "dir"
7750
8183
  },
7751
- tone: { converter: STRING_CONVERTER$29 },
7752
- size: { converter: STRING_CONVERTER$29 }
8184
+ tone: { converter: STRING_CONVERTER$30 },
8185
+ size: { converter: STRING_CONVERTER$30 }
7753
8186
  };
7754
8187
  notifyValue = (details) => {
7755
8188
  this.dispatchEvent(new CustomEvent("value-change", {
@@ -7772,6 +8205,7 @@ var XhRatingElement = class extends XhElement {
7772
8205
  defaultValue: this.defaultValue,
7773
8206
  count: this.count,
7774
8207
  allowHalf: this.allowHalf ?? false,
8208
+ allowClear: this.allowClear,
7775
8209
  disabled: this.disabled ?? false,
7776
8210
  readOnly: this.readOnly ?? false,
7777
8211
  required: this.required ?? false,
@@ -7814,7 +8248,7 @@ var XhRatingElement = class extends XhElement {
7814
8248
  };
7815
8249
  //#endregion
7816
8250
  //#region src/elements/result.ts
7817
- const STRING_CONVERTER$28 = { fromAttribute: (v) => v ?? void 0 };
8251
+ const STRING_CONVERTER$29 = { fromAttribute: (v) => v ?? void 0 };
7818
8252
  /**
7819
8253
  * `<xh-result>` —— 结果页行为宿主,无状态机,把 connectResult 产出的属性打到角色节点上。
7820
8254
  *
@@ -7838,8 +8272,8 @@ var XhResultElement = class extends XhElement {
7838
8272
  meta: resultMeta
7839
8273
  };
7840
8274
  static properties = {
7841
- status: { converter: STRING_CONVERTER$28 },
7842
- size: { converter: STRING_CONVERTER$28 }
8275
+ status: { converter: STRING_CONVERTER$29 },
8276
+ size: { converter: STRING_CONVERTER$29 }
7843
8277
  };
7844
8278
  wire() {
7845
8279
  const api = connectResult({
@@ -7859,7 +8293,7 @@ var XhResultElement = class extends XhElement {
7859
8293
  };
7860
8294
  //#endregion
7861
8295
  //#region src/elements/scroll-area.ts
7862
- const STRING_CONVERTER$27 = { fromAttribute: (v) => v ?? void 0 };
8296
+ const STRING_CONVERTER$28 = { fromAttribute: (v) => v ?? void 0 };
7863
8297
  const NUMBER_CONVERTER$15 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
7864
8298
  /**
7865
8299
  * `<xh-scroll-area>` —— Light-DOM 行为宿主:作者写 root/viewport/content/scrollbar/thumb/corner
@@ -7894,14 +8328,14 @@ var XhScrollAreaElement = class extends XhElement {
7894
8328
  meta: scrollAreaMeta
7895
8329
  };
7896
8330
  static properties = {
7897
- type: { converter: STRING_CONVERTER$27 },
8331
+ type: { converter: STRING_CONVERTER$28 },
7898
8332
  scrollHideDelay: {
7899
8333
  converter: NUMBER_CONVERTER$15,
7900
8334
  attribute: "scroll-hide-delay"
7901
8335
  },
7902
- orientation: { converter: STRING_CONVERTER$27 },
8336
+ orientation: { converter: STRING_CONVERTER$28 },
7903
8337
  direction: {
7904
- converter: STRING_CONVERTER$27,
8338
+ converter: STRING_CONVERTER$28,
7905
8339
  attribute: "dir"
7906
8340
  }
7907
8341
  };
@@ -7955,9 +8389,9 @@ var XhScrollAreaElement = class extends XhElement {
7955
8389
  };
7956
8390
  //#endregion
7957
8391
  //#region src/elements/select.ts
7958
- const STRING_CONVERTER$26 = { fromAttribute: (v) => v ?? void 0 };
8392
+ const STRING_CONVERTER$27 = { fromAttribute: (v) => v ?? void 0 };
7959
8393
  const NUMBER_CONVERTER$14 = { fromAttribute: (v) => v === null ? void 0 : Number(v) };
7960
- const BOOLEAN_CONVERTER$19 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
8394
+ const BOOLEAN_CONVERTER$20 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
7961
8395
  /**
7962
8396
  * `<xh-select>` —— Light-DOM 行为宿主:用户写 root/trigger/value-text/positioner/content/item/...
7963
8397
  * 角色节点,元素跑 select 机器并把 connect 产出打上去。浮层定位引擎在本元素里建好、经 refs 注入机器,
@@ -7973,6 +8407,8 @@ const BOOLEAN_CONVERTER$19 = { fromAttribute: (v) => v === null ? void 0 : v !==
7973
8407
  * @attr {boolean} open - 受控开合;缺省该属性即非受控
7974
8408
  * @attr {boolean} default-open - 非受控初始为展开
7975
8409
  * @attr {boolean} disabled - 整个控件禁用:trigger 用原生 disabled,表单影子不参与提交
8410
+ * @attr {boolean} invalid - 校验错误态:trigger 标红并输出 aria-invalid
8411
+ * @attr {number} max-tag-count - 多选标签最多摆几个,其余折进 api 的 overflowCount;缺省全摆
7976
8412
  * @attr {boolean} required - 原生表单校验:无选中值时提交被拦下;多选下的门槛是至少选中一项
7977
8413
  * @attr {string} name - 表单字段名;给定后表单影子才带 name 并参与提交
7978
8414
  * @attr {string} placeholder - 无选中时 value-text 显示的占位文字
@@ -7991,6 +8427,10 @@ const BOOLEAN_CONVERTER$19 = { fromAttribute: (v) => v === null ? void 0 : v !==
7991
8427
  * @csspart trigger - 触发按钮(aria-haspopup=listbox/aria-expanded/aria-controls 所在),同时是定位锚点,须是原生 button
7992
8428
  * @csspart value-text - 选中项文本的显示位;留空即由元素填入 displayText,作者写了内容则归作者
7993
8429
  * @csspart indicator - 展开指示符(aria-hidden,data-state 随开合)
8430
+ * @csspart control - 触发器与清空按钮的收纳容器兼定位基准;清空钮据此嵌进触发器右端、悬停时替换展开指示符
8431
+ * @csspart clear-trigger - 清空按钮:trigger 的兄弟节点(放进 control 即内嵌形态),没选中或禁用时带 hidden;可及名走 translations.clear
8432
+ * @csspart tag - 多选标签,须自带 value 属性标识选中值;放触发器里是纯展示,放外面配 tag-remove 可删
8433
+ * @csspart tag-remove - 标签删除按钮,须放在 tag 里;点按摘掉所在标签的选中值,可及名走 translations.removeTag
7994
8434
  * @csspart positioner - 浮层定位容器,坐标由引擎写成内联样式
7995
8435
  * @csspart content - role=listbox 容器(焦点域与消解层的根节点,键盘在此收口),收起时带 hidden
7996
8436
  * @csspart item - role=option 条目,须自带 value 属性标识身份;禁用写 aria-disabled="true"
@@ -8005,31 +8445,37 @@ var XhSelectElement = class extends XhElement {
8005
8445
  };
8006
8446
  static properties = {
8007
8447
  collection: { attribute: false },
8008
- value: { converter: STRING_CONVERTER$26 },
8448
+ value: { converter: STRING_CONVERTER$27 },
8009
8449
  defaultValue: {
8010
- converter: STRING_CONVERTER$26,
8450
+ converter: STRING_CONVERTER$27,
8011
8451
  attribute: "default-value"
8012
8452
  },
8013
- open: { converter: BOOLEAN_CONVERTER$19 },
8453
+ open: { converter: BOOLEAN_CONVERTER$20 },
8014
8454
  defaultOpen: {
8015
8455
  type: Boolean,
8016
8456
  attribute: "default-open"
8017
8457
  },
8018
8458
  disabled: { type: Boolean },
8459
+ invalid: { type: Boolean },
8019
8460
  required: { type: Boolean },
8020
- name: { converter: STRING_CONVERTER$26 },
8021
- placeholder: { converter: STRING_CONVERTER$26 },
8022
- placement: { converter: STRING_CONVERTER$26 },
8461
+ name: { converter: STRING_CONVERTER$27 },
8462
+ placeholder: { converter: STRING_CONVERTER$27 },
8463
+ placement: { converter: STRING_CONVERTER$27 },
8023
8464
  offset: { converter: NUMBER_CONVERTER$14 },
8024
- loop: { converter: BOOLEAN_CONVERTER$19 },
8465
+ loop: { converter: BOOLEAN_CONVERTER$20 },
8025
8466
  multiple: { type: Boolean },
8026
8467
  direction: {
8027
- converter: STRING_CONVERTER$26,
8468
+ converter: STRING_CONVERTER$27,
8028
8469
  attribute: "dir"
8029
8470
  },
8030
- variant: { converter: STRING_CONVERTER$26 },
8031
- tone: { converter: STRING_CONVERTER$26 },
8032
- size: { converter: STRING_CONVERTER$26 }
8471
+ variant: { converter: STRING_CONVERTER$27 },
8472
+ tone: { converter: STRING_CONVERTER$27 },
8473
+ size: { converter: STRING_CONVERTER$27 },
8474
+ translations: { attribute: false },
8475
+ maxTagCount: {
8476
+ converter: NUMBER_CONVERTER$14,
8477
+ attribute: "max-tag-count"
8478
+ }
8033
8479
  };
8034
8480
  idGen = createCounterIdGenerator();
8035
8481
  selectScope = createScope(null, this.idGen);
@@ -8067,6 +8513,7 @@ var XhSelectElement = class extends XhElement {
8067
8513
  open: this.open,
8068
8514
  defaultOpen: this.defaultOpen ?? false,
8069
8515
  disabled: this.disabled ?? false,
8516
+ invalid: this.invalid ?? false,
8070
8517
  required: this.required ?? false,
8071
8518
  name: this.name,
8072
8519
  placeholder: this.placeholder,
@@ -8078,6 +8525,8 @@ var XhSelectElement = class extends XhElement {
8078
8525
  variant: this.variant,
8079
8526
  tone: this.tone,
8080
8527
  size: this.size,
8528
+ translations: this.translations,
8529
+ maxTagCount: this.maxTagCount,
8081
8530
  onValueChange: this.notifyValue,
8082
8531
  onOpenChange: this.notifyOpen
8083
8532
  };
@@ -8177,8 +8626,15 @@ var XhSelectElement = class extends XhElement {
8177
8626
  };
8178
8627
  put("root", api.getRootProps());
8179
8628
  put("label", api.getLabelProps());
8629
+ put("control", api.getControlProps());
8180
8630
  put("trigger", api.getTriggerProps());
8181
8631
  put("indicator", api.getIndicatorProps());
8632
+ put("clear-trigger", api.getClearTriggerProps());
8633
+ for (const el of this.getParts("tag")) this.spreader.spread(el, api.getTagProps({ value: el.getAttribute("value") ?? "" }));
8634
+ for (const el of this.getParts("tag-remove")) {
8635
+ const owner = el.closest("[data-xh-part=\"tag\"]");
8636
+ this.spreader.spread(el, api.getTagRemoveProps({ value: owner?.getAttribute("value") ?? "" }));
8637
+ }
8182
8638
  put("positioner", api.getPositionerProps());
8183
8639
  put("content", api.getContentProps());
8184
8640
  const valueText = this.getPart("value-text");
@@ -8237,6 +8693,175 @@ var XhSeparatorElement = class extends XhElement {
8237
8693
  }
8238
8694
  };
8239
8695
  //#endregion
8696
+ //#region src/elements/side-nav.ts
8697
+ const STRING_CONVERTER$26 = { fromAttribute: (v) => v ?? void 0 };
8698
+ const BOOLEAN_CONVERTER$19 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
8699
+ /** 分支一系的归属容器;嵌套分支各认最近的那个。 */
8700
+ const BRANCH_SELECTOR$2 = "[data-xh-part=\"branch\"]";
8701
+ /** 分组一系的归属容器。 */
8702
+ const GROUP_SELECTOR = "[data-xh-part=\"group\"]";
8703
+ /**
8704
+ * `<xh-side-nav>` —— Light-DOM 行为宿主:管理后台侧栏导航。
8705
+ * 作者写 root/list 与若干 branch / link 角色节点,元素跑 side-nav 机器并把 connect 产出打上去。
8706
+ * 节点身份取自节点上的 value 属性;href 与禁用查 `collection` 这份树数据。
8707
+ *
8708
+ * @customElement xh-side-nav
8709
+ * @attr {string} value - 受控选中的叶子;缺省该属性即非受控
8710
+ * @attr {string} default-value - 非受控初始选中
8711
+ * @attr {boolean} accordion - 同层手风琴:展开一枝收起同层其余,默认 false
8712
+ * @attr {boolean} collapsed - 折叠成图标栏(内嵌展开整体收起、文字由皮肤藏掉;顶层分支换装浮层弹出)
8713
+ * @attr {boolean} collapsed-popout - 折叠态下顶层分支是否弹出子级面板,默认 true
8714
+ * @attr {boolean} disabled - 整个侧栏禁用
8715
+ * @attr {boolean} loop - 上下键走到首尾回绕,默认关
8716
+ * @attr {'ltr'|'rtl'} dir - 文字方向,只对调左右方向键的展开/收起语义,默认 ltr
8717
+ * @fires value-change - 选中变化;detail 为 `{ value: string | null }`
8718
+ * @fires expanded-change - 展开集合变化;detail 为 `{ value: string[] }`
8719
+ * @csspart root - nav 地标根容器(aria-label 由 translations.root 给)
8720
+ * @csspart list - 顶层列表容器
8721
+ * @csspart group - role=group 分组,须自带 value 属性
8722
+ * @csspart group-label - 分组标题(aria-labelledby 目标)
8723
+ * @csspart branch - 分支行容器,须自带 value 属性;它裹着自己的 branch-content
8724
+ * @csspart branch-trigger - 展开/收起按钮(aria-expanded / aria-controls)
8725
+ * @csspart branch-text - 行文字载体,折叠成图标栏时隐藏
8726
+ * @csspart branch-indicator - 展开方向指示符(aria-hidden)
8727
+ * @csspart branch-content - 内嵌子层容器,收起时隐藏
8728
+ * @csspart link - 去处链接,须自带 value 属性;选中输出 aria-current="page"
8729
+ * @csspart link-text - 链接文字载体,折叠成图标栏时隐藏
8730
+ */
8731
+ var XhSideNavElement = class extends XhElement {
8732
+ static partContract = {
8733
+ anatomy: sideNavAnatomy,
8734
+ meta: sideNavMeta
8735
+ };
8736
+ static properties = {
8737
+ value: { converter: STRING_CONVERTER$26 },
8738
+ defaultValue: {
8739
+ converter: STRING_CONVERTER$26,
8740
+ attribute: "default-value"
8741
+ },
8742
+ accordion: { converter: BOOLEAN_CONVERTER$19 },
8743
+ collapsed: { converter: BOOLEAN_CONVERTER$19 },
8744
+ collapsedPopout: {
8745
+ converter: BOOLEAN_CONVERTER$19,
8746
+ attribute: "collapsed-popout"
8747
+ },
8748
+ disabled: { converter: BOOLEAN_CONVERTER$19 },
8749
+ loop: { converter: BOOLEAN_CONVERTER$19 },
8750
+ direction: {
8751
+ converter: STRING_CONVERTER$26,
8752
+ attribute: "dir"
8753
+ },
8754
+ collection: { attribute: false },
8755
+ expandedValue: { attribute: false },
8756
+ defaultExpandedValue: { attribute: false },
8757
+ translations: { attribute: false }
8758
+ };
8759
+ notifyValue = (details) => {
8760
+ this.dispatchEvent(new CustomEvent("value-change", {
8761
+ detail: details,
8762
+ bubbles: true,
8763
+ composed: true
8764
+ }));
8765
+ };
8766
+ notifyExpanded = (details) => {
8767
+ this.dispatchEvent(new CustomEvent("expanded-change", {
8768
+ detail: details,
8769
+ bubbles: true,
8770
+ composed: true
8771
+ }));
8772
+ };
8773
+ idGen = createCounterIdGenerator();
8774
+ navScope = createScope(null, this.idGen);
8775
+ positionEngine = createPositionEngine();
8776
+ config = null;
8777
+ ctrl = new MachineController(this, sideNavMachine, () => this.machineProps(), {
8778
+ scope: this.navScope,
8779
+ onBuilt: (svc) => this.injectRefs(svc)
8780
+ });
8781
+ machineProps() {
8782
+ return {
8783
+ collection: this.collection,
8784
+ value: this.value,
8785
+ defaultValue: this.defaultValue,
8786
+ expandedValue: this.expandedValue,
8787
+ defaultExpandedValue: this.defaultExpandedValue,
8788
+ accordion: this.accordion,
8789
+ collapsed: this.collapsed,
8790
+ collapsedPopout: this.collapsedPopout,
8791
+ disabled: this.disabled,
8792
+ loop: this.loop,
8793
+ dir: this.direction,
8794
+ translations: this.translations,
8795
+ onValueChange: this.notifyValue,
8796
+ onExpandedChange: this.notifyExpanded
8797
+ };
8798
+ }
8799
+ ensureConfig() {
8800
+ if (this.config) return;
8801
+ this.config = createRuntimeConfig({
8802
+ scope: this.navScope,
8803
+ idGenerator: this.idGen
8804
+ });
8805
+ }
8806
+ /** 当前弹出分支名下的角色节点:按归属分支的 value 现查。 */
8807
+ findPopoutPart(svc, name) {
8808
+ const v = svc.context.get("popoutValue");
8809
+ if (v == null) return null;
8810
+ for (const el of this.getParts(name)) if (this.nodeOf(el, BRANCH_SELECTOR$2).value === v) return el;
8811
+ return null;
8812
+ }
8813
+ registerLayer = () => {
8814
+ this.ensureConfig();
8815
+ const svc = this.ctrl.service;
8816
+ return this.config.layerRegistry.register({
8817
+ kind: "popover",
8818
+ node: () => this.findPopoutPart(svc, "branch-content"),
8819
+ branches: () => [this.findPopoutPart(svc, "branch-trigger")].filter(Boolean),
8820
+ isModal: () => false,
8821
+ setModal: () => {},
8822
+ surfaces: () => []
8823
+ });
8824
+ };
8825
+ injectRefs(svc) {
8826
+ this.ensureConfig();
8827
+ svc.refs.set("config", this.config);
8828
+ svc.refs.set("registerLayer", this.registerLayer);
8829
+ svc.refs.set("position", this.positionEngine);
8830
+ svc.refs.set("getPopoutAnchorEl", () => this.findPopoutPart(svc, "branch-trigger"));
8831
+ svc.refs.set("getPopoutContentEl", () => this.findPopoutPart(svc, "branch-content"));
8832
+ }
8833
+ nodeOf(el, selector) {
8834
+ const owner = el.closest(selector);
8835
+ return { value: (owner && owner !== this && this.contains(owner) ? owner : el).getAttribute("value") ?? "" };
8836
+ }
8837
+ disconnectedCallback() {
8838
+ super.disconnectedCallback();
8839
+ this.config = null;
8840
+ }
8841
+ wire() {
8842
+ const api = connectSideNav(this.ctrl.service, wcNormalize);
8843
+ const put = (name, props) => {
8844
+ const el = this.getPart(name);
8845
+ if (el) this.spreader.spread(el, props);
8846
+ };
8847
+ put("root", api.getRootProps());
8848
+ put("list", api.getListProps());
8849
+ const putAll = (name, selector, get) => {
8850
+ for (const el of this.getParts(name)) this.spreader.spread(el, get(this.nodeOf(el, selector)));
8851
+ };
8852
+ putAll("group", GROUP_SELECTOR, (node) => api.getGroupProps(node));
8853
+ putAll("group-label", GROUP_SELECTOR, (node) => api.getGroupLabelProps(node));
8854
+ putAll("branch", BRANCH_SELECTOR$2, (node) => api.getBranchProps(node));
8855
+ putAll("branch-trigger", BRANCH_SELECTOR$2, (node) => api.getBranchTriggerProps(node));
8856
+ putAll("branch-indicator", BRANCH_SELECTOR$2, (node) => api.getBranchIndicatorProps(node));
8857
+ for (const el of this.getParts("branch-text")) this.spreader.spread(el, api.getBranchTextProps());
8858
+ for (const el of this.getParts("link-text")) this.spreader.spread(el, api.getLinkTextProps());
8859
+ putAll("branch-content", BRANCH_SELECTOR$2, (node) => api.getBranchContentProps(node));
8860
+ putAll("link", "[data-xh-part=\"link\"]", (node) => api.getLinkProps(node));
8861
+ for (const el of this.getParts("branch-content")) this.setPartHidden(el, el.hasAttribute("hidden"));
8862
+ }
8863
+ };
8864
+ //#endregion
8240
8865
  //#region src/elements/skeleton.ts
8241
8866
  const STRING_CONVERTER$25 = { fromAttribute: (v) => v ?? void 0 };
8242
8867
  const BOOLEAN_CONVERTER$18 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
@@ -8315,6 +8940,7 @@ const NUMBER_LIST_CONVERTER$1 = { fromAttribute: (v) => {
8315
8940
  * @attr {number} step - 方向键与吸附网格的步长,默认 1
8316
8941
  * @attr {number} large-step - PageUp/PageDown 的步长,默认 10 倍 step
8317
8942
  * @attr {number} min-steps-between-thumbs - 相邻滑块至少隔几格,默认 0
8943
+ * @attr {boolean} snap-to-marks - 只认刻度落点:拖动、点按与键盘都吸到最近/下一档刻度;刻度表经 marks property 赋
8318
8944
  * @attr {'horizontal'|'vertical'} orientation - 轨道朝向,默认 horizontal
8319
8945
  * @attr {'ltr'|'rtl'} dir - 文字方向,只改写水平轨道上左右两键与指针的语义,默认 ltr
8320
8946
  * @attr {boolean} disabled - 禁用:拇指退出 Tab 序列、推不动、不参与表单提交
@@ -8330,6 +8956,9 @@ const NUMBER_LIST_CONVERTER$1 = { fromAttribute: (v) => {
8330
8956
  * @csspart control - 指针命中区,按下即跳到落点并接管拖动
8331
8957
  * @csspart track - 轨道本体,值与坐标的换算以它的矩形为准
8332
8958
  * @csspart range - 已选区间,起止由内联逻辑属性给出
8959
+ * @csspart marks - 刻度容器
8960
+ * @csspart mark - 刻度点(纯装饰),须自带 value 属性;落进已选区间带 data-active
8961
+ * @csspart mark-label - 刻度文案,须自带 value 属性;点按把最近的滑块跳到这一档
8333
8962
  * @csspart thumb - role=slider 的拇指,键盘交互全在它身上;多滑块须写 index 属性
8334
8963
  * @csspart hidden-input - 拇指内的表单影子(须是原生 input)
8335
8964
  */
@@ -8355,6 +8984,11 @@ var XhSliderElement = class extends XhElement {
8355
8984
  converter: NUMBER_CONVERTER$13,
8356
8985
  attribute: "min-steps-between-thumbs"
8357
8986
  },
8987
+ snapToMarks: {
8988
+ converter: BOOLEAN_CONVERTER$17,
8989
+ attribute: "snap-to-marks"
8990
+ },
8991
+ marks: { attribute: false },
8358
8992
  orientation: { converter: STRING_CONVERTER$24 },
8359
8993
  direction: {
8360
8994
  converter: STRING_CONVERTER$24,
@@ -8400,6 +9034,8 @@ var XhSliderElement = class extends XhElement {
8400
9034
  step: this.step,
8401
9035
  largeStep: this.largeStep,
8402
9036
  minStepsBetweenThumbs: this.minStepsBetweenThumbs,
9037
+ marks: this.marks,
9038
+ snapToMarks: this.snapToMarks,
8403
9039
  orientation: this.orientation,
8404
9040
  dir: this.direction,
8405
9041
  disabled: this.disabled ?? false,
@@ -8438,6 +9074,9 @@ var XhSliderElement = class extends XhElement {
8438
9074
  put("control", api.getControlProps());
8439
9075
  put("track", api.getTrackProps());
8440
9076
  put("range", api.getRangeProps());
9077
+ put("marks", api.getMarksProps());
9078
+ for (const el of this.getParts("mark")) this.spreader.spread(el, api.getMarkProps({ value: Number(el.getAttribute("value")) }));
9079
+ for (const el of this.getParts("mark-label")) this.spreader.spread(el, api.getMarkLabelProps({ value: Number(el.getAttribute("value")) }));
8441
9080
  for (const el of this.getParts("thumb")) {
8442
9081
  const index = this.thumbIndex(el);
8443
9082
  this.spreader.spread(el, api.getThumbProps(index));
@@ -8491,7 +9130,7 @@ const STRING_CONVERTER$22 = { fromAttribute: (v) => v ?? void 0 };
8491
9130
  const NUMBER_CONVERTER$12 = { fromAttribute: (v) => v == null || v === "" ? void 0 : Number(v) };
8492
9131
  const BOOLEAN_CONVERTER$16 = { fromAttribute: (v) => v === null ? void 0 : v !== "false" };
8493
9132
  /**
8494
- * 布局是百分比数组,属性写成逗号分隔(两栏 size="30,70")。
9133
+ * 布局是百分比数组,属性写成逗号分隔(两栏 sizes="30,70")。
8495
9134
  * 解析不出任何有限数就当没写:留下 NaN 会一路写进 aria-valuenow 与定位百分比。
8496
9135
  */
8497
9136
  const NUMBER_LIST_CONVERTER = { fromAttribute: (v) => {
@@ -8529,16 +9168,16 @@ const PANELS_CONVERTER = { fromAttribute: (v) => {
8529
9168
  * 第 index 条分隔条坐在第 index 与第 index+1 块面板之间,调整的是前一块。
8530
9169
  *
8531
9170
  * @customElement xh-splitter
8532
- * @attr {string} size - 受控布局,逗号分隔的百分比(如 "30,70");缺省该属性即非受控
8533
- * @attr {string} default-size - 非受控初值,同样逗号分隔;缺省时按面板数等分
9171
+ * @attr {string} sizes - 受控布局,逗号分隔的百分比(如 "30,70");缺省该属性即非受控
9172
+ * @attr {string} default-sizes - 非受控初值,同样逗号分隔;缺省时按面板数等分
8534
9173
  * @attr {string} panels - 逐块约束的 JSON 数组:id / min / max / collapsible / collapsedSize
8535
9174
  * @attr {'horizontal'|'vertical'} orientation - 面板排布轴,默认 horizontal(并排)
8536
9175
  * @attr {'ltr'|'rtl'} dir - 文字方向,只对调水平排布下左右两键与指针位移的正负,默认 ltr
8537
9176
  * @attr {boolean} disabled - 禁用:分隔条退出 Tab 序列、拖不动也推不动
8538
9177
  * @attr {number} step - 方向键的步长(百分比),默认 1
8539
9178
  * @attr {number} large-step - Shift + 方向键的步长(百分比),默认 10
8540
- * @fires size-change - 布局变化(拖动途中会连发);detail 为 `{ size: number[] }`
8541
- * @fires size-change-end - 一次拖拽收尾发一次;detail 为 `{ size: number[], index: number }`
9179
+ * @fires sizes-change - 布局变化(拖动途中会连发);detail 为 `{ sizes: number[] }`
9180
+ * @fires sizes-change-end - 一次拖拽收尾发一次;detail 为 `{ sizes: number[], index: number }`
8542
9181
  * @csspart root - 承载 data-orientation / data-disabled / data-dragging 的容器,矩形以它为准
8543
9182
  * @csspart panel - 一块面板;尺寸由内联 flex-basis 给出,折叠时带 data-collapsed
8544
9183
  * @csspart resize-trigger - role=separator 的分隔条,指针与键盘交互全在它身上
@@ -8549,10 +9188,10 @@ var XhSplitterElement = class extends XhElement {
8549
9188
  meta: splitterMeta
8550
9189
  };
8551
9190
  static properties = {
8552
- size: { converter: NUMBER_LIST_CONVERTER },
8553
- defaultSize: {
9191
+ sizes: { converter: NUMBER_LIST_CONVERTER },
9192
+ defaultSizes: {
8554
9193
  converter: NUMBER_LIST_CONVERTER,
8555
- attribute: "default-size"
9194
+ attribute: "default-sizes"
8556
9195
  },
8557
9196
  panels: { converter: PANELS_CONVERTER },
8558
9197
  orientation: { converter: STRING_CONVERTER$22 },
@@ -8570,14 +9209,14 @@ var XhSplitterElement = class extends XhElement {
8570
9209
  idGen = createCounterIdGenerator();
8571
9210
  splitterScope = createScope(null, this.idGen);
8572
9211
  notifySize = (details) => {
8573
- this.dispatchEvent(new CustomEvent("size-change", {
9212
+ this.dispatchEvent(new CustomEvent("sizes-change", {
8574
9213
  detail: details,
8575
9214
  bubbles: true,
8576
9215
  composed: true
8577
9216
  }));
8578
9217
  };
8579
9218
  notifySizeEnd = (details) => {
8580
- this.dispatchEvent(new CustomEvent("size-change-end", {
9219
+ this.dispatchEvent(new CustomEvent("sizes-change-end", {
8581
9220
  detail: details,
8582
9221
  bubbles: true,
8583
9222
  composed: true
@@ -8589,16 +9228,16 @@ var XhSplitterElement = class extends XhElement {
8589
9228
  });
8590
9229
  machineProps() {
8591
9230
  return {
8592
- size: this.size,
8593
- defaultSize: this.defaultSize,
9231
+ sizes: this.sizes,
9232
+ defaultSizes: this.defaultSizes,
8594
9233
  panels: this.panels,
8595
9234
  orientation: this.orientation,
8596
9235
  dir: this.direction,
8597
9236
  disabled: this.disabled ?? false,
8598
9237
  step: this.step,
8599
9238
  largeStep: this.largeStep,
8600
- onSizeChange: this.notifySize,
8601
- onSizeChangeEnd: this.notifySizeEnd
9239
+ onSizesChange: this.notifySize,
9240
+ onSizesChangeEnd: this.notifySizeEnd
8602
9241
  };
8603
9242
  }
8604
9243
  injectRefs(svc) {
@@ -8812,11 +9451,14 @@ var XhStepsElement = class extends XhElement {
8812
9451
  * @attr {boolean} checked - 受控开合;缺省该属性即非受控
8813
9452
  * @attr {boolean} default-checked - 非受控初始为选中
8814
9453
  * @attr {boolean} disabled - 禁用
9454
+ * @attr {boolean} loading - 提交中:交互挂起、滑块转圈,仍可聚焦(aria-busy)
8815
9455
  * @attr {'brand'|'neutral'|'success'|'warning'|'danger'|'info'} tone - 语气
8816
9456
  * @attr {'sm'|'md'|'lg'} size - 尺寸
8817
9457
  * @fires checked-change - checked 状态变化;detail 为 `{ checked: boolean }`
8818
9458
  * @csspart root - role=switch 的按钮(承载 aria-checked / data-state)
8819
9459
  * @csspart thumb - 滑块
9460
+ * @attr {string} name - 表单字段名;给了 hidden-input 才参与提交
9461
+ * @csspart hidden-input - type=hidden 的表单出口,省略该节点即不参与表单
8820
9462
  */
8821
9463
  var XhSwitchElement = class extends XhElement {
8822
9464
  static partContract = {
@@ -8830,6 +9472,9 @@ var XhSwitchElement = class extends XhElement {
8830
9472
  attribute: "default-checked"
8831
9473
  },
8832
9474
  disabled: { type: Boolean },
9475
+ loading: { type: Boolean },
9476
+ name: { converter: { fromAttribute: (v) => v ?? void 0 } },
9477
+ value: { converter: { fromAttribute: (v) => v ?? void 0 } },
8833
9478
  tone: {},
8834
9479
  size: {}
8835
9480
  };
@@ -8846,8 +9491,11 @@ var XhSwitchElement = class extends XhElement {
8846
9491
  checked: this.checked,
8847
9492
  defaultChecked: this.defaultChecked ?? false,
8848
9493
  disabled: this.disabled ?? false,
9494
+ loading: this.loading ?? false,
8849
9495
  tone: this.tone,
8850
9496
  size: this.size,
9497
+ name: this.name,
9498
+ value: this.value,
8851
9499
  onCheckedChange: this.notify
8852
9500
  };
8853
9501
  }
@@ -8857,6 +9505,8 @@ var XhSwitchElement = class extends XhElement {
8857
9505
  if (root) this.spreader.spread(root, api.getRootProps());
8858
9506
  const thumb = this.getPart("thumb");
8859
9507
  if (thumb) this.spreader.spread(thumb, api.getThumbProps());
9508
+ const hidden = this.getPart("hidden-input");
9509
+ if (hidden) this.spreader.spread(hidden, api.getHiddenInputProps());
8860
9510
  }
8861
9511
  };
8862
9512
  //#endregion
@@ -8907,7 +9557,7 @@ const FOOTER_SELECTOR = "[data-xh-part=\"footer\"]";
8907
9557
  * @csspart sort-trigger - 排序把手,自占一个 Tab 位;按住 Shift 点是追加到排序链
8908
9558
  * @csspart expand-trigger - 展开把手(aria-hidden 且不占 Tab 位,键盘那一路由左右方向键承担)
8909
9559
  * @csspart expanded-row - role=row 详情行,须自带 value 属性与它所属的数据行配对,内部须放一个 cell 承载详情;收起时 hidden
8910
- * @csspart empty-state - 空态节点,表体为空且不在加载时显形
9560
+ * @csspart empty - 空态节点,表体为空且不在加载时显形
8911
9561
  * @csspart loading-state - 加载态节点,表体为空且正在加载时显形
8912
9562
  */
8913
9563
  var XhTableElement = class extends XhElement {
@@ -9028,9 +9678,9 @@ var XhTableElement = class extends XhElement {
9028
9678
  put("header", api.getHeaderProps());
9029
9679
  put("body", api.getBodyProps());
9030
9680
  put("footer", api.getFooterProps());
9031
- const emptyProps = api.getEmptyStateProps();
9681
+ const emptyProps = api.getEmptyProps();
9032
9682
  const loadingProps = api.getLoadingStateProps();
9033
- put("empty-state", emptyProps);
9683
+ put("empty", emptyProps);
9034
9684
  put("loading-state", loadingProps);
9035
9685
  const putAll = (name, get) => {
9036
9686
  for (const el of this.getParts(name)) this.spreader.spread(el, get(el));
@@ -9059,7 +9709,7 @@ var XhTableElement = class extends XhElement {
9059
9709
  putAll("expanded-row", (el) => api.getExpandedRowProps({ value: el.getAttribute("value") ?? "" }));
9060
9710
  for (const el of this.getParts("row")) if (el.hasAttribute("disabled")) el.removeAttribute("disabled");
9061
9711
  for (const el of this.getParts("expanded-row")) this.setPartHidden(el, !api.isExpanded(el.getAttribute("value") ?? ""));
9062
- this.setPartHidden(this.getPart("empty-state"), !!emptyProps.hidden);
9712
+ this.setPartHidden(this.getPart("empty"), !!emptyProps.hidden);
9063
9713
  this.setPartHidden(this.getPart("loading-state"), !!loadingProps.hidden);
9064
9714
  }
9065
9715
  };
@@ -9374,6 +10024,7 @@ const BOOLEAN_CONVERTER$11 = { fromAttribute: (v) => v === null ? void 0 : v !==
9374
10024
  * @attr {string} name - 表单字段名;给了才参与提交
9375
10025
  * @attr {number} max-length - 字符数上限;同时落成原生 maxlength 与机器侧截断
9376
10026
  * @attr {boolean} clearable - 开启清空:清空按钮显出并在有值时可用,Escape 接管
10027
+ * @attr {boolean} auto-size - 多行宿主(input 部件写成 textarea)的自动高度;行数界限对象经 autoSize property 赋
9377
10028
  * @attr {'outline'|'subtle'|'ghost'} variant - 视觉变体
9378
10029
  * @attr {'brand'|'neutral'|'success'|'warning'|'danger'|'info'} tone - 语气
9379
10030
  * @attr {'sm'|'md'|'lg'} size - 尺寸
@@ -9408,6 +10059,10 @@ var XhTextFieldElement = class extends XhElement {
9408
10059
  attribute: "max-length"
9409
10060
  },
9410
10061
  clearable: { converter: BOOLEAN_CONVERTER$11 },
10062
+ autoSize: {
10063
+ converter: BOOLEAN_CONVERTER$11,
10064
+ attribute: "auto-size"
10065
+ },
9411
10066
  variant: { converter: STRING_CONVERTER$16 },
9412
10067
  tone: { converter: STRING_CONVERTER$16 },
9413
10068
  size: { converter: STRING_CONVERTER$16 }
@@ -9432,6 +10087,7 @@ var XhTextFieldElement = class extends XhElement {
9432
10087
  name: this.name,
9433
10088
  maxLength: this.maxLength,
9434
10089
  clearable: this.clearable ?? false,
10090
+ autoSize: this.autoSize,
9435
10091
  variant: this.variant,
9436
10092
  tone: this.tone,
9437
10093
  size: this.size,
@@ -9446,7 +10102,10 @@ var XhTextFieldElement = class extends XhElement {
9446
10102
  };
9447
10103
  put("root", api.getRootProps());
9448
10104
  put("label", api.getLabelProps());
9449
- put("input", api.getInputProps());
10105
+ const inputEl = this.getPart("input");
10106
+ const host = inputEl?.tagName === "TEXTAREA" ? "textarea" : "input";
10107
+ put("input", api.getInputProps({ as: host }));
10108
+ if (host === "textarea" && inputEl) autoSizeTextarea(inputEl, api.autoSize);
9450
10109
  put("clear-trigger", api.getClearTriggerProps());
9451
10110
  this.setPartHidden(this.getPart("clear-trigger"), !api.clearable);
9452
10111
  }
@@ -9768,7 +10427,7 @@ function declaredUnit(el, position) {
9768
10427
  }
9769
10428
  /**
9770
10429
  * `<xh-time-picker>` —— Light-DOM 行为宿主:作者写 root/label/control/input(多个)/trigger/
9771
- * clear-trigger/positioner/content/column(多个)/option(多个)/hidden-input 角色节点,
10430
+ * clear-trigger/positioner/content/column(多个)/item(多个)/hidden-input 角色节点,
9772
10431
  * 元素跑 time-picker 机器并把 connect 产出打上去。浮层定位引擎在本元素里建好、经 refs 注入机器,
9773
10432
  * 锚点取 control(浮层因此与整个输入行对齐),被定位的浮层取 positioner。
9774
10433
  *
@@ -9806,7 +10465,7 @@ function declaredUnit(el, position) {
9806
10465
  * @csspart positioner - 浮层定位容器,坐标由引擎写成内联样式
9807
10466
  * @csspart content - 浮层容器(消解层与焦点域的根节点),收起时带 hidden
9808
10467
  * @csspart column - role=listbox 的一列,可自带 unit 属性声明单位,缺省按文档序
9809
- * @csspart option - role=option 的一格,须自带 value 属性(两位补零的显示串)
10468
+ * @csspart item - role=option 的一格,须自带 value 属性(两位补零的显示串)
9810
10469
  * @csspart hidden-input - type=hidden 的表单出口,值是完整 ISO 串
9811
10470
  */
9812
10471
  var XhTimePickerElement = class extends XhElement {
@@ -9958,13 +10617,13 @@ var XhTimePickerElement = class extends XhElement {
9958
10617
  const unit = declaredUnit(columnEl, position);
9959
10618
  this.spreader.spread(columnEl, api.getColumnProps({ unit }));
9960
10619
  this.setPartHidden(columnEl, !api.columns.some((column) => column.unit === unit));
9961
- for (const optionEl of this.getParts("option").filter((el) => columnEl.contains(el))) {
9962
- const value = optionEl.getAttribute("value") ?? "";
9963
- this.spreader.spread(optionEl, api.getOptionProps({
10620
+ for (const itemEl of this.getParts("item").filter((el) => columnEl.contains(el))) {
10621
+ const value = itemEl.getAttribute("value") ?? "";
10622
+ this.spreader.spread(itemEl, api.getItemProps({
9964
10623
  unit,
9965
10624
  value
9966
10625
  }));
9967
- this.fillText(optionEl, value);
10626
+ this.fillText(itemEl, value);
9968
10627
  }
9969
10628
  });
9970
10629
  this.setPartHidden(this.getPart("content"), !api.open);
@@ -10734,6 +11393,7 @@ const BOOLEAN_CONVERTER$4 = { fromAttribute: (v) => v === null ? void 0 : v !==
10734
11393
  * @attr {boolean} close-on-interact-outside - 层外交互关闭,默认 false;写 "true" 打开
10735
11394
  * @attr {boolean} show-backdrop - 画遮罩,默认 true;写 show-backdrop="false" 关掉
10736
11395
  * @attr {number} spotlight-padding - 高亮框在目标四周留出的空白(px),默认 8
11396
+ * @attr {boolean} auto-scroll - 展开与换步时自动把目标滚进视口(nearest),默认 true;写 auto-scroll="false" 关掉
10737
11397
  * @fires open-change - open 状态变化;detail 为 `{ open: boolean }`
10738
11398
  * @fires step-change - 步序变化;detail 为 `{ step: number }`
10739
11399
  * @fires complete - 末步再按下一步;detail 为 `{ step: number }`
@@ -10786,6 +11446,10 @@ var XhTourElement = class extends XhElement {
10786
11446
  converter: NUMBER_CONVERTER$3,
10787
11447
  attribute: "spotlight-padding"
10788
11448
  },
11449
+ autoScroll: {
11450
+ converter: BOOLEAN_CONVERTER$4,
11451
+ attribute: "auto-scroll"
11452
+ },
10789
11453
  steps: { attribute: false },
10790
11454
  translations: { attribute: false }
10791
11455
  };
@@ -10825,6 +11489,7 @@ var XhTourElement = class extends XhElement {
10825
11489
  closeOnInteractOutside: this.closeOnInteractOutside,
10826
11490
  showBackdrop: this.showBackdrop,
10827
11491
  spotlightPadding: this.spotlightPadding,
11492
+ autoScroll: this.autoScroll,
10828
11493
  translations: this.translations,
10829
11494
  onOpenChange: this.notifyOpen,
10830
11495
  onStepChange: this.notifyStep,
@@ -10887,6 +11552,10 @@ var XhTourElement = class extends XhElement {
10887
11552
  wire() {
10888
11553
  this.wireWith(this.ctrl.service);
10889
11554
  }
11555
+ /** 重量高亮框与浮层位置:目标节点被外部改动(换位、变尺寸)后调它校准。 */
11556
+ remeasure() {
11557
+ this.ctrl?.service.send({ type: "GEOMETRY.SYNC" });
11558
+ }
10890
11559
  wireWith(svc) {
10891
11560
  const api = connectTour(svc, wcNormalize);
10892
11561
  this.contentNode = this.getPart("content");
@@ -10935,7 +11604,7 @@ const SIDES = ["source", "target"];
10935
11604
  /**
10936
11605
  * 读条目节点上作者写的原生 disabled,顺手摘掉。
10937
11606
  *
10938
- * 集合条目的禁用一律由 aria-disabled 表达(禁用声明的事实源是 items,不是标记):
11607
+ * 集合条目的禁用一律由 aria-disabled 表达(禁用声明的事实源是 collection,不是标记):
10939
11608
  * 原生禁用的节点不可聚焦、也收不到 click,「禁用项仍是方向键起点、仍挡得住点击」
10940
11609
  * 这两条在原生 disabled 下根本无从成立。摘掉之后禁用态由 connect 写回的 aria-disabled 承接。
10941
11610
  */
@@ -10947,7 +11616,7 @@ function stripNativeDisabled(el) {
10947
11616
  * root/source-panel/target-panel/panel-header/panel-title/panel-count/search/list/item/...
10948
11617
  * 角色节点,元素跑 transfer 机器并把 connect 产出打上去。
10949
11618
  *
10950
- * 条目全集由 `items` 属性(property)给出,它是标签与禁用的唯一事实源;
11619
+ * 条目全集由 `collection` 属性(property)给出,它是标签与禁用的唯一事实源;
10951
11620
  * **两侧面板各挂一份全集**,不属于本侧、或被搜索筛掉的那一份由元素打上 hidden,
10952
11621
  * 节点不卸载。条目身份取节点上的 `value` 属性,归哪一侧则取它落在哪个面板里。
10953
11622
  *
@@ -10956,8 +11625,8 @@ function stripNativeDisabled(el) {
10956
11625
  * 导航与勾选在事件那一刻按 data-scope+data-part 查活 DOM,依赖 connect 回写的 data-value,
10957
11626
  * 因此 wire 必须先于交互跑过(基类 updated 已保证)。
10958
11627
  *
10959
- * 集合类输入(items / value / selected / filter)都表达不成属性,只能走 property:
10960
- * `el.items = [...]`、`el.value = ['a']`。
11628
+ * 集合类输入(collection / value / selected / filter)都表达不成属性,只能走 property:
11629
+ * `el.collection = [...]`、`el.value = ['a']`。
10961
11630
  *
10962
11631
  * @customElement xh-transfer
10963
11632
  * @attr {boolean} searchable - 每侧带一个搜索框;关掉时搜索框仍在 DOM 里但带 hidden
@@ -10966,7 +11635,7 @@ function stripNativeDisabled(el) {
10966
11635
  * @attr {boolean} loop - 列表内方向键走到尽头回绕,默认 true;写 loop="false" 关掉
10967
11636
  * @attr {'ltr'|'rtl'} dir - 文字方向,决定列表内哪个横向方向键是"搬向对面",默认 ltr
10968
11637
  * @fires value-change - 落在右侧的值变化;detail 为 `{ value: string[] }`
10969
- * @fires selected-change - 勾选集合变化;detail 为 `{ selected: string[] }`
11638
+ * @fires selection-change - 勾选集合变化;detail 为 `{ selected: string[] }`
10970
11639
  * @csspart root - 组件根容器(承载 data-disabled/data-one-way)
10971
11640
  * @csspart source-panel - 左侧面板容器,其内的角色节点一律归左侧
10972
11641
  * @csspart target-panel - 右侧面板容器,其内的角色节点一律归右侧
@@ -10975,7 +11644,7 @@ function stripNativeDisabled(el) {
10975
11644
  * @csspart panel-count - 计数节点,只带 data-count / data-checked-count,文案由作者写
10976
11645
  * @csspart search - 本侧搜索框,须是原生 input;searchable 关掉时带 hidden
10977
11646
  * @csspart list - role=listbox 容器,键盘在此收口,也是 roving tabindex 的兜底位
10978
- * @csspart item - role=option 条目,须自带 value 属性标识身份;禁用写在 items 里,不写在节点上
11647
+ * @csspart item - role=option 条目,须自带 value 属性标识身份;禁用写在 collection 里,不写在节点上
10979
11648
  * @csspart item-text - 条目文本
10980
11649
  * @csspart item-checkbox - 条目勾选标记(aria-hidden);oneWay 下右侧的那一份带 hidden
10981
11650
  * @csspart select-all-trigger - 本侧全选格,须是原生 button;三态经 aria-checked 上报
@@ -10988,7 +11657,7 @@ var XhTransferElement = class extends XhElement {
10988
11657
  meta: transferMeta
10989
11658
  };
10990
11659
  static properties = {
10991
- items: { attribute: false },
11660
+ collection: { attribute: false },
10992
11661
  value: { attribute: false },
10993
11662
  defaultValue: { attribute: false },
10994
11663
  selected: { attribute: false },
@@ -11014,7 +11683,7 @@ var XhTransferElement = class extends XhElement {
11014
11683
  }));
11015
11684
  };
11016
11685
  notifySelected = (details) => {
11017
- this.dispatchEvent(new CustomEvent("selected-change", {
11686
+ this.dispatchEvent(new CustomEvent("selection-change", {
11018
11687
  detail: details,
11019
11688
  bubbles: true,
11020
11689
  composed: true
@@ -11023,7 +11692,7 @@ var XhTransferElement = class extends XhElement {
11023
11692
  ctrl = new MachineController(this, transferMachine, () => this.machineProps());
11024
11693
  machineProps() {
11025
11694
  return {
11026
- items: this.items,
11695
+ collection: this.collection,
11027
11696
  value: this.value,
11028
11697
  defaultValue: this.defaultValue,
11029
11698
  selected: this.selected,
@@ -11035,7 +11704,7 @@ var XhTransferElement = class extends XhElement {
11035
11704
  loop: this.loop,
11036
11705
  dir: this.direction,
11037
11706
  onValueChange: this.notifyValue,
11038
- onSelectedChange: this.notifySelected
11707
+ onSelectionChange: this.notifySelected
11039
11708
  };
11040
11709
  }
11041
11710
  /**
@@ -11120,6 +11789,8 @@ const BRANCH_SELECTOR$1 = "[data-xh-part=\"branch\"]";
11120
11789
  *
11121
11790
  * @customElement xh-tree
11122
11791
  * @attr {'single'|'multiple'} selection-mode - 选择模式,默认 single
11792
+ * @attr {boolean} cascade - multiple 下父子级联勾选(整枝传导/半选/禁用冻结),默认 false
11793
+ * @attr {string} checked-strategy - 级联下对外值的收敛策略:child(默认)/ parent / all
11123
11794
  * @attr {boolean} expand-on-click - 点分支行顺带展开/收起,默认开;写 expand-on-click="false" 关掉
11124
11795
  * @attr {boolean} disabled - 整棵树禁用:所有节点转 aria-disabled,键盘与点击都改不了展开与选中
11125
11796
  * @attr {boolean} loop - 上下键走到首尾回绕,默认关;写 loop="true" 打开
@@ -11155,6 +11826,11 @@ var XhTreeElement = class extends XhElement {
11155
11826
  converter: STRING_CONVERTER$3,
11156
11827
  attribute: "selection-mode"
11157
11828
  },
11829
+ cascade: { type: Boolean },
11830
+ checkedStrategy: {
11831
+ converter: STRING_CONVERTER$3,
11832
+ attribute: "checked-strategy"
11833
+ },
11158
11834
  expandOnClick: {
11159
11835
  converter: BOOLEAN_CONVERTER$2,
11160
11836
  attribute: "expand-on-click"
@@ -11190,6 +11866,8 @@ var XhTreeElement = class extends XhElement {
11190
11866
  selectedValue: this.selectedValue,
11191
11867
  defaultSelectedValue: this.defaultSelectedValue,
11192
11868
  selectionMode: this.selectionMode,
11869
+ cascade: this.cascade,
11870
+ checkedStrategy: this.checkedStrategy,
11193
11871
  expandOnClick: this.expandOnClick,
11194
11872
  disabled: this.disabled ?? false,
11195
11873
  loop: this.loop,
@@ -11274,6 +11952,8 @@ const BRANCH_SELECTOR = "[data-xh-part=\"branch\"]";
11274
11952
  * @attr {boolean} open - 受控开合;缺省该属性即非受控
11275
11953
  * @attr {boolean} default-open - 非受控初始为展开
11276
11954
  * @attr {boolean} multiple - 多选:选中后浮层不收起,焦点留在树里
11955
+ * @attr {boolean} cascade - 多选下父子级联勾选(整枝传导/半选/禁用冻结),默认 false
11956
+ * @attr {string} checked-strategy - 级联下对外值的收敛策略:child(默认)/ parent / all
11277
11957
  * @attr {boolean} disabled - 整个控件禁用:trigger 用原生 disabled,表单出口不参与提交
11278
11958
  * @attr {boolean} read-only - 只读:浮层照常展开、树照常浏览,但选中值改不动、也清不掉
11279
11959
  * @attr {boolean} invalid - 校验失败标注
@@ -11296,8 +11976,8 @@ const BRANCH_SELECTOR = "[data-xh-part=\"branch\"]";
11296
11976
  * @csspart indicator - 展开指示符(aria-hidden,data-state 随开合)
11297
11977
  * @csspart clear-trigger - 清空按钮,须是原生 button;不占 Tab 位且对读屏隐藏
11298
11978
  * @csspart positioner - 浮层定位容器,坐标由引擎写成内联样式
11299
- * @csspart content - 浮层壳(焦点域与消解层的根节点),收起时带 hidden
11300
- * @csspart tree - role=tree 容器,键盘在此收口,也是没有锚点时的 Tab 兜底位
11979
+ * @csspart content - 浮层壳(焦点域与消解层的根节点,键盘在此收口),收起时带 hidden
11980
+ * @csspart tree - role=tree 容器,没有锚点时的 Tab 兜底位与落焦点
11301
11981
  * @csspart item - role=treeitem 叶子,须自带 value 属性标识身份
11302
11982
  * @csspart item-text - 叶子文本
11303
11983
  * @csspart item-indicator - 叶子选中标记(aria-hidden)
@@ -11329,6 +12009,11 @@ var XhTreeSelectElement = class extends XhElement {
11329
12009
  attribute: "default-open"
11330
12010
  },
11331
12011
  multiple: { type: Boolean },
12012
+ cascade: { type: Boolean },
12013
+ checkedStrategy: {
12014
+ converter: STRING_CONVERTER$2,
12015
+ attribute: "checked-strategy"
12016
+ },
11332
12017
  disabled: { type: Boolean },
11333
12018
  readOnly: {
11334
12019
  converter: BOOLEAN_CONVERTER$1,
@@ -11339,6 +12024,7 @@ var XhTreeSelectElement = class extends XhElement {
11339
12024
  tone: { converter: STRING_CONVERTER$2 },
11340
12025
  size: { converter: STRING_CONVERTER$2 },
11341
12026
  placeholder: { converter: STRING_CONVERTER$2 },
12027
+ translations: { attribute: false },
11342
12028
  placement: { converter: STRING_CONVERTER$2 },
11343
12029
  offset: { converter: NUMBER_CONVERTER$2 },
11344
12030
  loop: { converter: BOOLEAN_CONVERTER$1 },
@@ -11389,6 +12075,8 @@ var XhTreeSelectElement = class extends XhElement {
11389
12075
  open: this.open,
11390
12076
  defaultOpen: this.defaultOpen ?? false,
11391
12077
  multiple: this.multiple ?? false,
12078
+ cascade: this.cascade,
12079
+ checkedStrategy: this.checkedStrategy,
11392
12080
  disabled: this.disabled ?? false,
11393
12081
  readOnly: this.readOnly ?? false,
11394
12082
  invalid: this.invalid ?? false,
@@ -11396,6 +12084,7 @@ var XhTreeSelectElement = class extends XhElement {
11396
12084
  tone: this.tone,
11397
12085
  size: this.size,
11398
12086
  placeholder: this.placeholder,
12087
+ translations: this.translations,
11399
12088
  placement: this.placement,
11400
12089
  offset: this.offset,
11401
12090
  loop: this.loop,
@@ -11831,6 +12520,7 @@ function defineXhElements() {
11831
12520
  defineElement("xh-hover-card", XhHoverCardElement, version);
11832
12521
  defineElement("xh-icon", XhIconElement, version);
11833
12522
  defineElement("xh-image", XhImageElement, version);
12523
+ defineElement("xh-image-viewer", XhImageViewerElement, version);
11834
12524
  defineElement("xh-listbox", XhListboxElement, version);
11835
12525
  defineElement("xh-loading-bar", XhLoadingBarElement, version);
11836
12526
  defineElement("xh-menu", XhMenuElement, version);
@@ -11846,6 +12536,7 @@ function defineXhElements() {
11846
12536
  defineElement("xh-scroll-area", XhScrollAreaElement, version);
11847
12537
  defineElement("xh-select", XhSelectElement, version);
11848
12538
  defineElement("xh-separator", XhSeparatorElement, version);
12539
+ defineElement("xh-side-nav", XhSideNavElement, version);
11849
12540
  defineElement("xh-slider", XhSliderElement, version);
11850
12541
  defineElement("xh-splitter", XhSplitterElement, version);
11851
12542
  defineElement("xh-statistic", XhStatisticElement, version);
@@ -11875,6 +12566,6 @@ function defineXhElements() {
11875
12566
  defineElement("xh-watermark", XhWatermarkElement, version);
11876
12567
  }
11877
12568
  //#endregion
11878
- export { XhAccordionElement, XhAlertElement, XhAnchorElement, XhAvatarElement, XhBadgeElement, XhBreadcrumbElement, XhButtonElement, XhCalendarElement, XhCarouselElement, XhCascaderElement, XhCheckboxElement, XhCheckboxGroupElement, XhClipboardElement, XhCodeBlockElement, XhCollapsibleElement, XhColorPickerElement, XhComboboxElement, XhComposerElement, XhContextMenuElement, XhDateFieldElement, XhDatePickerElement, XhDialogElement, XhDrawerElement, XhEditableElement, XhEmptyStateElement, XhFieldElement, XhFileUploadElement, XhFormElement, XhHoverCardElement, XhIconElement, XhImageElement, XhListboxElement, XhLoadingBarElement, XhMenuElement, XhMenubarElement, XhNavigationMenuElement, XhNumberFieldElement, XhPaginationElement, XhPinInputElement, XhPopoverElement, XhProgressElement, XhRadioGroupElement, XhRatingElement, XhScrollAreaElement, XhSelectElement, XhSeparatorElement, XhSkeletonElement, XhSliderElement, XhSpinnerElement, XhSplitterElement, XhStepsElement, XhSwitchElement, XhTableElement, XhTabsElement, XhTagsInputElement, XhTextFieldElement, XhThreadElement, XhTimeFieldElement, XhTimePickerElement, XhToastElement, XhToasterElement, XhToggleElement, XhToggleGroupElement, XhToolbarElement, XhTooltipElement, XhTourElement, XhTransferElement, XhTreeElement, XhTreeSelectElement, XhVirtualizerElement, defineXhElements };
12569
+ export { XhAccordionElement, XhAlertElement, XhAnchorElement, XhAvatarElement, XhBadgeElement, XhBreadcrumbElement, XhButtonElement, XhCalendarElement, XhCarouselElement, XhCascaderElement, XhCheckboxElement, XhCheckboxGroupElement, XhClipboardElement, XhCodeBlockElement, XhCollapsibleElement, XhColorPickerElement, XhComboboxElement, XhComposerElement, XhContextMenuElement, XhDateFieldElement, XhDatePickerElement, XhDialogElement, XhDrawerElement, XhEditableElement, XhEmptyStateElement, XhFieldElement, XhFileUploadElement, XhFormElement, XhHoverCardElement, XhIconElement, XhImageElement, XhImageViewerElement, XhListboxElement, XhLoadingBarElement, XhMenuElement, XhMenubarElement, XhNavigationMenuElement, XhNumberFieldElement, XhPaginationElement, XhPinInputElement, XhPopoverElement, XhProgressElement, XhRadioGroupElement, XhRatingElement, XhScrollAreaElement, XhSelectElement, XhSeparatorElement, XhSideNavElement, XhSkeletonElement, XhSliderElement, XhSpinnerElement, XhSplitterElement, XhStepsElement, XhSwitchElement, XhTableElement, XhTabsElement, XhTagsInputElement, XhTextFieldElement, XhThreadElement, XhTimeFieldElement, XhTimePickerElement, XhToastElement, XhToasterElement, XhToggleElement, XhToggleGroupElement, XhToolbarElement, XhTooltipElement, XhTourElement, XhTransferElement, XhTreeElement, XhTreeSelectElement, XhVirtualizerElement, defineXhElements };
11879
12570
 
11880
12571
  //# sourceMappingURL=define.js.map