/** * Copyright 2023-present DreamNum Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import type { ITransformState, Nullable } from '@univerjs/core'; import type { ICanvasFloatDom, ICanvasFloatDomInfo, IDOMAnchor } from '@univerjs/sheets-drawing-ui'; import type { IFComponentKey } from '@univerjs/sheets-ui/facade'; import type { FRange } from '@univerjs/sheets/facade'; import type { ISaveCellImagesOptions } from './f-range'; import { FWorksheet } from '@univerjs/sheets/facade'; export interface IFICanvasFloatDom extends Omit, IFComponentKey { } export interface IFCanvasFloatDomResult extends Omit, IFComponentKey, Pick { position: ITransformState; id: string; } /** * @ignore */ export interface IFWorksheetDrawingUIMixin { /** * Get float dom by id * @param {string} id - float dom id * @returns {IFCanvasFloatDomResult | null} float dom info or null if not found * @example * ```ts * const fWorksheet = univerAPI.getActiveWorkbook().getSheetByName('Sheet1'); * if (!fWorksheet) return; * const floatDom = fWorksheet.getFloatDomById('myFloatDomId'); * if (floatDom) { * console.log('Float dom position:', floatDom.position); * console.log('Component key:', floatDom.componentKey); * console.log('Custom data:', floatDom.data); * } * ``` */ getFloatDomById(id: string): Nullable; /** * Get all float doms in current worksheet * @returns {IFCanvasFloatDomResult[]} array of float dom info * @example * ```ts * const fWorksheet = univerAPI.getActiveWorkbook().getSheetByName('Sheet1'); * if (!fWorksheet) return; * const allFloatDoms = fWorksheet.getAllFloatDoms(); * allFloatDoms.forEach(floatDom => { * console.log('Float dom ID:', floatDom.id); * console.log('Position:', floatDom.position); * }); * ``` */ getAllFloatDoms(): IFCanvasFloatDomResult[]; /** * Update float dom position and properties * @param {string} id - float dom id * @param {Partial} config - new float dom config * @returns {FWorksheet} The worksheet instance for chaining * @example * ```ts * const fWorksheet = univerAPI.getActiveWorkbook().getSheetByName('Sheet1'); * if (!fWorksheet) return; * const firstFloatDom = fWorksheet.getAllFloatDoms()[0]; * * if (!firstFloatDom) return; * * // Update first float dom position and size * fWorksheet.updateFloatDom(firstFloatDom.id, { * position: { * left: 100, * top: 100, * width: 200, * height: 150, * angle: 45, // rotate 45 degrees * } * }); * * // Update first float dom data * fWorksheet.updateFloatDom(firstFloatDom.id, { * data: { * label: 'Updated Label', * color: '#ff0000' * } * }); * * // Disable the first float dom from transform * fWorksheet.updateFloatDom(firstFloatDom.id, { * allowTransform: false * }); * ``` */ updateFloatDom(id: string, config: Partial): this; /** * Batch update float doms * @param {Array<{id: string, config: Partial}>} updates - array of update configs * @returns {FWorksheet} The worksheet instance for chaining * @example * ```ts * const fWorksheet = univerAPI.getActiveWorkbook().getSheetByName('Sheet1'); * if (!fWorksheet) return; * * // Update multiple float doms at once * const allFloatDoms = fWorksheet.getAllFloatDoms(); * fWorksheet.batchUpdateFloatDoms(allFloatDoms.map((floatDom, index) => { * if (floatDom.id === 'MyFloatDomId') { * return { * id: floatDom.id, * config: { * position: { * left: 100, * top: 100 * }, * data: { * label: 'Updated' * } * } * } * } * * return { * id: floatDom.id, * config: { * position: { * left: 300, * top: 100 * } * } * } * })); * ``` */ batchUpdateFloatDoms(updates: Array<{ id: string; config: Partial; }>): this; /** * Remove float dom by id * @param {string} id - float dom id * @returns {FWorksheet} The worksheet instance for chaining * @example * ```ts * const fWorksheet = univerAPI.getActiveWorkbook().getSheetByName('Sheet1'); * if (!fWorksheet) return; * const firstFloatDom = fWorksheet.getAllFloatDoms()[0]; * * if (!firstFloatDom) return; * * // Remove the first float dom * fWorksheet.removeFloatDom(firstFloatDom.id); * ``` */ removeFloatDom(id: string): this; /** * Add a float dom to position. * @param {IFICanvasFloatDom} layer - The float dom layer configuration. * @param {string} [id] - The float dom id, if not given will be auto generated. * @returns float dom id and dispose function * @example * ```tsx * const fWorksheet = univerAPI.getActiveWorkbook().getSheetByName('Sheet1'); * if (!fWorksheet) return; * * // You should register components at an appropriate time (e.g., when Univer is loaded) * // This is a React component. For Vue3 components, the third parameter should be `{ framework: 'vue3' }` * univerAPI.registerComponent( * 'myFloatDom', * ({ data }) => ( *
* popup content: * {' '} * {data?.label} *
* ), * ); * * // Add a floating DOM * // If disposable is null, floating DOM addition failed * const disposable = fWorksheet.addFloatDomToPosition({ * componentKey: 'myFloatDom', * initPosition: { * startX: 100, * endX: 300, * startY: 100, * endY: 200, * }, * * // Component data * data: { * label: 'hahah', * }, * }); * console.log(disposable?.id); // The id of the floating DOM * * // Remove the floating DOM after 2 seconds * setTimeout(() => { * disposable?.dispose(); * }, 2000); * ``` */ addFloatDomToPosition(layer: IFICanvasFloatDom, id?: string): Nullable<{ id: string; dispose: () => void; }>; /** * Add dom over range to FloatDOM, And FloatDOM is registerComponent(BuiltInUIPart.CONTENT) * @param {FRange} range - The range to add the float dom. * @param {Partial} layer - The float dom layer configuration. * @param {Partial} domLayout - The anchor configuration of the float dom. * @param {string} [id] - The float dom id, if not given will be auto generated * @returns float dom id and dispose function * @example * ```tsx * const fWorksheet = univerAPI.getActiveWorkbook().getSheetByName('Sheet1'); * if (!fWorksheet) return; * * // Register a range loading component * const RangeLoading = () => { * const divStyle = { * width: '100%', * height: '100%', * backgroundColor: '#fff', * border: '1px solid #ccc', * boxSizing: 'border-box' as const, * display: 'flex', * justifyContent: 'center', * alignItems: 'center', * textAlign: 'center' as const, * transformOrigin: 'top left', * }; * * return ( *
* Loading... *
* ); * }; * univerAPI.registerComponent('RangeLoading', RangeLoading); * * // Add the range loading component covering the range A1:C3 * const fRange = fWorksheet.getRange('A1:C3'); * const disposable = fWorksheet.addFloatDomToRange(fRange, { componentKey: 'RangeLoading' }, {}, 'myRangeLoading'); * console.log(disposable?.id); // The id of the floating DOM * * // Remove the floating DOM after 2 seconds * setTimeout(() => { * disposable?.dispose(); * }, 2000); * * // another example------------------- * // Register a float button component * const FloatButton = () => { * const divStyle = { * width: '100px', * height: '30px', * backgroundColor: '#fff', * border: '1px solid #ccc', * boxSizing: 'border-box' as const, * display: 'flex', * justifyContent: 'center', * alignItems: 'center', * textAlign: 'center' as const, * cursor: 'pointer', * }; * * const clickHandler = () => { * console.warn('click'); * }; * * return ( *
* FloatButton *
* ); * }; * univerAPI.registerComponent('FloatButton', FloatButton); * * // Add the float button to the range A5:C7, position is start from A5 cell, and width is 100px, height is 30px, margin is 100% of range width and height * const fRange2 = fWorksheet.getRange('A5:C7'); * const disposable2 = fWorksheet.addFloatDomToRange( * fRange2, * { * componentKey: 'FloatButton', * }, * { * width: 100, * height: 30, * marginX: '100%', // margin percent to range width, or pixel * marginY: '100%' * }, * 'myFloatButton' * ); * console.log(disposable2?.id); // The id of the floating DOM * ``` */ addFloatDomToRange(range: FRange, layer: Partial, domLayout: Partial, id?: string): Nullable<{ id: string; dispose: () => void; }>; /** * Add dom at column header, And FloatDOM is registerComponent(BuiltInUIPart.CONTENT) * @param {number} column - The column index to add the float dom. * @param {Partial} layer - The float dom layer configuration. * @param {IDOMAnchor} domPos - The anchor configuration of the float dom. * @param {string} [id] - The float dom id, if not given will be auto generated * @returns float dom id and dispose function * @example * ```ts * const fWorksheet = univerAPI.getActiveWorkbook().getSheetByName('Sheet1'); * if (!fWorksheet) return; * * // Register a float button component * const FloatButton = () => { * const divStyle = { * width: '100px', * height: '30px', * backgroundColor: '#fff', * border: '1px solid #ccc', * boxSizing: 'border-box' as const, * display: 'flex', * justifyContent: 'center', * alignItems: 'center', * textAlign: 'center' as const, * cursor: 'pointer', * }; * * const clickHandler = () => { * console.warn('click'); * }; * * return ( *
* FloatButton *
* ); * }; * univerAPI.registerComponent('FloatButton', FloatButton); * * // Add the float button to the column D header, position is right align, width is 100px, height is 30px, margin is 0 * const disposable = fWorksheet.addFloatDomToColumnHeader( * 3, * { * componentKey: 'FloatButton', * allowTransform: false, * }, * { * width: 100, * height: 30, * marginX: 0, * marginY: 0, * horizonOffsetAlign: 'right', * }, * 'myFloatButton' * ); * console.log(disposable?.id); // The id of the floating DOM * * // Remove the float button after 2 seconds * setTimeout(() => { * disposable?.dispose(); * }, 2000); * ``` */ addFloatDomToColumnHeader(column: number, layer: Partial, domPos: IDOMAnchor, id?: string): Nullable<{ id: string; dispose: () => void; }>; /** * Save all cell images from specified ranges to the file system. * This method will open a directory picker dialog and save all images to the selected directory. * * @param {ISaveCellImagesOptions} [options] - Options for saving images * @param {FRange[]} [ranges] - The ranges to get cell images from. If not provided, all images in the worksheet will be saved. * @returns {Promise} True if images are saved successfully, otherwise false * @example * ```ts * const fWorkbook = univerAPI.getActiveWorkbook(); * const fWorksheet = fWorkbook.getSheetByName('Sheet1'); * if (!fWorksheet) return; * * // Save cell images from multiple ranges * const range1 = fWorksheet.getRange('A1:B10'); * const range2 = fWorksheet.getRange('D1:E10'); * * // Save with default options (using cell address as file name) * await fWorksheet.saveCellImagesAsync(undefined, [range1, range2]); * * // Save with custom options * await fWorksheet.saveCellImagesAsync({ * useCellAddress: true, * useColumnIndex: 2, // Use values from column C for file names * }, [range1, range2]); * ``` */ saveCellImagesAsync(options?: ISaveCellImagesOptions, ranges?: FRange[]): Promise; } export declare class FWorksheetDrawingUIMixin extends FWorksheet implements IFWorksheetDrawingUIMixin { getFloatDomById(id: string): Nullable; getAllFloatDoms(): IFCanvasFloatDomResult[]; updateFloatDom(id: string, config: Partial>): this; batchUpdateFloatDoms(updates: Array<{ id: string; config: Partial>; }>): this; removeFloatDom(id: string): this; addFloatDomToPosition(layer: IFICanvasFloatDom, id?: string): Nullable<{ id: string; dispose: () => void; }>; addFloatDomToRange(fRange: FRange, layer: IFICanvasFloatDom, domLayout: IDOMAnchor, id?: string): Nullable<{ id: string; dispose: () => void; }>; addFloatDomToColumnHeader(column: number, layer: IFICanvasFloatDom, domLayout: IDOMAnchor, id?: string): Nullable<{ id: string; dispose: () => void; }>; saveCellImagesAsync(options?: ISaveCellImagesOptions, ranges?: FRange[]): Promise; } declare module '@univerjs/sheets/facade' { interface FWorksheet extends IFWorksheetDrawingUIMixin { } }