From 9e708fcf909ddb72f36b3520ace229cca86488af Mon Sep 17 00:00:00 2001 From: zyc9012 Date: Fri, 29 Apr 2022 11:25:55 +0800 Subject: [PATCH] feat: init apis --- .storybook/preview.js | 2 +- packages/core/src/api/cell.ts | 281 ++++++++++++++++++ packages/core/src/api/common.ts | 21 ++ packages/core/src/api/errors.ts | 2 + packages/core/src/api/index.ts | 5 + packages/core/src/api/rowcol.ts | 206 +++++++++++++ packages/core/src/index.ts | 4 + packages/core/src/modules/cell.ts | 12 +- packages/core/src/modules/toolbar.ts | 2 +- packages/react/src/components/Workbook/api.ts | 128 ++++++++ .../react/src/components/Workbook/index.tsx | 47 +-- stories/API.stories.tsx | 191 ++++++++++++ ...kbook.stories.tsx => Features.stories.tsx} | 0 13 files changed, 855 insertions(+), 46 deletions(-) create mode 100644 packages/core/src/api/cell.ts create mode 100644 packages/core/src/api/common.ts create mode 100644 packages/core/src/api/errors.ts create mode 100644 packages/core/src/api/index.ts create mode 100644 packages/core/src/api/rowcol.ts create mode 100644 packages/react/src/components/Workbook/api.ts create mode 100644 stories/API.stories.tsx rename stories/{Workbook.stories.tsx => Features.stories.tsx} (100%) diff --git a/.storybook/preview.js b/.storybook/preview.js index adfb128..7f66eea 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -9,7 +9,7 @@ export const parameters = { options: { storySort: { // put Workbook at first - order: ['Workbook'], + order: ["Features", "API"], }, }, }; diff --git a/packages/core/src/api/cell.ts b/packages/core/src/api/cell.ts new file mode 100644 index 0000000..166719f --- /dev/null +++ b/packages/core/src/api/cell.ts @@ -0,0 +1,281 @@ +import _ from "lodash"; +import { Context, getFlowdata } from "../context"; +import { + delFunctionGroup, + functionHTMLGenerate, + setCellValue as setCellValueInternal, + updateCell, + updateFormatCell, +} from "../modules"; +import { Cell, CellStyle } from "../types"; +import { CommonOptions, getSheet } from "./common"; +import { SHEET_NOT_FOUND } from "./errors"; + +export function getCellValue( + ctx: Context, + row: number, + column: number, + options: CommonOptions & { type?: keyof Cell } = {} +) { + if (!_.isNumber(row) || !_.isNumber(column)) { + throw new Error("row or column cannot be null or undefined"); + } + const sheet = getSheet(ctx, options); + const { type = "v" } = options; + const targetSheetData = sheet.data; + if (!targetSheetData) { + throw SHEET_NOT_FOUND; + } + const cellData = targetSheetData[row][column]; + let ret; + + if (cellData && _.isPlainObject(cellData)) { + ret = cellData[type]; + + if (type === "f" && ret != null) { + ret = functionHTMLGenerate(ret); + } else if (type === "f") { + ret = cellData.v; + } else if (cellData && cellData.ct && cellData.ct.fa === "yyyy-MM-dd") { + ret = cellData.m; + } + } + + if (ret === undefined) { + ret = null; + } + + return ret; +} + +export function setCellValue( + ctx: Context, + row: number, + column: number, + value: any, + cellInput: HTMLDivElement, + options: CommonOptions = {} +) { + const flowdata = getFlowdata(ctx); + if (!flowdata) return; + + // const curv = flowdata[row][column]; + + // // Store old value for hook function + // const oldValue = JSON.stringify(curv); + + if (!_.isNumber(row) || !_.isNumber(column)) { + throw new Error("row or column cannot be null or undefined"); + } + + const sheet = getSheet(ctx, options); + + // /* cell更新前触发 */ + // if ( + // !method.createHookFunction( + // "cellUpdateBefore", + // row, + // column, + // value, + // isRefresh + // ) + // ) { + // /* 如果cellUpdateBefore函数返回false 则不执行后续的更新 */ + // return; + // } + + const { data } = sheet; + // if (data.length === 0) { + // data = sheetmanage.buildGridData(file); + // } + + // luckysheetformula.updatecell(row, column, value); + const formatList = { + // ct:1, //celltype,Cell value format: text, time, etc. + bg: 1, // background,#fff000 + ff: 1, // fontfamily, + fc: 1, // fontcolor + bl: 1, // Bold + it: 1, // italic + fs: 1, // font size + cl: 1, // Cancelline, 0 Regular, 1 Cancelline + un: 1, // underline, 0 Regular, 1 underlines, fonts + vt: 1, // Vertical alignment, 0 middle, 1 up, 2 down + ht: 1, // Horizontal alignment,0 center, 1 left, 2 right + mc: 1, // Merge Cells + tr: 1, // Text rotation,0: 0、1: 45 、2: -45、3 Vertical text、4: 90 、5: -90 + tb: 1, // Text wrap,0 truncation, 1 overflow, 2 word wrap + // v: 1, //Original value + // m: 1, //Display value + rt: 1, // text rotation angle 0-180 alignment + // f: 1, //formula + qp: 1, // quotePrefix, show number as string + }; + + if (value == null || value.toString().length === 0) { + delFunctionGroup(ctx, row, column); + setCellValueInternal(ctx, row, column, data, value); + } else if (value instanceof Object) { + const curv: Cell = {}; + if (data?.[row]?.[column] == null) { + data![row][column] = {}; + } + const cell = data![row][column]!; + if (value.f != null && value.v == null) { + curv.f = value.f; + if (value.ct != null) { + curv.ct = value.ct; + } + updateCell(ctx, row, column, cellInput, curv); // update formula value + } else { + if (value.ct != null) { + curv.ct = value.ct; + } + if (value.f != null) { + curv.f = value.f; + } + if (value.v != null) { + curv.v = value.v; + } else { + curv.v = cell.v; + } + if (value.m != null) { + curv.m = value.m; + } + delFunctionGroup(ctx, row, column); + setCellValueInternal(ctx, row, column, data, curv); // update text value + } + _.forEach(value, (v, attr) => { + if (attr in formatList) { + updateFormatCell( + ctx, + data!, + attr as keyof CellStyle, + v, + row, + row, + column, + column + ); // change range format + } else { + // @ts-ignore + cell[attr] = v; + } + }); + data![row][column] = cell; + } else { + if ( + value.toString().substr(0, 1) === "=" || + value.toString().substr(0, 5) === " { + // // Hook function + // method.createHookFunction( + // "cellUpdated", + // row, + // column, + // JSON.parse(oldValue), + // ctx.flowdata[row][column], + // isRefresh + // ); + // }, 0); +} + +export function clearCell( + ctx: Context, + row: number, + column: number, + options: CommonOptions = {} +) { + if (!_.isNumber(row) || !_.isNumber(column)) { + throw new Error("row or column cannot be null or undefined"); + } + + const sheet = getSheet(ctx, options); + + const cell = sheet.data?.[row]?.[column]; + + if (cell && _.isPlainObject(cell)) { + delete cell.m; + delete cell.v; + + if (cell.f != null) { + delete cell.f; + delFunctionGroup(ctx, row, column, sheet.index); + + delete cell.spl; + } + } +} + +export function setCellFormat( + ctx: Context, + row: number, + column: number, + attr: keyof Cell, + value: any, + options: CommonOptions = {} +) { + if (!_.isNumber(row) || !_.isNumber(column)) { + throw new Error("row or column cannot be null or undefined"); + } + + if (!attr) { + throw new Error("attr cannot be null or undefined"); + } + + const sheet = getSheet(ctx, options); + + const targetSheetData = sheet.data!; + // if (targetSheetData.length === 0) { + // targetSheetData = sheetmanage.buildGridData(sheet); + // } + + const cellData = targetSheetData?.[row]?.[column] || {}; + const cfg = sheet.config || {}; + + // 特殊格式 + if (attr === "ct" && (!value || value.fa == null || value.t == null)) { + throw new Error( + "'fa' and 't' should be present in value when attr is 'ct'" + ); + } + + // @ts-ignore + if (attr === "bd") { + if (cfg.borderInfo == null) { + cfg.borderInfo = []; + } + + const borderInfo = { + rangeType: "range", + borderType: "border-all", + color: "#000", + style: "1", + range: [ + { + column: [column, column], + row: [row, row], + }, + ], + ...value, + }; + + cfg.borderInfo.push(borderInfo); + } else { + cellData[attr] = value; + } + + targetSheetData[row][column] = cellData; + + sheet.config = cfg; + ctx.config = cfg; +} diff --git a/packages/core/src/api/common.ts b/packages/core/src/api/common.ts new file mode 100644 index 0000000..1d7eb6f --- /dev/null +++ b/packages/core/src/api/common.ts @@ -0,0 +1,21 @@ +import { Context } from "../context"; +import { getSheetIndex } from "../utils"; +import { SHEET_NOT_FOUND } from "./errors"; + +export type CommonOptions = { order?: number }; + +export function getSheet(ctx: Context, options: CommonOptions = {}) { + const { order = getSheetIndex(ctx, ctx.currentSheetIndex) } = options; + + if (order == null) { + throw SHEET_NOT_FOUND; + } + + const sheet = ctx.luckysheetfile[order]; + + if (sheet == null) { + throw SHEET_NOT_FOUND; + } + + return sheet; +} diff --git a/packages/core/src/api/errors.ts b/packages/core/src/api/errors.ts new file mode 100644 index 0000000..f208858 --- /dev/null +++ b/packages/core/src/api/errors.ts @@ -0,0 +1,2 @@ +export const INVALID_PARAMS = new Error("invalid params"); +export const SHEET_NOT_FOUND = new Error("sheet not found"); diff --git a/packages/core/src/api/index.ts b/packages/core/src/api/index.ts new file mode 100644 index 0000000..d22d28c --- /dev/null +++ b/packages/core/src/api/index.ts @@ -0,0 +1,5 @@ +import type { CommonOptions } from "./common"; + +export type { CommonOptions }; +export * from "./cell"; +export * from "./rowcol"; diff --git a/packages/core/src/api/rowcol.ts b/packages/core/src/api/rowcol.ts new file mode 100644 index 0000000..74a6fb9 --- /dev/null +++ b/packages/core/src/api/rowcol.ts @@ -0,0 +1,206 @@ +import _ from "lodash"; +import { Context } from "../context"; +import { deleteRowCol, insertRowCol } from "../modules"; +import { CommonOptions, getSheet } from "./common"; +import { INVALID_PARAMS } from "./errors"; + +export function freeze( + ctx: Context, + type: "row" | "column" | "both", + range: { row: number; column: number }, + options: CommonOptions = {} +) { + const sheet = getSheet(ctx, options); + + const typeMap = { + row: "rangeRow", + column: "rangeColumn", + both: "rangeBoth", + }; + const innerType = typeMap[type]; + + sheet.frozen = { + // @ts-ignore + type: innerType, + range: { + column_focus: range.column, + row_focus: range.row, + }, + }; +} + +export function insertRowOrColumn( + ctx: Context, + type: "row" | "column", + index: number, + count: number, + direction: "lefttop" | "rightbottom", + options: CommonOptions = {} +) { + if ( + !["row", "column"].includes(type) || + !_.isNumber(index) || + !_.isNumber(count) || + !["lefttop", "rightbottom"].includes(direction) + ) { + throw INVALID_PARAMS; + } + + const sheet = getSheet(ctx, options); + + insertRowCol(ctx, { + type, + index, + count, + direction, + sheetIndex: sheet.index!, + }); +} + +export function deleteRowOrColumn( + ctx: Context, + type: "row" | "column", + start: number, + end: number, + options: CommonOptions = {} +) { + if ( + !["row", "column"].includes(type) || + !_.isNumber(start) || + !_.isNumber(end) + ) { + throw INVALID_PARAMS; + } + + const sheet = getSheet(ctx, options); + + deleteRowCol(ctx, { type, start, end, sheetIndex: sheet.index! }); +} + +export function setRowHeight( + ctx: Context, + rowInfo: Record, + options: CommonOptions = {} +) { + if (!_.isPlainObject(rowInfo)) { + throw INVALID_PARAMS; + } + + const sheet = getSheet(ctx, options); + + const cfg = sheet.config || {}; + if (cfg.rowlen == null) { + cfg.rowlen = {}; + } + + _.forEach(rowInfo, (len, r) => { + if (Number(r) >= 0) { + if (Number(len) >= 0) { + cfg.rowlen![Number(r)] = Number(len); + } + } + }); + + sheet.config = cfg; + + // server.saveParam("cg", file.index, cfg.rowlen, { k: "rowlen" }); + + // if (file.index === ctx.currentSheetIndex) { + // ctx.config = cfg; + // jfrefreshgrid_rhcw(ctx.flowdata.length, ctx.flowdata[0].length); + // } + + // if (success && typeof success === "function") { + // success(); + // } +} + +export function setColumnWidth( + ctx: Context, + columnInfo: Record, + options: CommonOptions = {} +) { + if (!_.isPlainObject(columnInfo)) { + throw INVALID_PARAMS; + } + + const sheet = getSheet(ctx, options); + + const cfg = sheet.config || {}; + if (cfg.columnlen == null) { + cfg.columnlen = {}; + } + + _.forEach(columnInfo, (len, c) => { + if (Number(c) >= 0) { + if (Number(len) >= 0) { + cfg.columnlen![Number(c)] = Number(len); + } + } + }); + + sheet.config = cfg; + + // server.saveParam("cg", file.index, cfg.columnlen, { k: "columnlen" }); + + // if (file.index === ctx.currentSheetIndex) { + // ctx.config = cfg; + // jfrefreshgrid_rhcw(ctx.flowdata.length, ctx.flowdata[0].length); + // } + + // if (success && typeof success === "function") { + // success(); + // } +} + +export function getRowHeight( + ctx: Context, + rows: number[], + options: CommonOptions = {} +) { + if (!_.isArray(rows) || rows.length === 0) { + throw INVALID_PARAMS; + } + + const sheet = getSheet(ctx, options); + + const cfg = sheet.config || {}; + const rowlen = cfg.rowlen || {}; + + const rowlenObj: Record = {}; + + rows.forEach((item) => { + if (Number(item) >= 0) { + const size = rowlen[Number(item)] || ctx.defaultrowlen; + rowlenObj[Number(item)] = size; + } + }); + + return rowlenObj; +} + +export function getColumnWidth( + ctx: Context, + columns: number[], + options: CommonOptions = {} +) { + if (!_.isArray(columns) || columns.length === 0) { + throw INVALID_PARAMS; + } + + const sheet = getSheet(ctx, options); + + const cfg = sheet.config || {}; + const columnlen = cfg.columnlen || {}; + + const columnlenObj: Record = {}; + + columns.forEach((item) => { + if (Number(item) >= 0) { + const size = columnlen[Number(item)] || ctx.defaultcollen; + columnlenObj[Number(item)] = size; + } + }); + + return columnlenObj; +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 453bbcd..4952e91 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,3 +1,7 @@ +import * as api from "./api"; + +export { api }; + export * from "./canvas"; export * from "./context"; export * from "./settings"; diff --git a/packages/core/src/modules/cell.ts b/packages/core/src/modules/cell.ts index af6d53e..36bd811 100644 --- a/packages/core/src/modules/cell.ts +++ b/packages/core/src/modules/cell.ts @@ -655,11 +655,11 @@ export function updateCell( ctx: Context, r: number, c: number, - $input: HTMLDivElement, + $input?: HTMLDivElement, value?: any ) { - let inputText = $input.innerText; - const inputHtml = $input.innerHTML; + let inputText = $input?.innerText; + const inputHtml = $input?.innerHTML; const flowdata = getFlowdata(ctx); if (!flowdata) return; @@ -696,7 +696,7 @@ export function updateCell( const isPrevInline = isInlineStringCell(curv); let isCurInline = - inputText.slice(0, 1) !== "=" && inputHtml.substring(0, 5) === " 0) { @@ -733,7 +733,7 @@ export function updateCell( } curv.ct.t = "inlineStr"; - curv.ct.s = convertSpanToShareString($input.querySelectorAll("span")); + curv.ct.s = convertSpanToShareString($input!.querySelectorAll("span")); if (isCopyVal) { curv.ct.s = [ { @@ -744,7 +744,7 @@ export function updateCell( } // API, we get value from user - value = value || $input.innerText; + value = value || $input?.innerText; // Hook function // if (!method.createHookFunction("cellUpdateBefore", r, c, value, isRefresh)) { diff --git a/packages/core/src/modules/toolbar.ts b/packages/core/src/modules/toolbar.ts index c0aefae..74d205b 100644 --- a/packages/core/src/modules/toolbar.ts +++ b/packages/core/src/modules/toolbar.ts @@ -41,7 +41,7 @@ type ToolbarItemClickHandler = ( type ToolbarItemSelectedFunc = (cell: Cell | null | undefined) => boolean; -function updateFormatCell( +export function updateFormatCell( ctx: Context, d: CellMatrix, attr: keyof Cell, diff --git a/packages/react/src/components/Workbook/api.ts b/packages/react/src/components/Workbook/api.ts new file mode 100644 index 0000000..70e5070 --- /dev/null +++ b/packages/react/src/components/Workbook/api.ts @@ -0,0 +1,128 @@ +import { + addSheet, + api, + Cell, + Context, + deleteRowCol, + deleteSheet, + insertRowCol, + Op, + opToPatch, +} from "@fortune-sheet/core"; +import produce, { applyPatches } from "immer"; +import { SetContextOptions } from "../../context"; + +export function generateAPIs( + context: Context, + setContext: ( + recipe: (ctx: Context) => void, + options?: SetContextOptions + ) => void, + cellInput: HTMLDivElement | null +) { + return { + applyOp: (ops: Op[]) => { + setContext((ctx_) => { + const [patches, specialOps] = opToPatch(ctx_, ops); + if (specialOps.length > 0) { + const [specialOp] = specialOps; + if (specialOp.op === "insertRowCol") { + ctx_ = produce(ctx_, (draftCtx) => { + insertRowCol(draftCtx, specialOp.value); + }); + } else if (specialOp.op === "deleteRowCol") { + ctx_ = produce(ctx_, (draftCtx) => { + deleteRowCol(draftCtx, specialOp.value); + }); + } else if (specialOp.op === "addSheet") { + ctx_ = produce(ctx_, (draftCtx) => { + addSheet(draftCtx); + }); + } else if (specialOp.op === "deleteSheet") { + ctx_ = produce(ctx_, (draftCtx) => { + deleteSheet(draftCtx, specialOp.value.index); + }); + } + } + const newContext = applyPatches(ctx_, patches); + return newContext; + }); + }, + + getCellValue: ( + row: number, + column: number, + options: { type?: keyof Cell; order?: number } = {} + ) => api.getCellValue(context, row, column, options), + + setCellValue: ( + row: number, + column: number, + value: any, + options: { type?: keyof Cell; order?: number } = {} + ) => + setContext((draftCtx) => + api.setCellValue(draftCtx, row, column, value, cellInput!, options) + ), + + clearCell: (row: number, column: number, options: api.CommonOptions = {}) => + setContext((draftCtx) => api.clearCell(draftCtx, row, column, options)), + + setCellFormat: ( + row: number, + column: number, + attr: keyof Cell, + value: any, + options: api.CommonOptions = {} + ) => + setContext((draftCtx) => + api.setCellFormat(draftCtx, row, column, attr, value, options) + ), + + freeze: ( + type: "row" | "column" | "both", + range: { row: number; column: number }, + options: api.CommonOptions = {} + ) => setContext((draftCtx) => api.freeze(draftCtx, type, range, options)), + + insertRowOrColumn: ( + type: "row" | "column", + index: number, + count: number, + direction: "lefttop" | "rightbottom" = "rightbottom", + options: api.CommonOptions = {} + ) => + setContext((draftCtx) => + api.insertRowOrColumn(draftCtx, type, index, count, direction, options) + ), + + deleteRowOrColumn: ( + type: "row" | "column", + start: number, + end: number, + options: api.CommonOptions = {} + ) => + setContext((draftCtx) => + api.deleteRowOrColumn(draftCtx, type, start, end, options) + ), + + setRowHeight: ( + rowInfo: Record, + options: api.CommonOptions = {} + ) => setContext((draftCtx) => api.setRowHeight(draftCtx, rowInfo, options)), + + setColumnWidth: ( + columnInfo: Record, + options: api.CommonOptions = {} + ) => + setContext((draftCtx) => + api.setColumnWidth(draftCtx, columnInfo, options) + ), + + getRowHeight: (rows: number[], options: api.CommonOptions = {}) => + api.getRowHeight(context, rows, options), + + getColumnWidth: (columns: number[], options: api.CommonOptions = {}) => + api.getColumnWidth(context, columns, options), + }; +} diff --git a/packages/react/src/components/Workbook/index.tsx b/packages/react/src/components/Workbook/index.tsx index 1396803..4dcd614 100644 --- a/packages/react/src/components/Workbook/index.tsx +++ b/packages/react/src/components/Workbook/index.tsx @@ -13,12 +13,7 @@ import { filterPatch, patchToOp, Op, - opToPatch, inverseRowColOptions, - insertRowCol, - deleteRowCol, - addSheet, - deleteSheet, ensureSheetIndex, } from "@fortune-sheet/core"; import React, { @@ -46,12 +41,11 @@ import ContextMenu from "../ContextMenu"; import SVGDefines from "../SVGDefines"; import SheetTabContextMenu from "../ContextMenu/SheetTab"; import MoreItemsContaier from "../Toolbar/MoreItemsContainer"; +import { generateAPIs } from "./api"; enablePatches(); -export type WorkbookInstance = { - applyOp: (ops: Op[]) => void; -}; +export type WorkbookInstance = ReturnType; type AdditionalProps = { onChange?: (data: SheetType[]) => void; @@ -78,34 +72,6 @@ const Workbook = React.forwardRef( [..._.values(props)] ); - const applyOp = useCallback((ops: Op[]) => { - setContext((ctx_) => { - const [patches, specialOps] = opToPatch(ctx_, ops); - if (specialOps.length > 0) { - const [specialOp] = specialOps; - if (specialOp.op === "insertRowCol") { - ctx_ = produce(ctx_, (draftCtx) => { - insertRowCol(draftCtx, specialOp.value); - }); - } else if (specialOp.op === "deleteRowCol") { - ctx_ = produce(ctx_, (draftCtx) => { - deleteRowCol(draftCtx, specialOp.value); - }); - } else if (specialOp.op === "addSheet") { - ctx_ = produce(ctx_, (draftCtx) => { - addSheet(draftCtx); - }); - } else if (specialOp.op === "deleteSheet") { - ctx_ = produce(ctx_, (draftCtx) => { - deleteSheet(draftCtx, specialOp.value.index); - }); - } - } - const newContext = applyPatches(ctx_, patches); - return newContext; - }); - }, []); - const emitOp = useCallback( (ctx: Context, patches: Patch[], options?: SetContextOptions) => { if (onOp) { @@ -115,8 +81,6 @@ const Workbook = React.forwardRef( [onOp] ); - useImperativeHandle(ref, () => ({ applyOp })); - const setContextWithProduce = useCallback( (recipe: (ctx: Context) => void, options: SetContextOptions = {}) => { setContext((ctx_) => { @@ -389,6 +353,13 @@ const Workbook = React.forwardRef( }; }, [onPaste]); + // expose APIs + useImperativeHandle( + ref, + () => generateAPIs(context, setContextWithProduce, cellInput.current), + [context, setContextWithProduce] + ); + const i = getSheetIndex(context, context.currentSheetIndex); if (i == null) { return null; diff --git a/stories/API.stories.tsx b/stories/API.stories.tsx new file mode 100644 index 0000000..4c41d1a --- /dev/null +++ b/stories/API.stories.tsx @@ -0,0 +1,191 @@ +import React, { useRef, useEffect } from "react"; +import { ComponentMeta, ComponentStory } from "@storybook/react"; +import { Workbook, WorkbookInstance } from "@fortune-sheet/react"; + +export default { + component: Workbook, +} as ComponentMeta; + +export const SetCellValue: ComponentStory = () => { + const ref = useRef(null); + useEffect(() => { + for (let i = 0; i < 5; i += 1) { + for (let j = 0; j < 5; j += 1) { + ref.current?.setCellValue(i, j, `${i + j}`); + } + } + ref.current?.setCellValue(0, 5, "=SUM(A1:E1)"); + ref.current?.setCellValue(1, 5, "=SUM(A2:E2)"); + ref.current?.setCellValue(2, 5, "=SUM(A3:E3)"); + ref.current?.setCellValue(3, 5, "=SUM(A4:E4)"); + ref.current?.setCellValue(4, 5, "=SUM(A5:E5)"); + }); + return ( +
+ +
+ ); +}; + +export const ClearCell: ComponentStory = () => { + const ref = useRef(null); + useEffect(() => { + ref.current?.clearCell(0, 0); + }); + return ( +
+ +
+ ); +}; + +export const SetCellFormat: ComponentStory = () => { + const ref = useRef(null); + useEffect(() => { + ref.current?.setCellFormat(0, 0, "bg", "green"); + }); + return ( +
+ +
+ ); +}; + +export const Freeze: ComponentStory = () => { + const ref = useRef(null); + useEffect(() => { + ref.current?.freeze("both", { row: 1, column: 1 }); + }); + return ( +
+ +
+ ); +}; + +export const InsertRowCol: ComponentStory = () => { + const ref = useRef(null); + useEffect(() => { + ref.current?.insertRowOrColumn("row", 0, 1); + ref.current?.setCellValue(1, 0, "inserted"); + ref.current?.insertRowOrColumn("column", 0, 1); + ref.current?.setCellValue(0, 1, "inserted"); + }); + return ( +
+ +
+ ); +}; + +export const DeleteRowCol: ComponentStory = () => { + const ref = useRef(null); + useEffect(() => { + ref.current?.deleteRowOrColumn("row", 1, 3); + }); + return ( +
+ +
+ ); +}; + +export const SetRowHeight: ComponentStory = () => { + const ref = useRef(null); + useEffect(() => { + ref.current?.setRowHeight({ "2": 100 }); + }); + return ( +
+ +
+ ); +}; + +export const SetColumnWidth: ComponentStory = () => { + const ref = useRef(null); + useEffect(() => { + ref.current?.setColumnWidth({ "2": 200 }); + }); + return ( +
+ +
+ ); +}; diff --git a/stories/Workbook.stories.tsx b/stories/Features.stories.tsx similarity index 100% rename from stories/Workbook.stories.tsx rename to stories/Features.stories.tsx