@particle-academy/fancy-sheets 0.6.1 → 0.6.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.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;
@@ -184,13 +184,17 @@ declare namespace SpreadsheetGrid {
184
184
  var displayName: string;
185
185
  }
186
186
 
187
+ /** Toolbar button groups that can be toggled on/off */
188
+ type ToolbarButton = "undo" | "bold" | "align" | "freeze" | "format" | "decimals" | "formulaBar";
187
189
  interface SpreadsheetToolbarProps {
188
- children?: React.ReactNode;
190
+ children?: React$1.ReactNode;
189
191
  className?: string;
190
192
  /** Additional toolbar content appended after default buttons */
191
- extra?: React.ReactNode;
193
+ extra?: React$1.ReactNode;
194
+ /** Which built-in button groups to show (default: all). Omit to show everything. */
195
+ buttons?: ToolbarButton[];
192
196
  }
193
- declare function SpreadsheetToolbar({ children, className, extra }: SpreadsheetToolbarProps): react_jsx_runtime.JSX.Element;
197
+ declare function SpreadsheetToolbar({ children, className, extra, buttons: buttonsProp }: SpreadsheetToolbarProps): react_jsx_runtime.JSX.Element;
194
198
  declare namespace SpreadsheetToolbar {
195
199
  var displayName: string;
196
200
  }
@@ -263,10 +267,12 @@ interface SheetWorkbookProps {
263
267
  hideTabs?: boolean;
264
268
  /** Extra content appended to the default toolbar */
265
269
  toolbarExtra?: ReactNode;
270
+ /** Which built-in toolbar buttons to show (default: all). Pass [] for only custom extra. */
271
+ toolbarButtons?: ToolbarButton[];
266
272
  /** Custom context menu items */
267
273
  contextMenuItems?: SpreadsheetContextMenuItem[] | ((address: string) => SpreadsheetContextMenuItem[]);
268
274
  }
269
- declare function SheetWorkbook({ hideToolbar, hideTabs, toolbarExtra, contextMenuItems, ...props }: SheetWorkbookProps): react_jsx_runtime.JSX.Element;
275
+ declare function SheetWorkbook({ hideToolbar, hideTabs, toolbarExtra, toolbarButtons, contextMenuItems, ...props }: SheetWorkbookProps): react_jsx_runtime.JSX.Element;
270
276
  declare namespace SheetWorkbook {
271
277
  var displayName: string;
272
278
  }
@@ -295,4 +301,4 @@ declare function workbookToCSV(workbook: WorkbookData, sheetId?: string): string
295
301
  type FormulaRangeFunction = (args: CellValue[][]) => CellValue;
296
302
  declare function registerFunction(name: string, fn: FormulaRangeFunction): void;
297
303
 
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 };
304
+ 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;
@@ -184,13 +184,17 @@ declare namespace SpreadsheetGrid {
184
184
  var displayName: string;
185
185
  }
186
186
 
187
+ /** Toolbar button groups that can be toggled on/off */
188
+ type ToolbarButton = "undo" | "bold" | "align" | "freeze" | "format" | "decimals" | "formulaBar";
187
189
  interface SpreadsheetToolbarProps {
188
- children?: React.ReactNode;
190
+ children?: React$1.ReactNode;
189
191
  className?: string;
190
192
  /** Additional toolbar content appended after default buttons */
191
- extra?: React.ReactNode;
193
+ extra?: React$1.ReactNode;
194
+ /** Which built-in button groups to show (default: all). Omit to show everything. */
195
+ buttons?: ToolbarButton[];
192
196
  }
193
- declare function SpreadsheetToolbar({ children, className, extra }: SpreadsheetToolbarProps): react_jsx_runtime.JSX.Element;
197
+ declare function SpreadsheetToolbar({ children, className, extra, buttons: buttonsProp }: SpreadsheetToolbarProps): react_jsx_runtime.JSX.Element;
194
198
  declare namespace SpreadsheetToolbar {
195
199
  var displayName: string;
196
200
  }
