import type { GridEvent, SheetChangeEvent, CellEvent, ExternalEditorConfig, GridSelectionEvent } from '../../treb-grid/src/index'; import { DataModel, Sheet } from '../../treb-data-model/src/index'; import type { SerializeOptions, Annotation, AnnotationType, GridSelection, ConnectedElementType, SerializedModel, FreezePane, ConditionalFormatDuplicateValuesOptions, ConditionalFormatGradientOptions, ConditionalFormat, StandardGradient, CondifionalFormatExpressionOptions, ConditionalFormatCellMatchOptions, SerializedNamed, ConditionalFormatDataBarOptions, ConditionalFormatType, AnnotationData } from '../../treb-data-model/src/index'; import { Grid, BorderConstants, ErrorCode } from '../../treb-grid/src/index'; import { Parser } from '../../treb-parser/src/index'; import 'extended-function-lib'; import { Calculator } from '../../treb-calculator/src/index'; import type { ICellAddress, EvaluateOptions, IArea, CellValue, Point, Complex, IRectangle, AddressReference, RangeReference, TableSortOptions, Table, TableTheme } from '../../treb-base-types/src/index'; import { type CellStyle, Localization, type Color, Area, DOMContext } from '../../treb-base-types/src/index'; import { EventSource } from '../../treb-utils/src/index'; import { Dialog } from './progress-dialog'; import { Spinner } from './spinner'; import { type EmbeddedSpreadsheetOptions, type ExportOptions } from './options'; import { type TREBDocument, LoadSource, type EmbeddedSheetEvent, type InsertTableOptions } from './types'; import type { SelectionState } from './selection-state'; import type { ToolbarMessage } from './toolbar-message'; import { Chart } from '../../treb-charts/src/index'; import type { SetRangeOptions, ClipboardData, PasteOptions } from '../../treb-grid/src/index'; import * as ImportExportMessages from '../../treb-export/src/import-export-messages'; /** * import type for our worker, plus markup files */ import { type WorkerProxy } from '../../treb-base-types/src/index'; import type { CustomGridFactory } from './custom-grid-factory'; /** * options for saving files. we add the option for JSON formatting. */ export interface SaveOptions extends SerializeOptions { /** pretty json formatting */ pretty?: boolean; } declare enum CalculationOptions { automatic = 0, manual = 1 } declare enum FileChooserOperation { None = 0, LoadFile = 1, InsertImage = 2 } /** * @internal */ export interface ToolbarCtl { Show: (show: boolean) => void; } declare enum SemanticVersionElement { major = 0, minor = 1, patch = 2 } interface SemanticVersionComparison { match: number; level?: SemanticVersionElement; } /** * options for the LoadDocument method */ export interface LoadDocumentOptions { scroll?: string | ICellAddress; flush?: boolean; recalculate?: boolean; override_sheet?: string; /** @internal */ override_selection?: GridSelection; source?: LoadSource; /** opaque data for reference */ path?: string; } /** * options for the GetRange method */ export interface GetRangeOptions { /** * return formatted values (apply number formats and return strings) * @deprecated */ formatted?: boolean; /** * return formulas instead of values. formula takes precedence over * "formatted"; if you pass both, returned values will *not* be formatted. * @deprecated * * @privateRemarks * * FIXME: that should throw? */ formula?: boolean; /** * by default, GetRange returns cell values. the optional type field * can be used to returns data in different formats. * * @remarks * * `formatted` returns formatted values, applying number formatting and * returning strings. * * `A1` returns cell formulas instead of values, in A1 format. * * `R1C1` returns cell formauls in R1C1 format. * * `formula` is an alias for 'A1', for backwards compatibility. * */ type?: 'formatted' | 'A1' | 'R1C1' | 'formula'; } /** * options for the ScrollTo method. * * @remarks * * this method was renamed because of a conflict with a DOM type, * which was causing problems with the documentation generator. */ export interface SheetScrollOptions { /** scroll in x-direction. defaults to true. */ x?: boolean; /** scroll in y-direction. defaults to true. */ y?: boolean; /** * smooth scrolling, if supported. we use scrollTo so support is as here: * https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTo */ smooth?: boolean; } /** * function type used for filtering tables */ export type TableFilterFunction = (value: CellValue, calculated_value: CellValue, style: CellStyle) => boolean; /** * embedded spreadsheet */ export declare class EmbeddedSpreadsheet { /** * this is temporary. we need a better way to handle this, perhaps * making the factory method (createSpreadsheet) async. * * for now, you can test on this set of promises to see when the * app is ready */ protected _ready_state: Promise[]; get ready(): Promise; /** @internal */ static treb_base_path: string; /** * @internal * * keep track of modules we've tried to load dynamically, so we don't * do it again. not sure if this is strictly necessary but especially if * we're logging I don't want to see it again */ protected static failed_dynamic_modules: string[]; /** @internal */ static one_time_warnings: Record; /** @internal */ protected static clipboard?: ClipboardData; protected DOM: DOMContext; /** * this flag will be set on LoadDocument. the intent is to be able to * know if you have loaded a network document, which may happen before you * have the chance to subscribe to events * * FIXME: we need to nail down the semantics of this. what does it mean if * you call reset? * * @internal */ loaded: boolean; /** * this is a cache of number formats and colors used in the document. it's * intended for an external toolbar. * * FIXME: should we preferentially use Color objects? (...) * * @internal */ document_styles: { number_formats: string[]; colors: string[]; theme_colors: Array<{ color: Color; resolved: string; }>[]; }; /** * this is a representation of selection state for an external toolbar. * we also use it to manage state changes. this used to be internal only, * now we are exposing it. we might want to only expose a copy via an * accessor, but for now we'll just expose the actual object. * * not sure why this was ever optional, we should just have an empty default * * @internal */ selection_state: SelectionState; /** * this is our options object, EmbeddedSpreadsheetOptions but we * narrow the storage key type to a string|undefined (can be boolean * in the input). * * @internal */ options: EmbeddedSpreadsheetOptions & { local_storage: string | undefined; }; /** * @internal * * this is not public (in the API, at least), for the moment, but * it is accessible. not sure which way we're going to go with this. */ get Localization(): Localization; /** FIXME: fix type (needs to be extensible) */ protected events: EventSource<{ type: string; }>; /** * automatic/manual * why is this protected? is there some reason we don't want people to use it? */ protected calculation: CalculationOptions; /** * this might be something that should travel with the document, * as a way to compare different versions... something to think * about. we could certainly preserve/restore it on save/load. * * UPDATE: we're now storing this with the document, as "revision". * for the future we should be able to use this as the basis for * dirty flags in various applications. */ protected file_version: number; /** * this is recordkeeping for "dirty" marking, which also supports * undo. if we preserve the file version this will have to track. */ protected last_save_version: number; /** * simpler flag for testing if we can revert */ protected initial_load_source: LoadSource | undefined; /** * calculator instance. we may share this if we're in a split view. */ protected calculator: Calculator; /** */ protected grid: Grid; /** * model moved from grid. we control it now. grid still maintains * its own view, including active sheet. */ protected model: DataModel; /** * dialog is assigned in the constructor, only if there's a containing * element (i.e. not when we're just using the engine) */ protected dialog?: Dialog; /** new spinner */ protected spinner?: Spinner; /** file chooser */ protected file_chooser?: HTMLInputElement; /** file chooser operation */ protected file_chooser_operation: FileChooserOperation; /** localized parser instance. we're sharing. */ protected get parser(): Parser; /** for destruction */ protected view_node?: HTMLElement; /** for destruction */ protected key_listener?: (event: KeyboardEvent) => void; protected views: Array<{ view: EmbeddedSpreadsheet; subscription?: number; }>; /** focus target if we have multiple views */ protected focus_target: EmbeddedSpreadsheet; /** parent, if we are a split view child */ protected parent_view?: EmbeddedSpreadsheet; /** * export worker (no longer using worker-loader). * export worker is loaded on demand, not by default. * * FIXME: type */ protected export_worker?: WorkerProxy; /** * undo pointer points to the next insert spot. that means that when * you push an undo operation, it goes into the slot [undo_pointer]. * * that means if you want to undo, and the pointer is at X, you need * to go to the state X-2 -- because X-1 is effectively the _current_ state. * and also if you do that (undo), you decrement the pointer by 1. * * this is confusing. */ private undo_pointer; private undo_stack; /** * ... */ private last_selection?; /** * convenience function returns the name of the active sheet. if the * sheet name has spaces or other characters that require quoting, it * will be quoted using single quotes. */ get active_sheet(): string; /** * this was added for riskamp.com; it doesn't track modified, really, because * it doesn't reflect saves. we need to do that but leave this one as-is for * backwards compatibility. * * @internal */ get modified(): boolean; /** document name (metadata) */ get document_name(): string | undefined; /** document name (metadata) */ set document_name(name: string | undefined); /** * opaque user data (metadata). `USER_DATA_TYPE` is a template * parameter you can set when creating the spreadsheet. */ get user_data(): USER_DATA_TYPE | undefined; /** * opaque user data (metadata). `USER_DATA_TYPE` is a template * parameter you can set when creating the spreadsheet. */ set user_data(data: USER_DATA_TYPE | undefined); /** current grid scale */ get scale(): number; /** current grid scale */ set scale(value: number); /** headless state */ get headless(): boolean; /** headless state */ set headless(value: boolean); /** * state is the current revision of the document. it is preserved any * time the document is saved. it should be a consistent indication of * the document version and can be used to compare versions. * * state is an atomically-incrementing integer but rolls over at 2^16. */ get state(): number; /** * this flag indicates we can revert the document. what that means is * we loaded a user-created version from localStorage, but there's a * backing network or inline document. or we did load the original version * but the user has made some document changes. * * it's like `dirty`, but that uses the load source as the ground truth, * which means if you load a modified document from localStorage it's * initially considered not-dirty (which is maybe just a bad design?) * * the intent of this field is to support enabling/disabling revert * logic, or to add a visual indicator that you are not looking at the * canonical version. * * @privateRemarks * for that to work we need to know that we loaded from localStorage -- * that's not something we're keeping track of at the moment. * * it might be good to include the "canonical version" when we put stuff * in localStorage... * */ get can_revert(): boolean; /** * indicates the current revision of the document is not equal to the * last-saved revision of the document. */ get dirty(): boolean; /** * explicitly set or clear the dirty flag. it's intended for use by clients * that have their own save routine. */ set dirty(value: boolean); /** * returns the names of all sheets in the current document */ get sheet_names(): string[]; /** * constructor takes spreadsheet options. type should be implicit, either * the default (here) or a subclass * * @internal */ constructor(options: EmbeddedSpreadsheetOptions & { model?: EmbeddedSpreadsheet; custom_grid?: CustomGridFactory; }); /** * update autocomplete functions. we're breaking this out into a * separate method so we can better manage language translation. */ protected UpdateAC(): void; /** * initialize calculator instance */ protected CreateCalculator(model: DataModel, options: EmbeddedSpreadsheetOptions): Calculator; /** * we moved error strings from grid, so we can (at some point) localize * them. returns a message and (optionally) a title for the dialog */ protected TranslateGridError(code: ErrorCode): { message: string; title?: string; }; /** * this will need to get overloaded for subclasses so they can * create the correct type */ protected CreateView(): EmbeddedSpreadsheet; /** * testing * * @internal */ Unsplit(): void; /** * set or remove an external editor. external editor is an interface used * to support outside tooling by highlighting a list of arguments and * responding to selection. */ ExternalEditor(config?: Partial): void; /** * this is not very efficient atm. we create another whole instance of this * class, do a lot of unecssary painting and layout. it works but it could * definitely be improved. * * @internal */ Split(): void; /** * method to list annotations in the spreadsheet, including internal id * (handle). the id is per-session, so it will be consistent as long as the * spreadsheet is open (and the annotation exists). * * @param sheet - sheet name or ID. omit to use the active sheet */ ListAnnotations(sheet?: number | string): (Partial & { id: string; })[]; /** * list conditional formats. uses the active sheet by default, or pass a * sheet name or id. */ ListConditionalFormats(sheet?: number | string): ConditionalFormatType[]; /** * @internalRemarks removing internal flag */ ConditionalFormatDuplicateValues(range: RangeReference | undefined, options: ConditionalFormatDuplicateValuesOptions): ConditionalFormat; /** * @internalRemarks removing internal flag */ ConditionalFormatGradient(range: RangeReference | undefined, options: ConditionalFormatGradientOptions | StandardGradient): ConditionalFormat; /** * */ ConditionalFormatDataBars(range: RangeReference | undefined, options?: ConditionalFormatDataBarOptions): ConditionalFormat; /** * @internalRemarks removing internal flag */ ConditionalFormatCellMatch(range: RangeReference | undefined, options: ConditionalFormatCellMatchOptions): ConditionalFormat; /** * @internalRemarks removing internal flag */ ConditionalFormatExpression(range: RangeReference | undefined, options: CondifionalFormatExpressionOptions): ConditionalFormat; /** * add a conditional format * * @internal */ AddConditionalFormat(format: ConditionalFormat): ConditionalFormat; /** * remove conditional format * * @internalRemarks removing internal flag */ RemoveConditionalFormat(format: ConditionalFormat): void; /** * clear conditional formats from the target range (or currently selected * range). we operate on format objects, meaning we'll remove the whole * format object rather than clip the area. * * @internalRemarks removing internal flag */ RemoveConditionalFormats(range?: RangeReference): void; InsertChartWithHeuristics(func: string, initial_area?: Area): boolean; /** * @internal */ HandleToolbarMessage(event: ToolbarMessage): void; /** * @internal * * @param show - true or false to show/hide, or leave undefined to toggle */ ShowToolbar(show?: boolean): void; /** * @internal * * @param show - true or false to show/hide, or leave undefined to toggle */ ShowSidebar(show?: boolean): void; protected FindAnnotation(id: string | number, sheet?: number | string): { annotation: Annotation; target: Sheet; } | undefined; AnnotationZOrder(id: string | number, operation: number | 'top' | 'bottom', sheet?: number | string): void; DeleteAnnotation(id: string | number, sheet?: number | string): void; MoveAnnotation(id: string | number, layout: RangeReference, sheet?: number | string): void; /** * Create (and return) a Chart object. * @internal */ CreateChart(): Chart; /** dynamically load language module */ LoadLanguage(language?: string): Promise; /** * Use this function to batch multiple document changes. Essentially the * grid stops broadcasting events for the duration of the function call, * and collects them instead. After the function call we update as necessary. * * @privateRemarks * * FIXME: we need to consider the case where this is nested, since we now * call it from the Paste method. that might be batched by a caller. we * need a batch stack, and we need to consolidate any options (paint is the * only option) and keep the top-of-stack last selection. * * Q: why does this work the way it does, anyway? why not just rely * on the actual events? if grid published them after a batch, wouldn't * everything just work? or is the problem that we normally handle events * serially? maybe we need to rethink how we handle events coming from * the grid. * * --- * * OK so now, grid will handle nested batching. it won't return anything * until the last batch is complete. so this should work in the case of * nested calls, because nothing will happen until the last one is complete. * */ Batch(func: () => void, paint?: boolean): void; /** set freeze area */ Freeze(rows?: number, columns?: number): void; /** freeze at current selection */ FreezeSelection(): void; /** return current freeze area */ GetFreeze(): FreezePane; /** * Update theme from CSS. Because the spreadsheet is painted, not * rendered, you need to notifiy us if external style (CSS) properties * have changed. We will update and repaint. */ UpdateTheme(): void; /** * Get sheet ID, by name (sheet name) or index. This may be useful for * constructing references programatically. * * @remarks * * Sheet IDs are positive integers. IDs are ephemeral, they should not be * retained after a document is closed or reloaded. They will likely (almost) * always be the same, but that's not guaranteed, so don't rely on them. * * @param sheet - sheet name or index. sheet names are matched case-insensitively. * * @returns ID, or undefined if the index is not found (0 is not a valid * sheet ID, so you can test for falsy). * * @public */ GetSheetID(sheet: string | number): number | undefined; /** * insert a table in the given range. optionally include a totals row. * this method does not make any changes to content or layout. it just * converts the range to a table. * * @param reference */ InsertTable(range?: RangeReference, options?: InsertTableOptions): void; RemoveTable(range?: RangeReference): void; UpdateTableStyle(range?: RangeReference, theme?: TableTheme | number): void; SetTabColor(sheet?: number | string, color?: Color): void; /** * Add a sheet, optionally named. */ AddSheet(name?: string): number; RemoveConnectedChart(id: number): void; UpdateConnectedChart(id: number, formula: string): void; /** * this is a generic version that takes a callback, so we can use * separately from charts. however (atm) we're using leaf vertices that * don't actually calculate, they just indicate the dirty state. so we * won't have access to the result of a calculation in the callback. * * @internal * */ CreateConnectedFormula(formula: string, callback?: (instance: ConnectedElementType) => void, options?: EvaluateOptions): number; /** * @internal * * @returns an id that can be used to manage the reference */ CreateConnectedChart(formula: string, target: HTMLElement, options: EvaluateOptions): number; /** * Insert an annotation node. Usually this means inserting a chart. Regarding * the argument separator, see the Evaluate function. * * @param formula - annotation formula. For charts, the chart formula. * @param type - annotation type. Defaults to `treb-chart`. * @param rect - coordinates, or a range reference for layout. * @param options - evaluate options. because this function used to take * the argument separator, we allow that to be passed directly, but this * is deprecated. new code should use the options object. */ InsertAnnotation(formula: string, type?: AnnotationType, rect?: IRectangle | RangeReference, options?: EvaluateOptions | ',' | ';'): void; /** * Insert an image. This method will open a file chooser and (if an image * is selected) insert the image into the document. */ InsertImage(): void; /** * Rename a sheet. * * @param index - old name or index of sheet. leave undefined to use * current active sheet. * * @public */ RenameSheet(index: string | number | undefined, new_name: string): void; /** * Delete a sheet. * * @param index - sheet name or index. Leave undefined to delete the active sheet. * * @public */ DeleteSheet(index?: string | number): void; /** * Show or hide sheet. This is a replacement for the `ShowSheet` method, * because that name is somewhat ambiguous. * * @param index - sheet name or index. * * @public */ HideSheet(index?: number | string, hide?: boolean): void; /** list sheets in the model */ ListSheets(): { name: string; hidden?: boolean; }[]; /** * Show or hide sheet. This method is deprecated because it's ambiguous. * To set a sheet's visibility, use `HideSheet`. To activate a sheet, use * `ActivateSheet`. * * @param index - sheet name or index. * * @see HideSheet * @deprecated Use `HideSheet` instead. */ ShowSheet(index?: number | string, show?: boolean): void; /** * Activate sheet. * * @param index - sheet name or index. * * @public */ ActivateSheet(index: number | string): void; /** * Set width of column(s). * * @param column - column, or columns (array), or undefined means all columns * @param width - desired width (can be 0) or undefined means 'auto-size' * @param allow_shrinking - for auto-size, allow shrinking. defaults to true. * * @privateRemarks * * TODO: this method assumes the current sheet. we need a method that can * (optionally) specify a sheet. * * @public */ SetColumnWidth(column?: number | number[], width?: number, allow_shrinking?: boolean): void; /** * Set height of row(s). * * @param row - row, or rows (array), or undefined means all rows * @param height - desired height (can be 0) or undefined means 'auto-size' * * @privateRemarks * * TODO: this method assumes the current sheet. we need a method that can * (optionally) specify a sheet. * * @public */ SetRowHeight(row?: number | number[], height?: number): void; /** * Insert row(s). * * @param before_row - leave undefined to use current selection. * * @public */ InsertRows(before_row?: number, count?: number): void; /** * Insert column(s). * * @param before_column - leave undefined to use current selection. * * @public */ InsertColumns(before_column?: number, count?: number): void; /** * Delete row(s). * * @param start_row - leave undefined to use current selection. in this * case the `count` parameter will be ignored and all rows in the selection * will be deleted. */ DeleteRows(start_row?: number, count?: number): void; /** * Delete columns(s). * * @param start_column - leave undefined to use current selection. in this * case the `count` parameter will be ignored and all columns in the * selection will be deleted. */ DeleteColumns(start_column?: number, count?: number): void; /** * filter a table. the reference can be the table name, or a cell in the table. * if the reference is an area (range), we're going to look at the top-left * cell. * * this method uses a function to filter rows based on cell values. leave the * function undefined to show all rows. this is a shortcut for "unfilter". * * @param column - the column to sort on. values from this column will be * passed to the filter function. * * @param filter - a callback function to filter based on cell values. this * will be called with the cell value (formula), the calculated value (if any), * and the cell style. return false to hide the row, and true to show the row. * if the filter parameter is omitted, all values will be shown. * */ FilterTable(reference: RangeReference, column?: number, filter?: TableFilterFunction): void; /** * sort a table. the reference can be the table name, or a cell in the table. * if the reference is an area (range), we're going to look at the top-left * cell. */ SortTable(reference: RangeReference, options?: Partial): void; /** * Merge cells in range. * * @param range - target range. leave undefined to use current selection. * * @public */ MergeCells(range?: RangeReference): void; /** * Unmerge cells in range. * * @param range - target range. leave undefined to use current selection. * * @public */ UnmergeCells(range?: RangeReference): void; Screenshot(type: 'png' | 'webp' | 'jpeg' | undefined, quality?: number | undefined, download?: boolean): Promise; /** * Export XLSX as a blob. This is intended for electron clients, who may * implement their own file save routines (because they have access to the * filesystem). * * @internal */ ExportBlob(serialized?: SerializedModel): Promise; /** * revert to the network version of this document, if `local_storage` * is set and the create options had either `document` or `inline-document` * set. * * FIXME: we should adjust for documents that fail to load. */ Revert(): void; /** * Export to XLSX file. * * @remarks * * this requires a bunch of processing -- one, we do this in a worker, and * two, it's demand loaded so we don't bloat up this embed script. */ Export(): void; /** * Return "live" reference to selection. * * @internal */ GetSelectionReference(): GridSelection; /** * Focus the grid. * * @public */ Focus(): void; /** * Update layout and repaint if necessary. * * @remarks * * This method should be called when the container is resized, to * trigger an update to layout. It should be called automatically * by a resize observer set in the containing tag class, but you * can call it manually if necessary. * * @public */ Resize(): void; /** * Clear/reset sheet. This will reset the undo stack as well, * so it cannot be undone. * * @public */ Reset(): void; /** * load a document from from local storage, using the given key. * this method will also set the local option for the storage key, so the * document will potentially be saved on modification. */ LoadFromLocalStorage(key: string): boolean; /** * load a network document by URI. CORS headers must be set appropriately * on documents originating from different hosts. */ LoadNetworkDocument(uri: string, options?: EmbeddedSpreadsheetOptions): Promise; /** * Load a desktop file. This method will show a file chooser and open * the selected file (if any). * * @public */ LoadLocalFile(): Promise; /** * Export sheet as CSV/TSV. This is an internal method called by the save * document methods, but you can call it directly if you want the text as * a string. * * @returns string * * @public */ ExportDelimited(options?: ExportOptions): string; /** * @deprecated - use SaveToDesktop * * @param filename * @param additional_options */ SaveLocalFile(filename?: string, additional_options?: SaveOptions): void; /** * Save the current document to a desktop file. This is the new version * of the method, renamed from SaveLocalFile. * * @param filename Filename or extension to use the document name. */ SaveToDesktop(filename?: string, additional_options?: SaveOptions): void; /** * Load CSV from string. This is used internally when loading network * documents and local files, but you can call it directly if you have * a CSV file as text. * * @public */ LoadCSV(csv: string, source?: LoadSource): void; /** * get or set the current scroll offset. scroll offset is automatically * saved if you save the document or switch tabs; this is for saving/ * restoring scroll if you cache the containing element. */ ScrollOffset(offset?: Point): Point | undefined; /** * unserialize document from data. * * @privateRemarks * * UPDATE: will no longer recalculate on load if the "rendered_values" * flag is set in the document (assuming it's correct), because we can * display those values. * * UPDATE: default scroll to A1 in open sheet * */ LoadDocument(data: TREBDocument, options?: LoadDocumentOptions): void; /** * Set note (comment) in cell. * * @param address target address, or leave undefined to use current selection. * @param note note text, or leave undefined to clear existing note. */ SetNote(address: AddressReference | undefined, note?: string): void; /** * set or clear cell valiation. * * @param target - target cell/area * @param validation - a spreadsheet range, list of data, or undefined. pass * undefined to remove existing cell validation. * @param error - setting an invalid value in the target cell is an error (and * is blocked). defaults to false. */ SetValidation(target: RangeReference, validation?: RangeReference | CellValue[], error?: boolean): void; /** * Delete a macro function. * * @public */ RemoveFunction(name: string): void; /** * Create a macro function. * * FIXME: this needs a control for argument separator, like other * functions that use formulas (@see SetRange) * * @public */ DefineFunction(name: string, argument_names?: string | string[], function_def?: string): void; /** * Serialize document to a plain javascript object. The result is suitable * for converting to JSON. This method is used by the SaveLocalFile and * SaveLocalStorage methods, but you can call it directly if you want to * save the document some other way. * * @privateRemarks * * serialize document; optionally include any MC data * optionally preserve rendered values * UPDATE: default rendered values -> true * * @public */ SerializeDocument(options?: SerializeOptions): TREBDocument; /** * Recalculate sheet. * * @privateRemarks * * the event parameter should not be used if this is called * as an API function, remove it from typings * * why is this async? it doesn't do anything async. * * @public */ Recalculate(event?: GridEvent): void; /** * Save document to local storage. * * @param key optional storage key. if omitted, the method will use * the key from local options (set at create time). */ SaveLocalStorage(key?: string | undefined): void; /** * Revert state one level from the undo stack. * * @public * @returns true if undo succeeded, false if the undo stack was empty */ Undo(): boolean; /** * Show the about dialog. * * @public */ About(): void; /** * scroll the given address into view. it could be at either side * of the window. optionally use smooth scrolling. */ ScrollIntoView(address: AddressReference, smooth?: boolean): void; /** * Scroll to the given address. In the current implementation this method * will not change sheets, although it probably should if the reference * is to a different sheet. * * @public */ ScrollTo(address: AddressReference, options?: SheetScrollOptions): void; /** * Resolve a string address/range to an address or area (range) object. * * @param reference A string like "A1" or "Sheet1!B2:C3". If a sheet name * is not included, the current active sheet is used. You can also pass a * named range as reference. * * @public */ Resolve(reference: string, options?: { r1c1?: boolean; }): ICellAddress | IArea | undefined; /** * Convert an address/range object to a string. this is a convenience * function for composing formulas. * * @param ref sheet reference as a string or structured object * @param [qualified=true] include sheet names * @param [named=true] resolve to named ranges, where applicable */ Unresolve(ref: RangeReference, qualified?: boolean, named?: boolean): string; /** * Evaluate an arbitrary expression in the spreadsheet. You should generally * use sheet names when referring to cells, to avoid ambiguity. Otherwise * cell references will resolve to the active sheet. * * @param expression - an expression in spreadsheet language * @param options - options for parsing the passed function * * @public */ Evaluate(expression: string, options?: EvaluateOptions): CellValue | CellValue[][]; ExpandRegion(): void; /** * Returns the current selection, as a string address or range. * * @param qualified include sheet name in result. default true. * * @returns selection as a string, or empty string if there's no selection. * * @public */ GetSelection(qualified?: boolean): string; /** * Parse a string and return a number (if possible). * * @privateRemarks * * We're using ValueParser, which the one used when you type into a grid * (not the Parser parser). It's intended to handle things that would look * wrong in functions, like currency symbols. * * @public */ ParseNumber(text: string): number | Complex | boolean | string | undefined; /** * Format a number with an arbitrary formatter. * * @privateRemarks * * FIXME: should this support complex numbers? not sure... * * @public */ FormatNumber(value: number | Complex, format?: string): string; /** * convert a javascript date (or timestamp) to a spreadsheet date */ SpreadsheetDate(javascript_date: number | Date): number; /** * convert a spreadsheet date to a javascript date */ JavascriptDate(spreadsheet_date: number): number; /** * Apply borders to range. * * @param range pass `undefined` as range to apply to current selection. * * @remarks * * Borders are part of style, but setting/removing borders is more * complicated than setting other style properties. usually you want * things to apply to ranges, rather than individual cells. removing * borders needs to consider neighbor borders. and so on. * * @public */ ApplyBorders(range: RangeReference | undefined, borders: BorderConstants, width?: number): void; /** * Apply style to range. * * @param range pass `undefined` as range to apply to current selection. * @param delta apply over existing properties. default true. * * @remarks * * Don't use this method to set borders, use `ApplyBorders`. * * @public */ ApplyStyle(range?: RangeReference, style?: CellStyle, delta?: boolean): void; /** * Remove a named range (removes the name, not the range). * * @public */ ClearName(name: string): void; ListNames(): SerializedNamed[]; /** * Create a named range or named expression. A named range refers to an * address or range. A named expression can be any value or formula. To set * the value as a literal string, enclose the string in double-quotes (as * you would when using a string as a function argument). * * @param value range, value or expression * * @remarks * * This function used to support passing `undefined` as the value, * which meant "create a named range using current selection". We don't * support that any more but you can accompilsh that with * `sheet.DefineName("Name", sheet.GetSelection())`. * * @public */ DefineName(name: string, value: RangeReference | CellValue, scope?: string | number, overwrite?: boolean): void; /** * Set or remove a link in a cell. * * @param target http/https URL or a spreadsheet reference (as text). set blank to remove link. * * @public */ SetLink(address?: AddressReference, target?: string): void; /** * Select a range. This function will change sheets if your reference * refers to a different sheet. if the argument is undefined or falsy * it will remove the selection (set to no selection). * * @public */ Select(range?: RangeReference, scroll?: boolean | 'smooth'): void; /** * override for paste method omits the data parameter. */ Paste(target?: RangeReference, options?: PasteOptions): void; /** * standard paste method accepts data argument * * @param target * @param data * @param options */ Paste(target?: RangeReference, data?: ClipboardData, options?: PasteOptions): void; /** * copy data. this method returns the copied data. it does not put it on * the system clipboard. this is for API access when the system clipboard * might not be available. * * @privateRemarks LLM API */ Copy(source?: RangeReference): ClipboardData; /** * cut data. this method returns the cut data. it does not put it on the * system clipboard. this method is similar to the Copy method, with * two differences: (1) we remove the source data, effectively clearing * the source range; and (2) the clipboard data retains references, meaning * if you paste the data in a different location it will refer to the same * cells. * * @privateRemarks LLM API */ Cut(source?: RangeReference): ClipboardData; /** * * @param range target range. leave undefined to use current selection. * * @public */ GetRange(range?: RangeReference, options?: GetRangeOptions): CellValue | CellValue[][] | undefined; /** * returns the style from the target address or range. * * @privateRemarks * optimally this could be consolidated with the `GetRange` function, but * that requires some gymnastics to manage the return type which I'm not * willing (at the moment) to do. * * @param range - target range. leave undefined to use current selection * @param apply_theme - include theme defaults when returning style * */ GetStyle(range?: RangeReference, apply_theme?: boolean): CellStyle | CellStyle[][] | undefined; /** * Set data in range. * * @param range target range. leave undefined to use current selection. * * @public */ SetRange(range?: RangeReference, data?: CellValue | CellValue[][], options?: SetRangeOptions): void; /** * Subscribe to spreadsheet events * @param subscriber - callback function * @returns a token used to cancel the subscription */ Subscribe(subscriber: (event: EmbeddedSheetEvent) => void): number; /** * Cancel subscription * @param token - the token returned from `Subscribe` */ Cancel(token: number): void; /** * overload returns undefined if no range and no selection */ protected RangeOrSelection(source: RangeReference | undefined): Area | undefined; /** * overload throws if no range and no selection (pass the error to throw) */ protected RangeOrSelection(source: RangeReference | undefined, error: string): Area; /** * serialize data model. moved from grid/grid base. this is moved so we * have access to the calculator, which we want so we can do function * translation on some new functions that don't necessarily map 1:1 to * XLSX functions. we can also do cleanup on functions where we're less * strict about arguments (ROUND, for example). * */ protected Serialize(options?: SerializeOptions): SerializedModel; /** * */ protected ApplyConditionalFormats(sheet: Sheet, call_update: boolean): void; protected ResolveTable(reference: RangeReference): Table | undefined; /** * replacement for (the great) FileSaver lib. we can now rely on all * browsers to handle this properly (fingers crossed). * * @param blob * @param filename */ protected SaveAs(blob: Blob, filename: string): void; protected Publish(event: EmbeddedSheetEvent): void; /** * */ ImportXLSX(// data: string, source: LoadSource): Promise { data: ArrayBuffer, source: LoadSource, path?: string): Promise; /** * some local cleanup, gets called in various import/load/reset functions * this is shrinking to the point of being unecessary... although we are * possibly overloading it. */ protected ResetInternal(): void; protected HandleCellEvent(event: CellEvent): void; protected OnSheetChange(event: SheetChangeEvent): void; protected HandleDrag(event: DragEvent): void; protected HandleDrop(event: DragEvent): void; /** * I'm restructuring the select file routine to simplify, in service * of figuring out what's going wrong in OSX/Chrome. the current routine * is unecssarily complicated. * * the original concern was that you don't receive a "cancel" event from * the file chooser dialog; but that is only relevant if you have ephemeral * dialogs. if you have a constant dialog (html input element) you don't need * to do this asynchronously because the dialog blocks. * * the downside is that you can't get a return value from 'LoadFile' or * 'InsertImage'. not sure how much of a problem that is. need to check * what RAW does. * * * @param accept */ protected SelectFile2(accept: string, operation: FileChooserOperation): void; /** * Insert an image. This method will open a file chooser and (if an image * is selected) insert the image into the document. * * @privateRemarks * * Should we have a separate method that takes either an Image (node) or * a data URI? */ protected InsertImageInternal(file: File): Promise; /** called when we have a file to write to */ protected LoadFileInternal(file: File, source: LoadSource, dialog?: boolean): Promise; /** testing * * this is called after recalc, check any annotations * (just sparklines atm) and update if necessary. */ protected UpdateAnnotations(): void; protected UpdateConnectedElements(): void; /** * this method should be called after changing the headless flag */ protected RebuildAllAnnotations(): void; /** * inflate all annotations. intended to be called after a document * load (including undo), which does not send `create` events. * * FIXME: why is this public? */ protected InflateAnnotations(): void; protected InflateAnnotation(annotation: Annotation): void; /** * save sheet to local storage and trigger (push) undo. our undo system * relies on tracking selection after storing the main data, and sometimes * we need to manage this explicitly: hence the parameter. * */ protected DocumentChange(undo_selection?: string): void; /** * if we have a boolean for a storage key, generate a (weak) hash * based on document URI. use the prefix to create separate keys * when using the autogenerated key (uri hash) */ protected ResolveStorageKey(key?: string | boolean, prefix?: string): string | undefined; /** * * @param json -- the serialized data is already calculated. that happens * when we are storing to localStorage as part of handling a change; since * we already have the json, we can pass it through. although we should * switch around the order, it would make it a little easier to manage. * * @param increment -- increment the file version. this is a parameter * so we can _not_ increment on the initial state push, on load. */ protected PushUndo(json?: string, last_selection?: string, increment?: boolean): void; /** * clear the undo stack, and optionally push an initial state */ protected FlushUndo(push?: boolean): void; /** * update selection: used for updating toolbar (i.e. highlight bold button) * * we can also use this to better manage selection in the undo system... * */ protected UpdateSelection(selection: GridSelection, reason?: GridSelectionEvent['reason']): void; /** update selection style for the toolbar, when an annotation is selected. */ protected UpdateSelectionStyleAnnotation(annotation: Annotation): void; /** update selection style for the toolbar */ protected UpdateSelectionStyle(selection?: GridSelection): void; protected UpdateDocumentStyles(): void; /** * this function is called when the file locale (as indicated by the * decimal separator) is different than the current active locale. * * so we know that we want to translate. that's why there are no tests * in this function. */ protected ConvertLocale(data: TREBDocument): void; /** * compare two semantic versions. returns an object indicating * the greater version (or equal), plus individual component comparisons. * * FIXME: move to util lib? */ protected CompareVersions(a?: string, b?: string): SemanticVersionComparison; /** * import data from serialized document, doing locale conversion if necessary */ protected ImportDocumentData(data: TREBDocument, override_sheet?: string): void; /** * switching to worker proxy so we can support node * FIXME: type */ protected LoadWorker(): Promise>; /** * handle key down to intercept ctrl+z (undo) * UPDATE: we're also handling F9 for recalc (optionally) * * FIXME: redo (ctrl+y or ctrl+shift+z) */ protected HandleKeyDown(event: KeyboardEvent): void; } export {};