@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
@@ -1,39 +1,46 @@
1
1
  /* ---------- row grouping: the group-by bar,headings and the totals row ---------- */
2
- .cx-groupbar{flex:none;display:flex;align-items:center;flex-wrap:wrap;gap:var(--cx-size-8px);padding:var(--cx-size-6px) var(--cx-size-12px);border-bottom:var(--cx-size-1px) solid var(--hfx-color-border,light-dark(#e2e4e7,#272a30));background:var(--hfx-color-row-alt,light-dark(#fafafa,#1d1f23));font-size:var(--cx-size-13px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));min-height:var(--cx-size-38px);}
3
- .cx-gchip{display:inline-flex;align-items:center;gap:var(--cx-size-6px);height:var(--cx-size-26px);padding:0 var(--cx-size-6px);border:var(--cx-size-1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));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));}
4
- .cx-data-grid .cx-gchip .cx-button{width:var(--cx-size-18px);min-height:var(--cx-size-18px);height:var(--cx-size-18px);padding:0;}
2
+ .cx-groupbar{flex:none;display:flex;align-items:center;flex-wrap:wrap;gap:var(--hfx-space-2,0.5rem);padding:var(--hfx-space-1-5,6px) var(--hfx-space-3,0.75rem);border-bottom:var(--hfx-border-width,1px) solid var(--hfx-color-surface-line,var(--hfx-color-border,light-dark(#e2e4e7,#272a30)));background:var(--hfx-color-row-alt,light-dark(#fafafa,#1d1f23));font-size:var(--hfx-type-small-size,0.8125rem);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));min-height:calc(var(--hfx-space-1,0.25rem)*9.5);}
3
+ .cx-gchip{display:inline-flex;align-items:center;gap:var(--hfx-space-1-5,6px);height:calc(var(--hfx-space-1,0.25rem)*6.5);padding:0 var(--hfx-space-1-5,6px);border:var(--hfx-border-width,1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));border-radius:var(--hfx-radius-control,var(--hfx-radius-md,6px));background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));}
4
+ .cx-data-grid .cx-gchip .cx-button{width:calc(var(--hfx-space-1,0.25rem)*4.5);min-height:calc(var(--hfx-space-1,0.25rem)*4.5);height:calc(var(--hfx-space-1,0.25rem)*4.5);padding:0;}
5
5
  .cx-data-grid .cx-grid-group{background:var(--hfx-color-row-alt,light-dark(#fafafa,#1d1f23));font-weight:700;}
6
- .cx-grid-group-toggle{flex:0 0 auto;padding:0;margin-right:var(--cx-size-6px);border:0;background:transparent;color:inherit;font:inherit;cursor:pointer;}
6
+ .cx-grid-group-toggle{flex:0 0 auto;padding:0;margin-right:var(--hfx-space-1-5,6px);border:0;background:transparent;color:inherit;font:inherit;cursor:pointer;}
7
7
  .cx-grid-group-toggle:focus-visible{outline:var(--hfx-focus-width,2px) solid var(--hfx-color-focus-ring,light-dark(#02726a,#37c9b8));outline-offset:var(--hfx-focus-offset,2px);}
8
8
  .cx-data-grid .cx-grid-group .cx-cell:first-child{overflow:visible;z-index:3;}
9
9
  .cx-grid-group-label{flex:none;display:flex;align-items:center;min-width:0;overflow:hidden;white-space:nowrap;}
10
10
  .cx-grid-group-text{flex:0 0 auto;max-width:100%;overflow:hidden;text-overflow:ellipsis;}
11
- .cx-grid-group-count{flex:none;margin-left:var(--cx-size-8px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-size:var(--cx-size-12px);font-weight:400;}
11
+ .cx-grid-group-count{flex:none;margin-left:var(--hfx-space-2,0.5rem);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font-size:var(--hfx-type-caption-size,0.75rem);font-weight:400;}
12
12
  .cx-data-grid .cx-grid-group .cx-cell{background:var(--hfx-color-row-alt,light-dark(#fafafa,#1d1f23));}
13
- .cx-data-grid .cx-grid-summary{position:sticky;bottom:0;z-index:4;background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));border-top:var(--cx-size-1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));font:inherit;}
13
+ .cx-data-grid .cx-grid-summary{position:sticky;bottom:0;z-index:4;background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));border-top:var(--hfx-border-width,1px) solid var(--hfx-color-border-strong,light-dark(#cdd0d5,#363a42));font:inherit;}
14
14
  .cx-summary-row{display:flex;height:var(--hfx-table-header-height,calc(40px - var(--cx-compact,0) * 8px));font-weight:700;}
15
15
  .cx-data-grid .cx-summary-row .cx-cell[data-cx-pin]{background:var(--hfx-color-surface-sunken,light-dark(#f7f8f9,#111317));}
16
- .cx-summary-row .cx-summary-caption{font-size:var(--cx-size-11d5px);letter-spacing:var(--cx-size-d04em);text-transform:uppercase;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));}
16
+ .cx-summary-row .cx-summary-caption{font:inherit;letter-spacing:normal;text-transform:none;color:inherit;}
17
17
  .cx-groupbar-label{flex:none;}
18
18
  .cx-groupbar-hint{font-style:italic;}
19
19
  .cx-groupbar-spacer{flex:1 1 auto;}
20
- .cx-groupbar.cx-group-drop{outline:var(--cx-size-2px) dashed var(--hfx-color-accent,light-dark(#11776f,#37c9b8));outline-offset:var(--hfx-focus-offset,2px);}
21
- .cx-data-grid .cx-groupbar .cx-groupbar-all{min-height:var(--cx-size-26px);height:var(--cx-size-26px);padding:0 var(--cx-size-8px);font-size:var(--cx-size-12px);}
20
+ .cx-groupbar.cx-group-drop{outline:calc(var(--hfx-border-width,1px)*2) dashed var(--hfx-color-accent,light-dark(#11776f,#37c9b8));outline-offset:var(--hfx-focus-offset,2px);}
21
+ .cx-data-grid .cx-groupbar .cx-groupbar-all{min-height:calc(var(--hfx-space-1,0.25rem)*6.5);height:calc(var(--hfx-space-1,0.25rem)*6.5);padding:0 var(--hfx-space-2,0.5rem);font-size:var(--hfx-type-caption-size,0.75rem);}
22
22
  .cx-gchip-name{cursor:grab;touch-action:none;white-space:nowrap;}
23
23
  .cx-data-grid .cx-gchip .cx-gchip-fold{font-weight:700;line-height:1;}
24
- .cx-gchip-order{height:var(--cx-size-20px);max-width:var(--cx-size-140px);border:var(--cx-size-1px) solid var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));border-radius:var(--hfx-radius-sm,4px);background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));font:inherit;font-size:var(--cx-size-12px);}
24
+ .cx-gchip-order{height:calc(var(--hfx-space-1,0.25rem)*5);max-width:140px;border:var(--hfx-border-width,1px) solid var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));border-radius:var(--hfx-radius-sm,4px);background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));font:inherit;font-size:var(--hfx-type-caption-size,0.75rem);}
25
25
  .cx-gchip:focus-within{border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));}
26
- .cx-data-grid .cx-grid-group .cx-cell:first-child{padding-inline-start:calc(var(--hfx-cell-padding-x,calc(12px - var(--cx-compact,0) * 4px)) + var(--cx-group-level,0) * var(--cx-size-16px));}
27
- .cx-grid-group-column{color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-weight:400;}
28
- .cx-grid-group-select{margin-inline-end:var(--cx-size-6px);}
26
+ .cx-data-grid .cx-grid-group .cx-cell:first-child{padding-inline-start:calc(var(--hfx-cell-padding-x,calc(12px - var(--cx-compact,0) * 4px)) + var(--cx-group-level,0) * var(--hfx-space-4,1rem));}
27
+ .cx-grid-group-column{color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font-weight:400;}
28
+ .cx-grid-group-select{margin-inline-end:var(--hfx-space-1-5,6px);}
29
29
  .cx-aggregate{font-variant-numeric:tabular-nums;}
30
30
  .cx-aggregate:not(:first-child){overflow:hidden;text-overflow:clip;}
31
- .cx-grid-group-aggregates{flex:0 1000 auto;min-width:0;margin-inline-start:var(--cx-size-12px);overflow:hidden;text-overflow:ellipsis;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font:inherit;font-weight:400;font-variant-numeric:tabular-nums;border:0;background:transparent;padding:0;cursor:pointer;white-space:nowrap;}
31
+ .cx-grid-group-aggregates{flex:0 1000 auto;min-width:0;margin-inline-start:var(--hfx-space-3,0.75rem);overflow:hidden;text-overflow:ellipsis;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font:inherit;font-weight:400;font-variant-numeric:tabular-nums;border:0;background:transparent;padding:0;cursor:pointer;white-space:nowrap;}
32
32
  .cx-grid-group-aggregates:focus-visible{outline:var(--hfx-focus-width,2px) solid var(--hfx-color-focus-ring,light-dark(#02726a,#37c9b8));outline-offset:var(--hfx-focus-offset,2px);}
33
- .cx-summary-row .cx-grid-group-aggregates{text-transform:none;letter-spacing:normal;font-size:var(--cx-size-13px);}
33
+ .cx-summary-row .cx-grid-group-aggregates{text-transform:none;letter-spacing:normal;font-size:var(--hfx-type-small-size,0.8125rem);}
34
34
  .cx-aggregate > .cx-aggregate-button{max-width:100%;margin-inline-start:0;font:inherit;color:inherit;flex:0 1 auto;text-align:left;}
35
- .cx-phone .cx-groupbar{padding:var(--cx-size-4px) var(--cx-size-8px);gap:var(--cx-size-6px);}
35
+ .cx-phone .cx-groupbar{padding:var(--hfx-space-1,0.25rem) var(--hfx-space-2,0.5rem);gap:var(--hfx-space-1-5,6px);}
36
36
  .cx-phone .cx-gchip{max-width:100%;}
37
37
  .cx-phone .cx-gchip-name{min-width:0;overflow:hidden;text-overflow:ellipsis;}
38
38
  .cx-phone :is(.cx-groupbar-label,.cx-gchip-order,.cx-gchip-fold){display:none;}
39
39
  @media (forced-colors:active){.cx-gchip{border-color:CanvasText;}}
40
+ .cx-gchip-bucket-value{width:calc(var(--hfx-space-4,1rem)*7);min-width:calc(var(--hfx-space-4,1rem)*3);max-width:calc(var(--hfx-space-4,1rem)*10);padding:var(--hfx-space-0-5,2px) var(--hfx-space-1,0.25rem);font:inherit;}
41
+ .cx-phone .cx-gchip-bucket{display:inline-block;max-width:calc(var(--hfx-space-4,1rem)*6);}
42
+ .cx-phone .cx-gchip-bucket-value{width:calc(var(--hfx-space-4,1rem)*3.5);min-width:calc(var(--hfx-space-4,1rem)*2);}
43
+ .cx-phone .cx-gchip:has(.cx-gchip-bucket) .cx-gchip-name{max-width:calc(var(--hfx-space-4,1rem)*3.5);}
44
+ .cx-groupbar .cx-gchip{height:calc(var(--hfx-control-height-sm,calc(28px - var(--cx-compact,0) * 4px)) + var(--hfx-border-width,1px)*2);}
45
+ .cx-groupbar .cx-gchip-order,.cx-data-grid .cx-groupbar .cx-gchip .cx-button,.cx-data-grid .cx-groupbar .cx-groupbar-all{height:var(--hfx-control-height-sm,calc(28px - var(--cx-compact,0) * 4px));min-height:var(--hfx-control-height-sm,calc(28px - var(--cx-compact,0) * 4px));}
46
+ .cx-data-grid .cx-groupbar .cx-gchip .cx-button{width:var(--hfx-control-height-sm,calc(28px - var(--cx-compact,0) * 4px));}
@@ -1,4 +1,4 @@
1
- (function(global){"use strict";const installed=new WeakSet();const part={version:"eedafc8438ac1b2b",requires:["detail-rows"],install(context){if(installed.has(context.DataGrid.prototype))return;const{DataGrid,GRID_ROWS,GRID_REPORTING,GRID_OPTIONS,GRID_OPTION_GRIDS,h,setText,fill,numberFormat,formatValue,cellValue,cellText,isCellObject,gridScalar,gridQuery,gridFreeze,gridOrder,gridIdOrder,gridQueryRows,gridButton,gridDecorateButton,gridCellRenderer,gridPresenterTone,GRID_TONE_RANK,validateGridRows,validateGridPage,checkDocument,requireIdentifier,validStructuralCount,PROTOCOL,gridOperationActive,reportingGroupKey,reportingGroupCompare,reportingSummaryEnabled,reportingDynamicGroups,GROUP_OPERATIONS,reportingAggregateParts,disposeRowHostCells,quietControls,TreeGrid}=context;const groupCounting=operation=>operation==="count"||operation==="distinctCount";function groupSummaryAggregates(view){const bindings=new Map();const add=aggregate=>{const existing=bindings.get(aggregate.id);if(existing&&(existing.column!==aggregate.column||existing.operation!==aggregate.operation))
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"c82705991ff01a4c",requires:["detail-rows"],install(context){if(installed.has(context.DataGrid.prototype))return;const{DataGrid,GRID_ROWS,GRID_REPORTING,GRID_OPTIONS,GRID_OPTION_GRIDS,h,setText,fill,numberFormat,formatValue,cellValue,cellText,isCellObject,gridScalar,gridQuery,gridFreeze,gridOrder,gridIdOrder,gridQueryRows,gridButton,gridDecorateButton,gridCellRenderer,gridPresenterTone,GRID_TONE_RANK,validateGridRows,validateGridPage,checkDocument,requireIdentifier,validStructuralCount,PROTOCOL,gridOperationActive,reportingGroupKey,reportingGroupCompare,reportingSummaryEnabled,reportingDynamicGroups,GROUP_OPERATIONS,reportingAggregateParts,disposeRowHostCells,quietControls,TreeGrid,GRID_BUCKETS,gridBucketDefinition}=context;const groupCounting=operation=>operation==="count"||operation==="distinctCount";function groupSummaryAggregates(view){const bindings=new Map();const add=aggregate=>{const existing=bindings.get(aggregate.id);if(existing&&(existing.column!==aggregate.column||existing.operation!==aggregate.operation))
2
2
  throw new Error("CanopyX: an aggregate identity must use the same column and operation.");if(!existing)bindings.set(aggregate.id,aggregate)};for(const aggregate of view.reporting?.aggregates||[])add(aggregate);for(const footer of view.footers||[])if(footer.scope==="all"||view.presentation!=="paged")
3
3
  footer.aggregates.forEach(add);if(bindings.size>32)throw new Error("CanopyX: at most 32 full-query aggregates are supported.");return[...bindings.values()]}
4
4
  function groupCustomAggregates(grid){const found=new Map();for(const plugin of grid.plugins)for(const[name,entry]of Object.entries(plugin.aggregates||{})){const definition=typeof entry==="function"?{compute:entry}:entry;if(!/^[a-z][a-zA-Z\d]{0,31}$/.test(name) || GROUP_OPERATIONS.includes(name) || !definition || typeof definition.compute !== "function" ||
@@ -13,37 +13,40 @@ return operation==="count"?count:distinct?distinct.size:!count?null:
13
13
  operation==="sum"?sum+correction:operation==="average"?(sum+correction)/ count : operation === "minimum" ? minimum : maximum;
14
14
  }
15
15
  function groupAggregateValues(grid,rows,first=0,last=rows.length){const values=Object.create(null);for(const aggregate of groupSummaryAggregates(grid.view))values[aggregate.id]=groupAggregateValue(grid,aggregate,rows,first,last);return values}
16
- function groupCheckValues(view,values,count){const declarations=groupSummaryAggregates(view);if(!values||typeof values!=="object"||Array.isArray(values)||Object.keys(values).length!==declarations.length)
16
+ GRID_ROWS.aggregateValue=groupAggregateValue;function groupCheckValues(view,values,count){const declarations=groupSummaryAggregates(view);if(!values||typeof values!=="object"||Array.isArray(values)||Object.keys(values).length!==declarations.length)
17
17
  throw new Error("CanopyX: summary aggregate bindings differ.");for(const aggregate of declarations){const value=values[aggregate.id];if(!Object.hasOwn(values,aggregate.id)||value!==null&&(typeof value!=="number"||!Number.isFinite(value)||Math.abs(value)>Number.MAX_SAFE_INTEGER)||
18
18
  groupCounting(aggregate.operation)&&(!validStructuralCount(value)||value>count)||
19
19
  !count&&!groupCounting(aggregate.operation)&&value!==null)throw new Error("CanopyX: invalid aggregate value.")}}
20
20
  const GROUP_MEASURE=DataGrid.prototype.measureGridColumn;Object.assign(DataGrid.prototype,{measureGridColumn(column){const result=GROUP_MEASURE.call(this,column),summary=this.summaryCandidate?.result||this.summary;const aggregates=this.rowsAttached&&summary&&!column.fixed&&(this.view.reporting.aggregates||[]).filter(item=>item.column===column.id);if(!aggregates?.length||!this.fitContext)return result;const context=this.fitContext,pad=this.fitFont[3];let widest=0,seen=0;context.font=this.fitFont[0].replace(/^\S+/, "700");
21
21
  const measure=values=>{widest=Math.max(widest,context.measureText(reportingAggregateParts(this,column,aggregates,values).text).width)};measure(summary.aggregates);const walk=list=>{for(const group of list||[]){if(++seen>200)return;measure(group.aggregates);walk(group.groups)}};walk(summary.groups);const need=Math.min(Math.max(420,result.width),Math.ceil(widest+2*pad+4));return need>result.width?Object.freeze({...result,width:need}):result},paintAggregates(cell,column,aggregates,values){const parts=reportingAggregateParts(this,column,aggregates,values);cell.title=parts.title;cell.classList.add("cx-aggregate");if(parts.text)cell.setAttribute("aria-label",parts.title);else cell.removeAttribute("aria-label");if(!parts.text){cell.replaceChildren();return}
22
- let button=cell.querySelector(":scope > .cx-aggregate-button");if(!button){button=h("button","cx-grid-group-aggregates cx-aggregate-button");button.type="button";button.setAttribute("aria-haspopup","dialog");cell.replaceChildren(button);button.addEventListener("click",event=>{event.stopPropagation();this.showReportingText(column,button._cxAggregateText,button)})}
23
- if(button.textContent!==parts.text)setText(button,parts.text);button._cxAggregateText=parts.title;button.title=parts.title;button.setAttribute("aria-label",parts.title)}});function groupLevelsOf(view,query){const grouping=view.reporting?.grouping;return grouping?[{column:grouping.column,direction:grouping.direction}]:query?.groupBy||[]}
24
- function groupOrder(view,level){const column=view.columns.find(item=>item.id===level.column),compare=reportingGroupCompare(GRID_REPORTING.compare(view));const byValue=(a,b,direction)=>compare({cells:{[column.id]:a.value}},{cells:{[column.id]:b.value}},column,direction);if(!level.aggregate)return(a,b)=>byValue(a,b,level.direction);return(a,b)=>{const x=a.aggregates[level.aggregate],y=b.aggregates[level.aggregate];if(x===null||y===null)return x===y?byValue(a,b,"asc"):x===null?1:-1;return(level.direction==="desc"?gridOrder(y,x):gridOrder(x,y))||byValue(a,b,"asc")}}
22
+ let button=cell.querySelector(":scope > .cx-aggregate-button");if(!button){button=h("button","cx-grid-group-aggregates cx-aggregate-button");button.type="button";button.setAttribute("aria-haspopup","dialog");cell.replaceChildren(button);button.addEventListener("click",event=>{event.stopPropagation();this.showAggregateMenu(column,aggregates,button._cxAggregateValues,button).catch(error=>this.emit("error",{error}))})}
23
+ if(button.textContent!==parts.text +(parts.caption||"")){setText(button,parts.text);if(parts.caption){const caption=h("span","cx-aggregate-caption");setText(caption,parts.caption);button.append(caption)}}
24
+ button._cxAggregateValues=values;button._cxAggregateText=parts.title;button.title=parts.title;button.setAttribute("aria-label",parts.title)}});function groupLevelsOf(view,query){const grouping=view.reporting?.grouping;return grouping?[{column:grouping.column,direction:grouping.direction}]:query?.groupBy||[]}
25
+ function groupOrder(view,level){const column=view.columns.find(item=>item.id===level.column),compare=reportingGroupCompare(GRID_REPORTING.compare(view));const byValue=(a,b,direction)=>level.bucket?a.value===null||b.value===null?a.value===b.value?0:a.value===null?1:-1:
26
+ direction==="desc"?gridOrder(b.value,a.value):gridOrder(a.value,b.value):compare({cells:{[column.id]:a.value}},{cells:{[column.id]:b.value}},column,direction);if(!level.aggregate)return(a,b)=>byValue(a,b,level.direction);return(a,b)=>{const x=a.aggregates[level.aggregate],y=b.aggregates[level.aggregate];if(x===null||y===null)return x===y?byValue(a,b,"asc"):x===null?1:-1;return(level.direction==="desc"?gridOrder(y,x):gridOrder(x,y))||byValue(a,b,"asc")}}
25
27
  function groupSummaryResult(grid,query,page,summary){const view=grid.view;checkDocument(summary,"gridSummary");if(JSON.stringify(summary).length>4194304||summary.view!==view.id||summary.revision!==page.revision||summary.matched!==page.matched||
26
28
  !Array.isArray(summary.groups)||!summary.query||
27
29
  !["protocol","type","view","offset","limit","sort","filters","search","revision"].every(key=>Object.hasOwn(summary.query,key))||
28
30
  summary.query.type!=="gridQuery"||summary.query.protocol!==PROTOCOL||summary.query.revision!==page.revision||summary.query.offset!==0||
29
31
  JSON.stringify(gridQuery(view,summary.query))!==JSON.stringify(query))throw new Error("CanopyX: summary ownership or counts differ.");groupCheckValues(view,summary.aggregates,summary.matched);const levels=groupLevelsOf(view,query),keys=new Set();if(!levels.length&&summary.groups.length)throw new Error("CanopyX: an ungrouped summary has no groups.");const check=(groups,depth,start,count)=>{const level=levels[depth],column=view.columns.find(item=>item.id===level.column),order=groupOrder(view,level),values=new Set();let offset=start,previous=null;for(const group of groups){if(!group||typeof group!=="object"||!Object.hasOwn(group,"value")||
30
- group.value!==null&&typeof group.value==="object")throw new Error("CanopyX: groups carry raw values.");requireIdentifier(group.key,"group key");const value=reportingGroupKey(gridScalar(group.value,column));if(group.cells!==undefined)validateGridRows([{id:group.key,cells:group.cells}],view.columns);if(keys.size>=10000||group.key.length>4096||keys.has(group.key)||values.has(value)||group.offset!==offset||
32
+ group.value!==null&&typeof group.value==="object")throw new Error("CanopyX: groups carry raw values.");requireIdentifier(group.key,"group key");const value=reportingGroupKey(gridScalar(group.value,level.bucket?{...column,kind:"number"}:column));if(group.cells!==undefined)validateGridRows([{id:group.key,cells:group.cells}],view.columns);if(keys.size>=10000||group.key.length>4096||keys.has(group.key)||values.has(value)||group.offset!==offset||
31
33
  !validStructuralCount(group.count)||!group.count)throw new Error("CanopyX: invalid complete group range.");groupCheckValues(view,group.aggregates,group.count);if(previous&&order(previous,group)>=0)throw new Error("CanopyX: groups do not follow their level's order.");keys.add(group.key);values.add(value);previous=group;if(depth+1<levels.length){if(!Array.isArray(group.groups)||!group.groups.length)throw new Error("CanopyX: a group of an outer level lists its inner groups.");check(group.groups,depth+1,group.offset,group.count)}else if(group.groups!==undefined)throw new Error("CanopyX: a group of the innermost level has no inner groups.");offset +=group.count}
32
34
  if(offset!==start+count)throw new Error("CanopyX: groups omit matching records.")};if(levels.length)check(summary.groups,0,0,summary.matched);return gridFreeze(JSON.parse(JSON.stringify(summary)))}
33
35
  function groupPath(summary,ordinal){const path=[];for(let list=summary.groups;list?.length;){let low=0,high=list.length;while(low<high){const middle=(low+high)>>>1;if(list[middle].offset<=ordinal)low=middle+1;else high=middle}
34
36
  const group=low?list[low-1]:null;if(!group||ordinal>=group.offset+group.count)break;path.push(group);list=group.groups}
35
37
  return path}
36
- const GROUP_GRIDS=new WeakMap();GRID_ROWS.order=(view,query)=>{const grid=GROUP_GRIDS.get(view),columns=new Map(view.columns.map(column=>[column.id,column])),levels=query.groupBy;const baseCompare=GRID_REPORTING.compare(view),compare=GRID_OPTION_GRIDS.has(view)?GRID_OPTIONS.compare(view,query,columns,baseCompare):baseCompare;const rest=query.sort.filter(sort=>!levels.some(level=>level.column===sort.column));const within=(a,b)=>{for(const sort of rest){const result=compare(a,b,columns.get(sort.column),sort.direction);if(result)return result}return gridIdOrder(a.id,b.id)};const arrange=(rows,depth)=>{if(depth===levels.length)return rows.sort(within);const level=levels[depth],column=columns.get(level.column),buckets=new Map();for(const row of rows){const key=reportingGroupKey(gridScalar(row.cells[column.id],column));if(!buckets.has(key))buckets.set(key,[]);buckets.get(key).push(row)}
37
- const groups=[...buckets.values()].map(list=>({list,value:cellValue(list[0].cells[column.id])??null,aggregates:level.aggregate?{[level.aggregate]:groupAggregateValue(grid,view.reporting.aggregates.find(item=>item.id===level.aggregate),list,0,list.length)}:{}}));groups.sort(groupOrder(view,level));return groups.flatMap(group=>arrange(group.list,depth+1))};return arrange(gridQueryRows(view,query,columns,null),0)};GRID_OPTIONS.groupRows=GRID_ROWS.order;function groupInnerKey(parent,key){const text=parent+"\u001f"+key;if(text.length<=4096)return text;let a=0x811c9dc5,b=0x01000193;for(let i=0;i<text.length;i++){const code=text.charCodeAt(i);a=Math.imul(a^code,16777619);b=Math.imul(b^code,2246822519)^(b>>>13)}
38
+ const GROUP_GRIDS=new WeakMap();GRID_ROWS.order=(view,query)=>{const grid=GROUP_GRIDS.get(view),columns=new Map(view.columns.map(column=>[column.id,column])),levels=query.groupBy;const baseCompare=GRID_REPORTING.compare(view),compare=GRID_OPTION_GRIDS.has(view)?GRID_OPTIONS.compare(view,query,columns,baseCompare):baseCompare;const rest=query.sort.filter(sort=>!levels.some(level=>level.column===sort.column));const within=(a,b)=>{for(const sort of rest){const result=compare(a,b,columns.get(sort.column),sort.direction);if(result)return result}return gridIdOrder(a.id,b.id)};const arrange=(rows,depth)=>{if(depth===levels.length)return rows.sort(within);const level=levels[depth],column=columns.get(level.column),buckets=new Map();for(const row of rows){const key=reportingGroupKey(groupBucketValue(level,column,row.cells[column.id]));if(!buckets.has(key))buckets.set(key,[]);buckets.get(key).push(row)}
39
+ const groups=[...buckets.values()].map(list=>({list,value:groupBucketValue(level,column,list[0].cells[column.id]),aggregates:level.aggregate?{[level.aggregate]:groupAggregateValue(grid,view.reporting.aggregates.find(item=>item.id===level.aggregate),list,0,list.length)}:{}}));groups.sort(groupOrder(view,level));return groups.flatMap(group=>arrange(group.list,depth+1))};return arrange(gridQueryRows(view,query,columns,null),0)};GRID_OPTIONS.groupRows=GRID_ROWS.order;function groupInnerKey(parent,key){const text=parent+"\u001f"+key;if(text.length<=4096)return text;let a=0x811c9dc5,b=0x01000193;for(let i=0;i<text.length;i++){const code=text.charCodeAt(i);a=Math.imul(a^code,16777619);b=Math.imul(b^code,2246822519)^(b>>>13)}
38
40
  return "#" +(a>>>0).toString(36)+(b>>>0).toString(36)+ ":"+text.length}
39
- function groupInlineSummary(grid,query){const view=grid.view,columns=new Map(view.columns.map(column=>[column.id,column])),levels=groupLevelsOf(view,query);const rows=query.groupBy?.length?GRID_ROWS.order(view,query):gridQueryRows(view,query,columns,GRID_REPORTING.compare(view));let total=0;const build=(start,end,depth,parent)=>{const column=columns.get(levels[depth].column),groups=[];for(let offset=start;offset<end;){const value=cellValue(rows[offset].cells[column.id])??null,key=reportingGroupKey(gridScalar(value,column));let last=offset+1;while(last<end&&reportingGroupKey(gridScalar(rows[last].cells[column.id],column))===key)last++;const id=parent===null?key:groupInnerKey(parent,key);if(++total>10000||id.length>4096)throw new Error("CanopyX: inline grouping exceeds its metadata bounds.");const group={key:id,value,offset,count:last-offset,aggregates:groupAggregateValues(grid,rows,offset,last),...groupWorstCells(view,rows,offset,last)};if(depth+1<levels.length)group.groups=build(offset,last,depth+1,id);groups.push(group);offset=last}
41
+ function groupInlineSummary(grid,query){const view=grid.view,columns=new Map(view.columns.map(column=>[column.id,column])),levels=groupLevelsOf(view,query);const rows=query.groupBy?.length?GRID_ROWS.order(view,query):gridQueryRows(view,query,columns,GRID_REPORTING.compare(view));let total=0;const build=(start,end,depth,parent)=>{const column=columns.get(levels[depth].column),groups=[];for(let offset=start;offset<end;){const value=groupBucketValue(levels[depth],column,rows[offset].cells[column.id]),key=reportingGroupKey(value);let last=offset+1;while(last<end&&reportingGroupKey(groupBucketValue(levels[depth],column,rows[last].cells[column.id]))===key)last++;const id=parent===null?key:groupInnerKey(parent,key);if(++total>10000||id.length>4096)throw new Error("CanopyX: inline grouping exceeds its metadata bounds.");const group={key:id,value,offset,count:last-offset,aggregates:groupAggregateValues(grid,rows,offset,last),...groupWorstCells(view,rows,offset,last)};if(depth+1<levels.length)group.groups=build(offset,last,depth+1,id);groups.push(group);offset=last}
40
42
  return groups};return{protocol:PROTOCOL,type:"gridSummary",view:view.id,revision:query.revision,query,matched:rows.length,groups:levels.length?build(0,rows.length,0,null):[],aggregates:groupAggregateValues(grid,rows)}}
41
43
  function groupWorstCells(view,rows,first,last){const cells=Object.create(null);for(const declared of view.columns){const presenter=declared.presenter||view.reporting.presenters?.[declared.id];if(!presenter||!["state","enum"].includes(presenter.kind))continue;let worst=null,rank=-1;for(let index=first;index<last;index++){const cell=rows[index].cells[declared.id],raw=cellValue(cell);if(raw==null)continue;const next=GRID_TONE_RANK[gridPresenterTone(presenter,raw,isCellObject(cell)?cell.tone:null)]??2;if(next>rank){worst=cell;rank=next}}
42
44
  if(worst!==null)cells[declared.id]=worst}
43
45
  return Object.keys(cells).length?{cells}:{}}
46
+ function groupBucketValue(level,column,cell){if(level.bucket)return GRID_BUCKETS.key(level.bucket,gridScalar(cell,column));const value=cellValue(cell)??null;return column.kind==="datetime"&&value!==null?new Date(gridScalar(cell,column)).toISOString():value}
44
47
  const GROUP_ATTACH=DataGrid.prototype.attachRows;const groupSummaryQuery=(view,query,revision)=>gridQuery(view,{...query,offset:0,limit:view.pageSize,revision});const groupNeedsSummary=(view,query)=>!!view.reporting?.grouping||!!query.groupBy?.length||!!view.reporting?.aggregates?.length;GRID_ROWS.requestPage=async function(query,signal){const page=await GRID_ROWS.base.requestPage.call(this,query,signal);if(!reportingSummaryEnabled(this.view)||signal!==this.dataLifetime.signal||!groupNeedsSummary(this.view,query))return page;validateGridPage(page,this.view,query);const request=groupSummaryQuery(this.view,query,page.revision),key=JSON.stringify(request);if(this.summaryCandidate?.key!==key){const hook=this.source.summary||(this.view.source.kind==="inline"?request=>groupInlineSummary(this,request):null);if(!hook)throw new Error("CanopyX: hosted summaries need an explicit source summary hook.");const summary=await this.runGridHook(signal=>hook.call(this.source,request,{signal}),signal);gridOperationActive(this,signal);this.summaryCandidate={key,result:groupSummaryResult(this,request,page,summary)}}
45
48
  const result=this.summaryCandidate.result,levels=groupLevelsOf(this.view,query);if(result.matched!==page.matched)throw new Error("CanopyX: a page differs from its complete-query summary count.");if(levels.length){const columns=levels.map(level=>this.view.columns.find(column=>column.id===level.column));for(let i=0;i<page.items.length;i++){const path=groupPath(result,page.offset+i);if(path.length!==levels.length||columns.some((column,depth)=>
46
- reportingGroupKey(gridScalar(page.items[i].cells[column.id],column))!==reportingGroupKey(gridScalar(path[depth].value,column))))
49
+ reportingGroupKey(groupBucketValue(levels[depth],column,page.items[i].cells[column.id]))!==reportingGroupKey(path[depth].value)))
47
50
  throw new Error("CanopyX: a page record differs from its complete-query group.")}}
48
51
  return page};Object.assign(DataGrid.prototype,{attachRows(){if(this.rowsAttached)return;GROUP_ATTACH.call(this);if(!reportingSummaryEnabled(this.view))return;GROUP_GRIDS.set(this.view,this);this.groupAggregates=groupCustomAggregates(this);for(const aggregate of this.view.reporting.aggregates||[])
49
52
  if(!GROUP_OPERATIONS.includes(aggregate.operation)&&this.view.source.kind==="inline"&&!this.groupAggregates.has(aggregate.operation))
@@ -59,27 +62,31 @@ const group=row.group,level=row.level,collapsed=this.collapsedGroups.has(group.k
59
62
  else{element.removeAttribute("aria-level");element.removeAttribute("aria-expanded")}
60
63
  element.style.height=this.rowH+"px";element.style.width=this.rowWidth+"px";element.style.setProperty("--cx-group-level",String(level-1));const priorButton=previous?.[0].cell.querySelector(".cx-grid-group-toggle"),button=priorButton||h("button","cx-grid-group-toggle");if(!priorButton){button.type="button";button.tabIndex=-1}
61
64
  if(button.disabled!==!!this.pendingQuery)button.disabled=!!this.pendingQuery;button.setAttribute("aria-expanded",String(!collapsed));button.setAttribute("aria-label",collapsed?this.labels.gridGroupExpand:this.labels.gridGroupCollapse);if(button.textContent!==(collapsed?"▸":"▾"))setText(button,collapsed?"▸":"▾");if(!priorButton)button.addEventListener("click",()=>{if(this.pendingQuery)return;try{this.setFocus(row,false);this.setGroupCollapsed(group.key,!this.collapsedGroups.has(group.key));this.setFocus(this.focused,true)}
62
- catch(error){this.emit("error",{error})}});const value=group.value===null?this.labels.gridGroupMissing:cellText(group.value,groupColumn,this.fmt),count=numberFormat(this.lang).format(group.count);const label=fill(this.view.reporting?.grouping?.headerTemplate||this.labels.gridGroupHeading,{column:groupColumn.title,value,count}),cells=[];this.cols.forEach((column,index)=>{const cell=previous?.[index].cell||this.cell(element,index,column.width,column.kind);cells.push({cell,content:cell});if(index===0){const priorHeading=cell.querySelector(".cx-grid-group-label"),heading=priorHeading||h("span","cx-grid-group-label");const text=heading.querySelector(".cx-grid-group-text")||h("span","cx-grid-group-text"),badge=heading.querySelector(".cx-grid-group-count")||h("span","cx-grid-group-count");text.replaceChildren();if(levels.length>1&&!this.view.reporting?.grouping?.headerTemplate){const name=h("span","cx-grid-group-column");setText(name,groupColumn.title);text.append(name,document.createTextNode(" "))}
63
- text.appendChild(document.createTextNode(this.view.reporting?.grouping?.headerTemplate?label:value));setText(badge,count);badge.hidden=!!this.view.reporting?.grouping?.headerTemplate;if(!priorHeading)heading.append(text,badge);if(!priorButton)cell.append(button);this.paintGroupSelection(cell,group);if(!priorHeading)cell.append(heading);cell.title=label;this.paintHiddenAggregates(heading,group.aggregates,cell,column.id,label);return}
65
+ catch(error){this.emit("error",{error})}});const bucket=levels[level-1].bucket;const value=group.value===null?this.labels.gridGroupMissing:bucket?GRID_BUCKETS.label(bucket,group.value,this.lang):cellText(group.value,groupColumn,this.fmt),count=numberFormat(this.lang).format(group.count);const label=fill(this.view.reporting?.grouping?.headerTemplate||this.labels.gridGroupHeading,{column:groupColumn.title,value,count}),cells=[];this.cols.forEach((column,index)=>{const cell=previous?.[index].cell||this.cell(element,index,column.width,column.kind);cells.push({cell,content:cell});if(index===0){const priorHeading=cell.querySelector(".cx-grid-group-label"),heading=priorHeading||h("span","cx-grid-group-label");const text=heading.querySelector(".cx-grid-group-text")||h("span","cx-grid-group-text"),badge=heading.querySelector(".cx-grid-group-count")||h("span","cx-grid-group-count");text.replaceChildren();if(levels.length>1&&!this.view.reporting?.grouping?.headerTemplate){const name=h("span","cx-grid-group-column");setText(name,groupColumn.title);text.append(name,document.createTextNode(" "))}
66
+ text.appendChild(document.createTextNode(this.view.reporting?.grouping?.headerTemplate?label:value));setText(badge,count);badge.hidden=!!this.view.reporting?.grouping?.headerTemplate||this.view.reporting.aggregates?.some(aggregate=>aggregate.operation==="count"&&group.aggregates[aggregate.id]===group.count);if(!priorHeading)heading.append(text,badge);if(!priorButton)cell.append(button);this.paintGroupSelection(cell,group);if(!priorHeading)cell.append(heading);cell.title=label;this.paintHiddenAggregates(heading,group.aggregates,cell,column.id,label);return}
64
67
  const aggregates=(this.view.reporting.aggregates||[]).filter(item=>item.column===column.id);if(aggregates.length)this.paintAggregates(cell,column,aggregates,group.aggregates);else{cell.replaceChildren();if(Object.hasOwn(group.cells||{},column.id)){const options=column.presenter||this.view.reporting.presenters?.[column.id];if(options)gridCellRenderer(this,column,options)({id:group.key,cells:group.cells},cell);else setText(cell,cellText(group.cells[column.id],column,this.fmt))}}});let room=this.cols[0].renderWidth??this.cols[0].width;for(let index=1;index<cells.length&&!cells[index].cell.textContent;index++)room +=this.cols[index].renderWidth??this.cols[index].width;const heading=cells[0].cell.querySelector(".cx-grid-group-label");heading.style.maxWidth=Math.max(40,room-44 -(level-1)*16 -(this.view.reporting.selectionControls&&this.multi?22:0))+ "px";element._cells=cells;quietControls(element);this.paintGridHighlights(element,row)},paintGroupSelection(cell,group){if(!this.view.reporting.selectionControls||!this.multi)return;const previous=cell.querySelector(".cx-grid-group-select"),check=previous||h("input","cx-grid-row-select cx-grid-group-select");if(!previous){check.type="checkbox";check.tabIndex=-1}
65
68
  const state=this.groupSelection(group);check.checked=state===true;check.indeterminate=state==="mixed";check.disabled=!!this.pendingQuery;check.setAttribute("aria-label",fill(this.labels.gridSelectGroup,{group:group.value===null?this.labels.gridGroupMissing:String(group.value)}));if(!previous)check.addEventListener("click",event=>{event.preventDefault();event.stopPropagation();this.runReportingSelection(()=>this.selectRange(group.offset,group.offset+group.count-1,{selected:this.groupSelection(group)!==true,additive:true}))});if(!previous)cell.appendChild(check)},groupSelection(group){let selected=0,loaded=0;for(const[ordinal,record]of this.rowCache){if(ordinal<group.offset||ordinal>=group.offset+group.count)continue;loaded++;if(this.reportingRowSelected(record))selected++}
66
- if(this.querySelection)return selected===loaded?true:selected?"mixed":false;return selected&&selected===group.count?true:selected?"mixed":false},paintHiddenAggregates(target,values,cell=target,headingColumn=null,title=this.labels.gridSummary||this.view.label){const shown=new Set(this.cols.filter(column=>column.id!==headingColumn).map(column=>column.id)),parts=[],details=[];for(const column of this.columns){const aggregates=shown.has(column.id)?[]:(this.view.reporting.aggregates||[]).filter(item=>item.column===column.id);if(aggregates.length){const formatted=reportingAggregateParts(this,column,aggregates,values);if(formatted.text){parts.push(column.title+" "+formatted.text);details.push(column.title+"\n"+formatted.title)}}}
69
+ if(this.querySelection)return selected===loaded?true:selected?"mixed":false;return selected&&selected===group.count?true:selected?"mixed":false},paintHiddenAggregates(target,values,cell=target,headingColumn=null,title=this.labels.gridSummary||this.view.label){const shown=new Set(this.cols.filter(column=>column.id!==headingColumn).map(column=>column.id)),parts=[],details=[],bindings=[];for(const column of this.columns){const aggregates=shown.has(column.id)?[]:(this.view.reporting.aggregates||[]).filter(item=>item.column===column.id);if(aggregates.length){const formatted=reportingAggregateParts(this,column,aggregates,values);if(formatted.text||aggregates.some(aggregate=>(this.aggregateShowAs?.[aggregate.id]??aggregate.showAs??"value")!=="value")){parts.push(column.title+" " +(formatted.text||"—")+(formatted.caption?" ("+formatted.caption+")":""));details.push(column.title+"\n"+formatted.title);bindings.push(...aggregates)}}}
67
70
  const previous=target.querySelector(":scope > .cx-hidden-aggregates");if(!parts.length){previous?.remove();return}
68
- const extra=previous||h("button","cx-grid-group-aggregates cx-hidden-aggregates");if(!previous)extra.type="button";extra.setAttribute("aria-haspopup","dialog");if(extra.textContent!==parts.join(" · "))setText(extra,parts.join(" · "));extra._cxAggregateText={title,text:details.join("\n")};extra.title=details.join("\n");extra.setAttribute("aria-label",details.join(", "));if(!previous){target.appendChild(extra);extra.addEventListener("click",event=>{event.stopPropagation();this.showReportingText({title:extra._cxAggregateText.title},extra._cxAggregateText.text,extra)})}
71
+ const extra=previous||h("button","cx-grid-group-aggregates cx-hidden-aggregates");if(!previous)extra.type="button";extra.setAttribute("aria-haspopup","dialog");if(extra.textContent!==parts.join(" · "))setText(extra,parts.join(" · "));extra._cxAggregateText={title,text:details.join("\n"),bindings,values};extra.title=details.join("\n");extra.setAttribute("aria-label",details.join(", "));if(!previous){target.appendChild(extra);extra.addEventListener("click",event=>{event.stopPropagation();const current=extra._cxAggregateText;this.showAggregateMenu({id:current.bindings[0].column,title:current.title},current.bindings,current.values,extra,current.text).catch(error=>this.emit("error",{error}))})}
69
72
  cell.title=(cell.title?cell.title+" · ":"")+ parts.join(" · ")},syncSummaryControls(){if(this.statusBar&&this.statusGroupSummary!==this.summary){this.statusGroupSummary=this.summary;this.statusGroups??=h("span");this.statusCount.after(this.statusGroups);this.statusGroups.hidden=!this.summary?.groups.length;if(this.summary)setText(this.statusGroups,fill(this.labels.gridGroupCount,{count:numberFormat(this.lang).format(this.summary.groups.length)}))}
70
73
  if(!this.summaryControls)return;this.summaryControls.hidden=!this.summary;if(!this.summary)return;if(this.summaryControls.parentElement!==this.grid)this.grid.appendChild(this.summaryControls);const count=this.rowProjection?this.rowProjection.rowCount():this.rowCount();this.grid.setAttribute("aria-rowcount",String(count+2 +(this.headDepth||0)));const key=[this.summary,count,this.layout,this.rowWidth,this.lang,...this.cols.map(column=>column.renderWidth+":"+column.effectivePin)];if(this.summaryRenderKey?.every((value,index)=>value===key[index]))return;this.summaryRenderKey=key;this.summaryControls.replaceChildren();const row=h("div","cx-summary-row");row.setAttribute("role","row");row.setAttribute("aria-rowindex",String(count+2 +(this.headDepth||0)));row.style.width=this.rowWidth+"px";this.cols.forEach((column,index)=>{const cell=this.newCell(index,column.width,column.kind);cell.setAttribute("role","gridcell");cell.style.width=column.renderWidth+"px";const aggregates=this.view.reporting.aggregates.filter(item=>item.column===column.id);if(aggregates.length)this.paintAggregates(cell,column,aggregates,this.summary.aggregates);else if(index===0){setText(cell,this.labels.gridSummary);cell.classList.add("cx-summary-caption")}
71
74
  if(index===0)this.paintHiddenAggregates(cell,this.summary.aggregates);row.appendChild(cell)});this.summaryControls.appendChild(row)}});const GROUP_CONTROL_BASE={};for(const name of["buildHeader","querySortHeader"])GROUP_CONTROL_BASE[name]=DataGrid.prototype[name];Object.assign(DataGrid.prototype,{attachGroupControls(){const reporting=this.view.reporting||{};this.groupingDynamic=reportingDynamicGroups(this.view);if(reporting.grouping||this.groupingDynamic){this.groupBar=h("div","cx-groupbar");this.groupBar.setAttribute("role","group");this.groupBar.setAttribute("aria-label",this.labels.gridGroupedBy);this.groupBar.hidden=this.opts.toolbar===false;this.notice.before(this.groupBar)}
72
75
  if(reporting.aggregates?.length){this.summaryControls=h("div","cx-grid-summary");this.summaryControls.setAttribute("role","rowgroup");this.summaryControls.setAttribute("aria-label",this.labels.gridSummary);this.summaryControls.hidden=true}
73
- if(this.groupingDynamic)document.addEventListener("canopyx:closemenus",event=>{const panel=event.detail?.source;if(panel?.classList?.contains("cx-column-menu"))queueMicrotask(()=>this.groupMenuItems(panel))},{signal:this.lifetime.signal});this.syncGroupBar();this.buildHeader()},buildHeader(){GROUP_CONTROL_BASE.buildHeader.call(this);const column=this.view.reporting?.grouping?.column;const header=column&&this.headCells.find(cell=>cell.getAttribute("data-cx-column")===column),button=header?.querySelector(".cx-sort");if(button){button.disabled=true;button.title=this.labels.gridGroupOrder}},groupLevelsNow(){return this.view.reporting.grouping?[this.view.reporting.grouping]:this.queryForChange().groupBy||[]},querySortHeader(id,event){const levels=this.groupingDynamic&&this.groupLevelsNow();if(!levels||!levels.some(level=>level.column===id))return GROUP_CONTROL_BASE.querySortHeader.call(this,id,event);this.setGroupBy(levels.map(level=>level.column===id?{...level,direction:level.direction==="asc"?"desc":"asc"}:level)).catch(()=>{})},groupMenuItems(panel){const id=this.gridPopover?.columnId,column=this.columns.find(item=>item.id===id),menu=panel.querySelector('[role="menu"]');if(!menu||!column?.sortable||this.gridPopover.panel!==panel)return;const levels=this.groupLevelsNow(),grouped=levels.some(level=>level.column===id);if(!grouped&&!this.view.reporting?.groupable)return;const item=gridButton(grouped?this.labels.gridUngroup:this.labels.gridGroupBy,()=>{this.closeGridPopover(false);this.setGroupBy(grouped?levels.filter(level=>level.column!==id):[...levels,{column:id,direction:"asc"}]).catch(error=>this.emit("error",{error}))});item.classList.add("cx-mi","cx-mi-group");item.setAttribute("role","menuitem");item.tabIndex=-1;item.disabled=!grouped&&levels.length>=4;item.prepend(h("span","ico"));menu.append(h("hr","cx-menu-rule"),item)},groupDrop(column){const levels=this.groupingDynamic&&this.groupLevelsNow();if(!levels||!this.view.reporting?.groupable||!column.sortable||levels.length>=4||levels.some(level=>level.column===column.id))return false;this.setGroupBy([...levels,{column:column.id,direction:"asc"}]).catch(error=>this.emit("error",{error}));return true},syncGroupBar(){const bar=this.groupBar;if(!bar)return;const levels=this.groupLevelsNow(),key=JSON.stringify([levels,this.groupCollapseVersion||0]);if(bar._key===key&&bar._summary===this.summary)return;const active=bar.contains(document.activeElement)?document.activeElement:null,chip=active?.closest(".cx-gchip");const place=this.groupChipFocus||active&&{level:chip?Number(chip.dataset.cxLevel):0,control:[...(chip||bar).querySelectorAll("button,select")].indexOf(active)};this.groupChipFocus=null;bar._key=key;bar._summary=this.summary;bar.replaceChildren();if(place)queueMicrotask(()=>{const scope=place.level?bar.querySelector('.cx-gchip[data-cx-level="'+place.level+'"]'):bar;const controls=[...(scope||bar).querySelectorAll("button,select")];(controls[Math.max(0,Math.min(controls.length-1,place.control))]||bar.querySelector("button,select"))?.focus()});const lead=h("span","cx-groupbar-label");setText(lead,this.labels.gridGroupedBy);bar.appendChild(lead);if(this.view.reporting.grouping){const chip=h("span","cx-gchip");setText(chip,this.columns.find(column=>column.id===levels[0].column).title);if(typeof this.opts.onUngroup==="function"){const remove=gridDecorateButton(gridButton("",()=>this.runGridHook(signal=>this.opts.onUngroup({query:this.getQuery(),signal}),this.dataLifetime.signal)
76
+ this.syncGroupBar();this.buildHeader()},buildHeader(){GROUP_CONTROL_BASE.buildHeader.call(this);const column=this.view.reporting?.grouping?.column;const header=column&&this.headCells.find(cell=>cell.getAttribute("data-cx-column")===column),button=header?.querySelector(".cx-sort");if(button){button.disabled=true;button.title=this.labels.gridGroupOrder}},groupLevelsNow(){return this.view.reporting.grouping?[this.view.reporting.grouping]:this.queryForChange().groupBy||[]},querySortHeader(id,event){const levels=this.groupingDynamic&&this.groupLevelsNow();if(!levels||!levels.some(level=>level.column===id))return GROUP_CONTROL_BASE.querySortHeader.call(this,id,event);this.setGroupBy(levels.map(level=>level.column===id?{...level,direction:level.direction==="asc"?"desc":"asc"}:level)).catch(()=>{})},appendColumnGroupActions(column,add,separator){if(!this.groupingDynamic||!column.sortable)return;const id=column.id,levels=this.groupLevelsNow(),grouped=levels.some(level=>level.column===id);if(!grouped&&!this.view.reporting?.groupable)return;separator();add(grouped?this.labels.gridUngroup:this.labels.gridGroupBy,()=>{const latest=this.groupLevelsNow(),present=latest.some(level=>level.column===id);if(this.destroyed||!this.groupingDynamic||!this.columns.some(item=>item.id===id&&item.sortable)||
77
+ grouped!==present||!grouped&&(!this.view.reporting?.groupable||latest.length>=4))return;return this.setGroupBy(grouped?latest.filter(level=>level.column!==id):[...latest,{column:id,direction:"asc"}])},!grouped&&levels.length>=4)},groupDrop(column){const levels=this.groupingDynamic&&this.groupLevelsNow();if(!levels||!this.view.reporting?.groupable||!column.sortable||levels.length>=4||levels.some(level=>level.column===column.id))return false;this.setGroupBy([...levels,{column:column.id,direction:"asc"}]).catch(error=>this.emit("error",{error}));return true},syncGroupBar(){const bar=this.groupBar;if(!bar)return;const levels=this.groupLevelsNow(),levelsKey=JSON.stringify(levels),key=JSON.stringify([levels,this.groupCollapseVersion||0]);if(bar._levelsKey!==undefined&&bar._levelsKey!==levelsKey&&this.gridPopover?.panel.classList.contains("cx-column-menu"))
78
+ this.closeGridPopover(false);bar._levelsKey=levelsKey;if(bar._key===key&&bar._summary===this.summary)return;const active=bar.contains(document.activeElement)?document.activeElement:null,chip=active?.closest(".cx-gchip");const place=this.groupChipFocus||active&&{level:chip?Number(chip.dataset.cxLevel):0,control:[...(chip||bar).querySelectorAll("button,select")].indexOf(active)};this.groupChipFocus=null;bar._key=key;bar._summary=this.summary;bar.replaceChildren();if(place)queueMicrotask(()=>{const scope=place.level?bar.querySelector('.cx-gchip[data-cx-level="'+place.level+'"]'):bar;const controls=[...(scope||bar).querySelectorAll("button,select")];(controls[Math.max(0,Math.min(controls.length-1,place.control))]||bar.querySelector("button,select"))?.focus()});const lead=h("span","cx-groupbar-label");setText(lead,this.labels.gridGroupedBy);bar.appendChild(lead);if(this.view.reporting.grouping){const chip=h("span","cx-gchip");setText(chip,this.columns.find(column=>column.id===levels[0].column).title);if(typeof this.opts.onUngroup==="function"){const remove=gridDecorateButton(gridButton("",()=>this.runGridHook(signal=>this.opts.onUngroup({query:this.getQuery(),signal}),this.dataLifetime.signal)
74
79
  .catch(error=>this.emit("error",{error}))),"close",true);remove.setAttribute("aria-label",this.labels.gridRemoveGrouping);chip.appendChild(remove)}
75
80
  bar.appendChild(chip);return}
76
81
  if(!levels.length){const hint=h("span","cx-groupbar-hint");setText(hint,this.labels.gridGroupDrop);bar.appendChild(hint);return}
77
82
  levels.forEach((level,index)=>{if(index){const next=h("span","cx-groupbar-next");next.setAttribute("aria-hidden","true");setText(next,"›");bar.appendChild(next)}
78
- bar.appendChild(this.groupChip(levels,level,index))});const spacer=h("span","cx-groupbar-spacer");bar.appendChild(spacer);const busy=!this.summary;for(const[label,collapsed]of[[this.labels.gridExpandAll,false],[this.labels.gridCollapseAll,true]]){const button=gridButton(label,()=>{if(!this.pendingQuery)this.setGroupLevelCollapsed(0,collapsed)});button.classList.add("cx-groupbar-all");button.disabled=busy;bar.appendChild(button)}},groupChip(levels,level,index){const column=this.columns.find(item=>item.id===level.column),chip=h("span","cx-gchip"),name=h("span","cx-gchip-name");const change=next=>this.setGroupBy(next).catch(error=>this.emit("error",{error}));chip.dataset.cxLevel=String(index+1);chip.title=this.labels.gridGroupMove;setText(name,column.title);chip.appendChild(name);const descending=level.direction==="desc",direction=gridDecorateButton(gridButton("",()=>
83
+ bar.appendChild(this.groupChip(levels,level,index))});const spacer=h("span","cx-groupbar-spacer");bar.appendChild(spacer);const busy=!this.summary;for(const[label,collapsed]of[[this.labels.gridExpandAll,false],[this.labels.gridCollapseAll,true]]){const button=gridButton(label,()=>{if(!this.pendingQuery)this.setGroupLevelCollapsed(0,collapsed)});button.classList.add("cx-groupbar-all");button.disabled=busy;bar.appendChild(button)}},groupChip(levels,level,index){const column=this.columns.find(item=>item.id===level.column),chip=h("span","cx-gchip"),name=h("span","cx-gchip-name");const change=next=>this.setGroupBy(next).catch(error=>this.emit("error",{error}));chip.dataset.cxLevel=String(index+1);chip.title=this.labels.gridGroupMove;setText(name,column.title);chip.appendChild(name);this.groupBucketControls(chip,levels,level,column);const descending=level.direction==="desc",direction=gridDecorateButton(gridButton("",()=>
79
84
  change(levels.map(item=>item===level?{...item,direction:descending?"asc":"desc"}:item))),descending?"down":"up",true);direction.classList.add("cx-gchip-direction");direction.setAttribute("aria-label",column.title+": " +(descending?this.labels.gridSortAscending:this.labels.gridSortDescending));direction.setAttribute("aria-pressed",String(descending));chip.appendChild(direction);const aggregates=this.view.reporting.aggregates||[];if(aggregates.length){const order=h("select","cx-gchip-order");order.setAttribute("aria-label",column.title+": "+this.labels.gridGroupSortBy);const option=(value,text)=>{const item=h("option");item.value=value;setText(item,text);order.appendChild(item)};option("",this.labels.gridGroupSortValue);aggregates.forEach(item=>option(item.id,fill(this.labels.gridGroupSortAggregate,{aggregate:item.label})));order.value=level.aggregate||"";order.addEventListener("change",()=>change(levels.map(item=>{if(item!==level)return item;const{aggregate,...rest}=item;return order.value?{...rest,aggregate:order.value}:rest})));chip.appendChild(order)}
80
85
  const keys=this.groupKeys(index+1),allCollapsed=keys.length>0&&keys.every(key=>this.collapsedGroups.has(key));const fold=gridButton(allCollapsed?"+":"−",()=>{if(!this.pendingQuery)this.setGroupLevelCollapsed(index+1,!allCollapsed)});fold.classList.add("cx-gchip-fold");fold.disabled=!keys.length;fold.setAttribute("aria-label",fill(allCollapsed?this.labels.gridExpandLevel:this.labels.gridCollapseLevel,{level:index+1}));fold.title=fold.getAttribute("aria-label");chip.appendChild(fold);const remove=gridDecorateButton(gridButton("",()=>change(levels.filter(item=>item!==level))),"close",true);remove.setAttribute("aria-label",column.title+": "+this.labels.gridUngroup);chip.appendChild(remove);chip.addEventListener("keydown",event=>{if(!event.altKey||!["ArrowLeft","ArrowRight"].includes(event.key))return;const target=index +(event.key==="ArrowLeft"?-1:1);if(target<0||target>=levels.length)return;event.preventDefault();const next=levels.slice();next.splice(target,0,next.splice(index,1)[0]);this.groupChipFocus={level:target+1,control:[...chip.querySelectorAll("button,select")].indexOf(event.target)};change(next)});name.addEventListener("pointerdown",event=>this.dragGroupChip(event,levels,index,chip));return chip},dragGroupChip(event,levels,index,chip){if(event.button!==0||this.pendingQuery)return;event.preventDefault();const pointer=event.pointerId,startX=event.clientX;let ghost=null,target=index;const chips=[...this.groupBar.querySelectorAll(".cx-gchip")];const move=ev=>{if(ev.pointerId!==pointer||!ghost&&Math.abs(ev.clientX-startX)<5)return;if(!ghost){ghost=h("div","cx-column-drag");ghost.setAttribute("aria-hidden","true");setText(ghost,chip.querySelector(".cx-gchip-name").textContent);document.body.appendChild(ghost)}
81
86
  ghost.style.left=ev.clientX+12+"px";ghost.style.top=ev.clientY+12+"px";const before=chips.filter(item=>{const box=item.getBoundingClientRect();return ev.clientX>box.left+box.width / 2; }).length;
82
- target=before>index?before-1:before};const stop=ev=>{if(ev&&ev.pointerId!==undefined&&ev.pointerId!==pointer)return;this.dragGroupChipEnd?.();const dropped=ghost&&ev?.type==="pointerup";ghost?.remove();if(dropped&&target!==index){const next=levels.slice();next.splice(target,0,next.splice(index,1)[0]);this.setGroupBy(next).catch(error=>this.emit("error",{error}))}};const cancel=ev=>{if(ev.pointerId===pointer){ghost?.remove();ghost=null;stop()}};const drag=new AbortController(),listen={signal:AbortSignal.any([drag.signal,this.lifetime.signal])};global.addEventListener("pointermove",move,listen);global.addEventListener("pointerup",stop,listen);global.addEventListener("pointercancel",cancel,listen);this.lifetime.signal.addEventListener("abort",()=>ghost?.remove(),{once:true,signal:drag.signal});this.dragGroupChipEnd=()=>drag.abort()}});const GROUP_QUERY=DataGrid.prototype.setQuery;Object.assign(DataGrid.prototype,{projectedRowKey(event,row){if(!row.group)return false;const cell=event.target.closest(".cx-cell");if(cell&&event.target===cell&&["Enter"," "].includes(event.key)){if(event.key==="Enter")this.focusCell(row,this.rowCells(cell.parentElement).indexOf(cell),0,true);event.preventDefault();return true}
87
+ target=before>index?before-1:before};const stop=ev=>{if(ev&&ev.pointerId!==undefined&&ev.pointerId!==pointer)return;this.dragGroupChipEnd?.();const dropped=ghost&&ev?.type==="pointerup";ghost?.remove();if(dropped&&target!==index){const next=levels.slice();next.splice(target,0,next.splice(index,1)[0]);this.setGroupBy(next).catch(error=>this.emit("error",{error}))}};const cancel=ev=>{if(ev.pointerId===pointer){ghost?.remove();ghost=null;stop()}};const drag=new AbortController(),listen={signal:AbortSignal.any([drag.signal,this.lifetime.signal])};global.addEventListener("pointermove",move,listen);global.addEventListener("pointerup",stop,listen);global.addEventListener("pointercancel",cancel,listen);this.lifetime.signal.addEventListener("abort",()=>ghost?.remove(),{once:true,signal:drag.signal});this.dragGroupChipEnd=()=>drag.abort()}});DataGrid.prototype.groupBucketControls=function(chip,levels,level,column){if(!["number","datetime"].includes(column.kind))return;const select=h("select","cx-select cx-gchip-order cx-gchip-bucket"),labels=this.labels;select.setAttribute("aria-label",column.title+": "+labels.gridBucket);const choices=column.kind==="datetime"?["day","week","month","quarter","year","hour","weekday"]:["width","edges"];for(const kind of["",...choices]){const option=h("option");option.value=kind;setText(option,kind?labels["gridBucket"+kind[0].toUpperCase()+ kind.slice(1)]:labels.gridBucketNone);select.append(option)}
88
+ select.value=level.bucket?.kind||"";select.title=labels.gridBucket+": "+select.selectedOptions[0].textContent;const apply=bucket=>this.setGroupBy(levels.map(item=>{if(item!==level)return item;const{bucket:old,...rest}=item;return bucket?{...rest,bucket}:rest})).catch(error=>this.emit("error",{error}));select.addEventListener("change",()=>{const kind=select.value;apply(!kind?null:kind==="width"?{kind,width:10,origin:0}:kind==="edges"?{kind,edges:[0,10,100]}:{kind,timeZone:level.bucket?.timeZone||"UTC",firstWeekday:level.bucket?.firstWeekday??1})});chip.append(select);if(!["width","edges"].includes(level.bucket?.kind))return;const input=(name,value,type,read)=>{const field=h("input","cx-input cx-gchip-bucket-value");field.type=type;field.value=String(value);if(type==="number")field.step="any";else field.maxLength=4096;field.setAttribute("aria-label",column.title+": "+labels[name]);field.title=labels[name];field.addEventListener("change",()=>{try{const bucket=gridBucketDefinition(read(field.value),column);field.setCustomValidity("");apply(bucket)}
89
+ catch(_){field.setCustomValidity(labels.gridBucketInvalid);field.reportValidity()}});chip.append(field)};if(level.bucket.kind==="width"){input("gridBucketWidth",level.bucket.width,"number",text=>({...level.bucket,width:text.trim()?Number(text):NaN}));input("gridBucketOrigin",level.bucket.origin,"number",text=>({...level.bucket,origin:text.trim()?Number(text):NaN}))}else input("gridBucketEdges",level.bucket.edges.join(", "),"text",text=>({kind:"edges",edges:text.split(",").map(item=>item.trim()?Number(item):NaN)}))};const GROUP_QUERY=DataGrid.prototype.setQuery;Object.assign(DataGrid.prototype,{projectedRowKey(event,row){if(!row.group)return false;const cell=event.target.closest(".cx-cell");if(cell&&event.target===cell&&["Enter"," "].includes(event.key)){if(event.key==="Enter")this.focusCell(row,this.rowCells(cell.parentElement).indexOf(cell),0,true);event.preventDefault();return true}
83
90
  if(cell&&(["ArrowLeft","ArrowRight","Home","End","Escape","F2"].includes(event.key)||
84
91
  event.target!==cell&&["Enter"," "].includes(event.key)))return TreeGrid.prototype.onCellKey.call(this,event);if(event.key==="F2"){this.focusCell(row,0,0,true);event.preventDefault();return true}
85
92
  if(!["ArrowLeft","ArrowRight","Enter"," "].includes(event.key))return false;if(event.target.closest("button,input,select")&&["Enter"," "].includes(event.key))return true;event.preventDefault();if(this.pendingQuery)return true;const collapsed=this.collapsedGroups.has(row.group.key),rows=this.rowProjection;if(event.key==="ArrowRight"&&!collapsed&&this.groupTree){const next=rows.rowItem(rows.indexOf(row)+ 1);if(next)this.focusProjected(next);return true}
@@ -1,26 +1,26 @@
1
1
  /* Search hits and filter hits. Hosts restyle them with the tokens --cx-hit-search-bg,--cx-hit-filter-bg,--cx-hit-current-bg,
2
2
  * --cx-hit-current-ring and --cx-hit-text;the defaults derive from the tones,so both palettes and host themes follow. */
3
- mark.cx-hit{color:var(--cx-hit-text,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));background:var(--cx-hit-search-bg,color-mix(in srgb,var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640)) var(--cx-hit-mix,28%),var(--hfx-color-surface,light-dark(#ffffff,#16181c))));border-radius:var(--cx-size-2px);padding:0;box-decoration-break:clone;-webkit-box-decoration-break:clone;}
4
- mark.cx-hit-filter{background:var(--cx-hit-filter-bg,color-mix(in srgb,var(--hfx-color-status-info-fg,light-dark(#2b5fc0,#74a2f7)) var(--cx-hit-mix,24%),var(--hfx-color-surface,light-dark(#ffffff,#16181c))));box-shadow:inset 0 calc(-1 * var(--cx-size-1px)) 0 color-mix(in srgb,var(--hfx-color-status-info-fg,light-dark(#2b5fc0,#74a2f7)) 70%,transparent);}
5
- mark.cx-hit-toned{background:color-mix(in srgb,var(--cx-hit-tone) var(--cx-hit-mix,24%),var(--hfx-color-surface,light-dark(#ffffff,#16181c)));box-shadow:inset 0 calc(-1 * var(--cx-size-1px)) 0 color-mix(in srgb,var(--cx-hit-tone) 75%,transparent);}
6
- mark.cx-hit-current{background:var(--cx-hit-current-bg,color-mix(in srgb,var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640)) calc(var(--cx-hit-mix,28%) + 24%),var(--hfx-color-surface,light-dark(#ffffff,#16181c))));outline:var(--cx-size-2px) solid var(--cx-hit-current-ring,var(--hfx-color-accent,light-dark(#11776f,#37c9b8)));outline-offset:0;}
3
+ mark.cx-hit{color:var(--cx-hit-text,var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5))));background:var(--cx-hit-search-bg,color-mix(in srgb,var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640)) var(--cx-hit-mix,28%),var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)))));border-radius:var(--cx-size-2px);padding:0;box-decoration-break:clone;-webkit-box-decoration-break:clone;}
4
+ mark.cx-hit-filter{background:var(--cx-hit-filter-bg,color-mix(in srgb,var(--hfx-color-status-info-fg,light-dark(#2b5fc0,#74a2f7)) var(--cx-hit-mix,24%),var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)))));box-shadow:inset 0 calc(-1 * var(--cx-size-1px)) 0 color-mix(in srgb,var(--hfx-color-status-info-fg,light-dark(#2b5fc0,#74a2f7)) 70%,transparent);}
5
+ mark.cx-hit-toned{background:color-mix(in srgb,var(--cx-hit-tone) var(--cx-hit-mix,24%),var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));box-shadow:inset 0 calc(-1 * var(--cx-size-1px)) 0 color-mix(in srgb,var(--cx-hit-tone) 75%,transparent);}
6
+ mark.cx-hit-current{background:var(--cx-hit-current-bg,color-mix(in srgb,var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640)) calc(var(--cx-hit-mix,28%) + 24%),var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)))));outline:var(--cx-size-2px) solid var(--cx-hit-current-ring,var(--hfx-color-accent,light-dark(#11776f,#37c9b8)));outline-offset:0;}
7
7
  .cx-host[data-cx-theme="dark"] mark.cx-hit{--cx-hit-mix:36%;}
8
- .cx-host[data-cx-theme="dark"] mark.cx-hit-current{color:var(--cx-hit-text,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));background:var(--cx-hit-current-bg,color-mix(in srgb,var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640)) 88%,var(--hfx-color-text,light-dark(#16181c,#f2f3f5))));}
8
+ .cx-host[data-cx-theme="dark"] mark.cx-hit-current{color:var(--cx-hit-text,var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));background:var(--cx-hit-current-bg,color-mix(in srgb,var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640)) 88%,var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)))));}
9
9
  @media (prefers-color-scheme:dark){
10
10
  .cx-host[data-cx-theme="auto"] mark.cx-hit{--cx-hit-mix:36%;}
11
- .cx-host[data-cx-theme="auto"] mark.cx-hit-current{color:var(--cx-hit-text,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));background:var(--cx-hit-current-bg,color-mix(in srgb,var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640)) 88%,var(--hfx-color-text,light-dark(#16181c,#f2f3f5))));}
11
+ .cx-host[data-cx-theme="auto"] mark.cx-hit-current{color:var(--cx-hit-text,var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c))));background:var(--cx-hit-current-bg,color-mix(in srgb,var(--hfx-color-status-warn-fg,light-dark(#8c5c05,#eeb640)) 88%,var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)))));}
12
12
  }
13
13
  .cx-cell.cx-hit-cell{box-shadow:inset 0 0 0 var(--cx-size-2px) var(--cx-hit-current-ring,var(--hfx-color-accent,light-dark(#11776f,#37c9b8)));}
14
- .cx-search .cx-matches{display:inline-flex;align-items:center;gap:var(--cx-size-2px);flex:none;margin-left:auto;color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-size:var(--cx-size-12d5px);font-variant-numeric:tabular-nums;white-space:nowrap;}
15
- .cx-toolbar > .cx-matches{display:inline-flex;align-items:center;gap:var(--cx-size-2px);color:var(--hfx-color-text-muted,light-dark(#626770,#8f949d));font-size:var(--cx-size-12d5px);}
14
+ .cx-search .cx-matches{display:inline-flex;align-items:center;gap:var(--cx-size-2px);flex:none;margin-left:auto;color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font-size:var(--cx-size-12d5px);font-variant-numeric:tabular-nums;white-space:nowrap;}
15
+ .cx-toolbar > .cx-matches{display:inline-flex;align-items:center;gap:var(--cx-size-2px);color:var(--hfx-color-text-secondary,var(--hfx-color-text-muted,light-dark(#626770,#8f949d)));font-size:var(--cx-size-12d5px);}
16
16
  .cx-matches-count{padding:0 var(--cx-size-4px);}
17
17
  .cx-matches-step{display:inline-grid;place-items:center;width:var(--cx-size-24px);height:var(--cx-size-24px);padding:0;border:0;border-radius:var(--hfx-radius-sm,4px);background:transparent;color:var(--hfx-color-text-secondary,light-dark(#4d525b,#b0b4bc));cursor:pointer;}
18
- .cx-matches-step:hover:not(:disabled){background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));color:var(--hfx-color-text,light-dark(#16181c,#f2f3f5));}
18
+ .cx-matches-step:hover:not(:disabled){background:var(--hfx-color-hover,light-dark(#f5f5f5,#232529));color:var(--hfx-color-text-primary,var(--hfx-color-text,light-dark(#16181c,#f2f3f5)));}
19
19
  .cx-matches-step:disabled{opacity:.4;cursor:default;}
20
20
  .cx-matches-step:focus-visible{outline:var(--hfx-focus-width,2px) solid var(--hfx-color-focus-ring,light-dark(#02726a,#37c9b8));outline-offset:0;}
21
21
  .cx-search.cx-has-matches kbd{display:none;}
22
22
  .cx-phone .cx-matches-step{width:var(--cx-size-36px);height:var(--cx-size-36px);}
23
- .cx-matches-toggle::before{content:"";flex:none;width:var(--cx-size-14px);height:var(--cx-size-14px);border:var(--cx-size-1px) solid var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));border-radius:var(--hfx-radius-sm,4px);background:var(--hfx-color-surface,light-dark(#ffffff,#16181c));}
23
+ .cx-matches-toggle::before{content:"";flex:none;width:var(--cx-size-14px);height:var(--cx-size-14px);border:var(--cx-size-1px) solid var(--hfx-color-border-control,light-dark(#8a8f98,#6e737c));border-radius:var(--hfx-radius-sm,4px);background:var(--hfx-color-surface-card,var(--hfx-color-surface,light-dark(#ffffff,#16181c)));}
24
24
  .cx-matches-toggle.on::before{content:"✓" / "";display:inline-grid;place-items:center;border-color:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));background:var(--hfx-color-accent,light-dark(#11776f,#37c9b8));color:var(--hfx-color-accent-contrast,light-dark(#ffffff,#0c0d10));font-weight:var(--hfx-weight-semibold,600);font-size:var(--hfx-type-caption-size,0.75rem);font-family:var(--hfx-font-sans,"Segoe UI Variable Text","Segoe UI",system-ui,-apple-system,"Helvetica Neue",Arial,sans-serif);line-height:1;}
25
25
  @media (forced-colors:active){
26
26
  mark.cx-hit{forced-color-adjust:none;background:Mark !important;color:MarkText !important;}
@@ -1,4 +1,4 @@
1
- (function(global){"use strict";const installed=new WeakSet();const part={version:"459b28e174406d32",install(context){if(installed.has(context.VIEW_MODES))return;const{toneVariable,VIEW_MODES,TreeGrid,h,setText,fill,numberFormat,foldText,cellText,cellValue,isCellObject,setAttr,toneOf,watchFlyout,densityRowHeight,layoutAnchor,layoutRows,layoutApplyTree,MAX_PROTOCOL_INTEGER,LAYOUT_DENSITIES,plural,svgIcon}=context;const HL_ASCII=/^[\x00-\x7f]*$/, HL_MARKS = /[\u0300-\u036f]/, HL_SEPARATOR = /[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]/;
1
+ (function(global){"use strict";const installed=new WeakSet();const part={version:"5ebf0042011ba4fd",install(context){if(installed.has(context.VIEW_MODES))return;const{toneVariable,VIEW_MODES,TreeGrid,h,setText,fill,numberFormat,foldText,cellText,cellValue,isCellObject,setAttr,toneOf,watchFlyout,densityRowHeight,layoutAnchor,layoutRows,layoutApplyTree,MAX_PROTOCOL_INTEGER,LAYOUT_DENSITIES,plural,svgIcon}=context;const HL_ASCII=/^[\x00-\x7f]*$/, HL_MARKS = /[\u0300-\u036f]/, HL_SEPARATOR = /[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]/;
2
2
  const HL_BASE=new Map(Object.entries({"\u0142":"l","\u0141":"L","\u0111":"d","\u0110":"D","\u00f8":"o","\u00d8":"O","\u0127":"h","\u0126":"H","\u0167":"t","\u0166":"T","\u0131":"i"}));function hlBase(unit){let base=HL_BASE.get(unit);if(base===undefined){const parts=unit.normalize("NFD");base=parts.length>1&&/^[\u0300-\u036f]+$/.test(parts.slice(1)) ? parts.charAt(0) : unit;
3
3
  HL_BASE.set(unit,base)}
4
4
  return base}