myio-js-library 0.1.504 → 0.1.505

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1164,7 +1164,7 @@ module.exports = __toCommonJS(index_exports);
1164
1164
  // package.json
1165
1165
  var package_default = {
1166
1166
  name: "myio-js-library",
1167
- version: "0.1.504",
1167
+ version: "0.1.505",
1168
1168
  description: "A clean, standalone JS SDK for MYIO projects",
1169
1169
  license: "MIT",
1170
1170
  repository: "github:gh-myio/myio-js-library",
@@ -14674,8 +14674,10 @@ function renderCardComponentV5({
14674
14674
  temperature,
14675
14675
  temperatureMin,
14676
14676
  temperatureMax,
14677
- temperatureStatus
14677
+ temperatureStatus,
14678
14678
  // 'ok' | 'above' | 'below' | undefined
14679
+ // Per-device exclude_groups_totals attribute (SERVER_SCOPE) — drives the orange marker
14680
+ excludeGroupsTotals
14679
14681
  } = entityObject;
14680
14682
  const MyIOToast2 = (function() {
14681
14683
  let toastContainer = null;
@@ -14904,6 +14906,20 @@ function renderCardComponentV5({
14904
14906
  height: 100%;
14905
14907
  }
14906
14908
 
14909
+ /* Subtle orange marker \u2014 device flagged in exclude_groups_totals */
14910
+ .myio-enhanced-card-container-v5.myio-card-excluded::after {
14911
+ content: '';
14912
+ position: absolute;
14913
+ left: 12px;
14914
+ right: 12px;
14915
+ bottom: 3px;
14916
+ height: 3px;
14917
+ border-radius: 2px;
14918
+ background: linear-gradient(90deg, rgba(245, 158, 11, 0), #f59e0b 50%, rgba(245, 158, 11, 0));
14919
+ pointer-events: none;
14920
+ z-index: 5;
14921
+ }
14922
+
14907
14923
  .myio-enhanced-card-container-v5 .myio-draggable-card {
14908
14924
  width: 100%;
14909
14925
  border-radius: 10px;
@@ -15196,6 +15212,12 @@ function renderCardComponentV5({
15196
15212
  `;
15197
15213
  container.innerHTML = cardHTML;
15198
15214
  const enhancedCardElement = container.querySelector(".device-card-centered");
15215
+ try {
15216
+ const _excl = typeof excludeGroupsTotals === "string" ? JSON.parse(excludeGroupsTotals) : excludeGroupsTotals;
15217
+ const _isExcluded = !!(_excl && _excl.enabled === true && (_excl.groups && Object.values(_excl.groups).some((v) => v === true) || Array.isArray(_excl.excludedGroups) && _excl.excludedGroups.length > 0));
15218
+ if (_isExcluded) container.classList.add("myio-card-excluded");
15219
+ } catch (e) {
15220
+ }
15199
15221
  if (!document.getElementById("myio-enhanced-card-layout-styles-v5")) {
15200
15222
  const layoutStyle = document.createElement("style");
15201
15223
  layoutStyle.id = "myio-enhanced-card-layout-styles-v5";
@@ -16035,8 +16057,8 @@ var INFO_TOOLTIP_CSS = `
16035
16057
  border: 1px solid #e2e8f0;
16036
16058
  border-radius: 12px;
16037
16059
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.12), 0 2px 10px rgba(0, 0, 0, 0.08);
16038
- min-width: 320px;
16039
- max-width: 400px;
16060
+ width: 395px;
16061
+ max-width: 90vw;
16040
16062
  font-size: 12px;
16041
16063
  color: #1e293b;
16042
16064
  overflow: hidden;
@@ -69988,8 +70010,7 @@ var ENERGY_SUMMARY_TOOLTIP_CSS = `
69988
70010
  border: 1px solid #e2e8f0;
69989
70011
  border-radius: 12px;
69990
70012
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15), 0 2px 10px rgba(0, 0, 0, 0.08);
69991
- min-width: 380px;
69992
- width: max-content;
70013
+ width: 395px;
69993
70014
  max-width: 90vw;
69994
70015
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
69995
70016
  font-size: 12px;
@@ -71819,7 +71840,7 @@ var EnergySummaryTooltip = {
71819
71840
  };
71820
71841
  summary.byCategory = [entrada, lojas, areaComum];
71821
71842
  summary.totalDevices = entrada.deviceCount + lojas.deviceCount + areaComumDeviceCount;
71822
- summary.totalConsumption = state6.grandTotal || entrada.consumption;
71843
+ summary.totalConsumption = entrada.consumption || state6.grandTotal || 0;
71823
71844
  const widgetAggregation = receivedData?.deviceStatusAggregation;
71824
71845
  if (widgetAggregation && widgetAggregation.hasData) {
71825
71846
  summary.byStatus = {
@@ -72042,8 +72063,7 @@ var WATER_SUMMARY_TOOLTIP_CSS = `
72042
72063
  border: 1px solid #e2e8f0;
72043
72064
  border-radius: 12px;
72044
72065
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15), 0 2px 10px rgba(0, 0, 0, 0.08);
72045
- min-width: 380px;
72046
- width: max-content;
72066
+ width: 395px;
72047
72067
  max-width: 90vw;
72048
72068
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
72049
72069
  font-size: 12px;
@@ -73877,7 +73897,7 @@ var PIE_COLORS = [
73877
73897
  ];
73878
73898
  var COLUMN_SUMMARY_CSS = `
73879
73899
  .myio-col-summary {
73880
- max-width: 300px;
73900
+ max-width: 320px;
73881
73901
  font-family: 'Nunito', 'Segoe UI', system-ui, sans-serif;
73882
73902
  }
73883
73903
  .myio-col-summary__kpis {
@@ -73895,14 +73915,10 @@ var COLUMN_SUMMARY_CSS = `
73895
73915
  .myio-col-summary__kpi-value {
73896
73916
  font-size: 12px; font-weight: 700; color: #1e293b; text-align: right;
73897
73917
  }
73898
- .myio-col-summary__kpi-value--accent {
73899
- font-size: 14px; color: #3e1a7d;
73900
- }
73918
+ .myio-col-summary__kpi-value--accent { font-size: 14px; color: #3e1a7d; }
73901
73919
  .myio-col-summary__body { display: block; }
73902
73920
  .myio-col-summary__lists { display: flex; flex-direction: column; }
73903
- .myio-col-summary__group {
73904
- display: flex; flex-direction: column; gap: 1px; margin-top: 8px;
73905
- }
73921
+ .myio-col-summary__group { display: flex; flex-direction: column; gap: 1px; margin-top: 8px; }
73906
73922
  .myio-col-summary__group-label {
73907
73923
  font-size: 10px; font-weight: 800; letter-spacing: 0.3px;
73908
73924
  text-transform: uppercase; color: #64748b; margin-bottom: 3px;
@@ -73915,9 +73931,7 @@ var COLUMN_SUMMARY_CSS = `
73915
73931
  flex: 1 1 auto; min-width: 0;
73916
73932
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
73917
73933
  }
73918
- .myio-col-summary__val {
73919
- flex: 0 0 auto; font-weight: 700; color: #16a34a; text-align: right;
73920
- }
73934
+ .myio-col-summary__val { flex: 0 0 auto; font-weight: 700; color: #16a34a; text-align: right; }
73921
73935
  .myio-col-summary__pct {
73922
73936
  flex: 0 0 auto; min-width: 44px; text-align: right;
73923
73937
  font-size: 10px; font-weight: 600; color: #64748b;
@@ -73933,19 +73947,37 @@ var COLUMN_SUMMARY_CSS = `
73933
73947
  font-size: 11px; font-weight: 800; letter-spacing: 0.3px;
73934
73948
  text-transform: uppercase; color: #3e1a7d; margin-bottom: 8px;
73935
73949
  }
73936
- .myio-col-summary__chart-body {
73937
- display: flex; gap: 16px; align-items: flex-start;
73950
+ .myio-col-summary__chart-hint {
73951
+ font-size: 10px; font-weight: 500; color: #94a3b8; margin: 0 0 8px;
73938
73952
  }
73953
+ .myio-col-summary__chart-body { display: flex; gap: 16px; align-items: flex-start; }
73939
73954
  .myio-col-summary__pie {
73940
- width: 190px; height: 190px; border-radius: 50%; flex-shrink: 0;
73941
- box-shadow: 0 2px 12px rgba(0,0,0,0.18);
73955
+ width: 200px; height: 200px; flex-shrink: 0;
73956
+ filter: drop-shadow(0 2px 8px rgba(0,0,0,0.15));
73957
+ }
73958
+ .myio-col-summary__slice {
73959
+ stroke: #ffffff; stroke-width: 1.5;
73960
+ transition: opacity 0.12s ease;
73961
+ cursor: pointer;
73942
73962
  }
73963
+ .myio-col-summary__slice.is-hl {
73964
+ stroke: #1e293b; stroke-width: 3;
73965
+ }
73966
+ .myio-col-summary__slice:hover { opacity: 0.85; }
73943
73967
  .myio-col-summary__legend {
73944
- flex: 1 1 auto; min-width: 0; max-height: 300px; overflow-y: auto;
73968
+ flex: 1 1 auto; min-width: 0; max-height: 320px; overflow-y: auto;
73945
73969
  display: flex; flex-direction: column; gap: 1px;
73946
73970
  }
73947
73971
  .myio-col-summary__legend-row {
73948
- display: flex; align-items: center; gap: 6px; padding: 2px 0; font-size: 11px;
73972
+ display: flex; align-items: center; gap: 6px; padding: 3px 5px; font-size: 11px;
73973
+ border-radius: 4px; cursor: pointer;
73974
+ transition: background 0.12s ease;
73975
+ }
73976
+ .myio-col-summary__legend-row:hover,
73977
+ .myio-col-summary__legend-row.is-hl { background: #f1ecfa; }
73978
+ .myio-col-summary__legend-row.is-excluded { opacity: 0.45; }
73979
+ .myio-col-summary__legend-row.is-excluded .myio-col-summary__legend-name {
73980
+ text-decoration: line-through;
73949
73981
  }
73950
73982
  .myio-col-summary__legend-dot {
73951
73983
  width: 9px; height: 9px; border-radius: 2px; flex-shrink: 0;
@@ -73959,12 +73991,14 @@ var COLUMN_SUMMARY_CSS = `
73959
73991
  flex: 0 0 auto; min-width: 42px; text-align: right; font-size: 10px; color: #64748b;
73960
73992
  }
73961
73993
 
73962
- /* Maximized \u2014 use the extra space: widen, show the pie chart, lists side-by-side. */
73994
+ /* Maximized \u2014 use the extra space: widen, big pie, lists side-by-side. */
73963
73995
  .myio-info-tooltip.maximized .myio-col-summary { max-width: none; }
73964
73996
  .myio-info-tooltip.maximized .myio-col-summary__chart {
73965
73997
  display: block; margin-bottom: 16px;
73966
73998
  padding-bottom: 14px; border-bottom: 1px solid #e3d9f3;
73967
73999
  }
74000
+ .myio-info-tooltip.maximized .myio-col-summary__pie { width: 380px; height: 380px; }
74001
+ .myio-info-tooltip.maximized .myio-col-summary__legend { max-height: 380px; }
73968
74002
  .myio-info-tooltip.maximized .myio-col-summary__lists {
73969
74003
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px;
73970
74004
  }
@@ -73998,79 +74032,90 @@ function fmtPct(value, total, decimals) {
73998
74032
  const p = total > 0 ? (Number(value) || 0) / total * 100 : 0;
73999
74033
  return p.toFixed(decimals).replace(".", ",") + "%";
74000
74034
  }
74001
- function buildPieChart(devices, total, fmt2, pctDecimals) {
74002
- const sorted = devices.slice().sort((a, b) => (Number(b.value) || 0) - (Number(a.value) || 0));
74003
- if (total <= 0 || !sorted.length) {
74004
- return `<div class="myio-col-summary__chart">
74005
- <div class="myio-col-summary__empty">Sem dados para o gr\xE1fico.</div>
74006
- </div>`;
74035
+ function sliceColor(originalIndex) {
74036
+ return PIE_COLORS[originalIndex % PIE_COLORS.length];
74037
+ }
74038
+ function polar(cx, cy, r, deg) {
74039
+ const rad = (deg - 90) * Math.PI / 180;
74040
+ return [cx + r * Math.cos(rad), cy + r * Math.sin(rad)];
74041
+ }
74042
+ function arcPath(cx, cy, r, a0, a1) {
74043
+ const [x0, y0] = polar(cx, cy, r, a0);
74044
+ const [x1, y1] = polar(cx, cy, r, a1);
74045
+ const large = a1 - a0 > 180 ? 1 : 0;
74046
+ return `M${cx},${cy} L${x0.toFixed(2)},${y0.toFixed(2)} A${r},${r} 0 ${large} 1 ${x1.toFixed(
74047
+ 2
74048
+ )},${y1.toFixed(2)} Z`;
74049
+ }
74050
+ var _state = null;
74051
+ var _rootEl = null;
74052
+ function visibleDevices() {
74053
+ if (!_state) return [];
74054
+ return _state.data.devices.map((d, idx) => ({ d, idx })).filter((x) => !_state.excluded.has(x.idx));
74055
+ }
74056
+ function buildPieSvg(visible, total) {
74057
+ if (!_state) return "";
74058
+ const positives = visible.filter((v) => (Number(v.d.value) || 0) > 0);
74059
+ if (!positives.length || total <= 0) {
74060
+ return `<svg class="myio-col-summary__pie" viewBox="0 0 220 220" role="img" aria-label="Sem dados">
74061
+ <circle cx="110" cy="110" r="100" fill="#f1f5f9"></circle>
74062
+ <text x="110" y="115" text-anchor="middle" font-size="12" fill="#94a3b8">sem dados</text>
74063
+ </svg>`;
74064
+ }
74065
+ const { fmt: fmt2, pd } = _state;
74066
+ if (positives.length === 1) {
74067
+ const v = positives[0];
74068
+ const val = Number(v.d.value) || 0;
74069
+ return `<svg class="myio-col-summary__pie" viewBox="0 0 220 220">
74070
+ <circle class="myio-col-summary__slice" data-idx="${v.idx}" cx="110" cy="110" r="100"
74071
+ fill="${sliceColor(v.idx)}"><title>${esc3(v.d.name)} \u2014 ${esc3(fmt2(val))} (${fmtPct(
74072
+ val,
74073
+ total,
74074
+ pd
74075
+ )})</title></circle>
74076
+ </svg>`;
74007
74077
  }
74008
74078
  let acc = 0;
74009
- const stops = [];
74010
- const legend = [];
74011
- sorted.forEach((d, i) => {
74012
- const v = Number(d.value) || 0;
74013
- const color = PIE_COLORS[i % PIE_COLORS.length];
74014
- const start = acc / total * 360;
74015
- acc += v;
74016
- const end = acc / total * 360;
74017
- stops.push(`${color} ${start.toFixed(3)}deg ${end.toFixed(3)}deg`);
74018
- legend.push(`<div class="myio-col-summary__legend-row">
74019
- <span class="myio-col-summary__legend-dot" style="background:${color};"></span>
74020
- <span class="myio-col-summary__legend-name" title="${esc3(d.name)}">${esc3(d.name)}</span>
74021
- <span class="myio-col-summary__legend-val">${esc3(fmt2(v))}</span>
74022
- <span class="myio-col-summary__legend-pct">${fmtPct(v, total, pctDecimals)}</span>
74023
- </div>`);
74024
- });
74025
- return `<div class="myio-col-summary__chart">
74026
- <div class="myio-col-summary__chart-title">Distribui\xE7\xE3o \u2014 ${sorted.length} dispositivos</div>
74027
- <div class="myio-col-summary__chart-body">
74028
- <div class="myio-col-summary__pie" style="background: conic-gradient(${stops.join(", ")});"></div>
74029
- <div class="myio-col-summary__legend">${legend.join("")}</div>
74030
- </div>
74031
- </div>`;
74032
- }
74033
- function buildContent(data) {
74034
- const devices = Array.isArray(data.devices) ? data.devices.slice() : [];
74035
- const fmt2 = data.formatValue || defaultFormatter(data.unit || "");
74036
- const pd = resolvePercentDecimals(data.percentDecimals);
74037
- const count = devices.length;
74038
- const total = devices.reduce((s, d) => s + (Number(d.value) || 0), 0);
74079
+ const paths = positives.map((v) => {
74080
+ const val = Number(v.d.value) || 0;
74081
+ const a0 = acc / total * 360;
74082
+ acc += val;
74083
+ const a1 = acc / total * 360;
74084
+ return `<path class="myio-col-summary__slice" data-idx="${v.idx}"
74085
+ d="${arcPath(110, 110, 100, a0, a1)}" fill="${sliceColor(v.idx)}"
74086
+ ><title>${esc3(v.d.name)} \u2014 ${esc3(fmt2(val))} (${fmtPct(val, total, pd)})</title></path>`;
74087
+ }).join("");
74088
+ return `<svg class="myio-col-summary__pie" viewBox="0 0 220 220">${paths}</svg>`;
74089
+ }
74090
+ function buildLegend(total) {
74091
+ if (!_state) return "";
74092
+ const { data, excluded, fmt: fmt2, pd } = _state;
74093
+ const rows = data.devices.map((d, idx) => {
74094
+ const val = Number(d.value) || 0;
74095
+ const isExcl = excluded.has(idx);
74096
+ const pct = isExcl ? "\u2014" : fmtPct(val, total, pd);
74097
+ return `<div class="myio-col-summary__legend-row${isExcl ? " is-excluded" : ""}" data-idx="${idx}"
74098
+ title="Clique para ${isExcl ? "incluir" : "remover"} da pizza">
74099
+ <span class="myio-col-summary__legend-dot" style="background:${sliceColor(idx)};"></span>
74100
+ <span class="myio-col-summary__legend-name">${esc3(d.name)}</span>
74101
+ <span class="myio-col-summary__legend-val">${esc3(fmt2(val))}</span>
74102
+ <span class="myio-col-summary__legend-pct">${pct}</span>
74103
+ </div>`;
74104
+ }).join("");
74105
+ return `<div class="myio-col-summary__legend">${rows}</div>`;
74106
+ }
74107
+ function buildInner() {
74108
+ if (!_state) return "";
74109
+ const { data, fmt: fmt2, pd } = _state;
74110
+ const visible = visibleDevices();
74111
+ const count = visible.length;
74112
+ const total = visible.reduce((s, v) => s + (Number(v.d.value) || 0), 0);
74039
74113
  const avg = count ? total / count : 0;
74040
74114
  const periodRow = data.periodLabel ? `<div class="myio-col-summary__kpi">
74041
74115
  <span class="myio-col-summary__kpi-label">Per\xEDodo</span>
74042
74116
  <span class="myio-col-summary__kpi-value">${esc3(data.periodLabel)}</span>
74043
74117
  </div>` : "";
74044
- if (!count) {
74045
- return `<div class="myio-col-summary">
74046
- <div class="myio-col-summary__kpis">
74047
- ${periodRow}
74048
- <div class="myio-col-summary__kpi">
74049
- <span class="myio-col-summary__kpi-label">Dispositivos</span>
74050
- <span class="myio-col-summary__kpi-value">0</span>
74051
- </div>
74052
- </div>
74053
- <div class="myio-col-summary__empty">Nenhum dispositivo.</div>
74054
- </div>`;
74055
- }
74056
- const desc = devices.slice().sort((a, b) => (Number(b.value) || 0) - (Number(a.value) || 0));
74057
- const top3 = desc.slice(0, 3);
74058
- const bottom3 = desc.slice(-3).reverse();
74059
- const near3 = devices.slice().sort(
74060
- (a, b) => Math.abs((Number(a.value) || 0) - avg) - Math.abs((Number(b.value) || 0) - avg)
74061
- ).slice(0, 3);
74062
- const row = (d) => `
74063
- <div class="myio-col-summary__row">
74064
- <span class="myio-col-summary__name" title="${esc3(d.name)}">${esc3(d.name)}</span>
74065
- <span class="myio-col-summary__val">${esc3(fmt2(Number(d.value) || 0))}</span>
74066
- <span class="myio-col-summary__pct">${fmtPct(Number(d.value) || 0, total, pd)}</span>
74067
- </div>`;
74068
- const group = (label, list) => list.length ? `<div class="myio-col-summary__group">
74069
- <span class="myio-col-summary__group-label">${label}</span>
74070
- ${list.map(row).join("")}
74071
- </div>` : "";
74072
- return `<div class="myio-col-summary">
74073
- <div class="myio-col-summary__kpis">
74118
+ const kpis = `<div class="myio-col-summary__kpis">
74074
74119
  ${periodRow}
74075
74120
  <div class="myio-col-summary__kpi">
74076
74121
  <span class="myio-col-summary__kpi-label">Dispositivos</span>
@@ -74086,26 +74131,98 @@ function buildContent(data) {
74086
74131
  <span class="myio-col-summary__kpi-label">Consumo total</span>
74087
74132
  <span class="myio-col-summary__kpi-value">${esc3(fmt2(total))}</span>
74088
74133
  </div>
74089
- </div>
74134
+ </div>`;
74135
+ if (!data.devices.length) {
74136
+ return `${kpis}<div class="myio-col-summary__empty">Nenhum dispositivo.</div>`;
74137
+ }
74138
+ const desc = visible.slice().sort((a, b) => (Number(b.d.value) || 0) - (Number(a.d.value) || 0));
74139
+ const top3 = desc.slice(0, 3);
74140
+ const bottom3 = desc.slice(-3).reverse();
74141
+ const near3 = visible.slice().sort(
74142
+ (a, b) => Math.abs((Number(a.d.value) || 0) - avg) - Math.abs((Number(b.d.value) || 0) - avg)
74143
+ ).slice(0, 3);
74144
+ const row = (v) => `
74145
+ <div class="myio-col-summary__row">
74146
+ <span class="myio-col-summary__name" title="${esc3(v.d.name)}">${esc3(v.d.name)}</span>
74147
+ <span class="myio-col-summary__val">${esc3(fmt2(Number(v.d.value) || 0))}</span>
74148
+ <span class="myio-col-summary__pct">${fmtPct(Number(v.d.value) || 0, total, pd)}</span>
74149
+ </div>`;
74150
+ const group = (label, list) => list.length ? `<div class="myio-col-summary__group">
74151
+ <span class="myio-col-summary__group-label">${label}</span>
74152
+ ${list.map(row).join("")}
74153
+ </div>` : "";
74154
+ return `${kpis}
74090
74155
  <div class="myio-col-summary__body">
74091
- ${buildPieChart(devices, total, fmt2, pd)}
74156
+ <div class="myio-col-summary__chart">
74157
+ <div class="myio-col-summary__chart-title">Distribui\xE7\xE3o \u2014 ${count} dispositivos</div>
74158
+ <p class="myio-col-summary__chart-hint">Passe o mouse para destacar \xB7 clique na lista para remover da pizza</p>
74159
+ <div class="myio-col-summary__chart-body">
74160
+ ${buildPieSvg(visible, total)}
74161
+ ${buildLegend(total)}
74162
+ </div>
74163
+ </div>
74092
74164
  <div class="myio-col-summary__lists">
74093
74165
  ${group("\u25B2 3 maiores", top3)}
74094
74166
  ${group("\u25BC 3 menores", bottom3)}
74095
74167
  ${group("\u25CF 3 na m\xE9dia", near3)}
74096
74168
  </div>
74097
- </div>
74098
- </div>`;
74169
+ </div>`;
74170
+ }
74171
+ function setHighlight(idx) {
74172
+ if (!_rootEl) return;
74173
+ _rootEl.querySelectorAll(".is-hl").forEach((el2) => el2.classList.remove("is-hl"));
74174
+ if (idx == null) return;
74175
+ _rootEl.querySelectorAll(`[data-idx="${idx}"]`).forEach((el2) => el2.classList.add("is-hl"));
74176
+ }
74177
+ function rerender() {
74178
+ if (!_rootEl) return;
74179
+ _rootEl.innerHTML = buildInner();
74180
+ }
74181
+ function wireRoot(root) {
74182
+ root.addEventListener("mouseover", (e) => {
74183
+ const el2 = e.target?.closest?.("[data-idx]");
74184
+ setHighlight(el2 ? el2.getAttribute("data-idx") : null);
74185
+ });
74186
+ root.addEventListener("mouseout", (e) => {
74187
+ const el2 = e.target?.closest?.("[data-idx]");
74188
+ if (el2) setHighlight(null);
74189
+ });
74190
+ root.addEventListener("click", (e) => {
74191
+ const legendRow = e.target?.closest?.(
74192
+ ".myio-col-summary__legend-row"
74193
+ );
74194
+ if (!legendRow || !_state) return;
74195
+ const idx = Number(legendRow.getAttribute("data-idx"));
74196
+ if (!Number.isInteger(idx)) return;
74197
+ if (_state.excluded.has(idx)) _state.excluded.delete(idx);
74198
+ else _state.excluded.add(idx);
74199
+ rerender();
74200
+ });
74099
74201
  }
74100
74202
  var ColumnSummaryTooltip = {
74101
74203
  /** Shows the column summary tooltip anchored to the trigger element. */
74102
74204
  show(triggerElement, data) {
74103
74205
  injectCSS10();
74206
+ _state = {
74207
+ data: data && Array.isArray(data.devices) ? data : { ...data, devices: [] },
74208
+ excluded: /* @__PURE__ */ new Set(),
74209
+ fmt: data.formatValue || defaultFormatter(data.unit || ""),
74210
+ pd: resolvePercentDecimals(data.percentDecimals)
74211
+ };
74104
74212
  InfoTooltip.show(triggerElement, {
74105
74213
  icon: "\u{1F4CA}",
74106
74214
  title: data.title ? `Resumo \u2014 ${data.title}` : "Resumo da Coluna",
74107
- content: buildContent(data)
74215
+ content: `<div class="myio-col-summary">${buildInner()}</div>`
74108
74216
  });
74217
+ if (typeof requestAnimationFrame === "function") {
74218
+ requestAnimationFrame(() => {
74219
+ const roots = document.querySelectorAll(
74220
+ ".myio-info-tooltip .myio-col-summary"
74221
+ );
74222
+ _rootEl = roots.length ? roots[roots.length - 1] : null;
74223
+ if (_rootEl) wireRoot(_rootEl);
74224
+ });
74225
+ }
74109
74226
  },
74110
74227
  /** Hides the tooltip immediately. */
74111
74228
  hide() {
@@ -102659,11 +102776,11 @@ var FilterModalComponent = class {
102659
102776
  }
102660
102777
  selectAllDevices() {
102661
102778
  const devices = this.options.devices || [];
102662
- const visibleDevices = devices.filter((d) => {
102779
+ const visibleDevices2 = devices.filter((d) => {
102663
102780
  const el2 = this.overlay.querySelector(`[data-device-id="${d.id}"]`);
102664
102781
  return el2 && !el2.classList.contains("myio-fm__device-item--hidden");
102665
102782
  });
102666
- visibleDevices.forEach((device) => {
102783
+ visibleDevices2.forEach((device) => {
102667
102784
  this.selectedDeviceIds.add(device.id);
102668
102785
  this.updateDeviceUI(device.id);
102669
102786
  });
@@ -102671,11 +102788,11 @@ var FilterModalComponent = class {
102671
102788
  }
102672
102789
  selectNoDevices() {
102673
102790
  const devices = this.options.devices || [];
102674
- const visibleDevices = devices.filter((d) => {
102791
+ const visibleDevices2 = devices.filter((d) => {
102675
102792
  const el2 = this.overlay.querySelector(`[data-device-id="${d.id}"]`);
102676
102793
  return el2 && !el2.classList.contains("myio-fm__device-item--hidden");
102677
102794
  });
102678
- visibleDevices.forEach((device) => {
102795
+ visibleDevices2.forEach((device) => {
102679
102796
  this.selectedDeviceIds.delete(device.id);
102680
102797
  this.updateDeviceUI(device.id);
102681
102798
  });
package/dist/index.d.cts CHANGED
@@ -7795,20 +7795,10 @@ declare const InfoTooltip: {
7795
7795
  * Compact view: search period, device count, average/total consumption and
7796
7796
  * the top 3 / bottom 3 / 3-closest-to-average devices.
7797
7797
  *
7798
- * Maximized view (InfoTooltip maximize button): the extra space is used for a
7799
- * pie chart of ALL devices with a scrollable legend, plus the three lists laid
7800
- * out side by side. The maximized layout is driven purely by CSS reacting to
7801
- * the `.myio-info-tooltip.maximized` class no InfoTooltip API change needed.
7802
- *
7803
- * @example
7804
- * const cleanup = ColumnSummaryTooltip.attach(iconEl, () => ({
7805
- * title: 'Lojas',
7806
- * periodLabel: '01/05/2026 — 21/05/2026',
7807
- * unit: 'kWh',
7808
- * devices: items.map((i) => ({ name: i.label, value: i.value })),
7809
- * formatValue: (v) => MyIO.formatEnergy(v),
7810
- * }));
7811
- * // later: cleanup();
7798
+ * Maximized view (InfoTooltip maximize button): an interactive SVG pie of all
7799
+ * devices with a legend. Hovering a slice highlights its legend row (and vice
7800
+ * versa); clicking a legend row toggles that device out of the pie/totals
7801
+ * (local to the tooltip — does NOT propagate to the dashboard).
7812
7802
  */
7813
7803
  interface ColumnSummaryDevice {
7814
7804
  name: string;