@shapesos/clay 0.15.0 → 0.16.0

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/artifacts.js CHANGED
@@ -11,11 +11,11 @@ import {
11
11
  artifactToClipboardText,
12
12
  artifactTypes,
13
13
  isSafeDownloadUrl
14
- } from "./chunk-XFJ6XMJZ.js";
14
+ } from "./chunk-2YCBDSPK.js";
15
15
  import "./chunk-PYDVANWI.js";
16
16
  import "./chunk-LXYCT4YO.js";
17
17
  import "./chunk-OLJIJYB5.js";
18
- import "./chunk-YZB6YXKK.js";
18
+ import "./chunk-U3IXCSV6.js";
19
19
  import "./chunk-C77QMQNT.js";
20
20
  import "./chunk-UXT2H3FM.js";
21
21
  import "./chunk-JF3P66JF.js";
package/dist/blocks.cjs CHANGED
@@ -1289,6 +1289,11 @@ var CHART_PALETTE = [
1289
1289
  ];
1290
1290
  var OTHERS_SLICE_COLOR = colors["brown-60"];
1291
1291
  var DEFAULT_OTHERS_CATEGORY_LABELS = ["others", "other"];
1292
+ var NONE_CATEGORY_VALUES = ["", "(none)", "none", "null", "undefined", "n/a", "-"];
1293
+ function isNoneCategory(value) {
1294
+ if (value === null || value === void 0) return true;
1295
+ return NONE_CATEGORY_VALUES.includes(String(value).trim().toLowerCase());
1296
+ }
1292
1297
  function isOthersCategory(value, labels) {
1293
1298
  if (value === null || value === void 0) return false;
1294
1299
  if (labels.length === 0) return false;
@@ -1344,6 +1349,13 @@ function truncateLabel(value, maxChars) {
1344
1349
  if (s.length <= maxChars) return s;
1345
1350
  return s.slice(0, Math.max(1, maxChars - 1)).trimEnd() + "\u2026";
1346
1351
  }
1352
+ var compactNumberFormat = new Intl.NumberFormat("en-US", { notation: "compact", maximumFractionDigits: 1 });
1353
+ function compactNumberTickFormatter(value) {
1354
+ if (value === null || value === void 0) return "";
1355
+ const n = typeof value === "number" ? value : Number(value);
1356
+ if (!Number.isFinite(n)) return String(value);
1357
+ return compactNumberFormat.format(n);
1358
+ }
1347
1359
  function evenlyDistributedVisibleIndices(n, target) {
1348
1360
  if (n <= target) {
1349
1361
  return new Set(Array.from({ length: n }, (_, i) => i));
@@ -1383,6 +1395,11 @@ function coerceNumericColumns(rows, numericKeys) {
1383
1395
 
1384
1396
  // src/components/chart/bar-chart/bar-chart.tsx
1385
1397
  var import_jsx_runtime12 = require("react/jsx-runtime");
1398
+ var STACK_TOTAL_KEY = "__stackTotal";
1399
+ var VALUE_LABEL_HEADROOM = 20;
1400
+ function sumSeries(row, keys) {
1401
+ return keys.reduce((sum, key) => sum + (Number(row[key]) || 0), 0);
1402
+ }
1386
1403
  function BarChart({
1387
1404
  data,
1388
1405
  xKey,
@@ -1408,15 +1425,24 @@ function BarChart({
1408
1425
  [data, seriesKeys]
1409
1426
  );
1410
1427
  const resolvedShowLegend = showLegend ?? series.length > 1;
1411
- const resolvedShowValueLabels = showValueLabels ?? (!stacked && series.length === 1);
1428
+ const resolvedShowValueLabels = showValueLabels ?? true;
1429
+ const plotData = (0, import_react9.useMemo)(() => {
1430
+ if (!stacked || !resolvedShowValueLabels) return coercedData;
1431
+ return coercedData.map((row) => ({ ...row, [STACK_TOTAL_KEY]: sumSeries(row, seriesKeys) }));
1432
+ }, [coercedData, stacked, resolvedShowValueLabels, seriesKeys]);
1412
1433
  const resolvedAngle = xAxisAngle ?? (coercedData.length >= 8 ? -30 : 0);
1413
1434
  const resolvedTickFormatter = (0, import_react9.useMemo)(
1414
1435
  () => xAxisTickFormatter ?? defaultBarTickFormatter(coercedData.length),
1415
1436
  [xAxisTickFormatter, coercedData.length]
1416
1437
  );
1417
1438
  const angledLabelPad = resolvedAngle === 0 ? 0 : Math.min(Math.abs(resolvedAngle) * 0.7, 40);
1418
- const chartMargin = { ...CHART_MARGIN, bottom: CHART_MARGIN.bottom + angledLabelPad };
1419
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChartContainer, { height, width, className, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_recharts2.BarChart, { data: coercedData, margin: chartMargin, barCategoryGap: "22%", children: [
1439
+ const valueLabelHeadroom = resolvedShowValueLabels ? VALUE_LABEL_HEADROOM : 0;
1440
+ const chartMargin = {
1441
+ ...CHART_MARGIN,
1442
+ top: CHART_MARGIN.top + valueLabelHeadroom,
1443
+ bottom: CHART_MARGIN.bottom + angledLabelPad
1444
+ };
1445
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChartContainer, { height, width, className, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_recharts2.BarChart, { data: plotData, margin: chartMargin, barCategoryGap: "22%", children: [
1420
1446
  showGrid ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_recharts2.CartesianGrid, { ...CHART_GRID_PROPS }) : null,
1421
1447
  showXAxis ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1422
1448
  import_recharts2.XAxis,
@@ -1431,7 +1457,7 @@ function BarChart({
1431
1457
  tickFormatter: resolvedTickFormatter
1432
1458
  }
1433
1459
  ) : null,
1434
- showYAxis ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_recharts2.YAxis, { ...CHART_AXIS_PROPS, width: 40 }) : null,
1460
+ showYAxis ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_recharts2.YAxis, { ...CHART_AXIS_PROPS, width: 40, tickFormatter: compactNumberTickFormatter }) : null,
1435
1461
  showTooltip ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_recharts2.Tooltip, { cursor: { fill: BAR_TOOLTIP_CURSOR_FILL }, content: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChartTooltipContent, {}) }) : null,
1436
1462
  resolvedShowLegend ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1437
1463
  import_recharts2.Legend,
@@ -1443,18 +1469,23 @@ function BarChart({
1443
1469
  content: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChartLegendContent, { iconType: "square" })
1444
1470
  }
1445
1471
  ) : null,
1446
- series.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1447
- import_recharts2.Bar,
1448
- {
1449
- dataKey: s.key,
1450
- name: s.label,
1451
- fill: colorForSeriesIndex(i, palette),
1452
- stackId: stacked ? "default" : s.key,
1453
- radius: barRadius(stacked, i, series.length),
1454
- children: resolvedShowValueLabels ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_recharts2.LabelList, { dataKey: s.key, position: "top", style: CHART_VALUE_LABEL_STYLE }) : null
1455
- },
1456
- s.key
1457
- ))
1472
+ series.map((s, i) => {
1473
+ const isTopSegment = i === series.length - 1;
1474
+ const labelDataKey = stacked ? STACK_TOTAL_KEY : s.key;
1475
+ const showLabel = resolvedShowValueLabels && (!stacked || isTopSegment);
1476
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1477
+ import_recharts2.Bar,
1478
+ {
1479
+ dataKey: s.key,
1480
+ name: s.label,
1481
+ fill: colorForSeriesIndex(i, palette),
1482
+ stackId: stacked ? "default" : s.key,
1483
+ radius: barRadius(stacked, i, series.length),
1484
+ children: showLabel ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_recharts2.LabelList, { dataKey: labelDataKey, position: "top", style: CHART_VALUE_LABEL_STYLE }) : null
1485
+ },
1486
+ s.key
1487
+ );
1488
+ })
1458
1489
  ] }) });
