@evotecit/canopyx 0.3.16 → 0.3.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/CanopyX.Html/Assets/canopyx-board.css +50 -0
  2. package/CanopyX.Html/Assets/canopyx-board.js +39 -0
  3. package/CanopyX.Html/Assets/canopyx-buckets.js +15 -0
  4. package/CanopyX.Html/Assets/canopyx-calculations.css +7 -0
  5. package/CanopyX.Html/Assets/canopyx-calculations.js +52 -0
  6. package/CanopyX.Html/Assets/canopyx-calendar-edit.js +3 -3
  7. package/CanopyX.Html/Assets/canopyx-calendar.css +74 -80
  8. package/CanopyX.Html/Assets/canopyx-calendar.js +26 -31
  9. package/CanopyX.Html/Assets/canopyx-cell-range.css +4 -4
  10. package/CanopyX.Html/Assets/canopyx-cell-range.js +16 -14
  11. package/CanopyX.Html/Assets/canopyx-changes.css +61 -79
  12. package/CanopyX.Html/Assets/canopyx-changes.js +18 -15
  13. package/CanopyX.Html/Assets/canopyx-column-groups.css +5 -1
  14. package/CanopyX.Html/Assets/canopyx-column-groups.js +15 -9
  15. package/CanopyX.Html/Assets/canopyx-compare.css +37 -0
  16. package/CanopyX.Html/Assets/canopyx-compare.js +12 -0
  17. package/CanopyX.Html/Assets/canopyx-data.js +3 -3
  18. package/CanopyX.Html/Assets/canopyx-detail-rows.css +4 -4
  19. package/CanopyX.Html/Assets/canopyx-detail-rows.js +1 -1
  20. package/CanopyX.Html/Assets/canopyx-editing.css +5 -5
  21. package/CanopyX.Html/Assets/canopyx-editing.js +2 -2
  22. package/CanopyX.Html/Assets/canopyx-enhance.js +5 -5
  23. package/CanopyX.Html/Assets/canopyx-export.js +54 -13
  24. package/CanopyX.Html/Assets/canopyx-facets.css +32 -22
  25. package/CanopyX.Html/Assets/canopyx-facets.js +19 -15
  26. package/CanopyX.Html/Assets/canopyx-filter-editor.css +75 -89
  27. package/CanopyX.Html/Assets/canopyx-filter-editor.js +20 -16
  28. package/CanopyX.Html/Assets/canopyx-flow-checks.css +3 -3
  29. package/CanopyX.Html/Assets/canopyx-flow-checks.js +1 -1
  30. package/CanopyX.Html/Assets/canopyx-flow-command.css +3 -3
  31. package/CanopyX.Html/Assets/canopyx-flow-command.js +1 -1
  32. package/CanopyX.Html/Assets/canopyx-flow-dialog.css +4 -4
  33. package/CanopyX.Html/Assets/canopyx-flow-dialog.js +1 -1
  34. package/CanopyX.Html/Assets/canopyx-flow-drafts.css +2 -2
  35. package/CanopyX.Html/Assets/canopyx-flow-drafts.js +1 -1
  36. package/CanopyX.Html/Assets/canopyx-flow-entry.css +142 -17
  37. package/CanopyX.Html/Assets/canopyx-flow-entry.js +5 -5
  38. package/CanopyX.Html/Assets/canopyx-flow-host.css +2 -2
  39. package/CanopyX.Html/Assets/canopyx-flow-host.js +1 -1
  40. package/CanopyX.Html/Assets/canopyx-flow-module.mjs +5 -5
  41. package/CanopyX.Html/Assets/canopyx-flow-pick.css +4 -4
  42. package/CanopyX.Html/Assets/canopyx-flow-pick.js +1 -1
  43. package/CanopyX.Html/Assets/canopyx-flow-preview.css +1 -1
  44. package/CanopyX.Html/Assets/canopyx-flow-preview.js +1 -1
  45. package/CanopyX.Html/Assets/canopyx-flow-records.css +2 -2
  46. package/CanopyX.Html/Assets/canopyx-flow-records.js +1 -1
  47. package/CanopyX.Html/Assets/canopyx-flow-tasks.css +4 -4
  48. package/CanopyX.Html/Assets/canopyx-flow-tasks.js +1 -1
  49. package/CanopyX.Html/Assets/canopyx-flow.css +41 -41
  50. package/CanopyX.Html/Assets/canopyx-flow.js +1 -1
  51. package/CanopyX.Html/Assets/canopyx-format-editor.css +9 -9
  52. package/CanopyX.Html/Assets/canopyx-format-editor.js +2 -2
  53. package/CanopyX.Html/Assets/canopyx-formatting.css +13 -13
  54. package/CanopyX.Html/Assets/canopyx-formatting.js +12 -11
  55. package/CanopyX.Html/Assets/canopyx-forms.css +3 -3
  56. package/CanopyX.Html/Assets/canopyx-forms.js +1 -1
  57. package/CanopyX.Html/Assets/canopyx-grid-module.mjs +220 -155
  58. package/CanopyX.Html/Assets/canopyx-grid-options.css +8 -8
  59. package/CanopyX.Html/Assets/canopyx-grid-options.js +9 -2
  60. package/CanopyX.Html/Assets/canopyx-grid.css +285 -150
  61. package/CanopyX.Html/Assets/canopyx-grid.js +220 -155
  62. package/CanopyX.Html/Assets/canopyx-grouping.css +23 -16
  63. package/CanopyX.Html/Assets/canopyx-grouping.js +24 -17
  64. package/CanopyX.Html/Assets/canopyx-highlight.css +10 -10
  65. package/CanopyX.Html/Assets/canopyx-highlight.js +1 -1
  66. package/CanopyX.Html/Assets/canopyx-interactive.css +215 -91
  67. package/CanopyX.Html/Assets/canopyx-interactive.js +47 -52
  68. package/CanopyX.Html/Assets/canopyx-labels-de.js +177 -9
  69. package/CanopyX.Html/Assets/canopyx-labels-es.js +177 -9
  70. package/CanopyX.Html/Assets/canopyx-labels-fr.js +176 -8
  71. package/CanopyX.Html/Assets/canopyx-labels-it.js +176 -8
  72. package/CanopyX.Html/Assets/canopyx-labels-pl.js +176 -8
  73. package/CanopyX.Html/Assets/canopyx-layouts.css +49 -21
  74. package/CanopyX.Html/Assets/canopyx-layouts.js +36 -14
  75. package/CanopyX.Html/Assets/canopyx-link.css +3 -3
  76. package/CanopyX.Html/Assets/canopyx-link.js +4 -4
  77. package/CanopyX.Html/Assets/canopyx-links.js +2 -2
  78. package/CanopyX.Html/Assets/canopyx-live.css +3 -5
  79. package/CanopyX.Html/Assets/canopyx-live.js +3 -3
  80. package/CanopyX.Html/Assets/canopyx-matrix.css +32 -39
  81. package/CanopyX.Html/Assets/canopyx-matrix.js +11 -11
  82. package/CanopyX.Html/Assets/canopyx-module.mjs +47 -52
  83. package/CanopyX.Html/Assets/canopyx-office-export.js +2936 -0
  84. package/CanopyX.Html/Assets/canopyx-pager.css +1 -1
  85. package/CanopyX.Html/Assets/canopyx-pager.js +1 -1
  86. package/CanopyX.Html/Assets/canopyx-path.css +45 -0
  87. package/CanopyX.Html/Assets/canopyx-path.js +28 -0
  88. package/CanopyX.Html/Assets/canopyx-pivot.css +75 -0
  89. package/CanopyX.Html/Assets/canopyx-pivot.js +72 -0
  90. package/CanopyX.Html/Assets/canopyx-plan.css +63 -0
  91. package/CanopyX.Html/Assets/canopyx-plan.js +71 -0
  92. package/CanopyX.Html/Assets/canopyx-presenters.js +2 -2
  93. package/CanopyX.Html/Assets/canopyx-record-panel.css +51 -45
  94. package/CanopyX.Html/Assets/canopyx-record-panel.js +30 -22
  95. package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +262 -197
  96. package/CanopyX.Html/Assets/canopyx-reporting.css +300 -164
  97. package/CanopyX.Html/Assets/canopyx-reporting.js +262 -197
  98. package/CanopyX.Html/Assets/canopyx-stack.css +35 -0
  99. package/CanopyX.Html/Assets/canopyx-stack.js +24 -0
  100. package/CanopyX.Html/Assets/canopyx-time-slider.css +18 -0
  101. package/CanopyX.Html/Assets/canopyx-time-slider.js +27 -0
  102. package/CanopyX.Html/Assets/canopyx-timeline.css +19 -19
  103. package/CanopyX.Html/Assets/canopyx-timeline.js +6 -5
  104. package/CanopyX.Html/Assets/canopyx-tree-tools.css +47 -46
  105. package/CanopyX.Html/Assets/canopyx-tree-tools.js +15 -12
  106. package/CanopyX.Html/Assets/canopyx-ui-menu.css +41 -0
  107. package/CanopyX.Html/Assets/canopyx-ui-menu.js +64 -0
  108. package/CanopyX.Html/Assets/canopyx-ui-navigation.css +73 -0
  109. package/CanopyX.Html/Assets/canopyx-ui-navigation.js +39 -0
  110. package/CanopyX.Html/Assets/canopyx-ui-overlays.css +79 -0
  111. package/CanopyX.Html/Assets/canopyx-ui-overlays.js +45 -0
  112. package/CanopyX.Html/Assets/canopyx-ui-picker.css +12 -0
  113. package/CanopyX.Html/Assets/canopyx-ui-picker.js +6 -0
  114. package/CanopyX.Html/Assets/canopyx-ui-stepper.css +174 -0
  115. package/CanopyX.Html/Assets/canopyx-ui-stepper.js +48 -0
  116. package/CanopyX.Html/Assets/canopyx-ui-tabs.css +153 -0
  117. package/CanopyX.Html/Assets/canopyx-ui-tabs.js +47 -0
  118. package/CanopyX.Html/Assets/canopyx-values.css +5 -0
  119. package/CanopyX.Html/Assets/canopyx-values.js +13 -0
  120. package/CanopyX.Html/Assets/canopyx-view-intents.css +12 -0
  121. package/CanopyX.Html/Assets/canopyx-view-intents.js +56 -0
  122. package/CanopyX.Html/Assets/canopyx.css +212 -85
  123. package/CanopyX.Html/Assets/canopyx.js +38 -26
  124. package/JavaScript/board.d.ts +30 -0
  125. package/JavaScript/changes.d.ts +4 -1
  126. package/JavaScript/column-groups.d.ts +24 -4
  127. package/JavaScript/facets.d.ts +5 -3
  128. package/JavaScript/grid.d.ts +161 -17
  129. package/JavaScript/hosts.d.ts +16 -1
  130. package/JavaScript/index.d.ts +4 -2
  131. package/JavaScript/locales/de.mjs +177 -9
  132. package/JavaScript/locales/es.mjs +177 -9
  133. package/JavaScript/locales/fr.mjs +176 -8
  134. package/JavaScript/locales/it.mjs +176 -8
  135. package/JavaScript/locales/pl.mjs +176 -8
  136. package/JavaScript/matrix.d.ts +4 -1
  137. package/JavaScript/path.d.ts +33 -0
  138. package/JavaScript/pivot.d.ts +135 -0
  139. package/JavaScript/plan.d.ts +23 -0
  140. package/JavaScript/protocol.d.ts +18 -3
  141. package/JavaScript/records.d.ts +4 -0
  142. package/JavaScript/stack.d.ts +28 -0
  143. package/JavaScript/time-slider.d.ts +58 -0
  144. package/JavaScript/ui.d.ts +261 -0
  145. package/JavaScript/view-intents.d.ts +45 -0
  146. package/README.md +76 -187
  147. package/README.nuget.md +63 -87
  148. package/ThirdParty/OfficeIMO/LICENSE +21 -0
  149. package/ThirdParty/OfficeIMO/README.md +13 -0
  150. package/package.json +76 -3
