@particle-academy/fancy-sheets 0.6.1 → 0.6.3
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 +194 -191
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -8
- package/dist/index.d.ts +16 -8
- package/dist/index.js +144 -145
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
2
|
+
import React$1, { ReactNode } from 'react';
|
|
3
3
|
|
|
4
4
|
/** Column-letter + row-number string, e.g. "A1", "BC42" */
|
|
5
5
|
type CellAddress = string;
|
|
@@ -105,12 +105,14 @@ interface SelectionState {
|
|
|
105
105
|
interface SpreadsheetContextMenuItem {
|
|
106
106
|
/** Display label */
|
|
107
107
|
label: string;
|
|
108
|
-
/** Called with the active cell address when the item is clicked */
|
|
109
|
-
onClick
|
|
108
|
+
/** Called with the active cell address when the item is clicked (omit for submenu parents) */
|
|
109
|
+
onClick?: (address: string) => void;
|
|
110
110
|
/** Whether the item is disabled — static or per-cell function */
|
|
111
111
|
disabled?: boolean | ((address: string) => boolean);
|
|
112
112
|
/** Render with danger styling */
|
|
113
113
|
danger?: boolean;
|
|
114
|
+
/** Nested sub-items — renders as a submenu when present */
|
|
115
|
+
items?: SpreadsheetContextMenuItem[];
|
|
114
116
|
}
|
|
115
117
|
interface SpreadsheetProps {
|
|
116
118
|
children: ReactNode;
|
|
@@ -184,13 +186,17 @@ declare namespace SpreadsheetGrid {
|
|
|
184
186
|
var displayName: string;
|
|
185
187
|
}
|
|
186
188
|
|
|
189
|
+
/** Toolbar button groups that can be toggled on/off */
|
|
190
|
+
type ToolbarButton = "undo" | "bold" | "align" | "freeze" | "format" | "decimals" | "formulaBar";
|
|
187
191
|
interface SpreadsheetToolbarProps {
|
|
188
|
-
children?: React.ReactNode;
|
|
192
|
+
children?: React$1.ReactNode;
|
|
189
193
|
className?: string;
|
|
190
194
|
/** Additional toolbar content appended after default buttons */
|
|
191
|
-
extra?: React.ReactNode;
|
|
195
|
+
extra?: React$1.ReactNode;
|
|
196
|
+
/** Which built-in button groups to show (default: all). Omit to show everything. */
|
|
197
|
+
buttons?: ToolbarButton[];
|
|
192
198
|
}
|
|
193
|
-
declare function SpreadsheetToolbar({ children, className, extra }: SpreadsheetToolbarProps): react_jsx_runtime.JSX.Element;
|
|
199
|
+
declare function SpreadsheetToolbar({ children, className, extra, buttons: buttonsProp }: SpreadsheetToolbarProps): react_jsx_runtime.JSX.Element;
|
|
194
200
|
declare namespace SpreadsheetToolbar {
|
|
195
201
|
var displayName: string;
|
|
196
202
|
}
|
|
@@ -263,10 +269,12 @@ interface SheetWorkbookProps {
|
|
|
263
269
|
hideTabs?: boolean;
|
|
264
270
|
/** Extra content appended to the default toolbar */
|
|
265
271
|
toolbarExtra?: ReactNode;
|
|
272
|
+
/** Which built-in toolbar buttons to show (default: all). Pass [] for only custom extra. */
|
|
273
|
+
toolbarButtons?: ToolbarButton[];
|
|
266
274
|
/** Custom context menu items */
|
|
267
275
|
contextMenuItems?: SpreadsheetContextMenuItem[] | ((address: string) => SpreadsheetContextMenuItem[]);
|
|
268
276
|
}
|
|
269
|
-
declare function SheetWorkbook({ hideToolbar, hideTabs, toolbarExtra, contextMenuItems, ...props }: SheetWorkbookProps): react_jsx_runtime.JSX.Element;
|
|
277
|
+
declare function SheetWorkbook({ hideToolbar, hideTabs, toolbarExtra, toolbarButtons, contextMenuItems, ...props }: SheetWorkbookProps): react_jsx_runtime.JSX.Element;
|
|
270
278
|
declare namespace SheetWorkbook {
|
|
271
279
|
var displayName: string;
|
|
272
280
|
}
|
|
@@ -295,4 +303,4 @@ declare function workbookToCSV(workbook: WorkbookData, sheetId?: string): string
|
|
|
295
303
|
type FormulaRangeFunction = (args: CellValue[][]) => CellValue;
|
|
296
304
|
declare function registerFunction(name: string, fn: FormulaRangeFunction): void;
|
|
297
305
|
|
|
298
|
-
export { type CellAddress, type CellComment, type CellData, type CellFormat, type CellMap, type CellRange, type CellValue, type ColumnWidths, type FormulaRangeFunction, type MergedRegion, type SelectionState, Sheet, type SheetData, type SheetProps, SheetWorkbook, type SheetWorkbookProps, Spreadsheet, type SpreadsheetContextMenuItem, type SpreadsheetContextValue, type SpreadsheetProps, type TextAlign, type WorkbookData, columnToLetter, createEmptySheet, createEmptyWorkbook, csvToWorkbook, letterToColumn, parseAddress, parseCSV, registerFunction, stringifyCSV, toAddress, useSpreadsheet, workbookToCSV };
|
|
306
|
+
export { type CellAddress, type CellComment, type CellData, type CellFormat, type CellMap, type CellRange, type CellValue, type ColumnWidths, type FormulaRangeFunction, type MergedRegion, type SelectionState, Sheet, type SheetData, type SheetProps, SheetWorkbook, type SheetWorkbookProps, Spreadsheet, type SpreadsheetContextMenuItem, type SpreadsheetContextValue, type SpreadsheetProps, type TextAlign, type ToolbarButton, type WorkbookData, columnToLetter, createEmptySheet, createEmptyWorkbook, csvToWorkbook, letterToColumn, parseAddress, parseCSV, registerFunction, stringifyCSV, toAddress, useSpreadsheet, workbookToCSV };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
2
|
+
import React$1, { ReactNode } from 'react';
|
|
3
3
|
|
|
4
4
|
/** Column-letter + row-number string, e.g. "A1", "BC42" */
|
|
5
5
|
type CellAddress = string;
|
|
@@ -105,12 +105,14 @@ interface SelectionState {
|
|
|
105
105
|
interface SpreadsheetContextMenuItem {
|
|
106
106
|
/** Display label */
|
|
107
107
|
label: string;
|
|
108
|
-
/** Called with the active cell address when the item is clicked */
|
|
109
|
-
onClick
|
|
108
|
+
/** Called with the active cell address when the item is clicked (omit for submenu parents) */
|
|
109
|
+
onClick?: (address: string) => void;
|
|
110
110
|
/** Whether the item is disabled — static or per-cell function */
|
|
111
111
|
disabled?: boolean | ((address: string) => boolean);
|
|
112
112
|
/** Render with danger styling */
|
|
113
113
|
danger?: boolean;
|
|
114
|
+
/** Nested sub-items — renders as a submenu when present */
|
|
115
|
+
items?: SpreadsheetContextMenuItem[];
|
|
114
116
|
}
|
|
115
117
|
interface SpreadsheetProps {
|
|
116
118
|
children: ReactNode;
|
|
@@ -184,13 +186,17 @@ declare namespace SpreadsheetGrid {
|
|
|
184
186
|
var displayName: string;
|
|
185
187
|
}
|
|
186
188
|
|
|
189
|
+
/** Toolbar button groups that can be toggled on/off */
|
|
190
|
+
type ToolbarButton = "undo" | "bold" | "align" | "freeze" | "format" | "decimals" | "formulaBar";
|
|
187
191
|
interface SpreadsheetToolbarProps {
|
|
188
|
-
children?: React.ReactNode;
|
|
192
|
+
children?: React$1.ReactNode;
|
|
189
193
|
className?: string;
|
|
190
194
|
/** Additional toolbar content appended after default buttons */
|
|
191
|
-
extra?: React.ReactNode;
|
|
195
|
+
extra?: React$1.ReactNode;
|
|
196
|
+
/** Which built-in button groups to show (default: all). Omit to show everything. */
|
|
197
|
+
buttons?: ToolbarButton[];
|
|
192
198
|
}
|
|
193
|
-
declare function SpreadsheetToolbar({ children, className, extra }: SpreadsheetToolbarProps): react_jsx_runtime.JSX.Element;
|
|
199
|
+
declare function SpreadsheetToolbar({ children, className, extra, buttons: buttonsProp }: SpreadsheetToolbarProps): react_jsx_runtime.JSX.Element;
|
|
194
200
|
declare namespace SpreadsheetToolbar {
|
|
195
201
|
var displayName: string;
|
|
196
202
|
}
|
|
@@ -263,10 +269,12 @@ interface SheetWorkbookProps {
|
|
|
263
269
|
hideTabs?: boolean;
|
|
264
270
|
/** Extra content appended to the default toolbar */
|
|
265
271
|
toolbarExtra?: ReactNode;
|
|
272
|
+
/** Which built-in toolbar buttons to show (default: all). Pass [] for only custom extra. */
|
|
273
|
+
toolbarButtons?: ToolbarButton[];
|
|
266
274
|
/** Custom context menu items */
|
|
267
275
|
contextMenuItems?: SpreadsheetContextMenuItem[] | ((address: string) => SpreadsheetContextMenuItem[]);
|
|
268
276
|
}
|
|
269
|
-
declare function SheetWorkbook({ hideToolbar, hideTabs, toolbarExtra, contextMenuItems, ...props }: SheetWorkbookProps): react_jsx_runtime.JSX.Element;
|
|
277
|
+
declare function SheetWorkbook({ hideToolbar, hideTabs, toolbarExtra, toolbarButtons, contextMenuItems, ...props }: SheetWorkbookProps): react_jsx_runtime.JSX.Element;
|
|
270
278
|
declare namespace SheetWorkbook {
|
|
271
279
|
var displayName: string;
|
|
272
280
|
}
|
|
@@ -295,4 +303,4 @@ declare function workbookToCSV(workbook: WorkbookData, sheetId?: string): string
|
|
|
295
303
|
type FormulaRangeFunction = (args: CellValue[][]) => CellValue;
|
|
296
304
|
declare function registerFunction(name: string, fn: FormulaRangeFunction): void;
|
|
297
305
|
|
|
298
|
-
export { type CellAddress, type CellComment, type CellData, type CellFormat, type CellMap, type CellRange, type CellValue, type ColumnWidths, type FormulaRangeFunction, type MergedRegion, type SelectionState, Sheet, type SheetData, type SheetProps, SheetWorkbook, type SheetWorkbookProps, Spreadsheet, type SpreadsheetContextMenuItem, type SpreadsheetContextValue, type SpreadsheetProps, type TextAlign, type WorkbookData, columnToLetter, createEmptySheet, createEmptyWorkbook, csvToWorkbook, letterToColumn, parseAddress, parseCSV, registerFunction, stringifyCSV, toAddress, useSpreadsheet, workbookToCSV };
|
|
306
|
+
export { type CellAddress, type CellComment, type CellData, type CellFormat, type CellMap, type CellRange, type CellValue, type ColumnWidths, type FormulaRangeFunction, type MergedRegion, type SelectionState, Sheet, type SheetData, type SheetProps, SheetWorkbook, type SheetWorkbookProps, Spreadsheet, type SpreadsheetContextMenuItem, type SpreadsheetContextValue, type SpreadsheetProps, type TextAlign, type ToolbarButton, type WorkbookData, columnToLetter, createEmptySheet, createEmptyWorkbook, csvToWorkbook, letterToColumn, parseAddress, parseCSV, registerFunction, stringifyCSV, toAddress, useSpreadsheet, workbookToCSV };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext, memo, useCallback, useState, useContext, useRef, useEffect, useMemo, useReducer } from 'react';
|
|
1
|
+
import React, { createContext, memo, useCallback, useState, useContext, useRef, useEffect, useMemo, useReducer } from 'react';
|
|
2
2
|
import { cn, ContextMenu } from '@particle-academy/react-fancy';
|
|
3
3
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
|
|
@@ -2033,6 +2033,26 @@ function tsvToCells(tsv) {
|
|
|
2033
2033
|
const cols = Math.max(...values.map((v) => v.length));
|
|
2034
2034
|
return { values, rows, cols };
|
|
2035
2035
|
}
|
|
2036
|
+
function renderMenuItems(items, activeCell) {
|
|
2037
|
+
return items.map((item, i) => {
|
|
2038
|
+
if (item.items && item.items.length > 0) {
|
|
2039
|
+
return /* @__PURE__ */ jsxs(ContextMenu.Sub, { children: [
|
|
2040
|
+
/* @__PURE__ */ jsx(ContextMenu.SubTrigger, { children: item.label }),
|
|
2041
|
+
/* @__PURE__ */ jsx(ContextMenu.SubContent, { children: renderMenuItems(item.items, activeCell) })
|
|
2042
|
+
] }, i);
|
|
2043
|
+
}
|
|
2044
|
+
return /* @__PURE__ */ jsx(
|
|
2045
|
+
ContextMenu.Item,
|
|
2046
|
+
{
|
|
2047
|
+
onClick: () => item.onClick?.(activeCell),
|
|
2048
|
+
disabled: typeof item.disabled === "function" ? item.disabled(activeCell) : item.disabled,
|
|
2049
|
+
danger: item.danger,
|
|
2050
|
+
children: item.label
|
|
2051
|
+
},
|
|
2052
|
+
i
|
|
2053
|
+
);
|
|
2054
|
+
});
|
|
2055
|
+
}
|
|
2036
2056
|
function SpreadsheetGrid({ className }) {
|
|
2037
2057
|
const {
|
|
2038
2058
|
columnCount,
|
|
@@ -2252,25 +2272,17 @@ function SpreadsheetGrid({ className }) {
|
|
|
2252
2272
|
if (!items || items.length === 0) return null;
|
|
2253
2273
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2254
2274
|
/* @__PURE__ */ jsx(ContextMenu.Separator, {}),
|
|
2255
|
-
items
|
|
2256
|
-
ContextMenu.Item,
|
|
2257
|
-
{
|
|
2258
|
-
onClick: () => item.onClick(selection.activeCell),
|
|
2259
|
-
disabled: typeof item.disabled === "function" ? item.disabled(selection.activeCell) : item.disabled,
|
|
2260
|
-
danger: item.danger,
|
|
2261
|
-
children: item.label
|
|
2262
|
-
},
|
|
2263
|
-
i
|
|
2264
|
-
))
|
|
2275
|
+
renderMenuItems(items, selection.activeCell)
|
|
2265
2276
|
] });
|
|
2266
2277
|
})()
|
|
2267
2278
|
] })
|
|
2268
2279
|
] });
|
|
2269
2280
|
}
|
|
2270
2281
|
SpreadsheetGrid.displayName = "SpreadsheetGrid";
|
|
2282
|
+
var ALL_BUTTONS = ["undo", "bold", "align", "freeze", "format", "decimals", "formulaBar"];
|
|
2271
2283
|
var btnClass = "inline-flex items-center justify-center rounded px-2 py-1 text-[12px] font-medium text-zinc-600 transition-colors hover:bg-zinc-100 disabled:opacity-40 dark:text-zinc-300 dark:hover:bg-zinc-800";
|
|
2272
2284
|
var activeBtnClass = "bg-zinc-200 dark:bg-zinc-700";
|
|
2273
|
-
function DefaultToolbar({ extra }) {
|
|
2285
|
+
function DefaultToolbar({ extra, buttons }) {
|
|
2274
2286
|
const {
|
|
2275
2287
|
selection,
|
|
2276
2288
|
activeSheet,
|
|
@@ -2320,105 +2332,97 @@ function DefaultToolbar({ extra }) {
|
|
|
2320
2332
|
}
|
|
2321
2333
|
};
|
|
2322
2334
|
const formulaBarValue = editingCell ? editValue : cell?.formula ? "=" + cell.formula : cell?.value != null ? String(cell.value) : "";
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
}
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
}
|
|
2353
|
-
),
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
] })
|
|
2367
|
-
},
|
|
2368
|
-
align
|
|
2369
|
-
)),
|
|
2370
|
-
/* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-zinc-200 dark:bg-zinc-700" }),
|
|
2371
|
-
/* @__PURE__ */ jsx(
|
|
2372
|
-
"button",
|
|
2373
|
-
{
|
|
2374
|
-
className: cn(btnClass, activeSheet.frozenRows > 0 && activeBtnClass),
|
|
2375
|
-
onClick: () => {
|
|
2376
|
-
if (activeSheet.frozenRows > 0) {
|
|
2377
|
-
setFrozenRows(0);
|
|
2378
|
-
} else {
|
|
2379
|
-
const row = selection.activeCell.match(/\d+/);
|
|
2380
|
-
setFrozenRows(row ? parseInt(row[0], 10) - 1 || 1 : 1);
|
|
2381
|
-
}
|
|
2382
|
-
},
|
|
2383
|
-
disabled: readOnly,
|
|
2384
|
-
title: activeSheet.frozenRows > 0 ? `Unfreeze rows (${activeSheet.frozenRows} frozen)` : "Freeze rows above current cell",
|
|
2385
|
-
children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
|
|
2386
|
-
/* @__PURE__ */ jsx("line", { x1: "3", y1: "9", x2: "21", y2: "9" }),
|
|
2387
|
-
/* @__PURE__ */ jsx("line", { x1: "3", y1: "4", x2: "21", y2: "4" }),
|
|
2388
|
-
/* @__PURE__ */ jsx("line", { x1: "3", y1: "14", x2: "21", y2: "14", strokeDasharray: "3 3" }),
|
|
2389
|
-
/* @__PURE__ */ jsx("line", { x1: "3", y1: "19", x2: "21", y2: "19", strokeDasharray: "3 3" })
|
|
2390
|
-
] })
|
|
2391
|
-
}
|
|
2392
|
-
),
|
|
2393
|
-
/* @__PURE__ */ jsx(
|
|
2394
|
-
"button",
|
|
2395
|
-
{
|
|
2396
|
-
className: cn(btnClass, activeSheet.frozenCols > 0 && activeBtnClass),
|
|
2397
|
-
onClick: () => {
|
|
2398
|
-
if (activeSheet.frozenCols > 0) {
|
|
2399
|
-
setFrozenCols(0);
|
|
2400
|
-
} else {
|
|
2401
|
-
const colMatch = selection.activeCell.match(/^([A-Z]+)/);
|
|
2402
|
-
if (colMatch) {
|
|
2403
|
-
const col = colMatch[1].split("").reduce((acc, ch) => acc * 26 + ch.charCodeAt(0) - 64, 0) - 1;
|
|
2404
|
-
setFrozenCols(col || 1);
|
|
2335
|
+
const divider = /* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-zinc-200 dark:bg-zinc-700" });
|
|
2336
|
+
const groups = [];
|
|
2337
|
+
if (buttons.has("undo")) {
|
|
2338
|
+
groups.push(
|
|
2339
|
+
/* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
2340
|
+
/* @__PURE__ */ jsx("button", { className: btnClass, onClick: undo, disabled: !canUndo || readOnly, title: "Undo (Ctrl+Z)", children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2341
|
+
/* @__PURE__ */ jsx("polyline", { points: "1 4 1 10 7 10" }),
|
|
2342
|
+
/* @__PURE__ */ jsx("path", { d: "M3.51 15a9 9 0 1 0 2.13-9.36L1 10" })
|
|
2343
|
+
] }) }),
|
|
2344
|
+
/* @__PURE__ */ jsx("button", { className: btnClass, onClick: redo, disabled: !canRedo || readOnly, title: "Redo (Ctrl+Y)", children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2345
|
+
/* @__PURE__ */ jsx("polyline", { points: "23 4 23 10 17 10" }),
|
|
2346
|
+
/* @__PURE__ */ jsx("path", { d: "M20.49 15a9 9 0 1 1-2.12-9.36L23 10" })
|
|
2347
|
+
] }) })
|
|
2348
|
+
] }, "undo")
|
|
2349
|
+
);
|
|
2350
|
+
}
|
|
2351
|
+
if (buttons.has("bold")) {
|
|
2352
|
+
groups.push(
|
|
2353
|
+
/* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
2354
|
+
/* @__PURE__ */ jsx("button", { className: cn(btnClass, isBold && activeBtnClass), onClick: () => setCellFormat(selectedAddresses, { bold: !isBold }), disabled: readOnly, title: "Bold", children: /* @__PURE__ */ jsx("span", { className: "font-bold", children: "B" }) }),
|
|
2355
|
+
/* @__PURE__ */ jsx("button", { className: cn(btnClass, isItalic && activeBtnClass), onClick: () => setCellFormat(selectedAddresses, { italic: !isItalic }), disabled: readOnly, title: "Italic", children: /* @__PURE__ */ jsx("span", { className: "italic", children: "I" }) })
|
|
2356
|
+
] }, "bold")
|
|
2357
|
+
);
|
|
2358
|
+
}
|
|
2359
|
+
if (buttons.has("align")) {
|
|
2360
|
+
groups.push(
|
|
2361
|
+
/* @__PURE__ */ jsx(React.Fragment, { children: ["left", "center", "right"].map((align) => /* @__PURE__ */ jsx("button", { className: cn(btnClass, textAlign === align && activeBtnClass), onClick: () => setCellFormat(selectedAddresses, { textAlign: align }), disabled: readOnly, title: `Align ${align}`, children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
|
|
2362
|
+
/* @__PURE__ */ jsx("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
|
|
2363
|
+
/* @__PURE__ */ jsx("line", { x1: align === "left" ? "3" : align === "center" ? "6" : "9", y1: "12", x2: align === "left" ? "15" : align === "center" ? "18" : "21", y2: "12" }),
|
|
2364
|
+
/* @__PURE__ */ jsx("line", { x1: "3", y1: "18", x2: "21", y2: "18" })
|
|
2365
|
+
] }) }, align)) }, "align")
|
|
2366
|
+
);
|
|
2367
|
+
}
|
|
2368
|
+
if (buttons.has("freeze")) {
|
|
2369
|
+
groups.push(
|
|
2370
|
+
/* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
2371
|
+
/* @__PURE__ */ jsx(
|
|
2372
|
+
"button",
|
|
2373
|
+
{
|
|
2374
|
+
className: cn(btnClass, activeSheet.frozenRows > 0 && activeBtnClass),
|
|
2375
|
+
onClick: () => {
|
|
2376
|
+
if (activeSheet.frozenRows > 0) {
|
|
2377
|
+
setFrozenRows(0);
|
|
2405
2378
|
} else {
|
|
2406
|
-
|
|
2379
|
+
const row = selection.activeCell.match(/\d+/);
|
|
2380
|
+
setFrozenRows(row ? parseInt(row[0], 10) - 1 || 1 : 1);
|
|
2407
2381
|
}
|
|
2408
|
-
}
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2382
|
+
},
|
|
2383
|
+
disabled: readOnly,
|
|
2384
|
+
title: activeSheet.frozenRows > 0 ? `Unfreeze rows (${activeSheet.frozenRows} frozen)` : "Freeze rows above current cell",
|
|
2385
|
+
children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
|
|
2386
|
+
/* @__PURE__ */ jsx("line", { x1: "3", y1: "9", x2: "21", y2: "9" }),
|
|
2387
|
+
/* @__PURE__ */ jsx("line", { x1: "3", y1: "4", x2: "21", y2: "4" }),
|
|
2388
|
+
/* @__PURE__ */ jsx("line", { x1: "3", y1: "14", x2: "21", y2: "14", strokeDasharray: "3 3" }),
|
|
2389
|
+
/* @__PURE__ */ jsx("line", { x1: "3", y1: "19", x2: "21", y2: "19", strokeDasharray: "3 3" })
|
|
2390
|
+
] })
|
|
2391
|
+
}
|
|
2392
|
+
),
|
|
2393
|
+
/* @__PURE__ */ jsx(
|
|
2394
|
+
"button",
|
|
2395
|
+
{
|
|
2396
|
+
className: cn(btnClass, activeSheet.frozenCols > 0 && activeBtnClass),
|
|
2397
|
+
onClick: () => {
|
|
2398
|
+
if (activeSheet.frozenCols > 0) {
|
|
2399
|
+
setFrozenCols(0);
|
|
2400
|
+
} else {
|
|
2401
|
+
const colMatch = selection.activeCell.match(/^([A-Z]+)/);
|
|
2402
|
+
if (colMatch) {
|
|
2403
|
+
const col = colMatch[1].split("").reduce((acc, ch) => acc * 26 + ch.charCodeAt(0) - 64, 0) - 1;
|
|
2404
|
+
setFrozenCols(col || 1);
|
|
2405
|
+
} else {
|
|
2406
|
+
setFrozenCols(1);
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
},
|
|
2410
|
+
disabled: readOnly,
|
|
2411
|
+
title: activeSheet.frozenCols > 0 ? `Unfreeze columns (${activeSheet.frozenCols} frozen)` : "Freeze columns left of current cell",
|
|
2412
|
+
children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
|
|
2413
|
+
/* @__PURE__ */ jsx("line", { x1: "9", y1: "3", x2: "9", y2: "21" }),
|
|
2414
|
+
/* @__PURE__ */ jsx("line", { x1: "4", y1: "3", x2: "4", y2: "21" }),
|
|
2415
|
+
/* @__PURE__ */ jsx("line", { x1: "14", y1: "3", x2: "14", y2: "21", strokeDasharray: "3 3" }),
|
|
2416
|
+
/* @__PURE__ */ jsx("line", { x1: "19", y1: "3", x2: "19", y2: "21", strokeDasharray: "3 3" })
|
|
2417
|
+
] })
|
|
2418
|
+
}
|
|
2419
|
+
)
|
|
2420
|
+
] }, "freeze")
|
|
2421
|
+
);
|
|
2422
|
+
}
|
|
2423
|
+
if (buttons.has("format")) {
|
|
2424
|
+
groups.push(
|
|
2425
|
+
/* @__PURE__ */ jsx(React.Fragment, { children: /* @__PURE__ */ jsxs(
|
|
2422
2426
|
"select",
|
|
2423
2427
|
{
|
|
2424
2428
|
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",
|
|
@@ -2436,39 +2440,32 @@ function DefaultToolbar({ extra }) {
|
|
|
2436
2440
|
/* @__PURE__ */ jsx("option", { value: "datetime", children: "Date & Time" })
|
|
2437
2441
|
]
|
|
2438
2442
|
}
|
|
2439
|
-
),
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
children:
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
]
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
),
|
|
2466
|
-
extra && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2467
|
-
/* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-zinc-200 dark:bg-zinc-700" }),
|
|
2468
|
-
extra
|
|
2469
|
-
] })
|
|
2470
|
-
] }),
|
|
2471
|
-
/* @__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: [
|
|
2443
|
+
) }, "format")
|
|
2444
|
+
);
|
|
2445
|
+
}
|
|
2446
|
+
if (buttons.has("decimals")) {
|
|
2447
|
+
groups.push(
|
|
2448
|
+
/* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
2449
|
+
/* @__PURE__ */ jsxs("button", { className: btnClass, onClick: () => setCellFormat(selectedAddresses, { decimals: Math.max(0, currentDecimals - 1) }), disabled: readOnly || currentDecimals <= 0, title: `Decrease decimal places (currently ${currentDecimals})`, children: [
|
|
2450
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px]", children: ".0" }),
|
|
2451
|
+
/* @__PURE__ */ jsx("span", { className: "text-[8px]", children: "\u2190" })
|
|
2452
|
+
] }),
|
|
2453
|
+
/* @__PURE__ */ jsxs("button", { className: btnClass, onClick: () => setCellFormat(selectedAddresses, { decimals: currentDecimals + 1 }), disabled: readOnly, title: `Increase decimal places (currently ${currentDecimals})`, children: [
|
|
2454
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px]", children: ".00" }),
|
|
2455
|
+
/* @__PURE__ */ jsx("span", { className: "text-[8px]", children: "\u2192" })
|
|
2456
|
+
] })
|
|
2457
|
+
] }, "decimals")
|
|
2458
|
+
);
|
|
2459
|
+
}
|
|
2460
|
+
if (extra) {
|
|
2461
|
+
groups.push(/* @__PURE__ */ jsx(React.Fragment, { children: extra }, "extra"));
|
|
2462
|
+
}
|
|
2463
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2464
|
+
groups.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5 border-b border-zinc-200 px-1.5 py-1 dark:border-zinc-700", children: groups.map((group, i) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
2465
|
+
i > 0 && divider,
|
|
2466
|
+
group
|
|
2467
|
+
] }, i)) }),
|
|
2468
|
+
buttons.has("formulaBar") && /* @__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: [
|
|
2472
2469
|
/* @__PURE__ */ jsx("span", { className: "w-12 shrink-0 text-center text-[11px] font-medium text-zinc-500 dark:text-zinc-400", children: selection.activeCell }),
|
|
2473
2470
|
/* @__PURE__ */ jsx("div", { className: "h-4 w-px bg-zinc-200 dark:bg-zinc-700" }),
|
|
2474
2471
|
/* @__PURE__ */ jsx(
|
|
@@ -2485,8 +2482,9 @@ function DefaultToolbar({ extra }) {
|
|
|
2485
2482
|
] })
|
|
2486
2483
|
] });
|
|
2487
2484
|
}
|
|
2488
|
-
function SpreadsheetToolbar({ children, className, extra }) {
|
|
2489
|
-
|
|
2485
|
+
function SpreadsheetToolbar({ children, className, extra, buttons: buttonsProp }) {
|
|
2486
|
+
const buttonsSet = new Set(buttonsProp ?? ALL_BUTTONS);
|
|
2487
|
+
return /* @__PURE__ */ jsx("div", { "data-fancy-sheets-toolbar": "", className: cn("", className), children: children ?? /* @__PURE__ */ jsx(DefaultToolbar, { extra, buttons: buttonsSet }) });
|
|
2490
2488
|
}
|
|
2491
2489
|
SpreadsheetToolbar.displayName = "SpreadsheetToolbar";
|
|
2492
2490
|
function SpreadsheetSheetTabs({ className }) {
|
|
@@ -2685,11 +2683,12 @@ function SheetWorkbook({
|
|
|
2685
2683
|
hideToolbar = false,
|
|
2686
2684
|
hideTabs = false,
|
|
2687
2685
|
toolbarExtra,
|
|
2686
|
+
toolbarButtons,
|
|
2688
2687
|
contextMenuItems,
|
|
2689
2688
|
...props
|
|
2690
2689
|
}) {
|
|
2691
2690
|
return /* @__PURE__ */ jsxs(Spreadsheet, { ...props, contextMenuItems, children: [
|
|
2692
|
-
!hideToolbar && /* @__PURE__ */ jsx(Spreadsheet.Toolbar, { extra: toolbarExtra }),
|
|
2691
|
+
!hideToolbar && /* @__PURE__ */ jsx(Spreadsheet.Toolbar, { extra: toolbarExtra, buttons: toolbarButtons }),
|
|
2693
2692
|
/* @__PURE__ */ jsx(Spreadsheet.Grid, {}),
|
|
2694
2693
|
!hideTabs && /* @__PURE__ */ jsx(Spreadsheet.SheetTabs, {})
|
|
2695
2694
|
] });
|