@evotecit/canopyx 0.3.16 → 0.3.18

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 (114) 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 +5 -24
  8. package/CanopyX.Html/Assets/canopyx-calendar.js +14 -19
  9. package/CanopyX.Html/Assets/canopyx-cell-range.js +16 -14
  10. package/CanopyX.Html/Assets/canopyx-changes.css +6 -24
  11. package/CanopyX.Html/Assets/canopyx-changes.js +18 -15
  12. package/CanopyX.Html/Assets/canopyx-compare.css +37 -0
  13. package/CanopyX.Html/Assets/canopyx-compare.js +12 -0
  14. package/CanopyX.Html/Assets/canopyx-data.js +3 -3
  15. package/CanopyX.Html/Assets/canopyx-editing.css +2 -2
  16. package/CanopyX.Html/Assets/canopyx-editing.js +2 -2
  17. package/CanopyX.Html/Assets/canopyx-enhance.js +4 -4
  18. package/CanopyX.Html/Assets/canopyx-export.js +54 -13
  19. package/CanopyX.Html/Assets/canopyx-facets.css +14 -5
  20. package/CanopyX.Html/Assets/canopyx-facets.js +19 -15
  21. package/CanopyX.Html/Assets/canopyx-filter-editor.css +71 -85
  22. package/CanopyX.Html/Assets/canopyx-filter-editor.js +20 -16
  23. package/CanopyX.Html/Assets/canopyx-flow-checks.css +1 -1
  24. package/CanopyX.Html/Assets/canopyx-flow-checks.js +1 -1
  25. package/CanopyX.Html/Assets/canopyx-flow-dialog.css +2 -2
  26. package/CanopyX.Html/Assets/canopyx-flow-dialog.js +1 -1
  27. package/CanopyX.Html/Assets/canopyx-flow-entry.css +136 -12
  28. package/CanopyX.Html/Assets/canopyx-flow-entry.js +2 -2
  29. package/CanopyX.Html/Assets/canopyx-flow-module.mjs +2 -2
  30. package/CanopyX.Html/Assets/canopyx-format-editor.js +2 -2
  31. package/CanopyX.Html/Assets/canopyx-formatting.js +10 -9
  32. package/CanopyX.Html/Assets/canopyx-grid-module.mjs +182 -128
  33. package/CanopyX.Html/Assets/canopyx-grid.css +228 -96
  34. package/CanopyX.Html/Assets/canopyx-grid.js +182 -128
  35. package/CanopyX.Html/Assets/canopyx-grouping.css +22 -15
  36. package/CanopyX.Html/Assets/canopyx-grouping.js +24 -17
  37. package/CanopyX.Html/Assets/canopyx-interactive.css +197 -74
  38. package/CanopyX.Html/Assets/canopyx-interactive.js +38 -45
  39. package/CanopyX.Html/Assets/canopyx-labels-de.js +177 -9
  40. package/CanopyX.Html/Assets/canopyx-labels-es.js +177 -9
  41. package/CanopyX.Html/Assets/canopyx-labels-fr.js +176 -8
  42. package/CanopyX.Html/Assets/canopyx-labels-it.js +176 -8
  43. package/CanopyX.Html/Assets/canopyx-labels-pl.js +176 -8
  44. package/CanopyX.Html/Assets/canopyx-layouts.css +48 -20
  45. package/CanopyX.Html/Assets/canopyx-layouts.js +36 -14
  46. package/CanopyX.Html/Assets/canopyx-link.js +2 -2
  47. package/CanopyX.Html/Assets/canopyx-live.css +1 -3
  48. package/CanopyX.Html/Assets/canopyx-live.js +3 -3
  49. package/CanopyX.Html/Assets/canopyx-matrix.css +1 -8
  50. package/CanopyX.Html/Assets/canopyx-matrix.js +11 -11
  51. package/CanopyX.Html/Assets/canopyx-module.mjs +38 -45
  52. package/CanopyX.Html/Assets/canopyx-office-export.js +2936 -0
  53. package/CanopyX.Html/Assets/canopyx-path.css +45 -0
  54. package/CanopyX.Html/Assets/canopyx-path.js +28 -0
  55. package/CanopyX.Html/Assets/canopyx-pivot.css +75 -0
  56. package/CanopyX.Html/Assets/canopyx-pivot.js +72 -0
  57. package/CanopyX.Html/Assets/canopyx-plan.css +56 -0
  58. package/CanopyX.Html/Assets/canopyx-plan.js +67 -0
  59. package/CanopyX.Html/Assets/canopyx-presenters.js +2 -2
  60. package/CanopyX.Html/Assets/canopyx-record-panel.css +8 -7
  61. package/CanopyX.Html/Assets/canopyx-record-panel.js +15 -14
  62. package/CanopyX.Html/Assets/canopyx-reporting-module.mjs +222 -161
  63. package/CanopyX.Html/Assets/canopyx-reporting.css +240 -107
  64. package/CanopyX.Html/Assets/canopyx-reporting.js +222 -161
  65. package/CanopyX.Html/Assets/canopyx-stack.css +35 -0
  66. package/CanopyX.Html/Assets/canopyx-stack.js +24 -0
  67. package/CanopyX.Html/Assets/canopyx-time-slider.css +18 -0
  68. package/CanopyX.Html/Assets/canopyx-time-slider.js +27 -0
  69. package/CanopyX.Html/Assets/canopyx-timeline.js +6 -5
  70. package/CanopyX.Html/Assets/canopyx-tree-tools.css +36 -35
  71. package/CanopyX.Html/Assets/canopyx-tree-tools.js +15 -12
  72. package/CanopyX.Html/Assets/canopyx-ui-menu.css +41 -0
  73. package/CanopyX.Html/Assets/canopyx-ui-menu.js +64 -0
  74. package/CanopyX.Html/Assets/canopyx-ui-navigation.css +73 -0
  75. package/CanopyX.Html/Assets/canopyx-ui-navigation.js +39 -0
  76. package/CanopyX.Html/Assets/canopyx-ui-overlays.css +79 -0
  77. package/CanopyX.Html/Assets/canopyx-ui-overlays.js +42 -0
  78. package/CanopyX.Html/Assets/canopyx-ui-picker.css +12 -0
  79. package/CanopyX.Html/Assets/canopyx-ui-picker.js +6 -0
  80. package/CanopyX.Html/Assets/canopyx-ui-stepper.css +174 -0
  81. package/CanopyX.Html/Assets/canopyx-ui-stepper.js +48 -0
  82. package/CanopyX.Html/Assets/canopyx-ui-tabs.css +153 -0
  83. package/CanopyX.Html/Assets/canopyx-ui-tabs.js +47 -0
  84. package/CanopyX.Html/Assets/canopyx-values.css +5 -0
  85. package/CanopyX.Html/Assets/canopyx-values.js +13 -0
  86. package/CanopyX.Html/Assets/canopyx-view-intents.css +12 -0
  87. package/CanopyX.Html/Assets/canopyx-view-intents.js +56 -0
  88. package/CanopyX.Html/Assets/canopyx.css +197 -71
  89. package/CanopyX.Html/Assets/canopyx.js +29 -19
  90. package/JavaScript/board.d.ts +30 -0
  91. package/JavaScript/changes.d.ts +4 -1
  92. package/JavaScript/facets.d.ts +5 -3
  93. package/JavaScript/grid.d.ts +150 -16
  94. package/JavaScript/hosts.d.ts +14 -1
  95. package/JavaScript/index.d.ts +4 -2
  96. package/JavaScript/locales/de.mjs +177 -9
  97. package/JavaScript/locales/es.mjs +177 -9
  98. package/JavaScript/locales/fr.mjs +176 -8
  99. package/JavaScript/locales/it.mjs +176 -8
  100. package/JavaScript/locales/pl.mjs +176 -8
  101. package/JavaScript/matrix.d.ts +4 -1
  102. package/JavaScript/path.d.ts +33 -0
  103. package/JavaScript/pivot.d.ts +135 -0
  104. package/JavaScript/plan.d.ts +23 -0
  105. package/JavaScript/protocol.d.ts +16 -3
  106. package/JavaScript/records.d.ts +2 -0
  107. package/JavaScript/stack.d.ts +28 -0
  108. package/JavaScript/time-slider.d.ts +58 -0
  109. package/JavaScript/ui.d.ts +261 -0
  110. package/JavaScript/view-intents.d.ts +45 -0
  111. package/README.md +22 -3
  112. package/ThirdParty/OfficeIMO/LICENSE +21 -0
  113. package/ThirdParty/OfficeIMO/README.md +13 -0
  114. package/package.json +76 -3