1459
1490
  }
1460
1491
  function barRadius(stacked, seriesIndex, seriesCount) {
@@ -1570,7 +1601,7 @@ function LineChart({
1570
1601
  tickFormatter: resolvedTickFormatter
1571
1602
  }
1572
1603
  ) : null,
1573
- showYAxis ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_recharts3.YAxis, { ...CHART_AXIS_PROPS, width: 40 }) : null,
1604
+ showYAxis ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_recharts3.YAxis, { ...CHART_AXIS_PROPS, width: 40, tickFormatter: compactNumberTickFormatter }) : null,
1574
1605
  showTooltip ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_recharts3.Tooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ChartTooltipContent, {}) }) : null,
1575
1606
  resolvedShowLegend ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1576
1607
  import_recharts3.Legend,
@@ -1628,6 +1659,42 @@ var LineChartVariantService = {
1628
1659
  // src/components/chart/pie-chart/pie-chart.tsx
1629
1660
  var import_react11 = require("react");
1630
1661
  var import_recharts4 = require("recharts");
1662
+
1663
+ // src/components/chart/pie-chart/utils.ts
1664
+ function mergedOthersLabel(leftoverRows, categoryKey, othersCategoryLabels) {
1665
+ const explicit = leftoverRows.find((row) => isOthersCategory(row[categoryKey], othersCategoryLabels));
1666
+ if (explicit) return String(explicit[categoryKey]);
1667
+ const fallback = othersCategoryLabels[0] ?? "Other";
1668
+ return fallback.charAt(0).toUpperCase() + fallback.slice(1);
1669
+ }
1670
+ function buildPieSlices(data, categoryKey, valueKey, othersCategoryLabels, palette) {
1671
+ const namedRows = [];
1672
+ const namedColors = [];
1673
+ const leftoverRows = [];
1674
+ for (const row of data) {
1675
+ const isLeftover = othersCategoryLabels.length > 0 && (isNoneCategory(row[categoryKey]) || isOthersCategory(row[categoryKey], othersCategoryLabels));
1676
+ if (isLeftover) {
1677
+ leftoverRows.push(row);
1678
+ } else {
1679
+ namedRows.push(row);
1680
+ namedColors.push(colorForSeriesIndex(namedRows.length - 1, palette));
1681
+ }
1682
+ }
1683
+ if (leftoverRows.length === 0) {
1684
+ return { orderedData: namedRows, sliceColors: namedColors };
1685
+ }
1686
+ const total = leftoverRows.reduce((sum, row) => sum + (Number(row[valueKey]) || 0), 0);
1687
+ const mergedRow = {
1688
+ [categoryKey]: mergedOthersLabel(leftoverRows, categoryKey, othersCategoryLabels),
1689
+ [valueKey]: total
1690
+ };
1691
+ return {
1692
+ orderedData: [...namedRows, mergedRow],
1693
+ sliceColors: [...namedColors, OTHERS_SLICE_COLOR]
1694
+ };
1695
+ }
1696
+
1697
+ // src/components/chart/pie-chart/pie-chart.tsx
1631
1698
  var import_jsx_runtime16 = require("react/jsx-runtime");
1632
1699
  function PieChart({
1633
1700
  data,
@@ -1646,23 +1713,7 @@ function PieChart({
1646
1713
  }) {
1647
1714
  const { orderedData, sliceColors } = (0, import_react11.useMemo)(() => {
1648
1715
  const coerced = coerceNumericColumns(data, [valueKey]);
1649
- const namedRows = [];
1650
- const namedColors = [];
1651
- const othersRows = [];
1652
- const othersColors = [];
1653
- for (const row of coerced) {
1654
- if (isOthersCategory(row[categoryKey], othersCategoryLabels)) {
1655
- othersRows.push(row);
1656
- othersColors.push(OTHERS_SLICE_COLOR);
1657
- } else {
1658
- namedRows.push(row);
1659
- namedColors.push(colorForSeriesIndex(namedRows.length - 1, palette));
1660
- }
1661
- }
1662
- return {
1663
- orderedData: [...namedRows, ...othersRows],
1664
- sliceColors: [...namedColors, ...othersColors]
1665
- };
1716
+ return buildPieSlices(coerced, categoryKey, valueKey, othersCategoryLabels, palette);
1666
1717
  }, [data, valueKey, categoryKey, othersCategoryLabels, palette]);
1667
1718
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChartContainer, { height, width, className, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_recharts4.PieChart, { margin: PIE_CHART_MARGIN, children: [
1668
1719
  showTooltip ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_recharts4.Tooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChartTooltipContent, {}) }) : null,