@@ -0,0 +1,45 @@
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"8dc12c5deb018c2c",install(context){if(installed.has(context.UI_IMPL))return;const{UI_IMPL,UI_TOOLS,h,setText,fill,watchTheme,overlayTheme,hostHtml}=context;const UI_LABELS={tabsMore:"More",tabsMoreSelected:"More: {label}",tabsScrollPrevious:"Previous tabs",tabsScrollNext:"Next tabs",tabsSection:"Section",tabsPosition:"{current} of {total}",tabsPause:"Pause",tabsPlay:"Play",tabsMotionDisabled:"Automatic tabs are disabled by reduced motion",stepperStepOf:"Step {current} of {total}",stepperBack:"Back",stepperNext:"Next",stepperFinish:"Finish",stepperSkip:"Skip",stepperSaveDraft:"Save draft",stepperAllSteps:"All steps",stepperOptional:"Optional",stepperCompleted:"Completed",stepperSkipped:"Skipped",stepperIssues:"{count} issues to fix",stepperIssue:"1 issue to fix",dialogClose:"Close",drawerClose:"Close",drawerPrevious:"Previous record",drawerNext:"Next record",stateLoading:"Loading…",stateRetry:"Retry",stateDetails:"Details"};const uiFocusSelector='button:not([disabled]),a[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';Object.assign(UI_TOOLS,{labels:values=>Object.assign({},UI_LABELS,values),content:(element,value)=>{if(value?.nodeType)element.replaceChildren(value);else hostHtml(element,value,null,"detail")},emit:(root,prefix,name,detail,cancelable=false)=>root.dispatchEvent(new CustomEvent("cx-"+prefix+":"+name,{detail,bubbles:true,cancelable})),focusables:root=>[...root.querySelectorAll(uiFocusSelector)].filter(element=>element.checkVisibility()&&!element.closest("[inert]")),observe(root,changed,signal){let width=-1,frame=0;const read=()=>{const next=root.getBoundingClientRect().width;if(next!==width){width=next;changed(width)}};const observer=new ResizeObserver(()=>{frame||=requestAnimationFrame(()=>{frame=0;read()})});observer.observe(root);read();const dispose=()=>{observer.disconnect();cancelAnimationFrame(frame)};signal?.addEventListener("abort",dispose,{once:true});return dispose},theme(host,element){const previous=new Map([...element.style].map(name=>[name,element.style.getPropertyValue(name)]));overlayTheme(host,element);for(const[name,value]of previous)if(name.startsWith("--hfx-")||name.startsWith("--cx-"))element.style.setProperty(name,value);const written=new Map([...element.style].map(name=>[name,element.style.getPropertyValue(name)]));return()=>{for(const[name,value]of written)if(element.style.getPropertyValue(name)===value){if(previous.has(name))element.style.setProperty(name,previous.get(name));else element.style.removeProperty(name)}}},position(element,anchor,placement="bottom-start",point){const viewport=global.visualViewport,width=viewport?.width||document.documentElement.clientWidth,height=viewport?.height||global.innerHeight;const offsetX=viewport?.offsetLeft||0,offsetY=viewport?.offsetTop||0;const style=getComputedStyle(element),gap=parseFloat(style.marginTop)||0,marginX=parseFloat(style.marginLeft)||0;const edge=Math.max(8,gap);const box=element.getBoundingClientRect(),target=point?{left:point.x,right:point.x,top:point.y,bottom:point.y}:anchor.getBoundingClientRect();const rtl=getComputedStyle(anchor).direction==="rtl",side=placement.split("-")[0],align=placement.split("-")[1]||"center";let x=(target.left+target.right-box.width)/ 2, y = target.bottom + gap, actual = side;
2
+ if(side==="top")y=target.top-box.height-gap;if(side==="left"||side==="right"){x=side==="left"?target.left-box.width-gap:target.right+gap;y=target.top}
3
+ else if(align!=="center")x=(align==="start")!==rtl?target.left:target.right-box.width;if(side==="top"&&y<offsetY){y=target.bottom+gap;actual="bottom"}
4
+ else if(side==="bottom"&&y+box.height>height+offsetY){y=target.top-box.height-gap;actual="top"}
5
+ else if(side==="right"&&x+box.width>width+offsetX){x=target.left-box.width-gap;actual="left"}
6
+ else if(side==="left"&&x<offsetX){x=target.right+gap;actual="right"}
7
+ x=Math.max(offsetX+edge,Math.min(x,offsetX+width-box.width-edge));y=Math.max(offsetY+edge,Math.min(y,offsetY+height-box.height-edge));const ratio=global.devicePixelRatio||1,snap=value=>Math.round(value*ratio)/ ratio;
8
+ element.style.left=snap(x)- marginX+"px";element.style.top=snap(y)- gap+"px";element.dataset.side=actual}});const uiOverlayStack=[];let uiModalLocks=0,uiScrollBefore="";function uiLockScroll(lock){if(lock){if(uiModalLocks++===0){uiScrollBefore=document.documentElement.style.overflow;document.documentElement.style.overflow="hidden"}}
9
+ else if(uiModalLocks&&--uiModalLocks===0&&document.documentElement.style.overflow==="hidden")document.documentElement.style.overflow=uiScrollBefore}
10
+ function uiTopOverlay(){return uiOverlayStack.at(-1)}
11
+ function uiOverlayKey(event){if(event.defaultPrevented)return;const top=uiTopOverlay();if(!top)return;if(event.key==="Escape"){event.preventDefault();event.stopImmediatePropagation();top.close("cancel")}
12
+ else if(event.key==="Tab"&&top.modal){const list=UI_TOOLS.focusables(top.element),first=list[0],last=list.at(-1);if(!list.length){event.preventDefault();top.element.focus()}
13
+ else if(event.shiftKey&&(document.activeElement===first||document.activeElement===top.element)){event.preventDefault();last.focus()}
14
+ else if(!event.shiftKey&&document.activeElement===last){event.preventDefault();first.focus()}}}
15
+ function uiOverlayPointer(event){const top=uiTopOverlay();if(!top)return;const box=top.element.getBoundingClientRect(),backdrop=event.target===top.element&&(event.clientX<box.left||event.clientX>box.right||event.clientY<box.top||event.clientY>box.bottom);if(!backdrop&&top.element.contains(event.target)||top.trigger?.contains(event.target))return;if(top.dismissible)top.close("outside",false)}
16
+ function uiStackPush(entry){if(!uiOverlayStack.length){document.addEventListener("keydown",uiOverlayKey);document.addEventListener("pointerdown",uiOverlayPointer,true)}
17
+ uiOverlayStack.push(entry)}
18
+ function uiStackRemove(entry){const at=uiOverlayStack.indexOf(entry);if(at>=0)uiOverlayStack.splice(at,1);if(!uiOverlayStack.length){document.removeEventListener("keydown",uiOverlayKey);document.removeEventListener("pointerdown",uiOverlayPointer,true)}}
19
+ UI_TOOLS.owns=(container,node)=>{if(container.contains(node))return true;for(const entry of uiOverlayStack){if(!entry.element.contains(node))continue;for(let owner=entry;owner;owner=owner.parent)
20
+ if(container.contains(owner.element)||owner.trigger&&container.contains(owner.trigger))return true}
21
+ return false};UI_TOOLS.overlay=(element,options={},signal)=>{const kind=options.kind||"popover",originalParent=element.parentNode,nextSibling=element.nextSibling;const triggerOf=()=>options.trigger||document.getElementById(element.dataset.cxTrigger||"");const decorateTrigger=()=>options.decorateTrigger!==false&&kind!=="tooltip"&&
22
+ !["row","gridcell","rowheader","treeitem"].includes(triggerOf()?.getAttribute("role"));let opened=false,modal=false,returnFocus=null,restoreTheme=null,inerted=[],reposition=null,generation=0;const nativeCloses=[];const styleBefore={left:element.style.left,top:element.style.top},hadTabindex=element.getAttribute("tabindex");const ariaModalBefore=element.getAttribute("aria-modal");const entry={element,get trigger(){return triggerOf()},get modal(){return modal},get dismissible(){return options.dismissible!==false},close};function closeNative(silent=false){nativeCloses.push({generation,silent});element.close()}
23
+ function close(reason="close",restoreFocus=options.focus!==false,force=false){if(!opened)return true;if(!force&&!UI_TOOLS.emit(element,kind,reason==="cancel"?"cancel":"beforeclose",{reason},true))return false;for(const child of uiOverlayStack.slice().reverse()){for(let parent=child.parent;parent;parent=parent.parent)if(parent===entry){child.close("parent",false,true);break}}
24
+ entry.parent=null;opened=false;uiStackRemove(entry);if(element.localName==="dialog"){if(element.open)closeNative();else if(reason!=="native")nativeCloses.push({generation,silent:false})}else if(element.matches(":popover-open"))element.hidePopover();element.hidden=true;element.dataset.state="closed";if(ariaModalBefore===null)element.removeAttribute("aria-modal");else element.setAttribute("aria-modal",ariaModalBefore);if(modal)uiLockScroll(false);for(const[node,value]of inerted)node.inert=value;inerted=[];modal=false;restoreTheme?.();restoreTheme=null;element.style.left=styleBefore.left;element.style.top=styleBefore.top;if(originalParent&&element.parentNode!==originalParent)originalParent.insertBefore(element,nextSibling?.parentNode===originalParent?nextSibling:null);if(entry.trigger&&decorateTrigger())entry.trigger.setAttribute("aria-expanded","false");reposition?.();reposition=null;if(restoreFocus){const target=returnFocus?.isConnected?returnFocus:triggerOf();target?.focus({preventScroll:true})}
25
+ UI_TOOLS.emit(element,kind,"close",{reason});return true}
26
+ function open(settings={}){if(signal?.aborted)return false;if(opened)close("reopen",false,true);generation++;const trigger=triggerOf(),host=options.host||trigger||originalParent||element;entry.parent=uiOverlayStack.slice().reverse().find(owner=>owner.element.contains(element)||
27
+ trigger&&owner.element.contains(trigger))||null;returnFocus=trigger||document.activeElement;modal=settings.modal??options.modal??false;restoreTheme=UI_TOOLS.theme(host,element);const parentDialog=trigger?.closest("dialog[open]");const portal=options.portal||parentDialog||trigger?.closest('main,[role="main"]')||document.body;if(element.localName!=="dialog"&&element.parentNode!==portal){const dir=element.getAttribute("dir"),value=element.style.getPropertyValue("direction"),priority=element.style.getPropertyPriority("direction");const direction=getComputedStyle(element).direction,undoTheme=restoreTheme;element.setAttribute("dir",direction);element.style.setProperty("direction",direction,priority);restoreTheme=()=>{const current=element.style.getPropertyValue("direction"),currentPriority=element.style.getPropertyPriority("direction");undoTheme();if(element.getAttribute("dir")===direction){if(dir===null)element.removeAttribute("dir");else element.setAttribute("dir",dir)}
28
+ if(current===direction&&currentPriority===priority){if(value)element.style.setProperty("direction",value,priority);else element.style.removeProperty("direction")}else if(current)element.style.setProperty("direction",current,currentPriority);else element.style.removeProperty("direction")};portal.appendChild(element)}
29
+ element.hidden=false;element.dataset.state="open";if(element.localName==="dialog"&&typeof element.showModal==="function"){if(modal)element.showModal();else element.show()}else if(typeof element.showPopover==="function"){element.setAttribute("popover","manual");element.showPopover()}else if(modal){for(const child of document.body.children)if(!child.contains(element)){inerted.push([child,child.inert]);child.inert=true}}
30
+ opened=true;if(modal)uiLockScroll(true);uiStackPush(entry);if(modal)element.setAttribute("aria-modal","true");else element.removeAttribute("aria-modal");if(trigger&&decorateTrigger())trigger.setAttribute("aria-expanded","true");if(options.anchored&&trigger){const placement=options.placement||element.dataset.placement;const position=()=>UI_TOOLS.position(element,trigger,placement,settings.point);position();global.addEventListener("resize",position);document.addEventListener("scroll",position,true);reposition=()=>{global.removeEventListener("resize",position);document.removeEventListener("scroll",position,true)}}
31
+ if(options.focus!==false){const target=typeof options.initialFocus==="function"?options.initialFocus(element):options.initialFocus;if(!element.hasAttribute("tabindex"))element.tabIndex=-1;(target||UI_TOOLS.focusables(element)[0]||element).focus({preventScroll:true})}
32
+ UI_TOOLS.emit(element,kind,"open",{});return true}
33
+ const cancel=event=>{event.preventDefault();if(uiTopOverlay()===entry)close("cancel")};element.addEventListener("cancel",cancel,{signal});const nativeClose=event=>{if(event.target!==element)return;const pending=nativeCloses.shift();if(pending?.silent||(pending&&pending.generation!==generation)||element.open){event.stopImmediatePropagation();return}
34
+ if(opened)close("native",options.focus!==false,true)};element.addEventListener("close",nativeClose,true);function setModal(value){if(!opened||modal===value)return;const active=document.activeElement;if(element.localName==="dialog"&&element.open){closeNative(true);if(value)element.showModal();else element.show()}
35
+ uiLockScroll(value);modal=value;if(value)element.setAttribute("aria-modal","true");else element.removeAttribute("aria-modal");if(active&&element.contains(active))active.focus({preventScroll:true})}
36
+ const destroy=()=>{close("destroy",false,true);element.removeEventListener("cancel",cancel);element.removeEventListener("close",nativeClose,true);if(hadTabindex===null)element.removeAttribute("tabindex");else element.setAttribute("tabindex",hadTabindex)};signal?.addEventListener("abort",destroy,{once:true});return{element,open,close,destroy,setModal,get opened(){return opened},get modal(){return modal}}};function uiDialog(root,options,signal,drawer){const labels=UI_TOOLS.labels(options.labels),trigger=options.trigger||document.getElementById(root.dataset.cxTrigger||"");const container=options.container||root.parentElement||document.body,alert=root.getAttribute("role")==="alertdialog";let phone=false;const overlay=UI_TOOLS.overlay(root,{kind:drawer?"drawer":"dialog",trigger,host:options.host||container,focus:options.focus,dismissible:options.dismissible??root.dataset.dismissible!=="false",initialFocus:options.initialFocus||(element=>
37
+ alert?element.querySelector('[data-cx-cancel],button:not([data-danger]):not([type="submit"])'):element.querySelector("input:not([type=hidden]),select,textarea"))},signal);const ownerHidden=()=>!container.getClientRects().length||/^(hidden|collapse)$/.test(getComputedStyle(container).visibility);
38
+ const closeHidden=()=>{if(!options.closeWhenHidden||!overlay.opened||!ownerHidden()||matchMedia("print").matches)return false;root._cxHidden=true;overlay.close("hidden",false,true);return true};if(options.closeWhenHidden){const visibility=new MutationObserver(closeHidden);for(let owner=container;owner;owner=owner.parentElement)visibility.observe(owner,{attributes:true,attributeFilter:["style","class","hidden"]});signal?.addEventListener("abort",()=>visibility.disconnect(),{once:true})}
39
+ const open=()=>{const opened=overlay.open({modal:!drawer||phone||options.modal===true||root.dataset.modal==="true"});return opened&&!closeHidden()};UI_TOOLS.observe(container,width=>{if(!width&&!container.getClientRects().length){closeHidden();return}
40
+ phone=width<640;root.dataset.phone=String(phone);root.classList.toggle("cx-phone",phone);if(drawer&&overlay.opened)overlay.setModal(phone||options.modal===true||root.dataset.modal==="true")},signal);trigger?.addEventListener("click",open,{signal});root.addEventListener("click",event=>{if(event.target.closest("[data-cx-close],[data-cx-cancel]"))overlay.close("cancel")},{signal});const body=root.querySelector('[data-hfx-part="body"]');body?.addEventListener("scroll",()=>{root.dataset.scrolled=String(body.scrollTop>0)},{signal});if(drawer)root.addEventListener("keydown",event=>{if(!options.records||/^(?:INPUT|TEXTAREA|SELECT)$/.test(event.target.tagName) || event.target.isContentEditable) return;
41
+ if(event.key==="ArrowUp"||event.key==="ArrowDown"){event.preventDefault();options.records(event.key==="ArrowUp"?-1:1)}},{signal});for(const button of root.querySelectorAll(".cx-overlay-close"))button.setAttribute("aria-label",drawer?labels.drawerClose:labels.dialogClose);return{...overlay,open,refresh(){},getState:()=>({open:overlay.opened,modal:overlay.modal})}}
42
+ UI_IMPL.dialog=(root,options,signal)=>uiDialog(root,options,signal,false);UI_IMPL.drawer=(root,options,signal)=>uiDialog(root,options,signal,true);UI_IMPL.popover=(root,options,signal)=>{const trigger=options.trigger||document.getElementById(root.dataset.cxTrigger||"");const overlay=UI_TOOLS.overlay(root,{...options,trigger,kind:"popover",anchored:true},signal);trigger?.addEventListener("click",()=>overlay.opened?overlay.close():overlay.open(),{signal});trigger?.addEventListener("keydown",event=>{if(event.key==="ArrowDown"){event.preventDefault();overlay.open()}},{signal});root.addEventListener("keydown",event=>{if(event.key!=="Tab")return;const items=UI_TOOLS.focusables(root),at=items.indexOf(document.activeElement);if(event.shiftKey&&at===0||!event.shiftKey&&at===items.length-1){const outside=UI_TOOLS.focusables(trigger?.closest("dialog[open]")||document).filter(item=>!root.contains(item));const next=event.shiftKey?trigger:outside[outside.indexOf(trigger)+ 1];if(overlay.close("tab",false)){event.preventDefault();(next||trigger)?.focus()}}},{signal});return overlay};UI_IMPL.tooltip=(root,options,signal)=>{const trigger=options.trigger||document.getElementById(root.dataset.cxTrigger||"");if(!trigger)throw new Error("CanopyX: tooltip needs a labelled trigger.");const overlay=UI_TOOLS.overlay(root,{...options,trigger,kind:"tooltip",anchored:true,placement:options.placement||root.dataset.placement||"top",focus:false},signal);const described=trigger.getAttribute("aria-describedby"),ids=new Set((described||"").split(/\s+/).filter(Boolean));
43
+ if(!root.id)root.id=trigger.id+"-tooltip";const hadDescription=ids.has(root.id);ids.add(root.id);trigger.setAttribute("aria-describedby",[...ids].join(" "));let showTimer,hideTimer;const hide=()=>{clearTimeout(showTimer);clearTimeout(hideTimer);if(document.activeElement!==trigger)hideTimer=setTimeout(()=>overlay.close("leave",false),100)};const show=delay=>{clearTimeout(showTimer);clearTimeout(hideTimer);showTimer=setTimeout(()=>overlay.open(),delay)};trigger.addEventListener("pointerenter",()=>show(400),{signal});trigger.addEventListener("pointerleave",hide,{signal});root.addEventListener("pointerenter",()=>clearTimeout(hideTimer),{signal});root.addEventListener("pointerleave",hide,{signal});trigger.addEventListener("focus",()=>{clearTimeout(hideTimer);overlay.open()},{signal});trigger.addEventListener("blur",hide,{signal});const destroy=()=>{clearTimeout(showTimer);clearTimeout(hideTimer);overlay.destroy();const current=new Set((trigger.getAttribute("aria-describedby")||"").split(/\s+/).filter(Boolean));
44
+ if(!hadDescription)current.delete(root.id);if(current.size)trigger.setAttribute("aria-describedby",[...current].join(" "));else trigger.removeAttribute("aria-describedby")};signal.addEventListener("abort",destroy,{once:true});return{...overlay,destroy}};UI_TOOLS.toolbarFlyout=(anchor,panel,isOpen,signal)=>{const trigger=anchor.querySelector(":scope > summary")||anchor;const pressed=new Set();let positionPending=false,releaseFrame=0;if(!panel.hasAttribute("role"))panel.setAttribute("role","dialog");if(!panel.hasAttribute("aria-label"))panel.setAttribute("aria-label",trigger.getAttribute("aria-label")||trigger.textContent.trim()||trigger.title);const overlay=UI_TOOLS.overlay(panel,{kind:"popover",trigger,host:anchor.closest(".cx-host")||anchor,portal:panel.parentNode,focus:false,decorateTrigger:false},signal);const position=()=>{if(signal.aborted||!isOpen())return;if(pressed.size||releaseFrame){positionPending=true;return}
45
+ positionPending=false;const box=trigger.getBoundingClientRect(),fixed=getComputedStyle(panel).position==="fixed";const below=Math.max(0,global.innerHeight-box.bottom-8),above=Math.max(0,box.top-8);const top=below<120&&above>below,room=top?above:below;panel.style.maxHeight=(panel.matches(".cx-fb,.cx-export-panel")?room:Math.min(320,room))+ "px";panel.style.bottom="auto";UI_TOOLS.position(panel,trigger,top?"top-start":"bottom-start");if(!fixed&&panel.offsetParent){const parent=panel.offsetParent,bounds=parent.getBoundingClientRect();panel.style.left=parseFloat(panel.style.left)- bounds.left+parent.scrollLeft-parent.clientLeft+"px";panel.style.top=parseFloat(panel.style.top)- bounds.top+parent.scrollTop-parent.clientTop+"px"}};panel.addEventListener("cx-popover:close",event=>{if(event.target!==panel)return;if(anchor.localName==="details")anchor.open=false;for(const inner of panel.querySelectorAll("details[open]"))inner.open=false;if(event.detail.reason==="cancel")trigger.focus({preventScroll:true})},{signal});panel.addEventListener("pointerdown",event=>pressed.add(event.pointerId),{signal});const release=event=>{if(!pressed.delete(event.pointerId))return;if(!releaseFrame)releaseFrame=global.requestAnimationFrame(()=>{releaseFrame=0;if(positionPending)position()})};for(const type of["pointerup","pointercancel"])global.addEventListener(type,release,{capture:true,signal});global.addEventListener("resize",position,{signal});global.addEventListener("scroll",position,{capture:true,signal});signal.addEventListener("abort",()=>{global.cancelAnimationFrame(releaseFrame);pressed.clear()},{once:true});return{position,open(){if(isOpen()&&!overlay.opened)overlay.open();position()},close(){overlay.close("toggle",false,true)}}};installed.add(context.UI_IMPL)}};(global.CanopyXParts||=[]).push(["ui-overlays",part])})(typeof window!=="undefined"?window:globalThis);
@@ -0,0 +1,12 @@
1
+ @layer hfx.components{
2
+ .cx-picker{min-inline-size:0;font-family:var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);font-size:var(--hfx-control-font-size,calc(var(--hfx-type-body-size,0.875rem) - var(--cx-compact,0) * .0625rem));}
3
+ .cx-picker-trigger{inline-size:100%;justify-content:flex-start;min-inline-size:0;text-align:start;}
4
+ .cx-picker-lead,.cx-picker-separator,.cx-picker-chevron{flex:none;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font-weight:var(--hfx-weight-regular,400);}
5
+ .cx-picker-label{min-inline-size:0;overflow-wrap:anywhere;color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));}
6
+ .cx-picker-icon{display:inline-flex;flex:none;align-items:center;justify-content:center;inline-size:var(--hfx-icon-md,16px);block-size:var(--hfx-icon-md,16px);}
7
+ .cx-picker-icon > :is(svg,img){inline-size:100%;block-size:100%;}
8
+ .cx-picker-chevron{margin-inline-start:auto;}
9
+ .cx-picker-badge{flex:none;min-block-size:var(--hfx-badge-height,20px);padding:0 var(--hfx-space-1,0.25rem);border-radius:var(--hfx-radius-badge,var(--hfx-radius-sm,4px));background:var(--hfx-color-accent-subtle,light-dark(#e7f1f1,#1b3435));color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));font-size:var(--hfx-type-caption-size,0.75rem);line-height:var(--hfx-type-caption-line,1.35);}
10
+ .cx-picker :is(.cx-picker-lead,.cx-picker-label,.cx-picker-separator,.cx-picker-icon,.cx-picker-badge)[hidden]{display:none;}
11
+ @media print{.cx-picker{display:none!important;}}
12
+ }
@@ -0,0 +1,6 @@
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"d415103478faf52a",requires:["ui-menu"],install(context){if(installed.has(context.UI_IMPL))return;const{UI_IMPL,UI_TOOLS,h,setText,fill,watchTheme,overlayTheme,hostHtml}=context;let uiPickerIdentity=0;UI_TOOLS.picker=(root,options={})=>{const element=h('div','cx-picker');element.dataset.hfxPart='picker';const trigger=h('button','cx-picker-trigger cx-ui-button');trigger.type='button';const lead=h('span','cx-picker-lead'),separator=h('span','cx-picker-separator');separator.setAttribute('aria-hidden','true');setText(separator,'·');const icon=h('span','cx-picker-icon');icon.setAttribute('aria-hidden','true');const label=h('span','cx-picker-label'),badge=h('span','cx-picker-badge');badge.dataset.hfxPart='badge';const chevron=h('span','cx-picker-chevron');chevron.setAttribute('aria-hidden','true');setText(chevron,'▾');trigger.append(lead,separator,icon,label,badge,chevron);const menu=h('div','cx-menu');menu.hidden=true;menu.setAttribute('role','menu');menu.id='cx-ui-picker-menu-' + ++uiPickerIdentity;trigger.id=menu.id+'-trigger';element.append(trigger,menu);root.append(element);let state={...options},destroyed=false,selectionVersion=0;const renderIcon=value=>value?.nodeType?value.cloneNode(true):value;const controller=UI_IMPL.menu(menu,{trigger,host:root,renderIcon,async onSelect(item){const ticket=++selectionVersion;syncChecks();try{await state.onSelect?.(item.id)}
2
+ catch{}
3
+ finally{if(!destroyed&&ticket===selectionVersion)syncChecks()}}});function syncChecks(){for(const item of menu.querySelectorAll('[role="menuitemradio"]')){const checked=item.dataset.itemId===state.selected;item.setAttribute('aria-checked',String(checked));item.dataset.state=item.getAttribute('aria-disabled')==='true'?'disabled':checked?'selected':''}}
4
+ function update(next={}){if(destroyed)return;selectionVersion++;state={...state,...next};const items=state.items||[],selected=items.find(item=>item.id===state.selected);setText(lead,state.lead);lead.hidden=!state.lead;setText(label,selected?.label);label.hidden=!selected;separator.hidden=!state.lead||!selected;setText(badge,selected?.badge);badge.hidden=selected?.badge==null||selected.badge==='';icon.replaceChildren();icon.hidden=selected?.icon==null;if(selected?.icon?.nodeType)icon.append(selected.icon.cloneNode(true));else if(selected?.icon!=null)setText(icon,selected.icon);trigger.setAttribute('aria-label',[state.lead,selected?.label,selected?.badge].filter(value=>value!=null&&value!=='').join(' '));trigger.disabled=!items.length;element.dataset.state=!items.length?'disabled':selected?'selected':'';controller.close('update',false,true);UI_TOOLS.menuItems(menu,items.map(item=>({...item,kind:'radio',checked:item.id===state.selected})),{renderIcon});controller.refresh()}
5
+ function destroy(){if(destroyed)return;destroyed=true;selectionVersion++;controller.destroy();element.remove()}
6
+ update();return{element,update,destroy}};installed.add(context.UI_IMPL)}};(global.CanopyXParts||=[]).push(["ui-picker",part])})(typeof window!=="undefined"?window:globalThis);
@@ -0,0 +1,174 @@
1
+ @layer hfx.components{
2
+ .cx-stepper-host{display:grid;gap:var(--hfx-space-4,1rem);}
3
+ .cx-stepper{
4
+ display:flex;
5
+ align-items:start;
6
+ list-style:none;
7
+ margin:0;
8
+ padding:0;
9
+ gap:var(--hfx-space-4,1rem);
10
+ }
11
+ .cx-step{
12
+ flex:1 1 0;
13
+ position:relative;
14
+ display:grid;
15
+ grid-template-columns:minmax(0,1fr);
16
+ align-content:start;
17
+ justify-items:start;
18
+ gap:var(--hfx-space-1,0.25rem);
19
+ min-inline-size:0;
20
+ color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));
21
+ }
22
+ .cx-step:not(:last-child)::after{
23
+ content:'';
24
+ position:absolute;
25
+ inset-block-start:calc(var(--hfx-step-marker,28px) / 2);
26
+ inset-inline-start:calc(var(--hfx-step-marker,28px) + var(--hfx-space-2,0.5rem));
27
+ inset-inline-end:0;
28
+ block-size:var(--hfx-indicator-width,2px);
29
+ background:var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));
30
+ }
31
+ .cx-step-btn{
32
+ display:grid;
33
+ justify-items:start;
34
+ align-content:start;
35
+ gap:var(--hfx-space-1,0.25rem);
36
+ border:0;
37
+ padding:0;
38
+ background:transparent;
39
+ color:inherit;
40
+ font:inherit;
41
+ text-align:start;
42
+ inline-size:100%;
43
+ cursor:pointer;
44
+ }
45
+ .cx-step-marker{
46
+ box-sizing:border-box;
47
+ display:inline-flex;
48
+ align-items:center;
49
+ justify-content:center;
50
+ inline-size:var(--hfx-step-marker,28px);
51
+ block-size:var(--hfx-step-marker,28px);
52
+ border:var(--hfx-indicator-width,2px) solid var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));
53
+ border-radius:50%;
54
+ background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));
55
+ color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));
56
+ font-size:var(--hfx-control-font-size,calc(var(--hfx-type-body-size,0.875rem) - var(--cx-compact,0) * .0625rem));
57
+ font-weight:var(--hfx-weight-semibold,600);
58
+ line-height:1;
59
+ }
60
+ .cx-step-label{font-size:var(--hfx-control-font-size,calc(var(--hfx-type-body-size,0.875rem) - var(--cx-compact,0) * .0625rem));font-weight:var(--hfx-weight-semibold,600);}
61
+ .cx-step-desc,.cx-step-position,.cx-step-state{
62
+ font-size:var(--hfx-type-caption-size,0.75rem);
63
+ line-height:var(--hfx-type-caption-line,1.35);
64
+ color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));
65
+ }
66
+ .cx-step[aria-current="step"]{color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));}
67
+ .cx-step[aria-current="step"] .cx-step-marker{
68
+ border-color:var(--hfx-color-accent-indicator,light-dark(#11776f,#37c9b8));
69
+ color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));
70
+ box-shadow:0 0 0 var(--hfx-space-1,0.25rem) var(--hfx-color-accent-subtle,light-dark(#e7f1f1,#1b3435));
71
+ }
72
+ .cx-step[data-state="done"]{color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));}
73
+ .cx-step[data-state="done"] .cx-step-marker{
74
+ background:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));
75
+ border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));
76
+ color:var(--hfx-color-accent-contrast,light-dark(#ffffff,#0c0d10));
77
+ }
78
+ .cx-step[data-state="done"]::after{background:var(--hfx-color-accent-indicator,light-dark(#11776f,#37c9b8));}
79
+ .cx-step-btn:hover .cx-step-marker{box-shadow:0 0 0 var(--hfx-space-1,0.25rem) var(--hfx-color-hover,light-dark(#f5f5f5,#232529));}
80
+ .cx-step[data-state="error"],.cx-step[data-state="error"] .cx-step-desc{color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));}
81
+ .cx-step[data-state="error"] .cx-step-marker{
82
+ background:var(--hfx-color-status-bad-bg,light-dark(#f9e4e4,#3c272a));
83
+ border-color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));
84
+ color:var(--hfx-color-status-bad-fg,light-dark(#b8292a,#f47171));
85
+ }
86
+ .cx-step[data-state="skipped"] .cx-step-marker{border-style:dashed;}
87
+ .cx-step[data-state="disabled"]{color:var(--hfx-color-text-disabled,light-dark(#a3a8b0,#5a5f68));}
88
+ .cx-step[data-state="disabled"] .cx-step-marker{
89
+ background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));
90
+ border-color:var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));
91
+ color:var(--hfx-color-text-disabled,light-dark(#a3a8b0,#5a5f68));
92
+ }
93
+ .cx-step[data-state="disabled"]::after{background:var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));}
94
+ .cx-step-panel{min-inline-size:0;}
95
+ .cx-step-print-state{display:none;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font-size:var(--hfx-type-caption-size,0.75rem);line-height:var(--hfx-type-caption-line,1.35);}
96
+ .cx-step-print-marker{display:none;}
97
+ .cx-step-panel > h3{margin-block:0 var(--hfx-space-3,0.75rem);font-size:var(--hfx-type-heading-size,0.9375rem);font-weight:var(--hfx-weight-semibold,600);}
98
+ .cx-stepper-footer{
99
+ display:flex;
100
+ align-items:center;
101
+ justify-content:end;
102
+ flex-wrap:wrap;
103
+ gap:var(--hfx-space-2,0.5rem);
104
+ padding-block-start:var(--hfx-space-3,0.75rem);
105
+ border-block-start:var(--hfx-border-width,1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));
106
+ }
107
+ .cx-step-position{margin-inline-end:auto;}
108
+ .cx-stepper-footer button,.cx-stepper-phone-back{
109
+ min-block-size:var(--hfx-control-height-md,calc(36px - var(--cx-compact,0) * 8px));
110
+ padding:var(--hfx-space-1,0.25rem) var(--hfx-control-padding-x,calc(14px - var(--cx-compact,0) * 4px));
111
+ border:var(--hfx-border-width,1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));
112
+ border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));
113
+ background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));
114
+ color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));
115
+ font-family:var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);
116
+ font-size:var(--hfx-control-font-size,calc(var(--hfx-type-body-size,0.875rem) - var(--cx-compact,0) * .0625rem));
117
+ font-weight:var(--hfx-weight-medium,500);
118
+ line-height:var(--hfx-type-body-line,1.5);
119
+ cursor:pointer;
120
+ }
121
+ .cx-stepper-footer button:hover,.cx-stepper-phone-back:hover{background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));}
122
+ .cx-stepper-footer :is([data-cx-stepper-action="next"],[data-cx-stepper-action="finish"]){
123
+ background:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));
124
+ border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));
125
+ color:var(--hfx-color-accent-contrast,light-dark(#ffffff,#0c0d10));
126
+ }
127
+ .cx-stepper-footer :is([data-cx-stepper-action="next"],[data-cx-stepper-action="finish"]):hover{background:var(--hfx-color-accent-hover,light-dark(#0d6760,#4dd9c8));}
128
+ .cx-stepper-footer :is([data-cx-stepper-action="skip"],[data-cx-stepper-action="save-draft"]){background:transparent;border-color:transparent;color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));}
129
+ .cx-stepper-footer :is([data-cx-stepper-action="skip"],[data-cx-stepper-action="save-draft"]):hover{background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));}
130
+ .cx-stepper-host[data-layout="vertical"][data-vertical="side"]:not([data-phone="true"]){grid-template-columns:auto minmax(0,1fr);}
131
+ .cx-stepper--vertical{flex-direction:column;align-items:stretch;}
132
+ .cx-stepper-host[data-layout="vertical"][data-vertical="side"]:not([data-phone="true"]) > .cx-stepper{grid-column:1;grid-row:1 / span 3;}
133
+ .cx-stepper-host[data-layout="vertical"][data-vertical="side"]:not([data-phone="true"]) > :is(.cx-step-panel,.cx-stepper-footer){grid-column:2;}
134
+ .cx-stepper--vertical > .cx-step{grid-template-columns:var(--hfx-step-marker,28px) minmax(0,1fr);column-gap:var(--hfx-space-3,0.75rem);}
135
+ .cx-stepper--vertical > .cx-step > .cx-step-btn{grid-column:1 / -1;grid-template-columns:var(--hfx-step-marker,28px) minmax(0,1fr);column-gap:var(--hfx-space-3,0.75rem);}
136
+ .cx-stepper--vertical .cx-step-marker{grid-column:1;grid-row:1 / span 2;}
137
+ .cx-stepper--vertical :is(.cx-step-label,.cx-step-desc){grid-column:2;}
138
+ .cx-stepper--vertical > .cx-step:not(:last-child)::after{
139
+ inset-inline-start:calc(var(--hfx-step-marker,28px) / 2);
140
+ inset-block-start:calc(var(--hfx-step-marker,28px) + var(--hfx-space-2,0.5rem));
141
+ inset-block-end:calc(-1 * var(--hfx-space-2,0.5rem));
142
+ inset-inline-end:auto;
143
+ inline-size:var(--hfx-indicator-width,2px);
144
+ block-size:auto;
145
+ }
146
+ .cx-stepper--vertical .cx-step-panel{grid-column:2;padding-block:var(--hfx-space-3,0.75rem);}
147
+ .cx-stepper-phone{display:grid;grid-template-columns:auto minmax(0,1fr);gap:var(--hfx-space-2,0.5rem);}
148
+ .cx-stepper-phone > :only-child{grid-column:1 / -1;}
149
+ .cx-stepper-phone-back[hidden] + [data-hfx-part="picker"]{grid-column:1 / -1;}
150
+ .cx-stepper-progress{grid-column:1 / -1;block-size:var(--hfx-space-1,0.25rem);border-radius:var(--hfx-radius-pill,999px);background:var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));overflow:hidden;}
151
+ .cx-stepper-progress > span{display:block;block-size:100%;background:var(--hfx-color-accent-indicator,light-dark(#11776f,#37c9b8));border-radius:inherit;}
152
+ .cx-stepper-host[data-phone="true"]{grid-template-columns:minmax(0,1fr);}
153
+ .cx-stepper-host[data-phone="true"] > :is(.cx-step-panel,.cx-stepper-footer){grid-column:1;}
154
+ .cx-stepper-host[data-phone="true"] .cx-stepper-footer{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));}
155
+ .cx-stepper-host[data-phone="true"] .cx-step-position{grid-column:1 / -1;}
156
+ .cx-stepper-host[data-phone="true"] .cx-stepper-footer [data-cx-stepper-action="back"]{grid-column:1;}
157
+ .cx-stepper-host[data-phone="true"] .cx-stepper-footer :is([data-cx-stepper-action="next"],[data-cx-stepper-action="finish"]){grid-column:2;}
158
+ .cx-stepper-host[data-mode="report"] > :is(.cx-stepper,.cx-stepper-footer,.cx-stepper-phone){display:none;}
159
+ @media (forced-colors: active){
160
+ .cx-step-marker{border-color:currentColor;}
161
+ .cx-step[aria-current="step"] .cx-step-marker{outline:var(--hfx-indicator-width,2px) solid currentColor;outline-offset:var(--hfx-focus-offset,2px);}
162
+ }
163
+ @media print{
164
+ .cx-stepper-host{display:block;}
165
+ .cx-stepper-host[data-mode="interactive"] > :is(.cx-stepper,.cx-stepper-footer,.cx-stepper-phone,[aria-live]){display:none;}
166
+ .cx-stepper-host[data-mode="interactive"] .cx-step-panel{display:block;break-inside:avoid;}
167
+ .cx-stepper-host[data-mode="interactive"] .cx-step-print-state{display:block;}
168
+ .cx-stepper-host[data-mode="interactive"] .cx-step-print-marker{display:inline-flex;margin-inline-end:var(--hfx-space-2,0.5rem);}
169
+ .cx-stepper-host[data-mode="interactive"] .cx-stepper--vertical{display:block;}
170
+ .cx-stepper--vertical > .cx-step{display:block;break-inside:avoid;}
171
+ .cx-stepper--vertical > .cx-step > :not(.cx-step-panel){display:none;}
172
+ .cx-stepper--vertical > .cx-step::after{display:none;}
173
+ }
174
+ }
@@ -0,0 +1,48 @@
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"a31fd5d0b314cdef",requires:["ui-navigation"],install(context){if(installed.has(context.UI_IMPL))return;const{UI_IMPL,UI_TOOLS,h,setText,fill,watchTheme,overlayTheme,hostHtml}=context;UI_IMPL.stepper=(root,options={},signal)=>{const n=UI_TOOLS.navigation,life=n.scope(signal),labels=UI_TOOLS.labels(options.labels);const mode=options.mode||root.dataset.mode||'interactive';const linear=options.linear??root.dataset.linear!=='false';let items=n.records(root,'stepper',options);let current=n.resolve(items,options.selectedIndex??options.selected)||items.find(item=>item.element.hasAttribute('aria-current'))||items.find(item=>!item.disabled);if(current?.disabled)current=items.find(item=>!item.disabled);let destroyed=false,completed=false,view,finishSelection;root.dataset.mode=mode;const states=new Map(items.map(item=>[item.id,item.state==='current'?'upcoming':item.state]));const visited=new Set(items.filter(item=>item.visited||item.index<(current?.index??0)||['done','error','skipped'].includes(item.state)).map(item=>item.id));if(current)visited.add(current.id);function syncRecords(){items.forEach(item=>{item.state=item===current&&!completed&&states.get(item.id)!=='error'?'current':states.get(item.id);item.visited=visited.has(item.id)});return current}
2
+ function getState(){syncRecords();return{selected:current?.id??null,finished:completed,steps:items.map(item=>({id:item.id,state:item.state,current:item===current,visited:item.visited,optional:item.optional}))}}
3
+ function allowed(item){return!!item&&!item.disabled&&(!linear||item===current||visited.has(item.id)||['done','error','skipped'].includes(states.get(item.id)))}
4
+ if(mode!=='interactive')return{select:async()=>false,getSelected:()=>current?.id??null,refresh(){},destroy(){life.abort()},preparePrint:async()=>{},next:async()=>false,back:async()=>false,skip:async()=>false,finish:async()=>false,setStepState(){return false},getState,ready:Promise.resolve()};const errors=UI_TOOLS.stepperErrors(root,labels);const deferred=n.deferred(root,'stepper',options,life,id=>select(id,'retry'));function render(focus=false){syncRecords();root.dataset.finished=String(completed);view?.update(items,current,states,visited,allowed,focus)}
5
+ function adjacent(direction){for(let index=(current?.index??0)+ direction;index>=0&&index<items.length;index +=direction){if(!items[index].disabled)return items[index]}
6
+ return null}
7
+ const selection=n.selection(root,'stepper',options,life,syncRecords,async(from,to,loadSignal,live,source)=>{if(from!==to){deferred.leave(from);if(source==='next'||source==='skip'){states.set(from.id,source==='skip'?'skipped':'done');errors.clear(from)}
8
+ if(options.resetForwardOnBack&&to.index<from.index){items.filter(item=>item.index>to.index).forEach(item=>{if(states.get(item.id)!=='disabled')states.set(item.id,'upcoming');visited.delete(item.id);errors.clear(item)})}}
9
+ current=to;visited.add(to.id);completed=false;render(from!==to);if(from!==to)UI_TOOLS.emit(root,'stepper','change',{from,to,state:getState()});await deferred.load(to,loadSignal,live);if(live())render()});async function validate(item,validationSignal,live){syncRecords();const result=await options.validate?.(item,validationSignal);if(!live())return false;if(result===false||Array.isArray(result)&&result.length){states.set(item.id,'error');errors.show(item,Array.isArray(result)?result:[labels.stateDetails]);render();errors.focus(item);return false}
10
+ errors.clear(item);return true}
11
+ function select(value,source='api'){if(destroyed)return Promise.resolve(false);finishSelection?.cancel();const target=n.resolve(items,value);if(!allowed(target)&&source!=='next'&&source!=='skip'){selection.cancel();return Promise.resolve(false)}
12
+ if(target===current&&source!=='retry'){selection.cancel();return Promise.resolve(true)}
13
+ return selection.request(target,async(from,to,requestSignal,live)=>{if(source==='next'&&!await validate(from,requestSignal,live))return false;return true},source)}
14
+ async function move(source){const to=adjacent(1);if(!to)return source==='skip'?Promise.resolve(false):finish();return select(to.id,source)}
15
+ const next=()=>move('next');const back=()=>{const target=adjacent(-1);return target?select(target.id,'back'):Promise.resolve(false)};const skip=()=>current?.optional?move('skip'):Promise.resolve(false);finishSelection=n.selection(root,'stepper',options,life,syncRecords,async(from,to,finishSignal,live)=>{if(!live())return;states.set(to.id,'done');completed=true;render();UI_TOOLS.emit(root,'stepper','finish',{step:to,state:getState(),signal:finishSignal});options.onFinish?.(getState())});async function finish(){if(destroyed||!current||adjacent(1))return false;selection.cancel();if(completed)return false;return finishSelection.request(current,(from,to,requestSignal,live)=>validate(to,requestSignal,live),'finish')}
16
+ function setStepState(value,state){const item=n.resolve(items,value);if(!item||!['upcoming','current','done','error','skipped','disabled'].includes(state)||state==='skipped'&&!item.optional||state==='current'&&item!==current||state==='disabled'&&item===current)return false;selection.cancel();finishSelection.cancel();completed=false;item.disabled=state==='disabled';states.set(item.id,state==='current'?'upcoming':state);if(['done','error','skipped'].includes(state))visited.add(item.id);render();return true}
17
+ function refresh(){if(destroyed)return;selection.cancel();finishSelection.cancel();const selected=current?.id;items=n.records(root,'stepper',options);items.forEach(item=>{if(!states.has(item.id))states.set(item.id,item.state==='current'?'upcoming':item.state)});current=n.resolve(items,selected)||items.find(item=>!item.disabled);if(current)visited.add(current.id);render()}
18
+ root.addEventListener('click',event=>{const action=event.target.closest('[data-cx-stepper-action]');if(action&&action.closest('[data-cx-stepper]')===root){if(action.getAttribute('aria-disabled')==='true')return;const actions={next,back,skip,finish,'save-draft':()=>{UI_TOOLS.emit(root,'stepper','savedraft',{state:getState()});options.onSaveDraft?.(getState())}};actions[action.dataset.cxStepperAction]?.();return}
19
+ const button=event.target.closest('.cx-step-btn');if(button&&button.closest('[data-cx-stepper]')===root)select(button.closest('[data-step-id]').dataset.stepId,'user')},{signal:life.signal});view=UI_TOOLS.stepperView(root,options,labels,life,id=>select(id,'picker'),back,errors.count);function destroy(){if(destroyed)return;destroyed=true;life.abort();view.destroy();deferred.destroy();errors.destroy();root.removeAttribute('data-cx-ready');items.forEach(item=>{if(item.panel)item.panel.hidden=false})}
20
+ root.dataset.cxReady='true';render();const ready=current?select(current.id,'retry'):Promise.resolve(false);signal?.addEventListener('abort',destroy,{once:true});return{select,getSelected:()=>current?.id??null,refresh,destroy,next,back,skip,finish,setStepState,getState,ready,preparePrint:()=>deferred.preparePrint()}};UI_TOOLS.stepperErrors=(root,labels)=>{const alerts=new Map(),fields=new Map();function clear(item){const entry=alerts.get(item?.id);if(!entry)return;for(const field of fields.get(item.id)||[]){const ids=(field.getAttribute('aria-describedby')||'').split(/\s+/).filter(id => id && id !== entry.element.id);
21
+ if(ids.length)field.setAttribute('aria-describedby',ids.join(' '));else field.removeAttribute('aria-describedby')}
22
+ entry.element.remove();alerts.delete(item.id);fields.delete(item.id)}
23
+ function show(item,messages){clear(item);if(!item.panel)return;const alert=h('div','cx-step-errors');alert.setAttribute('role','alert');alert.tabIndex=-1;alert.id=item.panel.id+'-validation';const heading=h('p');setText(heading,messages.length===1?labels.stepperIssue:fill(labels.stepperIssues,{count:messages.length}));const list=h('ul');for(const message of messages){const entry=h('li');setText(entry,message);list.append(entry)}
24
+ alert.append(heading,list);item.panel.prepend(alert);const invalid=Array.from(item.panel.querySelectorAll('[aria-invalid="true"],input:invalid,select:invalid,textarea:invalid'));for(const field of invalid){const ids=new Set((field.getAttribute('aria-describedby')||'').split(/\s+/).filter(Boolean));
25
+ ids.add(alert.id);field.setAttribute('aria-describedby',Array.from(ids).join(' '))}
26
+ alerts.set(item.id,{element:alert,count:messages.length});fields.set(item.id,invalid)}
27
+ return{show,clear,focus:item=>alerts.get(item.id)?.element.focus(),count:item=>alerts.get(item.id)?.count||0,destroy(){for(const id of Array.from(alerts.keys()))clear({id})}}};UI_TOOLS.stepperView=(root,options,labels,life,select,back,issueCount)=>{const n=UI_TOOLS.navigation,header=n.owned(root,'ol.cx-stepper')[0];const footer=n.owned(root,'.cx-stepper-footer')[0];const live=n.owned(root,'[aria-live="polite"]')[0];const originalButtons=new Map(n.owned(root,'[data-cx-stepper-action]').map(el=>[el.dataset.cxStepperAction,el.textContent]));const footerData=footer?.dataset||{};const actionLabel=(action,key,fallback)=>options[key]??footerData[key]??originalButtons.get(action)??fallback;const phone=h('div','cx-stepper-phone');const backButton=n.button(labels.stepperBack,'cx-stepper-phone-back');backButton.dataset.cxStepperAction='back';backButton.setAttribute('aria-label',labels.stepperBack);setText(backButton,'\u2039');const picker=UI_TOOLS.picker(root,{lead:'',items:[],selected:null,onSelect:select});const progress=h('div','cx-stepper-progress'),bar=h('span');progress.setAttribute('role','progressbar');progress.setAttribute('aria-label',labels.stepperAllSteps);progress.setAttribute('aria-valuemin','0');progress.setAttribute('aria-valuemax','100');progress.append(bar);phone.append(backButton,picker.element,progress);header?.before(phone);const home=new Map(),descriptions=new Map(),inserted=new Set(),printStates=new Map(),printMarkers=new Map();let items=[],current,states,visited,allowed,narrow=false;const placement=options.vertical??root.dataset.vertical;const vertical=options.vertical!=null?!!options.vertical
28
+ :header?.classList.contains('cx-stepper--vertical')||root.dataset.layout==='vertical'||placement==='inline';header?.classList.toggle('cx-stepper--vertical',!!vertical);root.dataset.layout=vertical?'vertical':'horizontal';root.dataset.vertical=placement==='inline'?'inline':'side';function status(item){const state=states.get(item.id),count=issueCount(item);if(state==='error')return count>1?fill(labels.stepperIssues,{count}):labels.stepperIssue;if(state==='done')return labels.stepperCompleted;if(state==='skipped')return labels.stepperSkipped;return item.optional?labels.stepperOptional:''}
29
+ function step(item){const el=item.element,state=item.state,enabled=item!==current&&allowed(item);el.dataset.state=state;el.dataset.visited=String(item.visited);if(item===current)el.setAttribute('aria-current','step');else el.removeAttribute('aria-current');if(item.disabled)el.setAttribute('aria-disabled','true');else el.removeAttribute('aria-disabled');let button=el.querySelector(':scope > .cx-step-btn');if(enabled&&!button){button=n.button('','cx-step-btn');Array.from(el.childNodes).filter(child=>child!==item.panel).forEach(child=>button.append(child));el.prepend(button)}else if(!enabled&&button){button.replaceWith(...button.childNodes);button=null}
30
+ if(button){button.dataset.cxStep=String(item.index);if(item.panel)button.setAttribute('aria-controls',item.panel.id)}
31
+ const marker=el.querySelector('.cx-step-marker');if(marker)setText(marker,state==='done'?'\u2713':state==='error'?'!':state==='skipped'?'\u2013':item.index+1);let description=el.querySelector('.cx-step-desc');if(!descriptions.has(el))descriptions.set(el,description?.textContent||'');const text=status(item)||descriptions.get(el);if(!description&&text){description=h('span','cx-step-desc');(button||el).append(description);inserted.add(description)}
32
+ if(description)setText(description,text);let accessible=el.querySelector('.cx-visually-hidden');if(!accessible){accessible=h('span','cx-visually-hidden');(button||el).append(accessible);inserted.add(accessible)}
33
+ setText(accessible,', '+n.position(labels,'stepperStepOf',item.index,items.length)+(text?', '+text:''));if(item.panel){if(!printStates.has(item.panel)){const line=h('p','cx-step-print-state');line.dataset.hfxPart='step-state';const heading=item.panel.querySelector('[data-hfx-part="title"],h3');if(heading)heading.after(line);else item.panel.prepend(line);printStates.set(item.panel,line);inserted.add(line)}
34
+ setText(printStates.get(item.panel),status(item));const heading=item.panel.querySelector('[data-hfx-part="title"],h3');if(heading&&!printMarkers.has(item.panel)){const marker=h('span','cx-step-marker cx-step-print-marker');marker.setAttribute('aria-hidden','true');heading.prepend(marker);printMarkers.set(item.panel,marker);inserted.add(marker)}
35
+ const printMarker=printMarkers.get(item.panel);if(printMarker)setText(printMarker,states.get(item.id)==='done'?'\u2713':states.get(item.id)==='error'?'!':states.get(item.id)==='skipped'?'\u2013':item.index+1);item.panel.hidden=item!==current;if(item.panel.dataset.state!=='loading')item.panel.dataset.state=state;if(vertical&&root.dataset.vertical==='inline'&&!narrow&&item.panel.parentElement!==el){if(!home.has(item.panel)){const anchor=document.createComment('step panel');item.panel.before(anchor);home.set(item.panel,anchor)}
36
+ el.append(item.panel)}else if((!vertical||root.dataset.vertical!=='inline'||narrow)&&home.has(item.panel))home.get(item.panel).after(item.panel)}}
37
+ function footerAction(action,visible,label){if(!footer)return;let button=footer.querySelector('[data-cx-stepper-action="'+action+'"]');if(!button&&visible){button=n.button(label,'');button.dataset.cxStepperAction=action;footer.append(button);inserted.add(button)}
38
+ if(button){button.hidden=!visible;setText(button,label)}}
39
+ function update(nextItems=items,selected=current,nextStates=states,nextVisited=visited,canSelect=allowed,focus=false){if(life.signal.aborted)return;const active=document.activeElement,ownedFocus=UI_TOOLS.owns(root,active);const navigationFocus=UI_TOOLS.owns(phone,active)||header?.contains(active)&&!items.some(item=>item.panel?.contains(active));items=nextItems;current=selected;states=nextStates;visited=nextVisited;allowed=canSelect;items.forEach(step);phone.hidden=!narrow;if(header)header.hidden=narrow;if(!current)return;const position=n.position(labels,'stepperStepOf',current.index,items.length);picker.update({lead:position,selected:current.id,items:n.pickerItems(items.map(item=>({...item,icon:states.get(item.id)==='done'?'\u2713':states.get(item.id)==='error'?'!':String(item.index+1),badge:status(item)||undefined})),current.id,item=>!allowed(item))});backButton.hidden=!items.some(item=>item.index<current.index&&!item.disabled);const percentage=(current.index+1)/ items.length * 100;
40
+ bar.style.inlineSize=percentage+'%';progress.setAttribute('aria-valuenow',String(Math.round(percentage)));progress.setAttribute('aria-valuetext',position);const footerPosition=footer?.querySelector('.cx-step-position');if(footerPosition)setText(footerPosition,position);const last=!items.some(item=>item.index>current.index&&!item.disabled);const saveDraft=options.saveDraftLabel!==undefined?options.saveDraftLabel!=null
41
+ :!!options.onSaveDraft||footerData.saveDraftEnabled==='true'||originalButtons.has('save-draft');const skip=options.skip??(options.skipLabel!==undefined?options.skipLabel!=null:footerData.skipEnabled!=='false');footerAction('save-draft',saveDraft,actionLabel('save-draft','saveDraftLabel',labels.stepperSaveDraft));footerAction('skip',current.optional&&skip,actionLabel('skip','skipLabel',labels.stepperSkip));footerAction('back',items.some(item=>item.index<current.index&&!item.disabled),actionLabel('back','backLabel',labels.stepperBack));footerAction('next',!last,actionLabel('next','nextLabel',labels.stepperNext));footerAction('finish',last,actionLabel('finish','finishLabel',labels.stepperFinish));for(const action of['save-draft','skip','back','next','finish']){const button=footer?.querySelector('[data-cx-stepper-action="'+action+'"]');if(button)footer.append(button)}
42
+ if(focus){const heading=current.panel?.querySelector('[data-hfx-part="title"],h1,h2,h3');if(heading){heading.tabIndex=-1;heading.focus()}
43
+ if(live)setText(live,position+': '+current.label)}else if(ownedFocus&&(document.activeElement!==active||!active.checkVisibility())){if(active.isConnected&&active.checkVisibility())active.focus({preventScroll:true});else if(navigationFocus){const target=narrow?picker.element.querySelector('button')
44
+ :current.panel?.querySelector('[data-hfx-part="title"],h1,h2,h3')||header?.querySelector('.cx-step-btn');if(target){if(target.tagName!=='BUTTON')target.tabIndex=-1;target.focus({preventScroll:true})}}}}
45
+ UI_TOOLS.observe(root,width=>{const measured=typeof width==='number'?width:root.getBoundingClientRect().width;narrow=measured<640;root.dataset.phone=String(narrow);if(states)update()},life.signal);function destroy(){for(const[panel,anchor]of home){anchor.after(panel);anchor.remove()}
46
+ for(const[el,text]of descriptions){const desc=el.querySelector('.cx-step-desc');if(desc)setText(desc,text)}
47
+ inserted.forEach(el=>el.remove());picker.destroy();phone.remove();if(header)header.hidden=false;root.removeAttribute('data-finished');delete root.dataset.phone}
48
+ return{update,destroy}};installed.add(context.UI_IMPL)}};(global.CanopyXParts||=[]).push(["ui-stepper",part])})(typeof window!=="undefined"?window:globalThis);
@@ -0,0 +1,153 @@
1
+ @layer hfx.components{
2
+ .cx-tabs{
3
+ --cx-tabs-motion-duration-fast:var(--hfx-motion-duration-fast,120ms);
4
+ --cx-tabs-motion-duration-base:var(--hfx-motion-duration-base,200ms);
5
+ --cx-tabs-motion-easing:var(--hfx-motion-easing-standard,cubic-bezier(.2,0,0,1));
6
+ --cx-tabs-motion-distance:var(--hfx-space-2,0.5rem);
7
+ display:grid;
8
+ grid-template-columns:minmax(0,1fr) auto;
9
+ align-items:start;
10
+ column-gap:var(--hfx-space-1,0.25rem);
11
+ }
12
+ .cx-tablist{
13
+ display:flex;
14
+ position:relative;
15
+ align-items:center;
16
+ gap:var(--hfx-space-1,0.25rem);
17
+ min-inline-size:0;
18
+ overflow:auto;
19
+ scrollbar-width:none;
20
+ border-block-end:var(--hfx-border-width,1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));
21
+ }
22
+ .cx-tablist::-webkit-scrollbar{display:none;}
23
+ .cx-tab{
24
+ display:inline-flex;
25
+ align-items:center;
26
+ justify-content:center;
27
+ flex:0 0 auto;
28
+ position:relative;
29
+ gap:var(--hfx-space-2,0.5rem);
30
+ min-block-size:var(--hfx-tab-height,calc(40px - var(--cx-compact,0) * 4px));
31
+ padding:0 var(--hfx-space-3,0.75rem);
32
+ border:0;
33
+ background:transparent;
34
+ color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));
35
+ font-family:var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);
36
+ font-size:var(--hfx-control-font-size,calc(var(--hfx-type-body-size,0.875rem) - var(--cx-compact,0) * .0625rem));
37
+ font-weight:var(--hfx-weight-medium,500);
38
+ line-height:var(--hfx-type-body-line,1.5);
39
+ cursor:pointer;
40
+ white-space:nowrap;
41
+ }
42
+ .cx-tab:hover:not([aria-disabled="true"]){color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));}
43
+ .cx-tab:active:not([aria-disabled="true"]){background:var(--hfx-color-active,light-dark(#ebebec,#2e3034));}
44
+ .cx-tab[aria-selected="true"]{color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));font-weight:var(--hfx-weight-semibold,600);}
45
+ .cx-tab[aria-disabled="true"]{color:var(--hfx-color-text-disabled,light-dark(#a3a8b0,#5a5f68));cursor:default;}
46
+ .cx-tab:focus-visible{outline-offset:calc(-1 * var(--hfx-focus-width,2px));}
47
+ .cx-tab-icon{inline-size:var(--hfx-icon-md,16px);block-size:var(--hfx-icon-md,16px);}
48
+ .cx-tab-badge{
49
+ display:inline-flex;
50
+ align-items:center;
51
+ min-block-size:var(--hfx-icon-md,16px);
52
+ padding-inline:var(--hfx-space-1,0.25rem);
53
+ border-radius:var(--hfx-radius-badge,var(--hfx-radius-sm,4px));
54
+ color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));
55
+ background:var(--hfx-color-accent-subtle,light-dark(#e7f1f1,#1b3435));
56
+ font-size:var(--hfx-type-caption-size,0.75rem);
57
+ line-height:var(--hfx-type-caption-line,1.35);
58
+ font-weight:var(--hfx-weight-medium,500);
59
+ }
60
+ .cx-tabs-indicator{
61
+ inline-size:var(--cx-tabs-indicator-size);
62
+ inset-inline-start:var(--cx-tabs-indicator-start);
63
+ position:absolute;
64
+ inset-block-end:0;
65
+ block-size:var(--hfx-indicator-width,2px);
66
+ background:var(--hfx-color-accent-indicator,light-dark(#11776f,#37c9b8));
67
+ pointer-events:none;
68
+ transition:inset-inline-start var(--hfx-motion-duration-base,200ms) var(--hfx-motion-easing-standard,cubic-bezier(.2,0,0,1)),inline-size var(--hfx-motion-duration-base,200ms) var(--hfx-motion-easing-standard,cubic-bezier(.2,0,0,1));
69
+ }
70
+ .cx-tabs--pills > .cx-tablist,.cx-tabs--segmented > .cx-tablist{border:0;}
71
+ :is(.cx-tabs--pills,.cx-tabs--segmented) > .cx-tablist > .cx-tab{
72
+ min-block-size:var(--hfx-control-height-md,calc(36px - var(--cx-compact,0) * 8px));
73
+ border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));
74
+ }
75
+ .cx-tabs--pills > .cx-tablist > .cx-tab[aria-selected="true"]{background:var(--hfx-color-accent-subtle,light-dark(#e7f1f1,#1b3435));color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));}
76
+ .cx-tabs--segmented > .cx-tablist{
77
+ background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));
78
+ padding:var(--hfx-space-0-5,2px);
79
+ border:var(--hfx-border-width,1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));
80
+ border-radius:calc(var(--hfx-radius-control,var(--hfx-radius-md,6px)) + var(--hfx-space-0-5,2px));
81
+ overflow:visible;
82
+ }
83
+ .cx-tabs--segmented > .cx-tablist > .cx-tab{flex:1 1 0;min-inline-size:0;white-space:normal;}
84
+ .cx-tabs--segmented > .cx-tablist > .cx-tab[aria-selected="true"]{
85
+ background:var(--hfx-color-surface-raised,light-dark(#ffffff,#1e2126));
86
+ box-shadow:var(--hfx-elevation-1,0 1px 2px rgba(22,24,28,.06)),0 0 0 var(--hfx-border-width,1px) var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));
87
+ }
88
+ :is(.cx-tabs--pills,.cx-tabs--segmented,.cx-tabs--vertical) > .cx-tablist > .cx-tabs-indicator{display:none;}
89
+ .cx-tabs--vertical{grid-template-columns:auto minmax(0,1fr);}
90
+ .cx-tabs--vertical > .cx-tablist{
91
+ flex-direction:column;
92
+ align-items:stretch;
93
+ grid-column:1;
94
+ grid-row:1 / span 3;
95
+ border-block-end:0;
96
+ border-inline-end:var(--hfx-border-width,1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));
97
+ }
98
+ .cx-tabs--vertical > .cx-tablist > .cx-tab{min-block-size:var(--hfx-control-height-md,calc(36px - var(--cx-compact,0) * 8px));justify-content:start;}
99
+ .cx-tabs--vertical .cx-tab-badge{margin-inline-start:auto;}
100
+ .cx-tabs--vertical > .cx-tablist > .cx-tab[aria-selected="true"]{background:var(--hfx-color-accent-subtle,light-dark(#e7f1f1,#1b3435));color:var(--hfx-color-accent-text,light-dark(#02726a,#37c9b8));}
101
+ .cx-tabs--vertical > .cx-tablist > .cx-tab[aria-selected="true"]::before{
102
+ content:'';
103
+ position:absolute;
104
+ inset-inline-start:0;
105
+ inset-block:var(--hfx-space-2,0.5rem);
106
+ inline-size:var(--hfx-indicator-width,2px);
107
+ background:var(--hfx-color-accent-indicator,light-dark(#11776f,#37c9b8));
108
+ }
109
+ .cx-tabs[data-overflow="wrap"] > .cx-tablist{flex-wrap:wrap;overflow:visible;}
110
+ .cx-tabs[data-overflow="menu"] > .cx-tablist{overflow:hidden;}
111
+ .cx-tabs-tools{display:flex;gap:var(--hfx-space-1,0.25rem);grid-column:2;grid-row:1;}
112
+ :is(.cx-tabs-scroll,.cx-tabs-play){
113
+ min-block-size:var(--hfx-control-height-sm,calc(28px - var(--cx-compact,0) * 4px));
114
+ padding:var(--hfx-space-1,0.25rem) var(--hfx-space-2,0.5rem);
115
+ border:0;
116
+ border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));
117
+ color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));
118
+ background:transparent;
119
+ font:inherit;
120
+ cursor:pointer;
121
+ }
122
+ :is(.cx-tabs-scroll,.cx-tabs-play):hover{background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));}
123
+ .cx-tabs-play{grid-column:2;display:inline-flex;align-items:center;gap:var(--hfx-space-2,0.5rem);border:var(--hfx-border-width,1px) solid var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
124
+ .cx-tabs-play::before{content:'\25b6' / '';}
125
+ .cx-tabs-play[data-state="playing"]::before{content:'\23f8' / '';}
126
+ .cx-tabs-play:disabled{color:var(--hfx-color-text-disabled,light-dark(#a3a8b0,#5a5f68));cursor:default;}
127
+ .cx-tabpanel{grid-column:1 / -1;min-inline-size:0;padding-block:var(--hfx-space-4,1rem);}
128
+ .cx-tabs--vertical > .cx-tabpanel{grid-column:2;grid-row:1 / span 3;padding-inline-start:var(--hfx-space-4,1rem);}
129
+ .cx-tabs[data-cx-ready] > .cx-tabpanel > .cx-tabpanel-heading{display:none;}
130
+ .cx-tabs-position{grid-column:1 / -1;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font-size:var(--hfx-type-caption-size,0.75rem);line-height:var(--hfx-type-caption-line,1.35);margin-block:var(--hfx-space-1,0.25rem);}
131
+ .cx-tabs-phone-picker{grid-column:1 / -1;inline-size:100%;}
132
+ .cx-tabs[data-phone="true"]{grid-template-columns:minmax(0,1fr);}
133
+ .cx-tabs[data-phone="true"] > .cx-tabs-tools{grid-column:1;grid-row:auto;justify-content:end;}
134
+ .cx-tabs[data-phone="true"] > .cx-tabpanel{grid-column:1;grid-row:auto;padding-inline:0;}
135
+ .cx-tabs[data-scroll-start="true"] > .cx-tablist{mask-image:linear-gradient(to right,transparent,currentColor var(--hfx-space-4,1rem),currentColor);}
136
+ .cx-tabs[data-scroll-end="true"] > .cx-tablist{mask-image:linear-gradient(to left,transparent,currentColor var(--hfx-space-4,1rem),currentColor);}
137
+ .cx-tabs:dir(rtl)[data-scroll-start="true"] > .cx-tablist{mask-image:linear-gradient(to left,transparent,currentColor var(--hfx-space-4,1rem),currentColor);}
138
+ .cx-tabs:dir(rtl)[data-scroll-end="true"] > .cx-tablist{mask-image:linear-gradient(to right,transparent,currentColor var(--hfx-space-4,1rem),currentColor);}
139
+ .cx-tabs[data-scroll-start="true"][data-scroll-end="true"] > .cx-tablist{mask-image:linear-gradient(to right,transparent,currentColor var(--hfx-space-4,1rem),currentColor calc(100% - var(--hfx-space-4,1rem)),transparent);}
140
+ @media (prefers-reduced-motion: reduce){.cx-tabs-indicator{transition:none;}}
141
+ @media (forced-colors: active){
142
+ .cx-tab[aria-selected="true"]{outline:var(--hfx-indicator-width,2px) solid currentColor;outline-offset:calc(-1 * var(--hfx-indicator-width,2px));}
143
+ .cx-tabs-indicator{background:currentColor;}
144
+ }
145
+ @media print{
146
+ .cx-tabs{display:block;}
147
+ .cx-tabs > :is(.cx-tablist,.cx-tabs-tools,.cx-tabs-phone-picker,.cx-tabs-position,.cx-tabs-play){display:none;}
148
+ .cx-tabs[data-print="all"] > .cx-tabpanel{display:block;}
149
+ .cx-tabs[data-print="selected"] > .cx-tabpanel[hidden]{display:none;}
150
+ .cx-tabs[data-cx-ready] > .cx-tabpanel > .cx-tabpanel-heading{display:block;}
151
+ .cx-tabpanel{break-inside:avoid;}
152
+ }
153
+ }
@@ -0,0 +1,47 @@
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"96b84956100933e7",requires:["ui-navigation"],install(context){if(installed.has(context.UI_IMPL))return;const{UI_IMPL,UI_TOOLS,h,setText,fill,watchTheme,overlayTheme,hostHtml}=context;UI_IMPL.tabs=(root,options={},signal)=>{const n=UI_TOOLS.navigation,life=n.scope(signal),labels=UI_TOOLS.labels(options.labels);const list=n.owned(root,'[role="tablist"]')[0];let items=[],current,layout,auto,destroyed=false;const style=options.style||['vertical','segmented','pills'].find(s=>root.classList.contains('cx-tabs--'+s))||'underline';for(const variant of['underline','pills','segmented','vertical'])root.classList.toggle('cx-tabs--'+variant,variant===style);root.classList.add('cx-tabs');const effectiveStyle=style==='segmented'&&n.owned(root,'[role="tab"]').length>5?'pills':style;if(effectiveStyle!==style){root.classList.replace('cx-tabs--segmented','cx-tabs--pills');if(options.debug===true)console.warn('[CanopyX] tabs: segmented supports 2–5 options; rendering as pills')}
2
+ root.dataset.overflow=options.overflow||root.dataset.overflow||'scroll';if(root.dataset.overflow==='wrap'&&effectiveStyle!=='pills')root.dataset.overflow='scroll';root.dataset.collapse=options.collapse||root.dataset.collapse||(effectiveStyle==='segmented'?'none':'picker');root.dataset.print=options.print||root.dataset.print||'all';root.dataset.transition=options.transition||'none';list?.setAttribute('aria-orientation',effectiveStyle==='vertical'?'vertical':'horizontal');const deferred=n.deferred(root,'tabs',options,life,id=>select(id));function render(){for(const item of items){const selected=item===current;item.element.setAttribute('aria-selected',String(selected));item.element.tabIndex=selected?0:-1;item.element.dataset.state=item.disabled?'disabled':selected?'selected':'';if(item.panel){item.panel.hidden=!selected;item.panel.dataset.state=selected?'selected':'';n.panelTabStop(item.panel)}}
3
+ layout?.update(items,current)}
4
+ const selection=n.selection(root,'tabs',options,life,()=>current,async(from,to,loadSignal,live)=>{if(from!==to)deferred.leave(from);current=to;render();if(options.hash&&root.id)writeHash(to.id);if(from!==to)UI_TOOLS.emit(root,'tabs','change',{from,to});const loaded=await deferred.load(to,loadSignal,live);if(live()&&loaded)animate(to,from);if(live())layout?.update(items,current)});function select(value,source='api'){if(destroyed)return Promise.resolve(false);if(source!=='auto'&&source!=='initial')auto?.stop();const target=n.resolve(items,value);if(!target||target.disabled){selection.cancel();return Promise.resolve(false)}
5
+ if(target===current&&!deferred.isDeferred(target)){selection.cancel();return Promise.resolve(true)}
6
+ return selection.request(target,undefined,source)}
7
+ function animate(to,from){if(!to.panel||root.dataset.transition==='none'||matchMedia('(prefers-reduced-motion: reduce)').matches)return;to.panel.getAnimations().forEach(animation=>animation.cancel());const css=getComputedStyle(root),slide=root.dataset.transition==='slide';const duration=css.getPropertyValue('--cx-tabs-motion-duration-' +(slide?'base':'fast')).trim();const ms=parseFloat(duration)*(duration.endsWith('ms')?1:1000);const distance=css.getPropertyValue('--cx-tabs-motion-distance').trim();const easing=css.getPropertyValue('--cx-tabs-motion-easing').trim();const sign=(to.index>=(from?.index??0)?1:-1)*(css.direction==='rtl'?-1:1);to.panel.animate([{opacity:0,transform:slide?'translateX(calc('+distance+' * '+sign+'))':'none'},{opacity:1,transform:'none'}],{duration:ms||0,easing})}
8
+ function hashId(){try{return new URLSearchParams(location.hash.slice(1)).get(root.id)}catch{return null}}
9
+ function writeHash(id){const params=new URLSearchParams(location.hash.slice(1));params.set(root.id,id);const hash='#'+params.toString();if(hash!==location.hash)history[options.hashHistory==='push'?'pushState':'replaceState'](null,'',hash)}
10
+ function refresh(){if(destroyed)return;selection.cancel();const id=current?.id;items=n.records(root,'tabs',options);current=items.find(item=>item.id===id&&!item.disabled)||items.find(item=>!item.disabled&&item.element.getAttribute('aria-selected')==='true')||items.find(item=>!item.disabled);render();auto?.reset()}
11
+ root.addEventListener('click',event=>{const tab=event.target.closest('[role="tab"]');if(tab&&items.some(item=>item.element===tab))select(tab.dataset.tabId,'user')},{signal:life.signal});list?.addEventListener('keydown',event=>{const index=items.findIndex(item=>item.element===event.target);if(index<0)return;const visible=items.filter(item=>!item.element.hidden),position=visible.indexOf(items[index]);const vertical=list.getAttribute('aria-orientation')==='vertical';const rtl=getComputedStyle(root).direction==='rtl';const forward=vertical?'ArrowDown':rtl?'ArrowLeft':'ArrowRight';const back=vertical?'ArrowUp':rtl?'ArrowRight':'ArrowLeft';let target;if(event.key===forward||event.key===back)target=visible[(position +(event.key===forward?1:-1)+ visible.length)%visible.length];if(event.key==='Home')target=visible[0];if(event.key==='End')target=visible[visible.length-1];if(target){event.preventDefault();items.forEach(item=>{item.element.tabIndex=item===target?0:-1});target.element.focus();target.element.scrollIntoView({block:'nearest',inline:'nearest'});const activation=options.activation||root.dataset.activation;const manual=activation==='manual'||activation!=='automatic'&&(options.beforeChange||items.some(deferred.isDeferred));if(!manual&&!target.disabled)select(target.id,'user')}else if(event.key==='Enter'||event.key===' '){event.preventDefault();select(items[index].id,'user')}},{signal:life.signal});list?.addEventListener('focusout',event=>{if(!list.contains(event.relatedTarget))items.forEach(item=>{item.element.tabIndex=item===current?0:-1})},{signal:life.signal});let touch;root.addEventListener('pointerdown',event=>{if(event.pointerType==='touch'&&root.dataset.phone==='true'&&event.target.closest('.cx-tabpanel')&&
12
+ !event.target.closest('a[href],button,input,select,textarea,[contenteditable="true"]')&&!getSelection()?.toString())touch={x:event.clientX,y:event.clientY,id:event.pointerId}},{signal:life.signal});root.addEventListener('pointerup',event=>{const start=touch;touch=null;if(!start||start.id!==event.pointerId)return;const dx=event.clientX-start.x,dy=event.clientY-start.y;if(Math.abs(dx)<48||Math.abs(dx)<=Math.abs(dy))return;const direction=(dx<0?1:-1)*(getComputedStyle(root).direction==='rtl'?-1:1);const target=items.slice().filter(item=>!item.disabled);const next=target[target.indexOf(current)+ direction];if(next)select(next.id,'user')},{signal:life.signal});root.addEventListener('pointercancel',()=>{touch=null},{signal:life.signal});if(options.hash)window.addEventListener('hashchange',()=>{const target=n.resolve(items,hashId());if(target&&target!==current)select(target.id,'hash')},{signal:life.signal});function destroy(){if(destroyed)return;destroyed=true;life.abort();auto?.destroy();layout?.destroy();deferred.destroy();root.removeAttribute('data-cx-ready');items.forEach(item=>{item.element.hidden=false;item.element.removeAttribute('aria-busy');if(item.panel){item.panel.hidden=false;item.panel.removeAttribute('aria-busy');item.panel.getAnimations().forEach(a=>a.cancel())}})}
13
+ refresh();layout=UI_TOOLS.tabsLayout(root,list,options,labels,life,id=>select(id,'user'));root.dataset.cxReady='true';render();const requested=options.hash&&n.resolve(items,hashId())||n.resolve(items,options.selectedIndex??options.selected);const initial=requested&&!requested.disabled?requested:current;if(options.hash&&root.id&&initial===current&&current)writeHash(current.id);const ready=select(initial?.id,'initial');auto=UI_TOOLS.tabsAuto(root,list,options,labels,life,()=>({items,current}),id=>select(id,'auto'),()=>selection.cancel(),ready);signal?.addEventListener('abort',destroy,{once:true});return{select,getSelected:()=>current?.id??null,refresh,preparePrint:()=>deferred.preparePrint(),destroy,ready}};UI_TOOLS.tabsLayout=(root,list,options,labels,life,select)=>{const n=UI_TOOLS.navigation;const phone=UI_TOOLS.picker(root,{lead:labels.tabsSection,items:[],selected:null,onSelect:select});phone.element.classList.add('cx-tabs-phone-picker');const position=h('div','cx-tabs-position');position.setAttribute('aria-live','polite');const tools=h('div','cx-tabs-tools');const previous=n.button(labels.tabsScrollPrevious,'cx-tabs-scroll cx-tabs-scroll--previous');const next=n.button(labels.tabsScrollNext,'cx-tabs-scroll cx-tabs-scroll--next');for(const el of[previous,next]){el.setAttribute('aria-label',el.textContent);el.setAttribute('aria-hidden','true');el.tabIndex=-1}
14
+ setText(previous,'‹');setText(next,'›');const more=UI_TOOLS.picker(root,{lead:'',items:[],selected:null,onSelect:select});more.element.classList.add('cx-tabs-more');tools.append(previous,next,more.element);list?.before(phone.element,position);list?.after(tools);const indicator=h('span','cx-tabs-indicator');indicator.setAttribute('aria-hidden','true');list?.append(indicator);let items=[],current,narrow=false,updating=false,frame;function scroll(direction){const rtl=getComputedStyle(root).direction==='rtl'?-1:1;list?.scrollBy({left:direction*list.clientWidth*rtl,behavior:matchMedia('(prefers-reduced-motion: reduce)').matches?'instant':'smooth'})}
15
+ previous.addEventListener('click',()=>scroll(-1),{signal:life.signal});next.addEventListener('click',()=>scroll(1),{signal:life.signal});function edges(){if(!list)return;const scrollable=root.dataset.overflow==='scroll'&&!narrow;const tabs=items.filter(item=>!item.element.hidden);const bounds=list.getBoundingClientRect(),rtl=getComputedStyle(root).direction==='rtl';const first=tabs[0]?.element.getBoundingClientRect(),last=tabs.at(-1)?.element.getBoundingClientRect();const before=!!first&&(rtl?first.right>bounds.right+1:first.left<bounds.left-1);const after=!!last&&(rtl?last.left<bounds.left-1:last.right>bounds.right+1);previous.hidden=!scrollable||!before;next.hidden=!scrollable||!after;root.dataset.scrollStart=String(scrollable&&before);root.dataset.scrollEnd=String(scrollable&&after)}
16
+ function update(nextItems=items,selected=current,reveal=false){if(updating||life.signal.aborted||!list)return;updating=true;items=nextItems;current=selected;const focus=document.activeElement,fromMore=UI_TOOLS.owns(more.element,focus);const fromList=list.contains(focus)||fromMore,fromPicker=UI_TOOLS.owns(phone.element,focus);const choiceId=fromMore||fromPicker?focus.closest('[data-item-id]')?.dataset.itemId:null;const focusedItem=items.find(item=>item.element.contains(focus)||item.id===choiceId);const model=n.pickerItems(items,current?.id);const measure=list.cloneNode(true);measure.hidden=false;measure.inert=true;measure.removeAttribute('id');measure.setAttribute('aria-hidden','true');measure.style.cssText='position:absolute;visibility:hidden;display:flex;flex-flow:row nowrap;inline-size:max-content;max-inline-size:none;';const measuredTabs=[...measure.querySelectorAll('[role="tab"]')];measuredTabs.forEach(tab=>{tab.hidden=false;tab.removeAttribute('id')});root.append(measure);const gap=parseFloat(getComputedStyle(list).gap)||0;const widths=measuredTabs.map(tab=>tab.getBoundingClientRect().width+gap);measure.remove();const total=Math.max(0,widths.reduce((sum,value)=>sum+value,0)- gap);const play=tools.querySelector('.cx-tabs-play');const available=Math.max(0,root.clientWidth -(play?play.getBoundingClientRect().width+gap:0));function measureMore(selected){more.update({lead:selected?fill(labels.tabsMoreSelected,{label:''}).trim():labels.tabsMore,items:model,selected:selected?.id??null});const clone=more.element.cloneNode(true);clone.hidden=false;clone.inert=true;clone.style.cssText='position:absolute;visibility:hidden;inline-size:max-content;';root.append(clone);const width=clone.getBoundingClientRect().width;clone.remove();return width}
17
+ let moreWidth=measureMore(null);const selectedEnd=widths.slice(0,items.indexOf(current)+ 1).reduce((sum,value)=>sum+value,0)- gap;if(root.dataset.overflow==='menu'&&total>available&&selectedEnd>available-moreWidth-gap)
18
+ moreWidth=measureMore(current);const minimum=root.dataset.overflow==='menu'&&items.length>3
19
+ ?Math.min(total,widths.slice(0,3).reduce((sum,value)=>sum+value,0)+ moreWidth):total;narrow=root.dataset.collapse==='picker'&&available<minimum +(narrow?8:0);root.dataset.phone=String(narrow);phone.update({lead:labels.tabsSection,items:model,selected:current?.id});phone.element.hidden=!narrow;position.hidden=!narrow;list.hidden=narrow;tools.hidden=narrow&&!tools.querySelector('.cx-tabs-play');setText(position,n.position(labels,'tabsPosition',current?.index??0,items.length));items.forEach(item=>{item.element.hidden=false});more.element.hidden=true;if(!narrow&&root.dataset.overflow==='menu'){if(widths.reduce((sum,value)=>sum+value,0)- gap>available){more.element.hidden=false;const budget=Math.max(0,available-moreWidth-gap);let used=0;const hidden=items.filter((item,index)=>{used +=widths[index];item.element.hidden=used-gap>budget;return item.element.hidden});const selectedHidden=hidden.includes(current);more.update({lead:selectedHidden?fill(labels.tabsMoreSelected,{label:''}).trim():labels.tabsMore,items:n.pickerItems(hidden,current?.id),selected:selectedHidden?current.id:null});more.element.dataset.state=selectedHidden?'selected':''}}
20
+ if(!narrow&&!current?.element.hidden&&root.dataset.overflow==='scroll'&&reveal){current?.element.scrollIntoView({block:'nearest',inline:'nearest'})}
21
+ if(!narrow&&current&&!current.element.hidden){const tab=current.element,css=getComputedStyle(tab);const inset=parseFloat(css.paddingInlineStart)||0;indicator.style.setProperty('--cx-tabs-indicator-size',Math.max(0,tab.offsetWidth-inset*2)+ 'px');indicator.style.setProperty('--cx-tabs-indicator-start',(getComputedStyle(root).direction==='rtl'
22
+ ?list.scrollWidth-tab.offsetLeft-tab.offsetWidth+inset:tab.offsetLeft+inset)+ 'px');indicator.hidden=false}else indicator.hidden=true;edges();updating=false;if((fromList||fromPicker)&&!focus.checkVisibility()){const choice=focusedItem||current;const target=narrow?phone.element.querySelector('button')
23
+ :choice&&!choice.element.hidden?choice.element
24
+ :!more.element.hidden?more.element.querySelector('button')
25
+ :items.find(item=>!item.element.hidden)?.element;target?.focus({preventScroll:true})}}
26
+ list?.addEventListener('scroll',edges,{signal:life.signal,passive:true});const resize=()=>{cancelAnimationFrame(frame);frame=requestAnimationFrame(()=>update())};UI_TOOLS.observe(root,resize,life.signal);document.fonts?.ready.then(()=>{if(!life.signal.aborted)resize()});document.fonts?.addEventListener('loadingdone',resize,{signal:life.signal});function destroy(){cancelAnimationFrame(frame);phone.destroy();more.destroy();phone.element.remove();position.remove();tools.remove();indicator.remove();if(list)list.hidden=false;for(const key of['phone','scrollStart','scrollEnd'])delete root.dataset[key]}
27
+ return{update:(nextItems,selected)=>update(nextItems,selected,selected!==current),destroy}};UI_TOOLS.tabsAuto=(root,list,options,labels,life,read,select,cancel,ready)=>{const config=options.autoProgress===undefined
28
+ ?root.dataset.autoProgressInterval===undefined?null:{interval:Number(root.dataset.autoProgressInterval),pauseOnHover:root.dataset.autoProgressPauseOnHover!=='false',pauseOnFocus:root.dataset.autoProgressPauseOnFocus!=='false'}:options.autoProgress;const idle={stop(){},reset(){},destroy(){}};if(!config||!Number.isFinite(config.interval)||config.interval<=0||life.signal.aborted)return idle;const n=UI_TOOLS.navigation,control=n.button(labels.tabsPause,'cx-tabs-play');const media=matchMedia('(prefers-reduced-motion: reduce)');let reduced=media.matches,paused=reduced,hovered=config.pauseOnHover!==false&&root.matches(':hover');let focused=config.pauseOnFocus!==false&&root.contains(document.activeElement);let started=false,pending=false,destroyed=false,generation=0;let elapsed=0,previous=null,frame=null;const tools=n.owned(root,'.cx-tabs-tools')[0];if(tools)tools.append(control);else list?.after(control);function paint(){const label=paused||media.matches?labels.tabsPlay:labels.tabsPause;if(control.textContent!==label)setText(control,label);if(control.getAttribute('aria-label')!==label)control.setAttribute('aria-label',label);control.dataset.state=paused||media.matches?'paused':'playing';control.disabled=media.matches;if(media.matches){control.setAttribute('title',labels.tabsMotionDisabled);control.setAttribute('aria-description',labels.tabsMotionDisabled)}else{control.removeAttribute('title');control.removeAttribute('aria-description')}}
29
+ function blocked(){return destroyed||life.signal.aborted||!started||paused||media.matches||hovered||focused||document.hidden||pending}
30
+ function schedule(){if(frame==null&&!blocked())frame=requestAnimationFrame(tick)}
31
+ function sync(){if(pending&&(hovered||focused||document.hidden))cancelPending();previous=null;if(blocked()){cancelAnimationFrame(frame);frame=null}
32
+ else schedule();paint()}
33
+ function cancelPending(){generation++;if(pending){pending=false;cancel()}}
34
+ async function advance(){const{items,current}=read(),enabled=items.filter(item=>!item.disabled);const next=enabled[(enabled.indexOf(current)+ 1)%enabled.length];if(!next||next===current){stop();return}
35
+ const ticket=++generation;pending=true;previous=null;let changed=false;try{changed=await select(next.id)}
36
+ finally{if(ticket===generation&&!destroyed&&!life.signal.aborted){pending=false;elapsed=0;if(!changed)paused=true;sync()}}}
37
+ function tick(now){frame=null;if(media.matches!==reduced){motionChanged();return}
38
+ if(blocked()){previous=null;return}
39
+ if(previous!=null)elapsed +=now-previous;previous=now;paint();if(elapsed>=config.interval){elapsed=0;void advance()}
40
+ else schedule()}
41
+ control.addEventListener('click',()=>{if(media.matches||destroyed)return;if(!paused)stop();else{paused=false;elapsed=0;sync()}},{signal:life.signal});if(config.pauseOnHover!==false){root.addEventListener('pointerenter',()=>{hovered=true;sync()},{signal:life.signal});root.addEventListener('pointerleave',()=>{hovered=false;sync()},{signal:life.signal})}
42
+ if(config.pauseOnFocus!==false){root.addEventListener('focusin',()=>{focused=true;sync()},{signal:life.signal});root.addEventListener('focusout',event=>{focused=root.contains(event.relatedTarget);sync()},{signal:life.signal})}
43
+ document.addEventListener('visibilitychange',sync,{signal:life.signal});function motionChanged(){if(media.matches===reduced)return;reduced=media.matches;if(reduced)stop();else sync()}
44
+ media.addEventListener('change',motionChanged,{signal:life.signal});function stop(){cancelPending();paused=true;elapsed=0;sync()}
45
+ function reset(){cancelPending();elapsed=0;sync()}
46
+ function destroy(){if(destroyed)return;destroyed=true;cancelPending();cancelAnimationFrame(frame);frame=null;control.remove()}
47
+ life.signal.addEventListener('abort',destroy,{once:true});Promise.resolve(ready).then(()=>{if(!destroyed&&!life.signal.aborted){started=true;sync()}},()=>{if(!destroyed&&!life.signal.aborted)stop()});paint();return{stop,reset,destroy}};installed.add(context.UI_IMPL)}};(global.CanopyXParts||=[]).push(["ui-tabs",part])})(typeof window!=="undefined"?window:globalThis);
@@ -0,0 +1,5 @@
1
+ .cx-show-as-fields{display:grid;gap:var(--hfx-space-3,0.75rem);padding:0;}
2
+ .cx-text-dialog pre:not([hidden]) + .cx-show-as-fields{margin-top:var(--hfx-space-3,0.75rem);}
3
+ .cx-show-as-field{display:grid;gap:var(--hfx-space-1-5,6px);min-width:0;}
4
+ .cx-show-as-field select{width:100%;min-width:0;max-width:100%;}
5
+ .cx-aggregate-caption{display:block;font-size:calc(var(--hfx-type-caption-size,0.75rem)*.9167);line-height:var(--hfx-type-caption-line-height,1.35);color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}