@@ -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,light-dark(#ffffff,#16181c));
55
+ color: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-muted,light-dark(#626770,#8f949d));
65
+ }
66
+ .cx-step[aria-current="step"]{color: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,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-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-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-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-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,light-dark(#ffffff,#16181c));
114
+ color: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-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:"89aeb7d73c4b8160",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-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,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,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-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-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-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,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-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:"96f562187c7e0732",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;}
@@ -0,0 +1,13 @@
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"0d7006b0f7bfca10",install(context){if(installed.has(context.GRID_SHOW_AS))return;const{DataGrid,GRID_SHOW_AS,GRID_SHOW_AS_MODES,h,setText,gridFreeze,reportingAggregateParts,reportingAggregateName,gridButton}=context;function showAsValues(values,mode,grand=null,parent=null,rowTotals,columnTotals){if(!Array.isArray(values)||values.length>10000||values.some(value=>value!==null&&!Number.isFinite(value))||!GRID_SHOW_AS_MODES.includes(mode)||
2
+ rowTotals&&rowTotals.length!==values.length||columnTotals&&columnTotals.length!==values.length)throw new Error("CanopyX: invalid aggregate display inputs.");const ranks=new Map();if(mode==="rank")values.filter(value=>value!==null).sort((a,b)=>b-a).forEach((value,index)=>{if(!ranks.has(value))ranks.set(value,index+1)});let running=0;return values.map((value,index)=>{if(value===null)return null;const divide=denominator=>denominator!==null&&denominator!==undefined&&denominator!==0?value / denominator : null;
3
+ let result;switch(mode){case "percentGrandTotal":result=divide(grand);break;case "percentParent":result=divide(parent);break;case "percentRow":result=divide(rowTotals?.[index]);break;case "percentColumn":result=divide(columnTotals?.[index]);break;case "runningTotal":running +=value;result=running;break;case "rank":result=ranks.get(value);break;case "difference":result=!index||values[index-1]===null?null:value-values[index-1];break;case "percentChange":result=!index||values[index-1]===null||values[index-1]===0?null:(value-values[index-1])/ values[index - 1]; break;
4
+ default:result=value}
5
+ return result===null||!Number.isFinite(result)?null:result})}
6
+ const showAsPercent=mode=>["percentGrandTotal","percentParent","percentRow","percentColumn","percentChange"].includes(mode);const showAsFormat=mode=>showAsPercent(mode)?"0.00%":mode==="rank"?"0":"0.00";Object.assign(GRID_SHOW_AS,{evaluate:showAsValues,percent:showAsPercent,numberFormat:showAsFormat});function showAsSummary(grid,summary){grid.aggregateDisplayCache||=new WeakMap();const cached=grid.aggregateDisplayCache.get(summary);if(cached)return cached;const aggregates=grid.view.reporting.aggregates||[],modes=grid.aggregateShowAs||{},byValues=new WeakMap();const modeOf=aggregate=>modes[aggregate.id]??aggregate.showAs??"value";const value=(number,mode)=>Object.freeze({value:number,mode,numberFormat:showAsFormat(mode)});const totals=Object.create(null),groups=Object.create(null);for(const aggregate of aggregates){const raw=summary.aggregates[aggregate.id],mode=modeOf(aggregate);totals[aggregate.id]=value(showAsValues([raw],mode,raw,raw)[0],mode)}
7
+ byValues.set(summary.aggregates,totals);const walk=(siblings,parent)=>{const display=siblings.map(()=>Object.create(null));for(const aggregate of aggregates){const mode=modeOf(aggregate),values=showAsValues(siblings.map(group=>group.aggregates[aggregate.id]),mode,summary.aggregates[aggregate.id],parent[aggregate.id]);values.forEach((number,index)=>{display[index][aggregate.id]=value(number,mode)})}
8
+ siblings.forEach((group,index)=>{groups[group.key]=display[index];byValues.set(group.aggregates,display[index]);walk(group.groups||[],group.aggregates)})};walk(summary.groups,summary.aggregates);const result=gridFreeze({totals,groups}),entry={result,byValues};grid.aggregateDisplayCache.set(summary,entry);return entry}
9
+ function showAsEntry(grid,values,aggregate){for(const summary of[grid.summary,grid.summaryCandidate?.result]){if(!summary)continue;const entry=showAsSummary(grid,summary).byValues.get(values)?.[aggregate.id];if(entry)return entry}
10
+ return{value:values[aggregate.id],mode:"value",numberFormat:"0.00"}}
11
+ Object.assign(GRID_SHOW_AS,{summary:showAsSummary,entry:showAsEntry});DataGrid.prototype.openAggregateMenu=function(column,aggregates,values,button,text){const controls=h("form","cx-show-as-fields"),choices=[];for(const aggregate of aggregates){const label=h("label","cx-show-as-field"),name=h("span"),select=h("select","cx-input");setText(name,reportingAggregateName(this,aggregate));select.setAttribute("aria-label",aggregate.label+": "+this.labels.gridShowAs);for(const mode of GRID_SHOW_AS_MODES.filter(mode=>!["percentRow","percentColumn"].includes(mode))){const option=h("option");option.value=mode;setText(option,this.labels["gridShowAs"+mode[0].toUpperCase()+ mode.slice(1)]);select.append(option)}
12
+ select.value=this.aggregateShowAs?.[aggregate.id]??aggregate.showAs??"value";choices.push([aggregate.id,select]);label.append(name,select);controls.append(label)}
13
+ const apply=gridButton(this.labels.gridApply,()=>{});apply.type="submit";apply.dataset.variant="primary";controls.append(apply);controls.addEventListener("submit",async event=>{event.preventDefault();for(const[id,select]of choices)await this.setAggregateShowAs(id,select.value);this.reportingText?._cxOverlay.close()});this.showReportingText(column,text??reportingAggregateParts(this,column,aggregates,values).title,button,undefined,false,controls)};installed.add(context.GRID_SHOW_AS)}};(global.CanopyXParts||=[]).push(["values",part])})(typeof window!=="undefined"?window:globalThis);
@@ -0,0 +1,12 @@
1
+ body .cx-host.cx-view-intent-preview{height:auto;min-width:0;margin-top:var(--hfx-space-3,0.75rem);padding:var(--hfx-space-3,0.75rem);border:var(--hfx-border-width,1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));}
2
+ .cx-view-intent-preview h3{margin:0 0 var(--hfx-space-2,0.5rem);font-size:inherit;font-weight:var(--hfx-weight-semibold,600);}
3
+ .cx-view-intent-preview .cx-grid-query-chips{display:flex;flex-wrap:wrap;gap:var(--hfx-space-1-5,6px);margin-bottom:var(--hfx-space-3,0.75rem);}
4
+ .cx-view-intent-preview .cx-grid-chip{display:inline-block;max-width:100%;height:auto;padding:var(--hfx-space-1,0.25rem) var(--hfx-space-2,0.5rem);border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));background:var(--hfx-color-accent-subtle,light-dark(#e7f1f1,#1b3435));white-space:normal;overflow-wrap:anywhere;}
5
+ .cx-view-intent-actions{display:flex;flex-wrap:wrap;gap:var(--hfx-space-2,0.5rem);}
6
+ .cx-view-intent-preview [role=status]{margin:var(--hfx-space-2,0.5rem) 0 0;overflow-wrap:anywhere;}
7
+ .cx-view-intent-preview [role=status]:empty{display:none;}
8
+ @media print{.cx-view-intent-preview{display:none !important;}}
9
+ @media (forced-colors:active){
10
+ .cx-view-intent-preview .cx-grid-chip{border:var(--hfx-border-width,1px) solid CanvasText;}
11
+ .cx-view-intent-actions [data-variant="primary"]{background:Highlight;color:HighlightText;border:var(--hfx-border-width,1px) solid Highlight;forced-color-adjust:none;}
12
+ }