@@ -263,10 +267,12 @@ interface SheetWorkbookProps {
263
267
  hideTabs?: boolean;
264
268
  /** Extra content appended to the default toolbar */
265
269
  toolbarExtra?: ReactNode;
270
+ /** Which built-in toolbar buttons to show (default: all). Pass [] for only custom extra. */
271
+ toolbarButtons?: ToolbarButton[];
266
272
  /** Custom context menu items */
267
273
  contextMenuItems?: SpreadsheetContextMenuItem[] | ((address: string) => SpreadsheetContextMenuItem[]);
268
274
  }
269
- declare function SheetWorkbook({ hideToolbar, hideTabs, toolbarExtra, contextMenuItems, ...props }: SheetWorkbookProps): react_jsx_runtime.JSX.Element;
275
+ declare function SheetWorkbook({ hideToolbar, hideTabs, toolbarExtra, toolbarButtons, contextMenuItems, ...props }: SheetWorkbookProps): react_jsx_runtime.JSX.Element;
270
276
  declare namespace SheetWorkbook {
271
277
  var displayName: string;
272
278
  }
@@ -295,4 +301,4 @@ declare function workbookToCSV(workbook: WorkbookData, sheetId?: string): string
295
301
  type FormulaRangeFunction = (args: CellValue[][]) => CellValue;
296
302
  declare function registerFunction(name: string, fn: FormulaRangeFunction): void;
297
303
 
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 };
304
+ 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
 
@@ -2268,9 +2268,10 @@ function SpreadsheetGrid({ className }) {
2268
2268
  ] });
2269
2269
  }
2270
2270
  SpreadsheetGrid.displayName = "SpreadsheetGrid";
2271
+ var ALL_BUTTONS = ["undo", "bold", "align", "freeze", "format", "decimals", "formulaBar"];
2271
2272
  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
2273
  var activeBtnClass = "bg-zinc-200 dark:bg-zinc-700";
