@particle-academy/fancy-sheets 0.4.1 → 0.4.2
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 +83 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +83 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -16,6 +16,8 @@ interface CellFormat {
|
|
|
16
16
|
textAlign?: TextAlign;
|
|
17
17
|
/** Display format — controls how the value is rendered */
|
|
18
18
|
displayFormat?: CellDisplayFormat;
|
|
19
|
+
/** Number of decimal places to display (for number/currency/percentage) */
|
|
20
|
+
decimals?: number;
|
|
19
21
|
}
|
|
20
22
|
/** A single cell's complete data */
|
|
21
23
|
interface CellData {
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ interface CellFormat {
|
|
|
16
16
|
textAlign?: TextAlign;
|
|
17
17
|
/** Display format — controls how the value is rendered */
|
|
18
18
|
displayFormat?: CellDisplayFormat;
|
|
19
|
+
/** Number of decimal places to display (for number/currency/percentage) */
|
|
20
|
+
decimals?: number;
|
|
19
21
|
}
|
|
20
22
|
/** A single cell's complete data */
|
|
21
23
|
interface CellData {
|
package/dist/index.js
CHANGED
|
@@ -1599,7 +1599,7 @@ function ColumnResizeHandle({ colIndex }) {
|
|
|
1599
1599
|
}
|
|
1600
1600
|
ColumnResizeHandle.displayName = "ColumnResizeHandle";
|
|
1601
1601
|
function ColumnHeaders() {
|
|
1602
|
-
const { columnCount, rowCount, rowHeight, getColumnWidth, selection, selectRange, _isDragging } = useSpreadsheet();
|
|
1602
|
+
const { columnCount, rowCount, rowHeight, getColumnWidth, selection, selectRange, _isDragging, isCellSelected } = useSpreadsheet();
|
|
1603
1603
|
const handleColumnMouseDown = useCallback(
|
|
1604
1604
|
(colIdx, e) => {
|
|
1605
1605
|
if (e.button !== 0) return;
|
|
@@ -1643,28 +1643,35 @@ function ColumnHeaders() {
|
|
|
1643
1643
|
style: { width: 48, minWidth: 48 }
|
|
1644
1644
|
}
|
|
1645
1645
|
),
|
|
1646
|
-
Array.from({ length: columnCount }, (_, i) =>
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1646
|
+
Array.from({ length: columnCount }, (_, i) => {
|
|
1647
|
+
const isColSelected = isCellSelected(toAddress(0, i));
|
|
1648
|
+
return /* @__PURE__ */ jsxs(
|
|
1649
|
+
"div",
|
|
1650
|
+
{
|
|
1651
|
+
className: cn(
|
|
1652
|
+
"relative flex shrink-0 cursor-pointer items-center justify-center border-r border-zinc-300 text-[11px] font-medium select-none hover:bg-zinc-200 dark:border-zinc-600 dark:hover:bg-zinc-700",
|
|
1653
|
+
isColSelected ? "bg-blue-100 text-blue-700 dark:bg-blue-900/50 dark:text-blue-300" : "text-zinc-500 dark:text-zinc-400"
|
|
1654
|
+
),
|
|
1655
|
+
style: { width: getColumnWidth(i), minWidth: getColumnWidth(i) },
|
|
1656
|
+
onMouseDown: (e) => handleColumnMouseDown(i, e),
|
|
1657
|
+
onMouseEnter: () => handleColumnMouseEnter(i),
|
|
1658
|
+
onMouseUp: handleMouseUp,
|
|
1659
|
+
children: [
|
|
1660
|
+
columnToLetter(i),
|
|
1661
|
+
/* @__PURE__ */ jsx(ColumnResizeHandle, { colIndex: i })
|
|
1662
|
+
]
|
|
1663
|
+
},
|
|
1664
|
+
i
|
|
1665
|
+
);
|
|
1666
|
+
})
|
|
1661
1667
|
]
|
|
1662
1668
|
}
|
|
1663
1669
|
);
|
|
1664
1670
|
}
|
|
1665
1671
|
ColumnHeaders.displayName = "ColumnHeaders";
|
|
1666
1672
|
function RowHeader({ rowIndex }) {
|
|
1667
|
-
const { rowHeight, columnCount, selection, selectRange, _isDragging } = useSpreadsheet();
|
|
1673
|
+
const { rowHeight, columnCount, selection, selectRange, _isDragging, isCellSelected } = useSpreadsheet();
|
|
1674
|
+
const isRowSelected = isCellSelected(toAddress(rowIndex, 0));
|
|
1668
1675
|
const handleMouseDown = useCallback(
|
|
1669
1676
|
(e) => {
|
|
1670
1677
|
if (e.button !== 0) return;
|
|
@@ -1695,7 +1702,10 @@ function RowHeader({ rowIndex }) {
|
|
|
1695
1702
|
"div",
|
|
1696
1703
|
{
|
|
1697
1704
|
"data-fancy-sheets-row-header": "",
|
|
1698
|
-
className:
|
|
1705
|
+
className: cn(
|
|
1706
|
+
"flex shrink-0 cursor-pointer items-center justify-center border-r border-b border-zinc-300 text-[11px] font-medium select-none hover:bg-zinc-200 dark:border-zinc-600 dark:hover:bg-zinc-700",
|
|
1707
|
+
isRowSelected ? "bg-blue-100 text-blue-700 dark:bg-blue-900/50 dark:text-blue-300" : "bg-zinc-100 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400"
|
|
1708
|
+
),
|
|
1699
1709
|
style: { width: 48, minWidth: 48, height: rowHeight },
|
|
1700
1710
|
onMouseDown: handleMouseDown,
|
|
1701
1711
|
onMouseEnter: handleMouseEnter,
|
|
@@ -1724,21 +1734,24 @@ function serialToDateTimeStr(serial) {
|
|
|
1724
1734
|
}
|
|
1725
1735
|
function isDateFormula(formula) {
|
|
1726
1736
|
if (!formula) return false;
|
|
1727
|
-
const f = formula.toUpperCase();
|
|
1728
|
-
return /^(TODAY|NOW|DATE|EDATE)\
|
|
1737
|
+
const f = formula.trim().toUpperCase();
|
|
1738
|
+
return /^(TODAY|NOW|DATE|EDATE)\s*\(/.test(f);
|
|
1729
1739
|
}
|
|
1730
1740
|
function formatCellValue(val, cell) {
|
|
1731
1741
|
if (val === null || val === void 0) return "";
|
|
1732
1742
|
const fmt = cell?.format?.displayFormat;
|
|
1733
1743
|
if (typeof val === "number") {
|
|
1744
|
+
const dec = cell?.format?.decimals;
|
|
1734
1745
|
if (fmt === "date") return serialToDateStr(val);
|
|
1735
1746
|
if (fmt === "datetime") return serialToDateTimeStr(val);
|
|
1736
|
-
if (fmt === "percentage") return (val * 100).toFixed(1) + "%";
|
|
1737
|
-
if (fmt === "currency") return "$" + val.toFixed(2);
|
|
1747
|
+
if (fmt === "percentage") return (val * 100).toFixed(dec ?? 1) + "%";
|
|
1748
|
+
if (fmt === "currency") return "$" + val.toFixed(dec ?? 2);
|
|
1749
|
+
if (fmt === "number" && dec !== void 0) return val.toFixed(dec);
|
|
1738
1750
|
if (fmt === "auto" || !fmt) {
|
|
1739
1751
|
if (cell?.formula && isDateFormula(cell.formula)) {
|
|
1740
1752
|
return val % 1 === 0 ? serialToDateStr(val) : serialToDateTimeStr(val);
|
|
1741
1753
|
}
|
|
1754
|
+
if (dec !== void 0) return val.toFixed(dec);
|
|
1742
1755
|
}
|
|
1743
1756
|
}
|
|
1744
1757
|
if (typeof val === "boolean") return val ? "TRUE" : "FALSE";
|
|
@@ -2182,6 +2195,8 @@ function DefaultToolbar() {
|
|
|
2182
2195
|
const isBold = cell?.format?.bold ?? false;
|
|
2183
2196
|
const isItalic = cell?.format?.italic ?? false;
|
|
2184
2197
|
const textAlign = cell?.format?.textAlign ?? "left";
|
|
2198
|
+
const displayFormat = cell?.format?.displayFormat ?? "auto";
|
|
2199
|
+
const decimals = cell?.format?.decimals;
|
|
2185
2200
|
const selectedAddresses = [selection.activeCell];
|
|
2186
2201
|
const handleFormulaBarChange = (e) => {
|
|
2187
2202
|
if (editingCell) {
|
|
@@ -2293,6 +2308,52 @@ function DefaultToolbar() {
|
|
|
2293
2308
|
/* @__PURE__ */ jsx("line", { x1: "19", y1: "3", x2: "19", y2: "21", strokeDasharray: "3 3" })
|
|
2294
2309
|
] })
|
|
2295
2310
|
}
|
|
2311
|
+
),
|
|
2312
|
+
/* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-zinc-200 dark:bg-zinc-700" }),
|
|
2313
|
+
/* @__PURE__ */ jsxs(
|
|
2314
|
+
"select",
|
|
2315
|
+
{
|
|
2316
|
+
className: "h-6 rounded border border-zinc-200 bg-transparent px-1 text-[11px] text-zinc-600 outline-none hover:border-zinc-300 dark:border-zinc-700 dark:text-zinc-400 dark:hover:border-zinc-600",
|
|
2317
|
+
value: displayFormat,
|
|
2318
|
+
onChange: (e) => setCellFormat(selectedAddresses, { displayFormat: e.target.value }),
|
|
2319
|
+
disabled: readOnly,
|
|
2320
|
+
title: "Cell format",
|
|
2321
|
+
children: [
|
|
2322
|
+
/* @__PURE__ */ jsx("option", { value: "auto", children: "Auto" }),
|
|
2323
|
+
/* @__PURE__ */ jsx("option", { value: "text", children: "Text" }),
|
|
2324
|
+
/* @__PURE__ */ jsx("option", { value: "number", children: "Number" }),
|
|
2325
|
+
/* @__PURE__ */ jsx("option", { value: "currency", children: "Currency ($)" }),
|
|
2326
|
+
/* @__PURE__ */ jsx("option", { value: "percentage", children: "Percentage (%)" }),
|
|
2327
|
+
/* @__PURE__ */ jsx("option", { value: "date", children: "Date" }),
|
|
2328
|
+
/* @__PURE__ */ jsx("option", { value: "datetime", children: "Date & Time" })
|
|
2329
|
+
]
|
|
2330
|
+
}
|
|
2331
|
+
),
|
|
2332
|
+
/* @__PURE__ */ jsxs(
|
|
2333
|
+
"button",
|
|
2334
|
+
{
|
|
2335
|
+
className: btnClass,
|
|
2336
|
+
onClick: () => setCellFormat(selectedAddresses, { decimals: Math.max(0, (decimals ?? 0) - 1) }),
|
|
2337
|
+
disabled: readOnly || (decimals ?? 0) <= 0,
|
|
2338
|
+
title: "Decrease decimal places",
|
|
2339
|
+
children: [
|
|
2340
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px]", children: ".0" }),
|
|
2341
|
+
/* @__PURE__ */ jsx("span", { className: "text-[8px]", children: "\u2190" })
|
|
2342
|
+
]
|
|
2343
|
+
}
|
|
2344
|
+
),
|
|
2345
|
+
/* @__PURE__ */ jsxs(
|
|
2346
|
+
"button",
|
|
2347
|
+
{
|
|
2348
|
+
className: btnClass,
|
|
2349
|
+
onClick: () => setCellFormat(selectedAddresses, { decimals: (decimals ?? 0) + 1 }),
|
|
2350
|
+
disabled: readOnly,
|
|
2351
|
+
title: "Increase decimal places",
|
|
2352
|
+
children: [
|
|
2353
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px]", children: ".00" }),
|
|
2354
|
+
/* @__PURE__ */ jsx("span", { className: "text-[8px]", children: "\u2192" })
|
|
2355
|
+
]
|
|
2356
|
+
}
|
|
2296
2357
|
)
|
|
2297
2358
|
] }),
|
|
2298
2359
|
/* @__PURE__ */ jsxs("div", { "data-fancy-sheets-formula-bar": "", className: "flex items-center gap-2 border-b border-zinc-200 px-2 py-1 dark:border-zinc-700", children: [
|