2273
- function DefaultToolbar({ extra }) {
2274
+ function DefaultToolbar({ extra, buttons }) {
2274
2275
  const {
2275
2276
  selection,
2276
2277
  activeSheet,
@@ -2320,105 +2321,97 @@ function DefaultToolbar({ extra }) {
2320
2321
  }
2321
2322
  };
2322
2323
  const formulaBarValue = editingCell ? editValue : cell?.formula ? "=" + cell.formula : cell?.value != null ? String(cell.value) : "";
2323
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2324
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 border-b border-zinc-200 px-1.5 py-1 dark:border-zinc-700", children: [
2325
- /* @__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: [
2326
- /* @__PURE__ */ jsx("polyline", { points: "1 4 1 10 7 10" }),
2327
- /* @__PURE__ */ jsx("path", { d: "M3.51 15a9 9 0 1 0 2.13-9.36L1 10" })
2328
- ] }) }),
2329
- /* @__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: [
2330
- /* @__PURE__ */ jsx("polyline", { points: "23 4 23 10 17 10" }),
2331
- /* @__PURE__ */ jsx("path", { d: "M20.49 15a9 9 0 1 1-2.12-9.36L23 10" })
2332
- ] }) }),
2333
- /* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-zinc-200 dark:bg-zinc-700" }),
2334
- /* @__PURE__ */ jsx(
2335
- "button",
2336
- {
2337
- className: cn(btnClass, isBold && activeBtnClass),
2338
- onClick: () => setCellFormat(selectedAddresses, { bold: !isBold }),
2339
- disabled: readOnly,
2340
- title: "Bold",
2341
- children: /* @__PURE__ */ jsx("span", { className: "font-bold", children: "B" })
2342
- }
2343
- ),
2344
- /* @__PURE__ */ jsx(
2345
- "button",
2346
- {
2347
- className: cn(btnClass, isItalic && activeBtnClass),
2348
- onClick: () => setCellFormat(selectedAddresses, { italic: !isItalic }),
2349
- disabled: readOnly,
2350
- title: "Italic",
2351
- children: /* @__PURE__ */ jsx("span", { className: "italic", children: "I" })
2352
- }
2353
- ),
2354
- /* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-zinc-200 dark:bg-zinc-700" }),
2355
- ["left", "center", "right"].map((align) => /* @__PURE__ */ jsx(
2356
- "button",
2357
- {
2358
- className: cn(btnClass, textAlign === align && activeBtnClass),
2359
- onClick: () => setCellFormat(selectedAddresses, { textAlign: align }),
2360
- disabled: readOnly,
2361
- title: `Align ${align}`,
2362
- children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
2363
- /* @__PURE__ */ jsx("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
2364
- /* @__PURE__ */ jsx("line", { x1: align === "left" ? "3" : align === "center" ? "6" : "9", y1: "12", x2: align === "left" ? "15" : align === "center" ? "18" : "21", y2: "12" }),
2365
- /* @__PURE__ */ jsx("line", { x1: "3", y1: "18", x2: "21", y2: "18" })
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);
2324
+ const divider = /* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-zinc-200 dark:bg-zinc-700" });
2325
+ const groups = [];
2326
+ if (buttons.has("undo")) {
2327
+ groups.push(
2328
+ /* @__PURE__ */ jsxs(React.Fragment, { children: [
2329
+ /* @__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: [
2330
+ /* @__PURE__ */ jsx("polyline", { points: "1 4 1 10 7 10" }),
2331
+ /* @__PURE__ */ jsx("path", { d: "M3.51 15a9 9 0 1 0 2.13-9.36L1 10" })
2332
+ ] }) }),
2333
+ /* @__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: [
2334
+ /* @__PURE__ */ jsx("polyline", { points: "23 4 23 10 17 10" }),
2335
+ /* @__PURE__ */ jsx("path", { d: "M20.49 15a9 9 0 1 1-2.12-9.36L23 10" })
2336
+ ] }) })
2337
+ ] }, "undo")
2338
+ );
2339
+ }
2340
+ if (buttons.has("bold")) {
2341
+ groups.push(
2342
+ /* @__PURE__ */ jsxs(React.Fragment, { children: [
2343
+ /* @__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" }) }),
2344
+ /* @__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" }) })
2345
+ ] }, "bold")
2346
+ );
2347
+ }
2348
+ if (buttons.has("align")) {
2349
+ groups.push(
2350
+ /* @__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: [
2351
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "6", x2: "21", y2: "6" }),
2352
+ /* @__PURE__ */ jsx("line", { x1: align === "left" ? "3" : align === "center" ? "6" : "9", y1: "12", x2: align === "left" ? "15" : align === "center" ? "18" : "21", y2: "12" }),
2353
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "18", x2: "21", y2: "18" })
2354
+ ] }) }, align)) }, "align")
2355
+ );
2356
+ }
2357
+ if (buttons.has("freeze")) {
2358
+ groups.push(
2359
+ /* @__PURE__ */ jsxs(React.Fragment, { children: [
2360
+ /* @__PURE__ */ jsx(
2361
+ "button",
2362
+ {
2363
+ className: cn(btnClass, activeSheet.frozenRows > 0 && activeBtnClass),
2364
+ onClick: () => {
2365
+ if (activeSheet.frozenRows > 0) {
2366
+ setFrozenRows(0);
2405
2367
  } else {
2406
- setFrozenCols(1);
2368
+ const row = selection.activeCell.match(/\d+/);
2369
+ setFrozenRows(row ? parseInt(row[0], 10) - 1 || 1 : 1);
2407
2370
  }
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
- /* @__PURE__ */ jsx("div", { className: "mx-1 h-4 w-px bg-zinc-200 dark:bg-zinc-700" }),
2421
- /* @__PURE__ */ jsxs(
2371
+ },
2372
+ disabled: readOnly,
2373
+ title: activeSheet.frozenRows > 0 ? `Unfreeze rows (${activeSheet.frozenRows} frozen)` : "Freeze rows above current cell",
2374
+ children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
2375
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "9", x2: "21", y2: "9" }),
2376
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "4", x2: "21", y2: "4" }),
2377
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "14", x2: "21", y2: "14", strokeDasharray: "3 3" }),
2378
+ /* @__PURE__ */ jsx("line", { x1: "3", y1: "19", x2: "21", y2: "19", strokeDasharray: "3 3" })
2379
+ ] })
2380
+ }
2381
+ ),
2382
+ /* @__PURE__ */ jsx(
2383
+ "button",
2384
+ {
2385
+ className: cn(btnClass, activeSheet.frozenCols > 0 && activeBtnClass),
2386
+ onClick: () => {
2387
+ if (activeSheet.frozenCols > 0) {
2388
+ setFrozenCols(0);
2389
+ } else {
2390
+ const colMatch = selection.activeCell.match(/^([A-Z]+)/);
2391
+ if (colMatch) {
2392
+ const col = colMatch[1].split("").reduce((acc, ch) => acc * 26 + ch.charCodeAt(0) - 64, 0) - 1;
2393
+ setFrozenCols(col || 1);
2394
+ } else {
2395
+ setFrozenCols(1);
2396
+ }
2397
+ }
2398
+ },
2399
+ disabled: readOnly,
2400
+ title: activeSheet.frozenCols > 0 ? `Unfreeze columns (${activeSheet.frozenCols} frozen)` : "Freeze columns left of current cell",
2401
+ children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [
2402
+ /* @__PURE__ */ jsx("line", { x1: "9", y1: "3", x2: "9", y2: "21" }),
2403
+ /* @__PURE__ */ jsx("line", { x1: "4", y1: "3", x2: "4", y2: "21" }),
2404
+ /* @__PURE__ */ jsx("line", { x1: "14", y1: "3", x2: "14", y2: "21", strokeDasharray: "3 3" }),
2405
+ /* @__PURE__ */ jsx("line", { x1: "19", y1: "3", x2: "19", y2: "21", strokeDasharray: "3 3" })
2406
+ ] })
2407
+ }
2408
+ )
2409
+ ] }, "freeze")
2410
+ );
2411
+ }
2412
+ if (buttons.has("format")) {
2413
+ groups.push(
2414
+ /* @__PURE__ */ jsx(React.Fragment, { children: /* @__PURE__ */ jsxs(
2422
2415
  "select",
2423
2416
  {
2424
2417
  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 +2429,32 @@ function DefaultToolbar({ extra }) {
2436
2429
  /* @__PURE__ */ jsx("option", { value: "datetime", children: "Date & Time" })
2437
2430
  ]
2438
2431
  }
2439
- ),
2440
- /* @__PURE__ */ jsxs(
2441
- "button",
2442
- {
2443
- className: btnClass,
2444
- onClick: () => setCellFormat(selectedAddresses, { decimals: Math.max(0, currentDecimals - 1) }),
2445
- disabled: readOnly || currentDecimals <= 0,
2446
- title: `Decrease decimal places (currently ${currentDecimals})`,
2447
- children: [
2448
- /* @__PURE__ */ jsx("span", { className: "text-[10px]", children: ".0" }),
2449
- /* @__PURE__ */ jsx("span", { className: "text-[8px]", children: "\u2190" })
2450
- ]
2451
- }
2452
- ),
2453
- /* @__PURE__ */ jsxs(
2454
- "button",
2455
- {
2456
- className: btnClass,
2457
- onClick: () => setCellFormat(selectedAddresses, { decimals: currentDecimals + 1 }),
2458
- disabled: readOnly,
2459
- title: `Increase decimal places (currently ${currentDecimals})`,
2460
- children: [
2461
- /* @__PURE__ */ jsx("span", { className: "text-[10px]", children: ".00" }),
2462
- /* @__PURE__ */ jsx("span", { className: "text-[8px]", children: "\u2192" })
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: [
2432
+ ) }, "format")
2433
+ );
2434
+ }
2435
+ if (buttons.has("decimals")) {
2436
+ groups.push(
2437
+ /* @__PURE__ */ jsxs(React.Fragment, { children: [
2438
+ /* @__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: [
2439
+ /* @__PURE__ */ jsx("span", { className: "text-[10px]", children: ".0" }),
2440
+ /* @__PURE__ */ jsx("span", { className: "text-[8px]", children: "\u2190" })
2441
+ ] }),
2442
+ /* @__PURE__ */ jsxs("button", { className: btnClass, onClick: () => setCellFormat(selectedAddresses, { decimals: currentDecimals + 1 }), disabled: readOnly, title: `Increase decimal places (currently ${currentDecimals})`, children: [
2443
+ /* @__PURE__ */ jsx("span", { className: "text-[10px]", children: ".00" }),
2444
+ /* @__PURE__ */ jsx("span", { className: "text-[8px]", children: "\u2192" })
2445
+ ] })
2446
+ ] }, "decimals")
2447
+ );
2448
+ }
2449
+ if (extra) {
2450
+ groups.push(/* @__PURE__ */ jsx(React.Fragment, { children: extra }, "extra"));
2451
+ }
2452
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2453
+ 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: [
2454
+ i > 0 && divider,
2455
+ group
2456
+ ] }, i)) }),
2457
+ 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
2458
  /* @__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
2459
  /* @__PURE__ */ jsx("div", { className: "h-4 w-px bg-zinc-200 dark:bg-zinc-700" }),
2474
2460
  /* @__PURE__ */ jsx(
@@ -2485,8 +2471,9 @@ function DefaultToolbar({ extra }) {
2485
2471
  ] })
2486
2472
  ] });
2487
2473
  }
2488
- function SpreadsheetToolbar({ children, className, extra }) {
2489
- return /* @__PURE__ */ jsx("div", { "data-fancy-sheets-toolbar": "", className: cn("", className), children: children ?? /* @__PURE__ */ jsx(DefaultToolbar, { extra }) });
2474
+ function SpreadsheetToolbar({ children, className, extra, buttons: buttonsProp }) {
2475
+ const buttonsSet = new Set(buttonsProp ?? ALL_BUTTONS);
2476
+ return /* @__PURE__ */ jsx("div", { "data-fancy-sheets-toolbar": "", className: cn("", className), children: children ?? /* @__PURE__ */ jsx(DefaultToolbar, { extra, buttons: buttonsSet }) });
2490
2477
  }
2491
2478
  SpreadsheetToolbar.displayName = "SpreadsheetToolbar";
2492
2479
  function SpreadsheetSheetTabs({ className }) {
@@ -2685,11 +2672,12 @@ function SheetWorkbook({
2685
2672
  hideToolbar = false,
2686
2673
  hideTabs = false,
2687
2674
  toolbarExtra,
2675
+ toolbarButtons,
2688
2676
  contextMenuItems,
2689
2677
  ...props
2690
2678
  }) {
2691
2679
  return /* @__PURE__ */ jsxs(Spreadsheet, { ...props, contextMenuItems, children: [
2692
- !hideToolbar && /* @__PURE__ */ jsx(Spreadsheet.Toolbar, { extra: toolbarExtra }),
2680
+ !hideToolbar && /* @__PURE__ */ jsx(Spreadsheet.Toolbar, { extra: toolbarExtra, buttons: toolbarButtons }),
2693
2681
  /* @__PURE__ */ jsx(Spreadsheet.Grid, {}),
2694
2682
  !hideTabs && /* @__PURE__ */ jsx(Spreadsheet.SheetTabs, {})
2695
2683
  ] });