From 9b94aa4899da1162857d01b242d5847fc4552434 Mon Sep 17 00:00:00 2001 From: righ Date: Mon, 22 Jan 2024 02:30:51 +0900 Subject: [PATCH 1/8] wip --- .../examples/basic/protection.stories.tsx | 57 +++++ src/components/Cell.tsx | 9 +- src/components/ContextMenu.tsx | 84 ++++--- src/components/Editor.tsx | 9 + src/components/GridSheet.tsx | 4 +- ...erTopCell.tsx => HorizontalHeaderCell.tsx} | 9 +- src/components/Resizer.tsx | 8 +- src/components/Tabular.tsx | 8 +- ...derLeftCell.tsx => VerticalHeaderCell.tsx} | 9 +- src/index.ts | 8 +- src/lib/protection.ts | 57 +++++ src/lib/structs.ts | 7 +- src/lib/table.ts | 219 +++++++++++++----- src/store/actions.ts | 37 ++- src/styles/contextmenu.less | 4 +- src/styles/minified.ts | 4 +- src/styles/root.min.css | 2 +- src/styles/tabular.less | 3 + src/types.ts | 24 +- 19 files changed, 418 insertions(+), 144 deletions(-) create mode 100644 .storybook/examples/basic/protection.stories.tsx rename src/components/{HeaderTopCell.tsx => HorizontalHeaderCell.tsx} (91%) rename src/components/{HeaderLeftCell.tsx => VerticalHeaderCell.tsx} (91%) create mode 100644 src/lib/protection.ts diff --git a/.storybook/examples/basic/protection.stories.tsx b/.storybook/examples/basic/protection.stories.tsx new file mode 100644 index 00000000..e9536277 --- /dev/null +++ b/.storybook/examples/basic/protection.stories.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import { ComponentStory } from "@storybook/react"; +import { generateInitial, GridSheet } from "../../../src"; +import { AddCol, Prevention, ReadOnly } from "../../../src/lib/protection"; + +export default { + title: "Basic", +}; + +type Props = { + numRows: number; + numCols: number; + defaultWidth: number; +}; + +const Sheet = ({ numRows, numCols, defaultWidth }: Props) => { + return ( + <> + + + ); +}; + +const Template: ComponentStory = (args) => ; + +export const Protection = Template.bind({}); +Protection.args = { numRows: 1000, numCols: 100, defaultWidth: 50 }; diff --git a/src/components/Cell.tsx b/src/components/Cell.tsx index c8d5b5fc..e332130b 100644 --- a/src/components/Cell.tsx +++ b/src/components/Cell.tsx @@ -37,10 +37,9 @@ export const Cell: React.FC = React.memo( editingCell, choosing, selectingZone, - headerTopSelecting, - headerLeftSelecting, + verticalHeaderSelecting, + horizontalheaderSelecting, copyingZone, - cutting, searchQuery, matchingCells, matchingCellIndex, @@ -179,11 +178,11 @@ export const Cell: React.FC = React.memo( } return false; } - if (headerTopSelecting) { + if (verticalHeaderSelecting) { dispatch(drag({ y: table.getNumRows(), x })); return false; } - if (headerLeftSelecting) { + if (horizontalheaderSelecting) { dispatch(drag({ y, x: table.getNumCols() })); return false; } diff --git a/src/components/ContextMenu.tsx b/src/components/ContextMenu.tsx index 335fadb2..7c806aa8 100644 --- a/src/components/ContextMenu.tsx +++ b/src/components/ContextMenu.tsx @@ -13,6 +13,7 @@ import { import { areaToZone, zoneShape, zoneToArea } from "../lib/structs"; import { Context } from "../store"; +import { Prevention, isProtected } from "../lib/protection"; export const ContextMenu: React.FC = () => { const { store, dispatch } = React.useContext(Context); @@ -21,8 +22,8 @@ export const ContextMenu: React.FC = () => { table, choosing, selectingZone, - headerTopSelecting, - headerLeftSelecting, + verticalHeaderSelecting, + horizontalheaderSelecting, editorRef, contextMenuPosition, } = store; @@ -49,6 +50,10 @@ export const ContextMenu: React.FC = () => { if (top === -1) { return null; } + const selectingTopCell = table.getByPoint({ y: selectingTop, x: 0 }); + const selectingLeftCell = table.getByPoint({ y: 0, x: selectingLeft }); + const selectingBottomCell = table.getByPoint({ y: selectingBottom, x: 0 }); + const selectingRightCell = table.getByPoint({ y: 0, x: selectingRight }); const historyIndex = table.getHistoryIndex(); return ( @@ -69,7 +74,7 @@ export const ContextMenu: React.FC = () => { >
  • { const area = clip(store); dispatch(cut(areaToZone(area))); @@ -81,7 +86,7 @@ export const ContextMenu: React.FC = () => {
  • { const area = clip(store); dispatch(copy(areaToZone(area))); @@ -93,7 +98,7 @@ export const ContextMenu: React.FC = () => {
  • { const text = editorRef.current?.value || ""; dispatch(paste({ text })); @@ -107,13 +112,13 @@ export const ContextMenu: React.FC = () => {
  • - {!headerTopSelecting && ( + {!verticalHeaderSelecting && (
  • table.maxNumRows - ? "disabled" - : "enabled" + (table.maxNumRows !== -1 && tableHeight + height > table.maxNumRows) || + isProtected(selectingTopCell?.protection, Prevention.AddRowAbove) + ? "gs-disabled" + : "gs-enabled" } onClick={(e) => { const newTable = table.addRows({ @@ -133,15 +138,18 @@ export const ContextMenu: React.FC = () => {
  • )} - {!headerTopSelecting && ( + {!verticalHeaderSelecting && (
  • table.maxNumRows - ? "disabled" - : "enabled" + (table.maxNumRows !== -1 && tableHeight + height > table.maxNumRows) || + isProtected(selectingBottomCell?.protection, Prevention.AddRowBelow) + ? "gs-disabled" + : "gs-enabled" } onClick={(e) => { + if (e.currentTarget.classList.contains("gs-disabled")) { + return; + } selectingZone.startY += height; selectingZone.endY += height; choosing.y += height; @@ -163,14 +171,18 @@ export const ContextMenu: React.FC = () => {
  • )} - {!headerLeftSelecting && ( + {!horizontalheaderSelecting && (
  • table.maxNumCols - ? "disabled" - : "enabled" + (table.maxNumCols !== -1 && tableWidth + width > table.maxNumCols) || + isProtected(selectingLeftCell?.protection, Prevention.AddColLeft) + ? "gs-disabled" + : "gs-enabled" } onClick={(e) => { + if (e.currentTarget.classList.contains("gs-disabled")) { + return; + } const newTable = table.addCols({ x: selectingLeft, numCols: width, @@ -188,14 +200,18 @@ export const ContextMenu: React.FC = () => {
  • )} - {!headerLeftSelecting && ( + {!horizontalheaderSelecting && (
  • table.maxNumCols - ? "disabled" - : "enabled" + (table.maxNumCols !== -1 && tableWidth + width > table.maxNumCols) || + isProtected(selectingRightCell?.protection, Prevention.AddColRight) + ? "gs-disabled" + : "gs-enabled" } onClick={(e) => { + if (e.currentTarget.classList.contains("gs-disabled")) { + return; + } selectingZone.startX += width; selectingZone.endX += width; choosing.x += width; @@ -217,15 +233,18 @@ export const ContextMenu: React.FC = () => {
  • )} - {!headerTopSelecting && ( + {!verticalHeaderSelecting && (
  • { + if (e.currentTarget.classList.contains("gs-disabled")) { + return; + } const newTable = table.removeRows({ y: selectingTop, numRows: height, @@ -243,12 +262,13 @@ export const ContextMenu: React.FC = () => {
  • )} - {!headerLeftSelecting && ( + {!horizontalheaderSelecting && (
  • { const newTable = table.removeCols({ diff --git a/src/components/Editor.tsx b/src/components/Editor.tsx index 53d5667b..aa77271e 100644 --- a/src/components/Editor.tsx +++ b/src/components/Editor.tsx @@ -22,6 +22,7 @@ import { import { Context } from "../store"; import { areaToZone } from "../lib/structs"; import {DEFAULT_HEIGHT} from "../constants"; +import { Prevention, isProtected } from "../lib/protection"; export const Editor: React.FC = () => { @@ -310,6 +311,10 @@ export const Editor: React.FC = () => { if (e.ctrlKey || e.metaKey) { return false; } + if (isProtected(cell?.protection, Prevention.Write)) { + console.warn("This cell is protected from writing."); + return false; + } dispatch(setEditingCell(address)); return false; }; @@ -334,6 +339,10 @@ export const Editor: React.FC = () => { e.currentTarget.value = ""; }} onDoubleClick={(e) => { + if (isProtected(cell?.protection, Prevention.Write)) { + console.warn("This cell is protected from writing."); + return; + } const input = e.currentTarget; if (!editing) { input.value = table.stringify({ y, x }, value); diff --git a/src/components/GridSheet.tsx b/src/components/GridSheet.tsx index 224ad878..831c4e0b 100644 --- a/src/components/GridSheet.tsx +++ b/src/components/GridSheet.tsx @@ -51,8 +51,8 @@ export const GridSheet: React.FC = ({ selectingZone: { startY: -1, startX: -1, endY: -1, endX: -1 }, copyingZone: { startY: -1, startX: -1, endY: -1, endX: -1 }, autofillDraggingTo: null, - headerTopSelecting: false, - headerLeftSelecting: false, + verticalHeaderSelecting: false, + horizontalheaderSelecting: false, editingCell: "", editorRect: { y: 0, x: 0, height: 0, width: 0 }, resizingRect: { y: -1, x: -1, height: -1, width: -1 }, diff --git a/src/components/HeaderTopCell.tsx b/src/components/HorizontalHeaderCell.tsx similarity index 91% rename from src/components/HeaderTopCell.tsx rename to src/components/HorizontalHeaderCell.tsx index d0d43a82..2fb4c6fa 100644 --- a/src/components/HeaderTopCell.tsx +++ b/src/components/HorizontalHeaderCell.tsx @@ -10,12 +10,13 @@ import { setResizingPositionX, } from "../store/actions"; import { DUMMY_IMG, DEFAULT_WIDTH } from "../constants"; +import { Prevention, isProtected } from "../lib/protection"; type Props = { x: number; }; -export const HeaderTopCell: React.FC = React.memo( +export const HorizontalHeaderCell: React.FC = React.memo( ({ x }) => { const { store, dispatch } = React.useContext(Context); const colId = x2c(x); @@ -25,7 +26,7 @@ export const HeaderTopCell: React.FC = React.memo( choosing, selectingZone, resizingRect, - headerTopSelecting, + verticalHeaderSelecting, headerHeight, editorRef, autofillDraggingTo, @@ -39,7 +40,7 @@ export const HeaderTopCell: React.FC = React.memo( className={`gs-header gs-header-horizontal gs-header-top ${choosing.x === x ? "gs-choosing" : "" } ${ between({ start: selectingZone.startX, end: selectingZone.endX }, x) - ? headerTopSelecting + ? verticalHeaderSelecting ? "gs-header-selecting" : "gs-selecting" : "" @@ -105,7 +106,7 @@ export const HeaderTopCell: React.FC = React.memo( > {col?.labeler ? table.getLabel(col.labeler, x) : colId}
    { dispatch(setResizingPositionX([x, e.clientX, e.clientX])); diff --git a/src/components/Resizer.tsx b/src/components/Resizer.tsx index f9a28f09..24900392 100644 --- a/src/components/Resizer.tsx +++ b/src/components/Resizer.tsx @@ -23,8 +23,8 @@ export const Resizer: React.FC = React.memo(() => { resizingPositionY: posY, resizingPositionX: posX, table, - headerTopSelecting, - headerLeftSelecting, + verticalHeaderSelecting, + horizontalheaderSelecting, selectingZone, editorRef, sheetRef, @@ -54,7 +54,7 @@ export const Resizer: React.FC = React.memo(() => { if (x !== -1) { let xs = [x]; if ( - headerTopSelecting && + verticalHeaderSelecting && between({ start: left, end: right }, x) ) { xs = makeSequence(left, right + 1); @@ -65,7 +65,7 @@ export const Resizer: React.FC = React.memo(() => { } if (y !== -1) { let ys = [y]; - if (headerLeftSelecting && between({ start: top, end: bottom }, y)) { + if (horizontalheaderSelecting && between({ start: top, end: bottom }, y)) { ys = makeSequence(top, bottom + 1); } ys.forEach((y, i) => { diff --git a/src/components/Tabular.tsx b/src/components/Tabular.tsx index 53d7c791..cffc811a 100644 --- a/src/components/Tabular.tsx +++ b/src/components/Tabular.tsx @@ -1,8 +1,8 @@ import React from "react"; import { Editor } from "./Editor"; import { Cell } from "./Cell"; -import { HeaderTopCell } from "./HeaderTopCell"; -import { HeaderLeftCell } from "./HeaderLeftCell"; +import { HorizontalHeaderCell } from "./HorizontalHeaderCell"; +import { VerticalHeaderCell } from "./VerticalHeaderCell"; import { SearchBox } from "./SearchBox"; import { Context } from "../store"; @@ -105,7 +105,7 @@ export const Tabular = ({ tableRef }: Props) => { }} > - { virtualized?.xs?.map?.((x) => ) } + { virtualized?.xs?.map?.((x) => ) } @@ -119,7 +119,7 @@ export const Tabular = ({ tableRef }: Props) => { { virtualized?.ys?.map((y, i) => { return ( - + { virtualized?.xs?.map((x) => ) } diff --git a/src/components/HeaderLeftCell.tsx b/src/components/VerticalHeaderCell.tsx similarity index 91% rename from src/components/HeaderLeftCell.tsx rename to src/components/VerticalHeaderCell.tsx index 342fcecb..fa61de9e 100644 --- a/src/components/HeaderLeftCell.tsx +++ b/src/components/VerticalHeaderCell.tsx @@ -10,12 +10,13 @@ import { setResizingPositionY, } from "../store/actions"; import { DUMMY_IMG, DEFAULT_HEIGHT } from "../constants"; +import { Prevention, isProtected } from "../lib/protection"; type Props = { y: number; }; -export const HeaderLeftCell: React.FC = React.memo( +export const VerticalHeaderCell: React.FC = React.memo( ({ y }) => { const rowId = `${y2r(y)}`; const { store, dispatch } = React.useContext(Context); @@ -23,7 +24,7 @@ export const HeaderLeftCell: React.FC = React.memo( const { choosing, selectingZone, - headerLeftSelecting, + horizontalheaderSelecting, resizingRect, headerWidth, editorRef, @@ -39,7 +40,7 @@ export const HeaderLeftCell: React.FC = React.memo( className={`gs-header gs-header-vertical gs-header-left ${choosing.y === y ? "gs-choosing" : "" } ${ between({ start: selectingZone.startY, end: selectingZone.endY }, y) - ? headerLeftSelecting + ? horizontalheaderSelecting ? "gs-header-selecting" : "gs-selecting" : "" @@ -105,7 +106,7 @@ export const HeaderLeftCell: React.FC = React.memo( > {row?.labeler ? table.getLabel(row.labeler, y) : rowId}
    { dispatch(setResizingPositionY([y, e.clientY, e.clientY])); diff --git a/src/index.ts b/src/index.ts index 04f2f395..f50bd873 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,12 @@ export { GridSheet } from "./components/GridSheet"; export { createTableRef } from "./components/Tabular"; -export { Renderer, RendererMixinType } from "./renderers/core"; -export { Parser, ParserMixinType } from "./parsers/core"; +export { Renderer } from "./renderers/core"; +export type { RendererMixinType } from "./renderers/core"; +export { Parser } from "./parsers/core"; +export type { ParserMixinType } from "./parsers/core"; export { oa2aa, aa2oa, generateInitial, generateInitialSimple } from "./lib/structs"; export { x2c, c2x, y2r, r2y, p2a, a2p } from "./lib/converters"; -export { +export type { MatrixType, CellType, FeedbackType, diff --git a/src/lib/protection.ts b/src/lib/protection.ts new file mode 100644 index 00000000..02948906 --- /dev/null +++ b/src/lib/protection.ts @@ -0,0 +1,57 @@ + +export enum Prevention { + DeleteRow = 0b00000000000000000000000000000000000000000000000000001, + DeleteCol = 0b00000000000000000000000000000000000000000000000000010, + AddRowAbove = 0b00000000000000000000000000000000000000000000000000100, + AddRowBelow = 0b00000000000000000000000000000000000000000000000001000, + AddColLeft = 0b00000000000000000000000000000000000000000000000010000, + AddColRight = 0b00000000000000000000000000000000000000000000000100000, + MoveFrom = 0b00000000000000000000000000000000000000000000001000000, + MoveTo = 0b00000000000000000000000000000000000000000000010000000, + Write = 0b00000000000000000000000000000000000000000000100000000, + Style = 0b00000000000000000000000000000000000000000001000000000, + Resize = 0b00000000000000000000000000000000000000000010000000000, + SetRenderer = 0b00000000000000000000000000000000000000000100000000000, + SetParser = 0b00000000000000000000000000000000000000001000000000000, +}; + +export const Move = + Prevention.MoveFrom | + Prevention.MoveTo; + +export const Update = + Prevention.Write | + Prevention.Style | + Prevention.Resize | + Prevention.SetRenderer | + Prevention.SetParser; + +export const AddRow = + Prevention.AddRowAbove | + Prevention.AddRowBelow; + +export const AddCol = + Prevention.AddColLeft | + Prevention.AddColRight; + +export const Add = + AddRow | + AddCol; + +export const Delete = + Prevention.DeleteRow | + Prevention.DeleteCol; + +export const ReadOnly = + Update | + Delete | + Add | + Move +; + +export const isProtected = (protection: number | undefined, flag: Prevention) => { + if (protection === undefined) { + return false; + } + return (protection & flag) === flag; +}; diff --git a/src/lib/structs.ts b/src/lib/structs.ts index e4762f6f..d4e6b440 100644 --- a/src/lib/structs.ts +++ b/src/lib/structs.ts @@ -197,7 +197,8 @@ export const aa2oa = ( export const putMatrix = ( dst: T[][], src: T[][], - dstArea: AreaType + dstArea: AreaType, + filter: (newValue: T, currentValue: T) => boolean = () => true, ) => { const lostRows: MatricesByAddress = {}; const { top, left, bottom, right } = dstArea; @@ -211,7 +212,9 @@ export const putMatrix = ( const value = src[y - top][x - left]; // -1 means excluding headers if (y < dstNumRows - 1 && x < dstNumCols - 1) { - dst[y][x] = value; + if (filter(value, dst[y][x])) { + dst[y][x] = value; + } continue; } if (lostRow.length === 0) { diff --git a/src/lib/table.ts b/src/lib/table.ts index 9311ce9a..c794f7ed 100644 --- a/src/lib/table.ts +++ b/src/lib/table.ts @@ -19,6 +19,10 @@ import { HistoryType, StoreReflectionType, ShapeType, + OperatorType, + NullableIdMatrix, + NullableIds, + NullableId, } from "../types"; import {areaShape, createMatrix, expandRange, matrixShape, putMatrix} from "./structs"; import { a2p, x2c, p2a, y2r, grantAddressAbsolute } from "./converters"; @@ -29,6 +33,7 @@ import { solveFormula } from "../formula/solver"; import {DEFAULT_HEIGHT, DEFAULT_WIDTH, HISTORY_LIMIT, OVERSCAN_X, OVERSCAN_Y} from "../constants"; import { shouldTracking } from "../store/helpers"; +import { Prevention, Update, isProtected } from "./protection"; type Props = { numRows?: number; @@ -59,7 +64,9 @@ type GetProps = { type MoveProps = { src: AreaType; dst: AreaType; + operator?: OperatorType; reflection?: StoreReflectionType; + historicize?: boolean; }; type GetFlattenProps = GetProps & { @@ -260,7 +267,7 @@ export class Table implements UserTable { const range = expandRange(address); const data = cells[address]; range.forEach((address) => { - const origin = this.data[address]; + const origin = cells[address]; cells[address] = { ...origin, ...data, @@ -268,6 +275,7 @@ export class Table implements UserTable { ...origin?.style, ...data?.style, }, + protection: (origin?.protection || 0) | (data?.protection || 0), }; }); }); @@ -292,6 +300,7 @@ export class Table implements UserTable { ...colDefault?.style, ...cell?.style, }, + protection: (common?.protection || 0) | (rowDefault?.protection || 0) | (colDefault?.protection || 0) | (cell?.protection || 0), } as CellType; stacked.value = convertFormulaAbsolute({ value: stacked?.value, @@ -435,7 +444,10 @@ export class Table implements UserTable { return value; } - public getById(id: Id) { + public getById(id: NullableId) { + if (id == null) { + return undefined; + } return this.data[id]; } @@ -716,7 +728,9 @@ export class Table implements UserTable { const idMatrix = history.lostRows[address]; idMatrix.map((ids) => ids.forEach((id) => { - delete this.data[id]; + if (id != null) { + delete this.data[id]; + } }) ); }); @@ -754,9 +768,10 @@ export class Table implements UserTable { matrix.push(ids); for (let x = left; x <= right; x++) { const id = this.idMatrix[y]?.[x]; - if (id) { - ids.push(id); + if (id == null) { + continue; } + ids.push(id); } } return matrix; @@ -805,37 +820,64 @@ export class Table implements UserTable { public move({ src, dst, + historicize = true, + operator = "SYSTEM", reflection = {}, }: MoveProps) { - const changedAt = new Date(); + const matrixNew = this.getNewIdMatrix(src); const matrixFrom = this.getIdMatrixFromArea(src); const matrixTo = this.getIdMatrixFromArea(dst); - const matrixNew = this.getNewIdMatrix(src); - putMatrix(this.idMatrix, matrixNew, src); - matrixFrom.forEach((ids) => { - ids - .map(this.getById.bind(this)) - .filter((c) => c) - .forEach((cell) => this.setChangedAt(cell, changedAt)); - }); - const lostRows = putMatrix(this.idMatrix, matrixFrom, dst); - this.pushHistory({ - applyed: true, - operation: "MOVE", - reflection, + putMatrix( + this.idMatrix, + matrixNew, + src, + (_, id) => { + const cell = this.data[id]; + if (operator === 'USER' && isProtected(cell?.protection, Prevention.MoveFrom)) { + return false; + } + return true; + } + ); + const lostRows = putMatrix( + this.idMatrix, matrixFrom, - matrixTo, - matrixNew, - pointFrom: { y: src.top, x: src.left }, - pointTo: { y: dst.top, x: dst.left }, - lostRows, - }); + dst, + (srcId, dstId) => { + const srcCell = this.data[srcId]; + const dstCell = this.data[dstId]; + if (operator === 'USER' && ( + isProtected(srcCell?.protection, Prevention.MoveFrom) || + isProtected(dstCell?.protection, Prevention.MoveTo) + )) { + return false; + } + if (srcCell != null) { + this.setChangedAt(srcCell, new Date()) + } + return true; + } + ); + if (historicize) { + this.pushHistory({ + applyed: true, + operation: "MOVE", + reflection, + src, + dst, + matrixFrom, + matrixTo, + matrixNew, + lostRows, + }); + } return this.shallowCopy({ copyCache: false }); } public copy({ src, dst, + operator = "SYSTEM", reflection = {}, }: MoveProps) { const { height: maxHeight, width: maxWidth } = areaShape({ @@ -881,38 +923,67 @@ export class Table implements UserTable { }; } } - return this.update({ diff, partial: false, reflection }); + return this.update({ + diff, + partial: false, + operator, + reflection, + }); } private _update({ diff, partial = true, updateChangedAt = true, + ignoreFields = ['labeler', 'protection'], + operator = 'SYSTEM', }: { diff: CellsByAddressType; partial?: boolean; updateChangedAt?: boolean; + ignoreFields?: (keyof CellType)[]; + operator?: OperatorType; }) { const diffBefore: CellsByIdType = {}; const diffAfter: CellsByIdType = {}; const changedAt = new Date(); + Object.keys(diff).forEach((address) => { const cell = { ...diff[address] }; - if (updateChangedAt) { - this.setChangedAt(cell, changedAt); + if (operator === 'USER' && isProtected(cell?.protection, Update)) { + return; } + cell.value = convertFormulaAbsolute({ value: cell.value, table: this, }); const point = a2p(address); const id = this.getId(point); - + const current = this.data[id]; + ignoreFields.forEach((key) => { + cell[key] = current?.[key]; + }); + if (operator === 'USER' && isProtected(current?.protection, Prevention.Write)) { + cell.value = current?.value; + } + if (operator === 'USER' && isProtected(current?.protection, Prevention.Style)) { + cell.style = current?.style; + cell.justifyContent = current?.justifyContent; + cell.alignItems = current?.alignItems; + } + if (operator === 'USER' && isProtected(current?.protection, Prevention.Resize)) { + cell.width = current?.width; + cell.height = current?.height; + } + if (updateChangedAt) { + this.setChangedAt(cell, changedAt); + } // must not partial diffBefore[id] = this.getByPoint(point); diffAfter[id] = cell; if (partial) { - this.data[id] = { ...this.data[id], ...cell }; + this.data[id] = { ...current, ...cell }; } else { this.data[id] = cell; } @@ -928,28 +999,34 @@ export class Table implements UserTable { diff, partial = true, updateChangedAt = true, + historicize = true, + operator = "SYSTEM", reflection = {}, }: { diff: CellsByAddressType; partial?: boolean; updateChangedAt?: boolean; + historicize?: boolean; + operator?: OperatorType; reflection?: StoreReflectionType; }) { const { diffBefore, diffAfter } = this._update({ diff, partial, + operator, updateChangedAt, }); - - this.pushHistory({ - applyed: true, - operation: "UPDATE", - reflection, - diffBefore, - diffAfter, - partial, - }); - + + if (historicize) { + this.pushHistory({ + applyed: true, + operation: "UPDATE", + reflection, + diffBefore, + diffAfter, + partial, + }); + } return this.shallowCopy({ copyCache: true }); } @@ -957,11 +1034,15 @@ export class Table implements UserTable { point, matrix, updateChangedAt = true, + historicize = true, + operator = "SYSTEM", reflection = {}, }: { point: PointType; matrix: MatrixType; updateChangedAt?: boolean; + historicize?: boolean; + operator?: OperatorType; reflection?: StoreReflectionType; }) { const { y: baseY, x: baseX } = point; @@ -984,6 +1065,8 @@ export class Table implements UserTable { diff, partial: true, updateChangedAt, + historicize, + operator, reflection, }); } @@ -992,17 +1075,23 @@ export class Table implements UserTable { point, value, updateChangedAt = true, + historicize = true, + operator = "SYSTEM", reflection = {}, }: { point: PointType; value: string; updateChangedAt?: boolean; + historicize?: boolean; + operator?: OperatorType; reflection?: StoreReflectionType; }) { return this.writeMatrix({ point, matrix: [[value]], updateChangedAt, + historicize, + operator, reflection, }); } @@ -1014,6 +1103,7 @@ export class Table implements UserTable { diff, partial, updateChangedAt, + operator = "SYSTEM", reflection = {}, }: { y: number; @@ -1022,6 +1112,7 @@ export class Table implements UserTable { diff: CellsByAddressType; partial?: boolean; updateChangedAt?: boolean; + operator?: OperatorType; reflection?: StoreReflectionType; }) { const returned = this.addRows({ @@ -1033,7 +1124,7 @@ export class Table implements UserTable { Object.assign( this.lastHistory!, - this._update({ diff, partial, updateChangedAt }), + this._update({ diff, partial, updateChangedAt, operator }), { partial } ); @@ -1044,11 +1135,13 @@ export class Table implements UserTable { y, numRows, baseY, + operator = "SYSTEM", reflection = {}, }: { y: number; numRows: number; baseY: number; + operator?: OperatorType; reflection?: StoreReflectionType; }) { if ( @@ -1088,12 +1181,21 @@ export class Table implements UserTable { public removeRows({ y, numRows, + operator = "SYSTEM", reflection = {}, }: { y: number; numRows: number; + operator?: OperatorType; reflection?: StoreReflectionType; }) { + for (let i = y; i < y + numRows; i++) { + const cell = this.getByPoint({ y: i, x: 0 }); + if (operator === "USER" && isProtected(cell?.protection, Prevention.DeleteRow)) { + console.warn(`Cannot delete row ${i}.`); + return this; + } + } if ( this.minNumRows !== -1 && this.getNumRows() - numRows < this.minNumRows @@ -1101,6 +1203,7 @@ export class Table implements UserTable { console.error(`At least ${this.minNumRows} row(s) are required.`); return this; } + const rows = this.idMatrix.splice(y, numRows); this.area.bottom -= numRows; this.pushHistory({ @@ -1194,12 +1297,22 @@ export class Table implements UserTable { public removeCols({ x, numCols, + operator = "SYSTEM", reflection = {}, }: { x: number; numCols: number; + operator?: OperatorType; reflection?: StoreReflectionType; }) { + for (let i = x; i < x + numCols; i++) { + const cell = this.getByPoint({ y: 0, x: i }); + if (operator === "USER" && isProtected(cell?.protection, Prevention.DeleteCol)) { + console.warn(`Cannot delete col ${i}.`); + return this; + } + } + if ( this.minNumCols !== -1 && this.getNumCols() - numCols < this.minNumCols @@ -1357,8 +1470,8 @@ export class Table implements UserTable { break; } case "MOVE": { - const { y: yFrom, x: xFrom } = history.pointFrom; - const { y: yTo, x: xTo } = history.pointTo; + const { top: yFrom, left: xFrom } = history.src; + const { top: yTo, left: xTo } = history.dst; const { height: rows, width: cols } = matrixShape({ matrix: history.matrixFrom, base: -1, @@ -1433,24 +1546,8 @@ export class Table implements UserTable { break; } case "MOVE": { - const { y: yFrom, x: xFrom } = history.pointFrom; - const { y: yTo, x: xTo } = history.pointTo; - const { height: rows, width: cols } = matrixShape({ - matrix: history.matrixFrom, - base: -1, - }); - putMatrix(this.idMatrix, history.matrixNew, { - top: yFrom, - left: xFrom, - bottom: yFrom + rows, - right: xFrom + cols, - }); - putMatrix(this.idMatrix, history.matrixFrom, { - top: yTo, - left: xTo, - bottom: yTo + rows, - right: xTo + cols, - }); + const {src, dst} = history; + this.move({src, dst, operator: "USER", historicize: false}); } } return { diff --git a/src/store/actions.ts b/src/store/actions.ts index 1546b490..a3a70c4a 100644 --- a/src/store/actions.ts +++ b/src/store/actions.ts @@ -22,6 +22,7 @@ import { tsv2matrix, p2a } from "../lib/converters"; import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from "../constants"; import { initSearchStatement, restrictPoints } from "./helpers"; import { smartScroll } from "../lib/virtualization"; +import { Prevention, isProtected } from "../lib/protection"; const actions: { [s: string]: CoreAction } = {}; @@ -283,6 +284,8 @@ export const cut = new CutAction().bind(); class PasteAction extends CoreAction { reduce(store: StoreType, payload: T): StoreType { const { choosing, copyingZone, selectingZone, cutting, table } = store; + const cell = table.getByPoint(choosing); + let selectingArea = zoneToArea(selectingZone); const copyingArea = zoneToArea(copyingZone); @@ -306,6 +309,7 @@ class PasteAction extends CoreAction { const newTable = table.move({ src, dst, + operator: "USER", reflection: { selectingZone: areaToZone(dst), copyingZone, @@ -354,6 +358,7 @@ class PasteAction extends CoreAction { newTable = table.copy({ src: copyingArea, dst: selectingArea, + operator: "USER", reflection: { copyingZone, selectingZone, @@ -378,8 +383,8 @@ class EscapeAction extends CoreAction { copyingZone: { startY: -1, startX: -1, endY: -1, endX: -1 }, cutting: false, editingCell: "", - headerTopSelecting: false, - headerLeftSelecting: false, + verticalHeaderSelecting: false, + horizontalheaderSelecting: false, }; } } @@ -401,8 +406,8 @@ class SelectAction extends CoreAction { return { ...store, selectingZone: payload, - headerTopSelecting: false, - headerLeftSelecting: false, + verticalHeaderSelecting: false, + horizontalheaderSelecting: false, }; } } @@ -424,8 +429,8 @@ class SelectRowsAction< ...store, selectingZone, choosing: { y: start, x: 0 } as PointType, - headerLeftSelecting: true, - headerTopSelecting: false, + horizontalheaderSelecting: true, + verticalHeaderSelecting: false, }; } } @@ -448,8 +453,8 @@ class SelectColsAction< ...store, selectingZone, choosing: { y: 0, x: start } as PointType, - headerLeftSelecting: false, - headerTopSelecting: true, + horizontalheaderSelecting: false, + verticalHeaderSelecting: true, }; } } @@ -489,6 +494,7 @@ class WriteAction extends CoreAction { const newTable = table.write({ point: choosing, value: payload, + operator: "USER", reflection: { selectingZone, choosing, @@ -515,14 +521,27 @@ class ClearAction extends CoreAction { } const { top, left, bottom, right } = selectingArea; const diff: CellsByAddressType = {}; + let diffCount = 0; for (let y = top; y <= bottom; y++) { for (let x = left; x <= right; x++) { - diff[p2a({ y, x })] = { value: null }; + const cell = table.getByPoint({ y, x }); + const address = p2a({ y, x }); + if (isProtected(cell?.protection, Prevention.Write)) { + continue; + } + if (cell?.value != null) { + diff[address] = { value: null }; + diffCount++; + } } } + if (diffCount === 0) { + return store; + } const newTable = table.update({ diff, partial: true, + operator: "USER", reflection: { selectingZone, choosing, diff --git a/src/styles/contextmenu.less b/src/styles/contextmenu.less index 078ea850..ac895685 100644 --- a/src/styles/contextmenu.less +++ b/src/styles/contextmenu.less @@ -27,13 +27,13 @@ padding: 5px 10px; list-style-type: none; - &.enabled { + &.gs-enabled { cursor: pointer; &:hover { background-color: #eeeeee; } } - &.disabled { + &.gs-disabled { opacity: 0.5; cursor: not-allowed; } diff --git a/src/styles/minified.ts b/src/styles/minified.ts index 2e582806..97b6934b 100644 --- a/src/styles/minified.ts +++ b/src/styles/minified.ts @@ -1,3 +1,3 @@ // yarn generate-style -export const LAST_MODIFIED = 1701006810; -export const CSS = `.gridsheet-1{overflow:hidden;position:relative;box-sizing:content-box;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif}.gridsheet-1.light{background-color:#f7f7f7;color:#000}.gridsheet-1.light .gs-editor.gs-editing textarea{background-color:#f5f5f5;color:#111;caret-color:#000}.gridsheet-1.light .gs-header{background-color:#eee;color:#666}.gridsheet-1.light .gs-header.gs-selecting{background-color:#ddd}.gridsheet-1.light .gs-header.gs-choosing{background-color:#bbb}.gridsheet-1.light .gs-header.gs-header-selecting{background-color:#555;color:#fff}.gridsheet-1.dark{background-color:#323232;color:#eee}.gridsheet-1.dark .gs-editor.gs-editing textarea{background-color:#353535;color:#ddd;caret-color:#ddd}.gridsheet-1.dark .gs-header{background-color:#474747;color:#eee}.gridsheet-1.dark .gs-header.gs-selecting{background-color:#777}.gridsheet-1.dark .gs-header.gs-choosing{background-color:#999}.gridsheet-1.dark .gs-header.gs-header-selecting{background-color:#bbb;color:#444}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer.gs-selected{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:rgba(0,127,255,.08);top:0;left:0;z-index:2}.gridsheet-1 .gs-line{position:relative;top:0;left:0;border:dotted 1px #07f;box-sizing:border-box}.gridsheet-1 .gs-line span{font-size:10px;padding:3px;background-color:#07f;color:#fff;margin:0;position:absolute;top:0;left:0}.gridsheet-1.gs-table-width-larger{border-right:solid 1px rgba(128,128,128,.5)}.gridsheet-1.gs-table-height-larger{border-bottom:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-cell{background-clip:padding-box;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);padding:0;margin:0;box-sizing:border-box;position:relative}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell.gs-selected .gs-cell-rendered-wrapper-inner{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-cell.gs-selected .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-pointed{margin-top:-1px;margin-left:-1px;z-index:1}.gridsheet-1 .gs-cell.gs-pointed.gs-editing{color:transparent}.gridsheet-1 .gs-cell.gs-pointed .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-matching{background-color:rgba(0,200,100,.2)}.gridsheet-1 .gs-cell.gs-searching{border:solid 2px #00aa78}.gridsheet-1 .gs-cell .formula-error-triangle{position:absolute;top:0;right:0;border-top:3px solid rgba(200,0,0,.9);border-right:3px solid rgba(200,0,0,.9);border-bottom:3px solid transparent;border-left:3px solid transparent;z-index:1}.gridsheet-1 .gs-cell .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;font-size:8px;font-weight:400;font-style:normal;background-color:rgba(0,128,255,.2);color:rgba(255,255,255,.6);padding:0 2px;display:none;opacity:.7}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer{width:100%;height:100%}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-inner{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box}.gridsheet-1 .gs-cell .gs-cell-rendered{overflow:hidden;font-size:13px;letter-spacing:1px;white-space:pre-wrap;line-height:24px;cursor:auto;word-wrap:break-word;word-break:break-all;padding:0 2px}.gridsheet-1 .gs-cell .gs-cell-rendered>*{position:relative}.gridsheet-1 .gs-cell .gs-cell-rendered>.backface{z-index:0}.gridsheet-1 .gs-cell .gs-autofill-drag{background-color:#07f;position:absolute;width:7px;height:7px;bottom:0;right:0;margin-right:-3.5px;margin-bottom:-3.5px;cursor:crosshair;z-index:1}.gridsheet-1 .gs-contextmenu-modal{position:fixed;top:0;left:0;width:100%;height:100vh;z-index:3}.gridsheet-1 .gs-contextmenu{z-index:3;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px}.gridsheet-1 .gs-contextmenu ul{min-width:250px;color:#555;margin:0;padding:0}.gridsheet-1 .gs-contextmenu ul li{padding:5px 10px;list-style-type:none;display:flex}.gridsheet-1 .gs-contextmenu ul li.enabled{cursor:pointer}.gridsheet-1 .gs-contextmenu ul li.enabled:hover{background-color:#eee}.gridsheet-1 .gs-contextmenu ul li.disabled{opacity:.5;cursor:not-allowed}.gridsheet-1 .gs-contextmenu ul li.gs-menu-divider{background-color:#aaa;margin:10px 0;padding:0;height:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-name{flex:1;font-size:15px;letter-spacing:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut{font-size:10px;line-height:15px;color:#999;width:15px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:before{content:"("}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:after{content:")"}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gridsheet-1 .gs-editor{position:fixed;opacity:0;z-index:-1;background-color:#aaa}.gridsheet-1 .gs-editor textarea{width:100%;padding:0 2px;position:absolute;font-size:13px;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;caret-color:transparent;cursor:default}.gridsheet-1 .gs-editor.gs-editing{z-index:3;opacity:1}.gridsheet-1 .gs-editor.gs-editing textarea{cursor:text;min-width:100%;white-space:pre;outline:solid 2px #07f;border:none!important;height:auto}.gridsheet-1 .gs-editor.gs-editing .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;margin-top:-20px;margin-right:-2px;padding:3px 5px;font-size:10px;background-color:#07f;color:#fff;z-index:1}.gridsheet-1 .gs-tabular{overflow:auto;display:block;box-sizing:border-box}.gridsheet-1 .gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse}.gridsheet-1 .gs-table{border:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-adjuster{padding:0;visibility:hidden}.gridsheet-1 .gs-header-top{top:0;overflow:hidden}.gridsheet-1 .gs-header-left{left:0}.gridsheet-1 .gs-header-top.gs-header-left{z-index:3}.gridsheet-1 .gs-header{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gridsheet-1 .gs-header .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gridsheet-1 .gs-header .gs-resizer:hover{background-color:#07f}.gridsheet-1 .gs-header .gs-header-outer{height:100%;box-sizing:border-box}.gridsheet-1 .gs-header .gs-header-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gridsheet-1 .gs-header-left-top{border-right:solid .5px transparent;border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal{min-height:20px}.gridsheet-1 .gs-header-horizontal .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-header-outer{border-left:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal.gs-header-top-end .gs-header-outer{border-right:none}.gridsheet-1 .gs-header-vertical{overflow:hidden;min-width:30px}.gridsheet-1 .gs-header-vertical .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-header-outer{border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-vertical.gs-header-left-end .gs-header-outer{border-bottom:none}.gridsheet-1 .gs-search{width:300px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;display:flex;background-color:#fdfdfd;border:solid 2px #eee;border-radius:5px;padding:10px;position:fixed;top:10px;right:10px;z-index:5}.gridsheet-1 .gs-search .gs-searchbox{display:flex;position:relative;border:solid 2px #07f;border-radius:5px;flex:1}.gridsheet-1 .gs-search .gs-searchbox input[type=text]{padding:5px;background-color:transparent;border:none;outline:0;z-index:1;flex:1}.gridsheet-1 .gs-search .gs-searchbox .gs-search-progress{color:#999;padding:6px 3px;font-size:13px;text-align:right}.gridsheet-1 .gs-search .gs-search-close{margin:6px 5px;cursor:pointer;color:#ddd;width:50px;text-align:center}`; +export const LAST_MODIFIED = 1706379419; +export const CSS = `.gridsheet-1{overflow:hidden;position:relative;box-sizing:content-box;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif}.gridsheet-1.light{background-color:#f7f7f7;color:#000}.gridsheet-1.light .gs-editor.gs-editing textarea{background-color:#f5f5f5;color:#111;caret-color:#000}.gridsheet-1.light .gs-header{background-color:#eee;color:#666}.gridsheet-1.light .gs-header.gs-selecting{background-color:#ddd}.gridsheet-1.light .gs-header.gs-choosing{background-color:#bbb}.gridsheet-1.light .gs-header.gs-header-selecting{background-color:#555;color:#fff}.gridsheet-1.dark{background-color:#323232;color:#eee}.gridsheet-1.dark .gs-editor.gs-editing textarea{background-color:#353535;color:#ddd;caret-color:#ddd}.gridsheet-1.dark .gs-header{background-color:#474747;color:#eee}.gridsheet-1.dark .gs-header.gs-selecting{background-color:#777}.gridsheet-1.dark .gs-header.gs-choosing{background-color:#999}.gridsheet-1.dark .gs-header.gs-header-selecting{background-color:#bbb;color:#444}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer.gs-selected{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:rgba(0,127,255,.08);top:0;left:0;z-index:2}.gridsheet-1 .gs-line{position:relative;top:0;left:0;border:dotted 1px #07f;box-sizing:border-box}.gridsheet-1 .gs-line span{font-size:10px;padding:3px;background-color:#07f;color:#fff;margin:0;position:absolute;top:0;left:0}.gridsheet-1.gs-table-width-larger{border-right:solid 1px rgba(128,128,128,.5)}.gridsheet-1.gs-table-height-larger{border-bottom:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-cell{background-clip:padding-box;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);padding:0;margin:0;box-sizing:border-box;position:relative}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell.gs-selected .gs-cell-rendered-wrapper-inner{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-cell.gs-selected .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-pointed{margin-top:-1px;margin-left:-1px;z-index:1}.gridsheet-1 .gs-cell.gs-pointed.gs-editing{color:transparent}.gridsheet-1 .gs-cell.gs-pointed .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-matching{background-color:rgba(0,200,100,.2)}.gridsheet-1 .gs-cell.gs-searching{border:solid 2px #00aa78}.gridsheet-1 .gs-cell .formula-error-triangle{position:absolute;top:0;right:0;border-top:3px solid rgba(200,0,0,.9);border-right:3px solid rgba(200,0,0,.9);border-bottom:3px solid transparent;border-left:3px solid transparent;z-index:1}.gridsheet-1 .gs-cell .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;font-size:8px;font-weight:400;font-style:normal;background-color:rgba(0,128,255,.2);color:rgba(255,255,255,.6);padding:0 2px;display:none;opacity:.7}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer{width:100%;height:100%}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-inner{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box}.gridsheet-1 .gs-cell .gs-cell-rendered{overflow:hidden;font-size:13px;letter-spacing:1px;white-space:pre-wrap;line-height:24px;cursor:auto;word-wrap:break-word;word-break:break-all;padding:0 2px}.gridsheet-1 .gs-cell .gs-cell-rendered>*{position:relative}.gridsheet-1 .gs-cell .gs-cell-rendered>.backface{z-index:0}.gridsheet-1 .gs-cell .gs-autofill-drag{background-color:#07f;position:absolute;width:7px;height:7px;bottom:0;right:0;margin-right:-3.5px;margin-bottom:-3.5px;cursor:crosshair;z-index:1}.gridsheet-1 .gs-contextmenu-modal{position:fixed;top:0;left:0;width:100%;height:100vh;z-index:3}.gridsheet-1 .gs-contextmenu{z-index:3;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px}.gridsheet-1 .gs-contextmenu ul{min-width:250px;color:#555;margin:0;padding:0}.gridsheet-1 .gs-contextmenu ul li{padding:5px 10px;list-style-type:none;display:flex}.gridsheet-1 .gs-contextmenu ul li.gs-enabled{cursor:pointer}.gridsheet-1 .gs-contextmenu ul li.gs-enabled:hover{background-color:#eee}.gridsheet-1 .gs-contextmenu ul li.gs-disabled{opacity:.5;cursor:not-allowed}.gridsheet-1 .gs-contextmenu ul li.gs-menu-divider{background-color:#aaa;margin:10px 0;padding:0;height:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-name{flex:1;font-size:15px;letter-spacing:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut{font-size:10px;line-height:15px;color:#999;width:15px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:before{content:"("}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:after{content:")"}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gridsheet-1 .gs-editor{position:fixed;opacity:0;z-index:-1;background-color:#aaa}.gridsheet-1 .gs-editor textarea{width:100%;padding:0 2px;position:absolute;font-size:13px;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;caret-color:transparent;cursor:default}.gridsheet-1 .gs-editor.gs-editing{z-index:3;opacity:1}.gridsheet-1 .gs-editor.gs-editing textarea{cursor:text;min-width:100%;white-space:pre;outline:solid 2px #07f;border:none!important;height:auto}.gridsheet-1 .gs-editor.gs-editing .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;margin-top:-20px;margin-right:-2px;padding:3px 5px;font-size:10px;background-color:#07f;color:#fff;z-index:1}.gridsheet-1 .gs-tabular{overflow:auto;display:block;box-sizing:border-box}.gridsheet-1 .gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse}.gridsheet-1 .gs-table{border:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-adjuster{padding:0;visibility:hidden}.gridsheet-1 .gs-header-top{top:0;overflow:hidden}.gridsheet-1 .gs-header-left{left:0}.gridsheet-1 .gs-header-top.gs-header-left{z-index:3}.gridsheet-1 .gs-header{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gridsheet-1 .gs-header .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gridsheet-1 .gs-header .gs-resizer:hover{background-color:#07f}.gridsheet-1 .gs-header .gs-resizer.gs-protected{display:none}.gridsheet-1 .gs-header .gs-header-outer{height:100%;box-sizing:border-box}.gridsheet-1 .gs-header .gs-header-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gridsheet-1 .gs-header-left-top{border-right:solid .5px transparent;border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal{min-height:20px}.gridsheet-1 .gs-header-horizontal .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-header-outer{border-left:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal.gs-header-top-end .gs-header-outer{border-right:none}.gridsheet-1 .gs-header-vertical{overflow:hidden;min-width:30px}.gridsheet-1 .gs-header-vertical .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-header-outer{border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-vertical.gs-header-left-end .gs-header-outer{border-bottom:none}.gridsheet-1 .gs-search{width:300px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;display:flex;background-color:#fdfdfd;border:solid 2px #eee;border-radius:5px;padding:10px;position:fixed;top:10px;right:10px;z-index:5}.gridsheet-1 .gs-search .gs-searchbox{display:flex;position:relative;border:solid 2px #07f;border-radius:5px;flex:1}.gridsheet-1 .gs-search .gs-searchbox input[type=text]{padding:5px;background-color:transparent;border:none;outline:0;z-index:1;flex:1}.gridsheet-1 .gs-search .gs-searchbox .gs-search-progress{color:#999;padding:6px 3px;font-size:13px;text-align:right}.gridsheet-1 .gs-search .gs-search-close{margin:6px 5px;cursor:pointer;color:#ddd;width:50px;text-align:center}`; diff --git a/src/styles/root.min.css b/src/styles/root.min.css index 83b2d068..1b3c18c7 100644 --- a/src/styles/root.min.css +++ b/src/styles/root.min.css @@ -1 +1 @@ -.gridsheet-1{overflow:hidden;position:relative;box-sizing:content-box;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif}.gridsheet-1.light{background-color:#f7f7f7;color:#000}.gridsheet-1.light .gs-editor.gs-editing textarea{background-color:#f5f5f5;color:#111;caret-color:#000}.gridsheet-1.light .gs-header{background-color:#eee;color:#666}.gridsheet-1.light .gs-header.gs-selecting{background-color:#ddd}.gridsheet-1.light .gs-header.gs-choosing{background-color:#bbb}.gridsheet-1.light .gs-header.gs-header-selecting{background-color:#555;color:#fff}.gridsheet-1.dark{background-color:#323232;color:#eee}.gridsheet-1.dark .gs-editor.gs-editing textarea{background-color:#353535;color:#ddd;caret-color:#ddd}.gridsheet-1.dark .gs-header{background-color:#474747;color:#eee}.gridsheet-1.dark .gs-header.gs-selecting{background-color:#777}.gridsheet-1.dark .gs-header.gs-choosing{background-color:#999}.gridsheet-1.dark .gs-header.gs-header-selecting{background-color:#bbb;color:#444}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer.gs-selected{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:rgba(0,127,255,.08);top:0;left:0;z-index:2}.gridsheet-1 .gs-line{position:relative;top:0;left:0;border:dotted 1px #07f;box-sizing:border-box}.gridsheet-1 .gs-line span{font-size:10px;padding:3px;background-color:#07f;color:#fff;margin:0;position:absolute;top:0;left:0}.gridsheet-1.gs-table-width-larger{border-right:solid 1px rgba(128,128,128,.5)}.gridsheet-1.gs-table-height-larger{border-bottom:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-cell{background-clip:padding-box;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);padding:0;margin:0;box-sizing:border-box;position:relative}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell.gs-selected .gs-cell-rendered-wrapper-inner{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-cell.gs-selected .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-pointed{margin-top:-1px;margin-left:-1px;z-index:1}.gridsheet-1 .gs-cell.gs-pointed.gs-editing{color:transparent}.gridsheet-1 .gs-cell.gs-pointed .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-matching{background-color:rgba(0,200,100,.2)}.gridsheet-1 .gs-cell.gs-searching{border:solid 2px #00aa78}.gridsheet-1 .gs-cell .formula-error-triangle{position:absolute;top:0;right:0;border-top:3px solid rgba(200,0,0,.9);border-right:3px solid rgba(200,0,0,.9);border-bottom:3px solid transparent;border-left:3px solid transparent;z-index:1}.gridsheet-1 .gs-cell .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;font-size:8px;font-weight:400;font-style:normal;background-color:rgba(0,128,255,.2);color:rgba(255,255,255,.6);padding:0 2px;display:none;opacity:.7}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer{width:100%;height:100%}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-inner{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box}.gridsheet-1 .gs-cell .gs-cell-rendered{overflow:hidden;font-size:13px;letter-spacing:1px;white-space:pre-wrap;line-height:24px;cursor:auto;word-wrap:break-word;word-break:break-all;padding:0 2px}.gridsheet-1 .gs-cell .gs-cell-rendered>*{position:relative}.gridsheet-1 .gs-cell .gs-cell-rendered>.backface{z-index:0}.gridsheet-1 .gs-cell .gs-autofill-drag{background-color:#07f;position:absolute;width:7px;height:7px;bottom:0;right:0;margin-right:-3.5px;margin-bottom:-3.5px;cursor:crosshair;z-index:1}.gridsheet-1 .gs-contextmenu-modal{position:fixed;top:0;left:0;width:100%;height:100vh;z-index:3}.gridsheet-1 .gs-contextmenu{z-index:3;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px}.gridsheet-1 .gs-contextmenu ul{min-width:250px;color:#555;margin:0;padding:0}.gridsheet-1 .gs-contextmenu ul li{padding:5px 10px;list-style-type:none;display:flex}.gridsheet-1 .gs-contextmenu ul li.enabled{cursor:pointer}.gridsheet-1 .gs-contextmenu ul li.enabled:hover{background-color:#eee}.gridsheet-1 .gs-contextmenu ul li.disabled{opacity:.5;cursor:not-allowed}.gridsheet-1 .gs-contextmenu ul li.gs-menu-divider{background-color:#aaa;margin:10px 0;padding:0;height:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-name{flex:1;font-size:15px;letter-spacing:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut{font-size:10px;line-height:15px;color:#999;width:15px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:before{content:"("}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:after{content:")"}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gridsheet-1 .gs-editor{position:fixed;opacity:0;z-index:-1;background-color:#aaa}.gridsheet-1 .gs-editor textarea{width:100%;padding:0 2px;position:absolute;font-size:13px;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;caret-color:transparent;cursor:default}.gridsheet-1 .gs-editor.gs-editing{z-index:3;opacity:1}.gridsheet-1 .gs-editor.gs-editing textarea{cursor:text;min-width:100%;white-space:pre;outline:solid 2px #07f;border:none!important;height:auto}.gridsheet-1 .gs-editor.gs-editing .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;margin-top:-20px;margin-right:-2px;padding:3px 5px;font-size:10px;background-color:#07f;color:#fff;z-index:1}.gridsheet-1 .gs-tabular{overflow:auto;display:block;box-sizing:border-box}.gridsheet-1 .gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse}.gridsheet-1 .gs-table{border:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-adjuster{padding:0;visibility:hidden}.gridsheet-1 .gs-header-top{top:0;overflow:hidden}.gridsheet-1 .gs-header-left{left:0}.gridsheet-1 .gs-header-top.gs-header-left{z-index:3}.gridsheet-1 .gs-header{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gridsheet-1 .gs-header .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gridsheet-1 .gs-header .gs-resizer:hover{background-color:#07f}.gridsheet-1 .gs-header .gs-header-outer{height:100%;box-sizing:border-box}.gridsheet-1 .gs-header .gs-header-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gridsheet-1 .gs-header-left-top{border-right:solid .5px transparent;border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal{min-height:20px}.gridsheet-1 .gs-header-horizontal .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-header-outer{border-left:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal.gs-header-top-end .gs-header-outer{border-right:none}.gridsheet-1 .gs-header-vertical{overflow:hidden;min-width:30px}.gridsheet-1 .gs-header-vertical .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-header-outer{border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-vertical.gs-header-left-end .gs-header-outer{border-bottom:none}.gridsheet-1 .gs-search{width:300px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;display:flex;background-color:#fdfdfd;border:solid 2px #eee;border-radius:5px;padding:10px;position:fixed;top:10px;right:10px;z-index:5}.gridsheet-1 .gs-search .gs-searchbox{display:flex;position:relative;border:solid 2px #07f;border-radius:5px;flex:1}.gridsheet-1 .gs-search .gs-searchbox input[type=text]{padding:5px;background-color:transparent;border:none;outline:0;z-index:1;flex:1}.gridsheet-1 .gs-search .gs-searchbox .gs-search-progress{color:#999;padding:6px 3px;font-size:13px;text-align:right}.gridsheet-1 .gs-search .gs-search-close{margin:6px 5px;cursor:pointer;color:#ddd;width:50px;text-align:center} \ No newline at end of file +.gridsheet-1{overflow:hidden;position:relative;box-sizing:content-box;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif}.gridsheet-1.light{background-color:#f7f7f7;color:#000}.gridsheet-1.light .gs-editor.gs-editing textarea{background-color:#f5f5f5;color:#111;caret-color:#000}.gridsheet-1.light .gs-header{background-color:#eee;color:#666}.gridsheet-1.light .gs-header.gs-selecting{background-color:#ddd}.gridsheet-1.light .gs-header.gs-choosing{background-color:#bbb}.gridsheet-1.light .gs-header.gs-header-selecting{background-color:#555;color:#fff}.gridsheet-1.dark{background-color:#323232;color:#eee}.gridsheet-1.dark .gs-editor.gs-editing textarea{background-color:#353535;color:#ddd;caret-color:#ddd}.gridsheet-1.dark .gs-header{background-color:#474747;color:#eee}.gridsheet-1.dark .gs-header.gs-selecting{background-color:#777}.gridsheet-1.dark .gs-header.gs-choosing{background-color:#999}.gridsheet-1.dark .gs-header.gs-header-selecting{background-color:#bbb;color:#444}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer.gs-selected{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:rgba(0,127,255,.08);top:0;left:0;z-index:2}.gridsheet-1 .gs-line{position:relative;top:0;left:0;border:dotted 1px #07f;box-sizing:border-box}.gridsheet-1 .gs-line span{font-size:10px;padding:3px;background-color:#07f;color:#fff;margin:0;position:absolute;top:0;left:0}.gridsheet-1.gs-table-width-larger{border-right:solid 1px rgba(128,128,128,.5)}.gridsheet-1.gs-table-height-larger{border-bottom:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-cell{background-clip:padding-box;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);padding:0;margin:0;box-sizing:border-box;position:relative}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell.gs-selected .gs-cell-rendered-wrapper-inner{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-cell.gs-selected .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-pointed{margin-top:-1px;margin-left:-1px;z-index:1}.gridsheet-1 .gs-cell.gs-pointed.gs-editing{color:transparent}.gridsheet-1 .gs-cell.gs-pointed .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-matching{background-color:rgba(0,200,100,.2)}.gridsheet-1 .gs-cell.gs-searching{border:solid 2px #00aa78}.gridsheet-1 .gs-cell .formula-error-triangle{position:absolute;top:0;right:0;border-top:3px solid rgba(200,0,0,.9);border-right:3px solid rgba(200,0,0,.9);border-bottom:3px solid transparent;border-left:3px solid transparent;z-index:1}.gridsheet-1 .gs-cell .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;font-size:8px;font-weight:400;font-style:normal;background-color:rgba(0,128,255,.2);color:rgba(255,255,255,.6);padding:0 2px;display:none;opacity:.7}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer{width:100%;height:100%}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-inner{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box}.gridsheet-1 .gs-cell .gs-cell-rendered{overflow:hidden;font-size:13px;letter-spacing:1px;white-space:pre-wrap;line-height:24px;cursor:auto;word-wrap:break-word;word-break:break-all;padding:0 2px}.gridsheet-1 .gs-cell .gs-cell-rendered>*{position:relative}.gridsheet-1 .gs-cell .gs-cell-rendered>.backface{z-index:0}.gridsheet-1 .gs-cell .gs-autofill-drag{background-color:#07f;position:absolute;width:7px;height:7px;bottom:0;right:0;margin-right:-3.5px;margin-bottom:-3.5px;cursor:crosshair;z-index:1}.gridsheet-1 .gs-contextmenu-modal{position:fixed;top:0;left:0;width:100%;height:100vh;z-index:3}.gridsheet-1 .gs-contextmenu{z-index:3;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px}.gridsheet-1 .gs-contextmenu ul{min-width:250px;color:#555;margin:0;padding:0}.gridsheet-1 .gs-contextmenu ul li{padding:5px 10px;list-style-type:none;display:flex}.gridsheet-1 .gs-contextmenu ul li.gs-enabled{cursor:pointer}.gridsheet-1 .gs-contextmenu ul li.gs-enabled:hover{background-color:#eee}.gridsheet-1 .gs-contextmenu ul li.gs-disabled{opacity:.5;cursor:not-allowed}.gridsheet-1 .gs-contextmenu ul li.gs-menu-divider{background-color:#aaa;margin:10px 0;padding:0;height:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-name{flex:1;font-size:15px;letter-spacing:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut{font-size:10px;line-height:15px;color:#999;width:15px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:before{content:"("}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:after{content:")"}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gridsheet-1 .gs-editor{position:fixed;opacity:0;z-index:-1;background-color:#aaa}.gridsheet-1 .gs-editor textarea{width:100%;padding:0 2px;position:absolute;font-size:13px;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;caret-color:transparent;cursor:default}.gridsheet-1 .gs-editor.gs-editing{z-index:3;opacity:1}.gridsheet-1 .gs-editor.gs-editing textarea{cursor:text;min-width:100%;white-space:pre;outline:solid 2px #07f;border:none!important;height:auto}.gridsheet-1 .gs-editor.gs-editing .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;margin-top:-20px;margin-right:-2px;padding:3px 5px;font-size:10px;background-color:#07f;color:#fff;z-index:1}.gridsheet-1 .gs-tabular{overflow:auto;display:block;box-sizing:border-box}.gridsheet-1 .gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse}.gridsheet-1 .gs-table{border:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-adjuster{padding:0;visibility:hidden}.gridsheet-1 .gs-header-top{top:0;overflow:hidden}.gridsheet-1 .gs-header-left{left:0}.gridsheet-1 .gs-header-top.gs-header-left{z-index:3}.gridsheet-1 .gs-header{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gridsheet-1 .gs-header .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gridsheet-1 .gs-header .gs-resizer:hover{background-color:#07f}.gridsheet-1 .gs-header .gs-resizer.gs-protected{display:none}.gridsheet-1 .gs-header .gs-header-outer{height:100%;box-sizing:border-box}.gridsheet-1 .gs-header .gs-header-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gridsheet-1 .gs-header-left-top{border-right:solid .5px transparent;border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal{min-height:20px}.gridsheet-1 .gs-header-horizontal .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-header-outer{border-left:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal.gs-header-top-end .gs-header-outer{border-right:none}.gridsheet-1 .gs-header-vertical{overflow:hidden;min-width:30px}.gridsheet-1 .gs-header-vertical .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-header-outer{border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-vertical.gs-header-left-end .gs-header-outer{border-bottom:none}.gridsheet-1 .gs-search{width:300px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;display:flex;background-color:#fdfdfd;border:solid 2px #eee;border-radius:5px;padding:10px;position:fixed;top:10px;right:10px;z-index:5}.gridsheet-1 .gs-search .gs-searchbox{display:flex;position:relative;border:solid 2px #07f;border-radius:5px;flex:1}.gridsheet-1 .gs-search .gs-searchbox input[type=text]{padding:5px;background-color:transparent;border:none;outline:0;z-index:1;flex:1}.gridsheet-1 .gs-search .gs-searchbox .gs-search-progress{color:#999;padding:6px 3px;font-size:13px;text-align:right}.gridsheet-1 .gs-search .gs-search-close{margin:6px 5px;cursor:pointer;color:#ddd;width:50px;text-align:center} \ No newline at end of file diff --git a/src/styles/tabular.less b/src/styles/tabular.less index 24e3c11a..5a003443 100644 --- a/src/styles/tabular.less +++ b/src/styles/tabular.less @@ -51,6 +51,9 @@ &:hover { background-color: #0077ff; } + &.gs-protected { + display: none; + } } .gs-header-outer { diff --git a/src/types.ts b/src/types.ts index 27a18cda..6078edc1 100644 --- a/src/types.ts +++ b/src/types.ts @@ -50,6 +50,7 @@ export type CellType = { renderer?: string; parser?: string; custom?: Custom; + protection?: number; changedAt?: Date; }; @@ -102,8 +103,8 @@ export type StoreType = { copyingZone: ZoneType; selectingZone: ZoneType; autofillDraggingTo: PointType | null; - headerTopSelecting: boolean; - headerLeftSelecting: boolean; + verticalHeaderSelecting: boolean; + horizontalheaderSelecting: boolean; editingCell: string; editorRect: RectType; resizingRect: RectType; @@ -136,8 +137,11 @@ export type Props = { }; export type Id = string; +export type NullableId = Id | undefined; export type Ids = Id[]; +export type NullableIds = NullableId[]; export type IdMatrix = Ids[]; +export type NullableIdMatrix = NullableIds[]; export type Address = string; export type MatricesByAddress = { [origin: Address]: MatrixType }; @@ -162,12 +166,12 @@ export type HistoryMoveType = { operation: "MOVE"; applyed: boolean; reflection?: StoreReflectionType; - matrixFrom: IdMatrix; - matrixTo: IdMatrix; - matrixNew: IdMatrix; - pointFrom: PointType; - pointTo: PointType; - lostRows: MatricesByAddress; + src: AreaType; + dst: AreaType; + matrixFrom: NullableIdMatrix; + matrixTo: NullableIdMatrix; + matrixNew: NullableIdMatrix; + lostRows: MatricesByAddress; }; export type HistoryAddRowsType = { @@ -224,4 +228,6 @@ export type Virtualization = { xs: number[]; ys: number[]; adjuster: AreaType; -}; \ No newline at end of file +}; +export type OperatorType = 'USER' | 'SYSTEM'; + From 1fcb43fc7ce8076516406b8669bc1969547c9362 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 28 Jan 2024 17:04:44 +0900 Subject: [PATCH 2/8] fix a bug --- src/lib/autofill.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/lib/autofill.ts b/src/lib/autofill.ts index 5b713fbb..74dc5fa1 100644 --- a/src/lib/autofill.ts +++ b/src/lib/autofill.ts @@ -2,9 +2,9 @@ import React from "react"; import { isEqual } from 'date-fns'; -import {AreaType, CellsByAddressType, CellType, PointType, StoreType} from "../types"; +import type {AreaType, CellsByAddressType, CellType, PointType, StoreType} from "../types"; import { Table } from "../lib/table"; -import {areaShape, areaToZone, complementSelectingArea, concatAreas, createMatrix, zoneToArea} from "./structs"; +import {areaShape, areaToZone, complementSelectingArea, concatAreas, zoneToArea} from "./structs"; import {p2a} from "./converters"; import {convertFormulaAbsolute} from "../formula/evaluator"; import {TimeDelta} from "./time"; @@ -46,7 +46,7 @@ export class Autofill { for (let i = 0; i < dstShape.height; i++) { const patterns = this.getChangePatterns(matrix[i]); for (let j = 0; j < dstShape.width; j++) { - const baseCell = matrix[i % srcShape.height][j % srcShape.width]; + const baseCell = matrix[i % srcShape.height]?.[j % srcShape.width]; const x = sign > 0 ? this.dst.left + j : this.dst.right - j; const px = sign > 0 ? j % srcShape.width : (srcShape.width - 1 - (j % srcShape.width)) % srcShape.width; diff[p2a({y: this.dst.top + i, x})] = {...baseCell, value: patterns[px].next().value}; @@ -56,10 +56,11 @@ export class Autofill { for (let i = 0; i < dstShape.width; i++) { const patterns = this.getChangePatterns(matrix.map((row) => row[i])); for (let j = 0; j < dstShape.height; j++) { - const baseCell = matrix[i % srcShape.height][j % srcShape.width]; + const baseCell = matrix[j % srcShape.height]?.[i % srcShape.width]; const y = sign > 0 ? this.dst.top + j : this.dst.bottom - j; const py = sign > 0 ? j % srcShape.height : (srcShape.height - 1 - (j % srcShape.height)) % srcShape.height; - diff[p2a({y, x: this.dst.left + i})] = {...baseCell, value: patterns[py].next().value}; + const value = patterns[py].next().value; + diff[p2a({y, x: this.dst.left + i})] = {...baseCell, value}; } } } From 76a81aec2bb3d0e252d0ecf6bfadfc7a236ebd36 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 28 Jan 2024 19:02:33 +0900 Subject: [PATCH 3/8] flatten --- .../examples/basic/protection.stories.tsx | 22 +++--- src/components/ContextMenu.tsx | 14 ++-- src/components/Editor.tsx | 6 +- src/components/HorizontalHeaderCell.tsx | 4 +- src/components/Resizer.tsx | 1 + src/components/VerticalHeaderCell.tsx | 4 +- src/lib/protection.ts | 75 ++++++++++--------- src/lib/table.ts | 27 ++++--- src/store/actions.ts | 4 +- 9 files changed, 86 insertions(+), 71 deletions(-) diff --git a/.storybook/examples/basic/protection.stories.tsx b/.storybook/examples/basic/protection.stories.tsx index e9536277..46933e80 100644 --- a/.storybook/examples/basic/protection.stories.tsx +++ b/.storybook/examples/basic/protection.stories.tsx @@ -1,7 +1,7 @@ import React from "react"; import { ComponentStory } from "@storybook/react"; import { generateInitial, GridSheet } from "../../../src"; -import { AddCol, Prevention, ReadOnly } from "../../../src/lib/protection"; +import * as protection from "../../../src/lib/protection"; export default { title: "Basic", @@ -25,23 +25,27 @@ const Sheet = ({ numRows, numCols, defaultWidth }: Props) => { cells: { default: { width: defaultWidth }, 4: { - protection: Prevention.DeleteRow, + protection: protection.DeleteRow, }, 1: { - protection: Prevention.Resize, + protection: protection.Resize, + style: { backgroundColor: "#eeeeee" }, }, "A:B": { - protection: AddCol | Prevention.DeleteCol, + protection: protection.AddCol | protection.DeleteCol, + style: { backgroundColor: "#dddddd" }, }, A: { - protection: Prevention.Resize, - }, - B: { + protection: protection.Resize, style: { backgroundColor: "#eeeeee" }, }, + C: { + style: {backgroundColor: "#ffffff"} + }, B2: { - value: "b2", - protection: ReadOnly, + value: "READONLY", + protection: protection.ReadOnly, + style: { backgroundColor: "#aaaaaa" }, } }, ensured: { numRows, numCols }, diff --git a/src/components/ContextMenu.tsx b/src/components/ContextMenu.tsx index 7c806aa8..36caf099 100644 --- a/src/components/ContextMenu.tsx +++ b/src/components/ContextMenu.tsx @@ -13,7 +13,7 @@ import { import { areaToZone, zoneShape, zoneToArea } from "../lib/structs"; import { Context } from "../store"; -import { Prevention, isProtected } from "../lib/protection"; +import * as protection from "../lib/protection"; export const ContextMenu: React.FC = () => { const { store, dispatch } = React.useContext(Context); @@ -116,7 +116,7 @@ export const ContextMenu: React.FC = () => {
  • table.maxNumRows) || - isProtected(selectingTopCell?.protection, Prevention.AddRowAbove) + protection.isProtected(selectingTopCell?.protection, protection.AddRowAbove) ? "gs-disabled" : "gs-enabled" } @@ -142,7 +142,7 @@ export const ContextMenu: React.FC = () => {
  • table.maxNumRows) || - isProtected(selectingBottomCell?.protection, Prevention.AddRowBelow) + protection.isProtected(selectingBottomCell?.protection, protection.AddRowBelow) ? "gs-disabled" : "gs-enabled" } @@ -175,7 +175,7 @@ export const ContextMenu: React.FC = () => {
  • table.maxNumCols) || - isProtected(selectingLeftCell?.protection, Prevention.AddColLeft) + protection.isProtected(selectingLeftCell?.protection, protection.AddColLeft) ? "gs-disabled" : "gs-enabled" } @@ -204,7 +204,7 @@ export const ContextMenu: React.FC = () => {
  • table.maxNumCols) || - isProtected(selectingRightCell?.protection, Prevention.AddColRight) + protection.isProtected(selectingRightCell?.protection, protection.AddColRight) ? "gs-disabled" : "gs-enabled" } @@ -237,7 +237,7 @@ export const ContextMenu: React.FC = () => {
  • {
  • { @@ -311,7 +311,7 @@ export const Editor: React.FC = () => { if (e.ctrlKey || e.metaKey) { return false; } - if (isProtected(cell?.protection, Prevention.Write)) { + if (protection.isProtected(cell?.protection, protection.Write)) { console.warn("This cell is protected from writing."); return false; } @@ -339,7 +339,7 @@ export const Editor: React.FC = () => { e.currentTarget.value = ""; }} onDoubleClick={(e) => { - if (isProtected(cell?.protection, Prevention.Write)) { + if (protection.isProtected(cell?.protection, protection.Write)) { console.warn("This cell is protected from writing."); return; } diff --git a/src/components/HorizontalHeaderCell.tsx b/src/components/HorizontalHeaderCell.tsx index 2fb4c6fa..687d5c4b 100644 --- a/src/components/HorizontalHeaderCell.tsx +++ b/src/components/HorizontalHeaderCell.tsx @@ -10,7 +10,7 @@ import { setResizingPositionX, } from "../store/actions"; import { DUMMY_IMG, DEFAULT_WIDTH } from "../constants"; -import { Prevention, isProtected } from "../lib/protection"; +import * as protection from "../lib/protection"; type Props = { x: number; @@ -106,7 +106,7 @@ export const HorizontalHeaderCell: React.FC = React.memo( > {col?.labeler ? table.getLabel(col.labeler, x) : colId}
    { dispatch(setResizingPositionX([x, e.clientX, e.clientX])); diff --git a/src/components/Resizer.tsx b/src/components/Resizer.tsx index 24900392..f9f5d480 100644 --- a/src/components/Resizer.tsx +++ b/src/components/Resizer.tsx @@ -75,6 +75,7 @@ export const Resizer: React.FC = React.memo(() => { const newTable = table.update({ diff, partial: true, + operator: "USER", reflection: { selectingZone }, }); dispatch(updateTable(newTable)); diff --git a/src/components/VerticalHeaderCell.tsx b/src/components/VerticalHeaderCell.tsx index fa61de9e..23d7465e 100644 --- a/src/components/VerticalHeaderCell.tsx +++ b/src/components/VerticalHeaderCell.tsx @@ -10,7 +10,7 @@ import { setResizingPositionY, } from "../store/actions"; import { DUMMY_IMG, DEFAULT_HEIGHT } from "../constants"; -import { Prevention, isProtected } from "../lib/protection"; +import * as protection from "../lib/protection"; type Props = { y: number; @@ -106,7 +106,7 @@ export const VerticalHeaderCell: React.FC = React.memo( > {row?.labeler ? table.getLabel(row.labeler, y) : rowId}
    { dispatch(setResizingPositionY([y, e.clientY, e.clientY])); diff --git a/src/lib/protection.ts b/src/lib/protection.ts index 02948906..0b42243d 100644 --- a/src/lib/protection.ts +++ b/src/lib/protection.ts @@ -1,55 +1,58 @@ -export enum Prevention { - DeleteRow = 0b00000000000000000000000000000000000000000000000000001, - DeleteCol = 0b00000000000000000000000000000000000000000000000000010, - AddRowAbove = 0b00000000000000000000000000000000000000000000000000100, - AddRowBelow = 0b00000000000000000000000000000000000000000000000001000, - AddColLeft = 0b00000000000000000000000000000000000000000000000010000, - AddColRight = 0b00000000000000000000000000000000000000000000000100000, - MoveFrom = 0b00000000000000000000000000000000000000000000001000000, - MoveTo = 0b00000000000000000000000000000000000000000000010000000, - Write = 0b00000000000000000000000000000000000000000000100000000, - Style = 0b00000000000000000000000000000000000000000001000000000, - Resize = 0b00000000000000000000000000000000000000000010000000000, - SetRenderer = 0b00000000000000000000000000000000000000000100000000000, - SetParser = 0b00000000000000000000000000000000000000001000000000000, -}; +export type Prevention = number; + +export const + DeleteRow: Prevention = 0b00000000000000000000000000000000000000000000000000001, // 1 + DeleteCol: Prevention = 0b00000000000000000000000000000000000000000000000000010, // 2 + AddRowAbove: Prevention = 0b00000000000000000000000000000000000000000000000000100, // 4 + AddRowBelow: Prevention = 0b00000000000000000000000000000000000000000000000001000, // 8 + AddColLeft: Prevention = 0b00000000000000000000000000000000000000000000000010000, // 16 + AddColRight: Prevention = 0b00000000000000000000000000000000000000000000000100000, // 32 + MoveFrom: Prevention = 0b00000000000000000000000000000000000000000000001000000, // 64 + MoveTo: Prevention = 0b00000000000000000000000000000000000000000000010000000, // 128 + Write: Prevention = 0b00000000000000000000000000000000000000000000100000000, // 256 + Style: Prevention = 0b00000000000000000000000000000000000000000001000000000, // 512 + Resize: Prevention = 0b00000000000000000000000000000000000000000010000000000, // 1024 + SetRenderer: Prevention = 0b00000000000000000000000000000000000000000100000000000, // 2048 + SetParser: Prevention = 0b00000000000000000000000000000000000000001000000000000 // 4096 +; + -export const Move = - Prevention.MoveFrom | - Prevention.MoveTo; +export const Move: Prevention = // 192 + MoveFrom | + MoveTo; -export const Update = - Prevention.Write | - Prevention.Style | - Prevention.Resize | - Prevention.SetRenderer | - Prevention.SetParser; +export const Update: Prevention = // 1792 + Write | + Style | + Resize | + SetRenderer | + SetParser; -export const AddRow = - Prevention.AddRowAbove | - Prevention.AddRowBelow; +export const AddRow: Prevention = // 12 + AddRowAbove | + AddRowBelow; -export const AddCol = - Prevention.AddColLeft | - Prevention.AddColRight; +export const AddCol: Prevention = // 48 + AddColLeft | + AddColRight; -export const Add = +export const Add: Prevention = // 60 AddRow | AddCol; -export const Delete = - Prevention.DeleteRow | - Prevention.DeleteCol; +export const Delete: Prevention = // 3 + DeleteRow | + DeleteCol; -export const ReadOnly = +export const ReadOnly: Prevention = // Update | Delete | Add | Move ; -export const isProtected = (protection: number | undefined, flag: Prevention) => { +export const isProtected = (protection: Prevention | undefined, flag: Prevention) => { if (protection === undefined) { return false; } diff --git a/src/lib/table.ts b/src/lib/table.ts index c794f7ed..8ef912c6 100644 --- a/src/lib/table.ts +++ b/src/lib/table.ts @@ -33,7 +33,7 @@ import { solveFormula } from "../formula/solver"; import {DEFAULT_HEIGHT, DEFAULT_WIDTH, HISTORY_LIMIT, OVERSCAN_X, OVERSCAN_Y} from "../constants"; import { shouldTracking } from "../store/helpers"; -import { Prevention, Update, isProtected } from "./protection"; +import * as protection from "./protection"; type Props = { numRows?: number; @@ -833,7 +833,7 @@ export class Table implements UserTable { src, (_, id) => { const cell = this.data[id]; - if (operator === 'USER' && isProtected(cell?.protection, Prevention.MoveFrom)) { + if (operator === 'USER' && protection.isProtected(cell?.protection, protection.MoveFrom)) { return false; } return true; @@ -847,8 +847,8 @@ export class Table implements UserTable { const srcCell = this.data[srcId]; const dstCell = this.data[dstId]; if (operator === 'USER' && ( - isProtected(srcCell?.protection, Prevention.MoveFrom) || - isProtected(dstCell?.protection, Prevention.MoveTo) + protection.isProtected(srcCell?.protection, protection.MoveFrom) || + protection.isProtected(dstCell?.protection, protection.MoveTo) )) { return false; } @@ -908,6 +908,7 @@ export class Table implements UserTable { y: topFrom + (i % maxHeight), x: leftFrom + (j % maxWidth), }), + protection: 0, // Is this okay? }; const value = convertFormulaAbsolute({ value: cell?.value, @@ -950,7 +951,7 @@ export class Table implements UserTable { Object.keys(diff).forEach((address) => { const cell = { ...diff[address] }; - if (operator === 'USER' && isProtected(cell?.protection, Update)) { + if (operator === 'USER' && protection.isProtected(cell?.protection, protection.Update)) { return; } @@ -964,18 +965,24 @@ export class Table implements UserTable { ignoreFields.forEach((key) => { cell[key] = current?.[key]; }); - if (operator === 'USER' && isProtected(current?.protection, Prevention.Write)) { + if (operator === 'USER' && protection.isProtected(current?.protection, protection.Write)) { cell.value = current?.value; } - if (operator === 'USER' && isProtected(current?.protection, Prevention.Style)) { + if (operator === 'USER' && protection.isProtected(current?.protection, protection.Style)) { cell.style = current?.style; cell.justifyContent = current?.justifyContent; cell.alignItems = current?.alignItems; } - if (operator === 'USER' && isProtected(current?.protection, Prevention.Resize)) { + if (operator === 'USER' && protection.isProtected(current?.protection, protection.Resize)) { cell.width = current?.width; cell.height = current?.height; } + if (operator === 'USER' && protection.isProtected(current?.protection, protection.SetRenderer)) { + cell.renderer = current?.renderer; + } + if (operator === 'USER' && protection.isProtected(current?.protection, protection.SetParser)) { + cell.parser = current?.parser; + } if (updateChangedAt) { this.setChangedAt(cell, changedAt); } @@ -1191,7 +1198,7 @@ export class Table implements UserTable { }) { for (let i = y; i < y + numRows; i++) { const cell = this.getByPoint({ y: i, x: 0 }); - if (operator === "USER" && isProtected(cell?.protection, Prevention.DeleteRow)) { + if (operator === "USER" && protection.isProtected(cell?.protection, protection.DeleteRow)) { console.warn(`Cannot delete row ${i}.`); return this; } @@ -1307,7 +1314,7 @@ export class Table implements UserTable { }) { for (let i = x; i < x + numCols; i++) { const cell = this.getByPoint({ y: 0, x: i }); - if (operator === "USER" && isProtected(cell?.protection, Prevention.DeleteCol)) { + if (operator === "USER" && protection.isProtected(cell?.protection, protection.DeleteCol)) { console.warn(`Cannot delete col ${i}.`); return this; } diff --git a/src/store/actions.ts b/src/store/actions.ts index a3a70c4a..0520cbb8 100644 --- a/src/store/actions.ts +++ b/src/store/actions.ts @@ -22,7 +22,7 @@ import { tsv2matrix, p2a } from "../lib/converters"; import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from "../constants"; import { initSearchStatement, restrictPoints } from "./helpers"; import { smartScroll } from "../lib/virtualization"; -import { Prevention, isProtected } from "../lib/protection"; +import * as protection from "../lib/protection"; const actions: { [s: string]: CoreAction } = {}; @@ -526,7 +526,7 @@ class ClearAction extends CoreAction { for (let x = left; x <= right; x++) { const cell = table.getByPoint({ y, x }); const address = p2a({ y, x }); - if (isProtected(cell?.protection, Prevention.Write)) { + if (protection.isProtected(cell?.protection, protection.Write)) { continue; } if (cell?.value != null) { From 77873420b3b93f959754445d05e5f75b029046f6 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 28 Jan 2024 19:02:44 +0900 Subject: [PATCH 4/8] fix selecting cell border lack --- src/styles/cell.less | 2 +- src/styles/minified.ts | 4 ++-- src/styles/root.min.css | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/styles/cell.less b/src/styles/cell.less index deeb9bfe..1608d67d 100644 --- a/src/styles/cell.less +++ b/src/styles/cell.less @@ -1,5 +1,5 @@ .gs-cell { - background-clip: padding-box; + background-clip: content-box; border-top: solid 1px rgba(128, 128, 128, 0.3); border-left: solid 1px rgba(128, 128, 128, 0.3); padding: 0; diff --git a/src/styles/minified.ts b/src/styles/minified.ts index 97b6934b..d5ce0d0e 100644 --- a/src/styles/minified.ts +++ b/src/styles/minified.ts @@ -1,3 +1,3 @@ // yarn generate-style -export const LAST_MODIFIED = 1706379419; -export const CSS = `.gridsheet-1{overflow:hidden;position:relative;box-sizing:content-box;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif}.gridsheet-1.light{background-color:#f7f7f7;color:#000}.gridsheet-1.light .gs-editor.gs-editing textarea{background-color:#f5f5f5;color:#111;caret-color:#000}.gridsheet-1.light .gs-header{background-color:#eee;color:#666}.gridsheet-1.light .gs-header.gs-selecting{background-color:#ddd}.gridsheet-1.light .gs-header.gs-choosing{background-color:#bbb}.gridsheet-1.light .gs-header.gs-header-selecting{background-color:#555;color:#fff}.gridsheet-1.dark{background-color:#323232;color:#eee}.gridsheet-1.dark .gs-editor.gs-editing textarea{background-color:#353535;color:#ddd;caret-color:#ddd}.gridsheet-1.dark .gs-header{background-color:#474747;color:#eee}.gridsheet-1.dark .gs-header.gs-selecting{background-color:#777}.gridsheet-1.dark .gs-header.gs-choosing{background-color:#999}.gridsheet-1.dark .gs-header.gs-header-selecting{background-color:#bbb;color:#444}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer.gs-selected{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:rgba(0,127,255,.08);top:0;left:0;z-index:2}.gridsheet-1 .gs-line{position:relative;top:0;left:0;border:dotted 1px #07f;box-sizing:border-box}.gridsheet-1 .gs-line span{font-size:10px;padding:3px;background-color:#07f;color:#fff;margin:0;position:absolute;top:0;left:0}.gridsheet-1.gs-table-width-larger{border-right:solid 1px rgba(128,128,128,.5)}.gridsheet-1.gs-table-height-larger{border-bottom:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-cell{background-clip:padding-box;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);padding:0;margin:0;box-sizing:border-box;position:relative}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell.gs-selected .gs-cell-rendered-wrapper-inner{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-cell.gs-selected .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-pointed{margin-top:-1px;margin-left:-1px;z-index:1}.gridsheet-1 .gs-cell.gs-pointed.gs-editing{color:transparent}.gridsheet-1 .gs-cell.gs-pointed .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-matching{background-color:rgba(0,200,100,.2)}.gridsheet-1 .gs-cell.gs-searching{border:solid 2px #00aa78}.gridsheet-1 .gs-cell .formula-error-triangle{position:absolute;top:0;right:0;border-top:3px solid rgba(200,0,0,.9);border-right:3px solid rgba(200,0,0,.9);border-bottom:3px solid transparent;border-left:3px solid transparent;z-index:1}.gridsheet-1 .gs-cell .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;font-size:8px;font-weight:400;font-style:normal;background-color:rgba(0,128,255,.2);color:rgba(255,255,255,.6);padding:0 2px;display:none;opacity:.7}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer{width:100%;height:100%}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-inner{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box}.gridsheet-1 .gs-cell .gs-cell-rendered{overflow:hidden;font-size:13px;letter-spacing:1px;white-space:pre-wrap;line-height:24px;cursor:auto;word-wrap:break-word;word-break:break-all;padding:0 2px}.gridsheet-1 .gs-cell .gs-cell-rendered>*{position:relative}.gridsheet-1 .gs-cell .gs-cell-rendered>.backface{z-index:0}.gridsheet-1 .gs-cell .gs-autofill-drag{background-color:#07f;position:absolute;width:7px;height:7px;bottom:0;right:0;margin-right:-3.5px;margin-bottom:-3.5px;cursor:crosshair;z-index:1}.gridsheet-1 .gs-contextmenu-modal{position:fixed;top:0;left:0;width:100%;height:100vh;z-index:3}.gridsheet-1 .gs-contextmenu{z-index:3;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px}.gridsheet-1 .gs-contextmenu ul{min-width:250px;color:#555;margin:0;padding:0}.gridsheet-1 .gs-contextmenu ul li{padding:5px 10px;list-style-type:none;display:flex}.gridsheet-1 .gs-contextmenu ul li.gs-enabled{cursor:pointer}.gridsheet-1 .gs-contextmenu ul li.gs-enabled:hover{background-color:#eee}.gridsheet-1 .gs-contextmenu ul li.gs-disabled{opacity:.5;cursor:not-allowed}.gridsheet-1 .gs-contextmenu ul li.gs-menu-divider{background-color:#aaa;margin:10px 0;padding:0;height:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-name{flex:1;font-size:15px;letter-spacing:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut{font-size:10px;line-height:15px;color:#999;width:15px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:before{content:"("}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:after{content:")"}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gridsheet-1 .gs-editor{position:fixed;opacity:0;z-index:-1;background-color:#aaa}.gridsheet-1 .gs-editor textarea{width:100%;padding:0 2px;position:absolute;font-size:13px;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;caret-color:transparent;cursor:default}.gridsheet-1 .gs-editor.gs-editing{z-index:3;opacity:1}.gridsheet-1 .gs-editor.gs-editing textarea{cursor:text;min-width:100%;white-space:pre;outline:solid 2px #07f;border:none!important;height:auto}.gridsheet-1 .gs-editor.gs-editing .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;margin-top:-20px;margin-right:-2px;padding:3px 5px;font-size:10px;background-color:#07f;color:#fff;z-index:1}.gridsheet-1 .gs-tabular{overflow:auto;display:block;box-sizing:border-box}.gridsheet-1 .gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse}.gridsheet-1 .gs-table{border:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-adjuster{padding:0;visibility:hidden}.gridsheet-1 .gs-header-top{top:0;overflow:hidden}.gridsheet-1 .gs-header-left{left:0}.gridsheet-1 .gs-header-top.gs-header-left{z-index:3}.gridsheet-1 .gs-header{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gridsheet-1 .gs-header .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gridsheet-1 .gs-header .gs-resizer:hover{background-color:#07f}.gridsheet-1 .gs-header .gs-resizer.gs-protected{display:none}.gridsheet-1 .gs-header .gs-header-outer{height:100%;box-sizing:border-box}.gridsheet-1 .gs-header .gs-header-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gridsheet-1 .gs-header-left-top{border-right:solid .5px transparent;border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal{min-height:20px}.gridsheet-1 .gs-header-horizontal .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-header-outer{border-left:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal.gs-header-top-end .gs-header-outer{border-right:none}.gridsheet-1 .gs-header-vertical{overflow:hidden;min-width:30px}.gridsheet-1 .gs-header-vertical .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-header-outer{border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-vertical.gs-header-left-end .gs-header-outer{border-bottom:none}.gridsheet-1 .gs-search{width:300px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;display:flex;background-color:#fdfdfd;border:solid 2px #eee;border-radius:5px;padding:10px;position:fixed;top:10px;right:10px;z-index:5}.gridsheet-1 .gs-search .gs-searchbox{display:flex;position:relative;border:solid 2px #07f;border-radius:5px;flex:1}.gridsheet-1 .gs-search .gs-searchbox input[type=text]{padding:5px;background-color:transparent;border:none;outline:0;z-index:1;flex:1}.gridsheet-1 .gs-search .gs-searchbox .gs-search-progress{color:#999;padding:6px 3px;font-size:13px;text-align:right}.gridsheet-1 .gs-search .gs-search-close{margin:6px 5px;cursor:pointer;color:#ddd;width:50px;text-align:center}`; +export const LAST_MODIFIED = 1706436064; +export const CSS = `.gridsheet-1{overflow:hidden;position:relative;box-sizing:content-box;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif}.gridsheet-1.light{background-color:#f7f7f7;color:#000}.gridsheet-1.light .gs-editor.gs-editing textarea{background-color:#f5f5f5;color:#111;caret-color:#000}.gridsheet-1.light .gs-header{background-color:#eee;color:#666}.gridsheet-1.light .gs-header.gs-selecting{background-color:#ddd}.gridsheet-1.light .gs-header.gs-choosing{background-color:#bbb}.gridsheet-1.light .gs-header.gs-header-selecting{background-color:#555;color:#fff}.gridsheet-1.dark{background-color:#323232;color:#eee}.gridsheet-1.dark .gs-editor.gs-editing textarea{background-color:#353535;color:#ddd;caret-color:#ddd}.gridsheet-1.dark .gs-header{background-color:#474747;color:#eee}.gridsheet-1.dark .gs-header.gs-selecting{background-color:#777}.gridsheet-1.dark .gs-header.gs-choosing{background-color:#999}.gridsheet-1.dark .gs-header.gs-header-selecting{background-color:#bbb;color:#444}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer.gs-selected{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:rgba(0,127,255,.08);top:0;left:0;z-index:2}.gridsheet-1 .gs-line{position:relative;top:0;left:0;border:dotted 1px #07f;box-sizing:border-box}.gridsheet-1 .gs-line span{font-size:10px;padding:3px;background-color:#07f;color:#fff;margin:0;position:absolute;top:0;left:0}.gridsheet-1.gs-table-width-larger{border-right:solid 1px rgba(128,128,128,.5)}.gridsheet-1.gs-table-height-larger{border-bottom:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-cell{background-clip:content-box;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);padding:0;margin:0;box-sizing:border-box;position:relative}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell.gs-selected .gs-cell-rendered-wrapper-inner{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-cell.gs-selected .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-pointed{margin-top:-1px;margin-left:-1px;z-index:1}.gridsheet-1 .gs-cell.gs-pointed.gs-editing{color:transparent}.gridsheet-1 .gs-cell.gs-pointed .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-matching{background-color:rgba(0,200,100,.2)}.gridsheet-1 .gs-cell.gs-searching{border:solid 2px #00aa78}.gridsheet-1 .gs-cell .formula-error-triangle{position:absolute;top:0;right:0;border-top:3px solid rgba(200,0,0,.9);border-right:3px solid rgba(200,0,0,.9);border-bottom:3px solid transparent;border-left:3px solid transparent;z-index:1}.gridsheet-1 .gs-cell .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;font-size:8px;font-weight:400;font-style:normal;background-color:rgba(0,128,255,.2);color:rgba(255,255,255,.6);padding:0 2px;display:none;opacity:.7}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer{width:100%;height:100%}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-inner{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box}.gridsheet-1 .gs-cell .gs-cell-rendered{overflow:hidden;font-size:13px;letter-spacing:1px;white-space:pre-wrap;line-height:24px;cursor:auto;word-wrap:break-word;word-break:break-all;padding:0 2px}.gridsheet-1 .gs-cell .gs-cell-rendered>*{position:relative}.gridsheet-1 .gs-cell .gs-cell-rendered>.backface{z-index:0}.gridsheet-1 .gs-cell .gs-autofill-drag{background-color:#07f;position:absolute;width:7px;height:7px;bottom:0;right:0;margin-right:-3.5px;margin-bottom:-3.5px;cursor:crosshair;z-index:1}.gridsheet-1 .gs-contextmenu-modal{position:fixed;top:0;left:0;width:100%;height:100vh;z-index:3}.gridsheet-1 .gs-contextmenu{z-index:3;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px}.gridsheet-1 .gs-contextmenu ul{min-width:250px;color:#555;margin:0;padding:0}.gridsheet-1 .gs-contextmenu ul li{padding:5px 10px;list-style-type:none;display:flex}.gridsheet-1 .gs-contextmenu ul li.gs-enabled{cursor:pointer}.gridsheet-1 .gs-contextmenu ul li.gs-enabled:hover{background-color:#eee}.gridsheet-1 .gs-contextmenu ul li.gs-disabled{opacity:.5;cursor:not-allowed}.gridsheet-1 .gs-contextmenu ul li.gs-menu-divider{background-color:#aaa;margin:10px 0;padding:0;height:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-name{flex:1;font-size:15px;letter-spacing:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut{font-size:10px;line-height:15px;color:#999;width:15px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:before{content:"("}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:after{content:")"}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gridsheet-1 .gs-editor{position:fixed;opacity:0;z-index:-1;background-color:#aaa}.gridsheet-1 .gs-editor textarea{width:100%;padding:0 2px;position:absolute;font-size:13px;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;caret-color:transparent;cursor:default}.gridsheet-1 .gs-editor.gs-editing{z-index:3;opacity:1}.gridsheet-1 .gs-editor.gs-editing textarea{cursor:text;min-width:100%;white-space:pre;outline:solid 2px #07f;border:none!important;height:auto}.gridsheet-1 .gs-editor.gs-editing .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;margin-top:-20px;margin-right:-2px;padding:3px 5px;font-size:10px;background-color:#07f;color:#fff;z-index:1}.gridsheet-1 .gs-tabular{overflow:auto;display:block;box-sizing:border-box}.gridsheet-1 .gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse}.gridsheet-1 .gs-table{border:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-adjuster{padding:0;visibility:hidden}.gridsheet-1 .gs-header-top{top:0;overflow:hidden}.gridsheet-1 .gs-header-left{left:0}.gridsheet-1 .gs-header-top.gs-header-left{z-index:3}.gridsheet-1 .gs-header{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gridsheet-1 .gs-header .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gridsheet-1 .gs-header .gs-resizer:hover{background-color:#07f}.gridsheet-1 .gs-header .gs-resizer.gs-protected{display:none}.gridsheet-1 .gs-header .gs-header-outer{height:100%;box-sizing:border-box}.gridsheet-1 .gs-header .gs-header-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gridsheet-1 .gs-header-left-top{border-right:solid .5px transparent;border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal{min-height:20px}.gridsheet-1 .gs-header-horizontal .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-header-outer{border-left:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal.gs-header-top-end .gs-header-outer{border-right:none}.gridsheet-1 .gs-header-vertical{overflow:hidden;min-width:30px}.gridsheet-1 .gs-header-vertical .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-header-outer{border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-vertical.gs-header-left-end .gs-header-outer{border-bottom:none}.gridsheet-1 .gs-search{width:300px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;display:flex;background-color:#fdfdfd;border:solid 2px #eee;border-radius:5px;padding:10px;position:fixed;top:10px;right:10px;z-index:5}.gridsheet-1 .gs-search .gs-searchbox{display:flex;position:relative;border:solid 2px #07f;border-radius:5px;flex:1}.gridsheet-1 .gs-search .gs-searchbox input[type=text]{padding:5px;background-color:transparent;border:none;outline:0;z-index:1;flex:1}.gridsheet-1 .gs-search .gs-searchbox .gs-search-progress{color:#999;padding:6px 3px;font-size:13px;text-align:right}.gridsheet-1 .gs-search .gs-search-close{margin:6px 5px;cursor:pointer;color:#ddd;width:50px;text-align:center}`; diff --git a/src/styles/root.min.css b/src/styles/root.min.css index 1b3c18c7..1606c7f6 100644 --- a/src/styles/root.min.css +++ b/src/styles/root.min.css @@ -1 +1 @@ -.gridsheet-1{overflow:hidden;position:relative;box-sizing:content-box;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif}.gridsheet-1.light{background-color:#f7f7f7;color:#000}.gridsheet-1.light .gs-editor.gs-editing textarea{background-color:#f5f5f5;color:#111;caret-color:#000}.gridsheet-1.light .gs-header{background-color:#eee;color:#666}.gridsheet-1.light .gs-header.gs-selecting{background-color:#ddd}.gridsheet-1.light .gs-header.gs-choosing{background-color:#bbb}.gridsheet-1.light .gs-header.gs-header-selecting{background-color:#555;color:#fff}.gridsheet-1.dark{background-color:#323232;color:#eee}.gridsheet-1.dark .gs-editor.gs-editing textarea{background-color:#353535;color:#ddd;caret-color:#ddd}.gridsheet-1.dark .gs-header{background-color:#474747;color:#eee}.gridsheet-1.dark .gs-header.gs-selecting{background-color:#777}.gridsheet-1.dark .gs-header.gs-choosing{background-color:#999}.gridsheet-1.dark .gs-header.gs-header-selecting{background-color:#bbb;color:#444}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer.gs-selected{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:rgba(0,127,255,.08);top:0;left:0;z-index:2}.gridsheet-1 .gs-line{position:relative;top:0;left:0;border:dotted 1px #07f;box-sizing:border-box}.gridsheet-1 .gs-line span{font-size:10px;padding:3px;background-color:#07f;color:#fff;margin:0;position:absolute;top:0;left:0}.gridsheet-1.gs-table-width-larger{border-right:solid 1px rgba(128,128,128,.5)}.gridsheet-1.gs-table-height-larger{border-bottom:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-cell{background-clip:padding-box;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);padding:0;margin:0;box-sizing:border-box;position:relative}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell.gs-selected .gs-cell-rendered-wrapper-inner{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-cell.gs-selected .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-pointed{margin-top:-1px;margin-left:-1px;z-index:1}.gridsheet-1 .gs-cell.gs-pointed.gs-editing{color:transparent}.gridsheet-1 .gs-cell.gs-pointed .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-matching{background-color:rgba(0,200,100,.2)}.gridsheet-1 .gs-cell.gs-searching{border:solid 2px #00aa78}.gridsheet-1 .gs-cell .formula-error-triangle{position:absolute;top:0;right:0;border-top:3px solid rgba(200,0,0,.9);border-right:3px solid rgba(200,0,0,.9);border-bottom:3px solid transparent;border-left:3px solid transparent;z-index:1}.gridsheet-1 .gs-cell .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;font-size:8px;font-weight:400;font-style:normal;background-color:rgba(0,128,255,.2);color:rgba(255,255,255,.6);padding:0 2px;display:none;opacity:.7}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer{width:100%;height:100%}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-inner{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box}.gridsheet-1 .gs-cell .gs-cell-rendered{overflow:hidden;font-size:13px;letter-spacing:1px;white-space:pre-wrap;line-height:24px;cursor:auto;word-wrap:break-word;word-break:break-all;padding:0 2px}.gridsheet-1 .gs-cell .gs-cell-rendered>*{position:relative}.gridsheet-1 .gs-cell .gs-cell-rendered>.backface{z-index:0}.gridsheet-1 .gs-cell .gs-autofill-drag{background-color:#07f;position:absolute;width:7px;height:7px;bottom:0;right:0;margin-right:-3.5px;margin-bottom:-3.5px;cursor:crosshair;z-index:1}.gridsheet-1 .gs-contextmenu-modal{position:fixed;top:0;left:0;width:100%;height:100vh;z-index:3}.gridsheet-1 .gs-contextmenu{z-index:3;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px}.gridsheet-1 .gs-contextmenu ul{min-width:250px;color:#555;margin:0;padding:0}.gridsheet-1 .gs-contextmenu ul li{padding:5px 10px;list-style-type:none;display:flex}.gridsheet-1 .gs-contextmenu ul li.gs-enabled{cursor:pointer}.gridsheet-1 .gs-contextmenu ul li.gs-enabled:hover{background-color:#eee}.gridsheet-1 .gs-contextmenu ul li.gs-disabled{opacity:.5;cursor:not-allowed}.gridsheet-1 .gs-contextmenu ul li.gs-menu-divider{background-color:#aaa;margin:10px 0;padding:0;height:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-name{flex:1;font-size:15px;letter-spacing:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut{font-size:10px;line-height:15px;color:#999;width:15px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:before{content:"("}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:after{content:")"}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gridsheet-1 .gs-editor{position:fixed;opacity:0;z-index:-1;background-color:#aaa}.gridsheet-1 .gs-editor textarea{width:100%;padding:0 2px;position:absolute;font-size:13px;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;caret-color:transparent;cursor:default}.gridsheet-1 .gs-editor.gs-editing{z-index:3;opacity:1}.gridsheet-1 .gs-editor.gs-editing textarea{cursor:text;min-width:100%;white-space:pre;outline:solid 2px #07f;border:none!important;height:auto}.gridsheet-1 .gs-editor.gs-editing .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;margin-top:-20px;margin-right:-2px;padding:3px 5px;font-size:10px;background-color:#07f;color:#fff;z-index:1}.gridsheet-1 .gs-tabular{overflow:auto;display:block;box-sizing:border-box}.gridsheet-1 .gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse}.gridsheet-1 .gs-table{border:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-adjuster{padding:0;visibility:hidden}.gridsheet-1 .gs-header-top{top:0;overflow:hidden}.gridsheet-1 .gs-header-left{left:0}.gridsheet-1 .gs-header-top.gs-header-left{z-index:3}.gridsheet-1 .gs-header{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gridsheet-1 .gs-header .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gridsheet-1 .gs-header .gs-resizer:hover{background-color:#07f}.gridsheet-1 .gs-header .gs-resizer.gs-protected{display:none}.gridsheet-1 .gs-header .gs-header-outer{height:100%;box-sizing:border-box}.gridsheet-1 .gs-header .gs-header-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gridsheet-1 .gs-header-left-top{border-right:solid .5px transparent;border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal{min-height:20px}.gridsheet-1 .gs-header-horizontal .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-header-outer{border-left:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal.gs-header-top-end .gs-header-outer{border-right:none}.gridsheet-1 .gs-header-vertical{overflow:hidden;min-width:30px}.gridsheet-1 .gs-header-vertical .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-header-outer{border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-vertical.gs-header-left-end .gs-header-outer{border-bottom:none}.gridsheet-1 .gs-search{width:300px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;display:flex;background-color:#fdfdfd;border:solid 2px #eee;border-radius:5px;padding:10px;position:fixed;top:10px;right:10px;z-index:5}.gridsheet-1 .gs-search .gs-searchbox{display:flex;position:relative;border:solid 2px #07f;border-radius:5px;flex:1}.gridsheet-1 .gs-search .gs-searchbox input[type=text]{padding:5px;background-color:transparent;border:none;outline:0;z-index:1;flex:1}.gridsheet-1 .gs-search .gs-searchbox .gs-search-progress{color:#999;padding:6px 3px;font-size:13px;text-align:right}.gridsheet-1 .gs-search .gs-search-close{margin:6px 5px;cursor:pointer;color:#ddd;width:50px;text-align:center} \ No newline at end of file +.gridsheet-1{overflow:hidden;position:relative;box-sizing:content-box;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;font-family:"SF Pro Text","SF Pro Icons","Helvetica Neue",Helvetica,Arial,Meiryo,sans-serif}.gridsheet-1.light{background-color:#f7f7f7;color:#000}.gridsheet-1.light .gs-editor.gs-editing textarea{background-color:#f5f5f5;color:#111;caret-color:#000}.gridsheet-1.light .gs-header{background-color:#eee;color:#666}.gridsheet-1.light .gs-header.gs-selecting{background-color:#ddd}.gridsheet-1.light .gs-header.gs-choosing{background-color:#bbb}.gridsheet-1.light .gs-header.gs-header-selecting{background-color:#555;color:#fff}.gridsheet-1.dark{background-color:#323232;color:#eee}.gridsheet-1.dark .gs-editor.gs-editing textarea{background-color:#353535;color:#ddd;caret-color:#ddd}.gridsheet-1.dark .gs-header{background-color:#474747;color:#eee}.gridsheet-1.dark .gs-header.gs-selecting{background-color:#777}.gridsheet-1.dark .gs-header.gs-choosing{background-color:#999}.gridsheet-1.dark .gs-header.gs-header-selecting{background-color:#bbb;color:#444}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer.gs-selected{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-resizing{width:100%;height:100%;position:absolute;background-color:rgba(0,127,255,.08);top:0;left:0;z-index:2}.gridsheet-1 .gs-line{position:relative;top:0;left:0;border:dotted 1px #07f;box-sizing:border-box}.gridsheet-1 .gs-line span{font-size:10px;padding:3px;background-color:#07f;color:#fff;margin:0;position:absolute;top:0;left:0}.gridsheet-1.gs-table-width-larger{border-right:solid 1px rgba(128,128,128,.5)}.gridsheet-1.gs-table-height-larger{border-bottom:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-cell{background-clip:content-box;border-top:solid 1px rgba(128,128,128,.3);border-left:solid 1px rgba(128,128,128,.3);padding:0;margin:0;box-sizing:border-box;position:relative}.gridsheet-1 .gs-cell.gs-copying textarea:focus{outline:solid 1px #07f}.gridsheet-1 .gs-cell.gs-selected .gs-cell-rendered-wrapper-inner{background-color:rgba(0,128,255,.2)}.gridsheet-1 .gs-cell.gs-selected .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-pointed{margin-top:-1px;margin-left:-1px;z-index:1}.gridsheet-1 .gs-cell.gs-pointed.gs-editing{color:transparent}.gridsheet-1 .gs-cell.gs-pointed .gs-cell-label{display:block}.gridsheet-1 .gs-cell.gs-matching{background-color:rgba(0,200,100,.2)}.gridsheet-1 .gs-cell.gs-searching{border:solid 2px #00aa78}.gridsheet-1 .gs-cell .formula-error-triangle{position:absolute;top:0;right:0;border-top:3px solid rgba(200,0,0,.9);border-right:3px solid rgba(200,0,0,.9);border-bottom:3px solid transparent;border-left:3px solid transparent;z-index:1}.gridsheet-1 .gs-cell .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;font-size:8px;font-weight:400;font-style:normal;background-color:rgba(0,128,255,.2);color:rgba(255,255,255,.6);padding:0 2px;display:none;opacity:.7}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-outer{width:100%;height:100%}.gridsheet-1 .gs-cell .gs-cell-rendered-wrapper-inner{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden;display:flex;box-sizing:border-box}.gridsheet-1 .gs-cell .gs-cell-rendered{overflow:hidden;font-size:13px;letter-spacing:1px;white-space:pre-wrap;line-height:24px;cursor:auto;word-wrap:break-word;word-break:break-all;padding:0 2px}.gridsheet-1 .gs-cell .gs-cell-rendered>*{position:relative}.gridsheet-1 .gs-cell .gs-cell-rendered>.backface{z-index:0}.gridsheet-1 .gs-cell .gs-autofill-drag{background-color:#07f;position:absolute;width:7px;height:7px;bottom:0;right:0;margin-right:-3.5px;margin-bottom:-3.5px;cursor:crosshair;z-index:1}.gridsheet-1 .gs-contextmenu-modal{position:fixed;top:0;left:0;width:100%;height:100vh;z-index:3}.gridsheet-1 .gs-contextmenu{z-index:3;position:fixed;background-color:#fff;padding:5px 0;border-radius:5px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px}.gridsheet-1 .gs-contextmenu ul{min-width:250px;color:#555;margin:0;padding:0}.gridsheet-1 .gs-contextmenu ul li{padding:5px 10px;list-style-type:none;display:flex}.gridsheet-1 .gs-contextmenu ul li.gs-enabled{cursor:pointer}.gridsheet-1 .gs-contextmenu ul li.gs-enabled:hover{background-color:#eee}.gridsheet-1 .gs-contextmenu ul li.gs-disabled{opacity:.5;cursor:not-allowed}.gridsheet-1 .gs-contextmenu ul li.gs-menu-divider{background-color:#aaa;margin:10px 0;padding:0;height:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-name{flex:1;font-size:15px;letter-spacing:1px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut{font-size:10px;line-height:15px;color:#999;width:15px}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:before{content:"("}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut:after{content:")"}.gridsheet-1 .gs-contextmenu ul li .gs-menu-shortcut .gs-menu-underline{text-decoration:underline}.gridsheet-1 .gs-editor{position:fixed;opacity:0;z-index:-1;background-color:#aaa}.gridsheet-1 .gs-editor textarea{width:100%;padding:0 2px;position:absolute;font-size:13px;line-height:24px;letter-spacing:1px;top:0;left:0;border:none;outline:0;background-color:transparent;resize:none;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;overflow:hidden;caret-color:transparent;cursor:default}.gridsheet-1 .gs-editor.gs-editing{z-index:3;opacity:1}.gridsheet-1 .gs-editor.gs-editing textarea{cursor:text;min-width:100%;white-space:pre;outline:solid 2px #07f;border:none!important;height:auto}.gridsheet-1 .gs-editor.gs-editing .gs-cell-label{font-family:monospace,serif;position:absolute;top:0;right:0;margin-top:-20px;margin-right:-2px;padding:3px 5px;font-size:10px;background-color:#07f;color:#fff;z-index:1}.gridsheet-1 .gs-tabular{overflow:auto;display:block;box-sizing:border-box}.gridsheet-1 .gs-tabular-inner>table{table-layout:fixed;border-collapse:collapse}.gridsheet-1 .gs-table{border:solid 1px rgba(128,128,128,.5)}.gridsheet-1 .gs-adjuster{padding:0;visibility:hidden}.gridsheet-1 .gs-header-top{top:0;overflow:hidden}.gridsheet-1 .gs-header-left{left:0}.gridsheet-1 .gs-header-top.gs-header-left{z-index:3}.gridsheet-1 .gs-header{z-index:2;padding:0;position:sticky;font-size:13px;font-weight:400;box-sizing:border-box;vertical-align:top}.gridsheet-1 .gs-header .gs-resizer{position:absolute;border-color:transparent;box-sizing:border-box;z-index:2}.gridsheet-1 .gs-header .gs-resizer:hover{background-color:#07f}.gridsheet-1 .gs-header .gs-resizer.gs-protected{display:none}.gridsheet-1 .gs-header .gs-header-outer{height:100%;box-sizing:border-box}.gridsheet-1 .gs-header .gs-header-inner{height:100%;box-sizing:border-box;vertical-align:middle;overflow:hidden;display:flex;align-items:center;justify-content:center}.gridsheet-1 .gs-header-left-top{border-right:solid .5px transparent;border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal{min-height:20px}.gridsheet-1 .gs-header-horizontal .gs-resizer{top:0;right:0;width:3px;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-resizer.gs-dragging{border-right-style:dotted;height:1000000px!important;cursor:e-resize}.gridsheet-1 .gs-header-horizontal .gs-header-outer{border-left:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-horizontal.gs-header-top-end .gs-header-outer{border-right:none}.gridsheet-1 .gs-header-vertical{overflow:hidden;min-width:30px}.gridsheet-1 .gs-header-vertical .gs-resizer{left:0;bottom:0;height:3px;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-resizer.gs-dragging{border-bottom-style:dotted;width:1000000px!important;cursor:n-resize}.gridsheet-1 .gs-header-vertical .gs-header-outer{border-bottom:solid .5px rgba(128,128,128,.3)}.gridsheet-1 .gs-header-vertical.gs-header-left-end .gs-header-outer{border-bottom:none}.gridsheet-1 .gs-search{width:300px;box-shadow:rgba(60,64,67,.3) 0 1px 2px 0,rgba(60,64,67,.15) 0 1px 3px 1px;display:flex;background-color:#fdfdfd;border:solid 2px #eee;border-radius:5px;padding:10px;position:fixed;top:10px;right:10px;z-index:5}.gridsheet-1 .gs-search .gs-searchbox{display:flex;position:relative;border:solid 2px #07f;border-radius:5px;flex:1}.gridsheet-1 .gs-search .gs-searchbox input[type=text]{padding:5px;background-color:transparent;border:none;outline:0;z-index:1;flex:1}.gridsheet-1 .gs-search .gs-searchbox .gs-search-progress{color:#999;padding:6px 3px;font-size:13px;text-align:right}.gridsheet-1 .gs-search .gs-search-close{margin:6px 5px;cursor:pointer;color:#ddd;width:50px;text-align:center} \ No newline at end of file From d8ab1934995e8fe042bf74a436f93527985cccf8 Mon Sep 17 00:00:00 2001 From: righ Date: Sun, 28 Jan 2024 19:35:01 +0900 Subject: [PATCH 5/8] rename remove to delete --- src/components/ContextMenu.tsx | 8 ++++---- src/lib/table.ts | 24 ++++++++++++------------ src/store/helpers.ts | 4 ++-- src/types.ts | 12 ++++++------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/components/ContextMenu.tsx b/src/components/ContextMenu.tsx index 36caf099..01306ba2 100644 --- a/src/components/ContextMenu.tsx +++ b/src/components/ContextMenu.tsx @@ -245,7 +245,7 @@ export const ContextMenu: React.FC = () => { if (e.currentTarget.classList.contains("gs-disabled")) { return; } - const newTable = table.removeRows({ + const newTable = table.deleteRows({ y: selectingTop, numRows: height, reflection: { @@ -257,7 +257,7 @@ export const ContextMenu: React.FC = () => { }} >
    - Remove {height} row{height > 0 && "s"} + Delete {height} row{height > 0 && "s"}
  • )} @@ -271,7 +271,7 @@ export const ContextMenu: React.FC = () => { : "gs-enabled" } onClick={(e) => { - const newTable = table.removeCols({ + const newTable = table.deleteCols({ x: selectingLeft, numCols: width, reflection: { @@ -283,7 +283,7 @@ export const ContextMenu: React.FC = () => { }} >
    - Remove {width} column{width > 0 && "s"} + Delete {width} column{width > 0 && "s"}
    )} diff --git a/src/lib/table.ts b/src/lib/table.ts index 8ef912c6..b1a89f86 100644 --- a/src/lib/table.ts +++ b/src/lib/table.ts @@ -148,7 +148,7 @@ export interface UserTable { baseY: number; reflection?: StoreReflectionType; }): UserTable; - removeRows(args: { + deleteRows(args: { y: number; numRows: number; reflection?: StoreReflectionType; @@ -168,7 +168,7 @@ export interface UserTable { baseX: number; reflection?: StoreReflectionType; }): UserTable; - removeCols(args: { + deleteCols(args: { x: number; numCols: number; reflection?: StoreReflectionType; @@ -714,8 +714,8 @@ export class Table implements UserTable { private cleanObsolete(history: HistoryType) { if ( - history.operation === "REMOVE_ROWS" || - history.operation === "REMOVE_COLS" + history.operation === "DELETE_ROWS" || + history.operation === "DELETE_COLS" ) { history.idMatrix.forEach((ids) => { ids.forEach((id) => { @@ -1185,7 +1185,7 @@ export class Table implements UserTable { }); return this.shallowCopy({ copyCache: false }); } - public removeRows({ + public deleteRows({ y, numRows, operator = "SYSTEM", @@ -1215,7 +1215,7 @@ export class Table implements UserTable { this.area.bottom -= numRows; this.pushHistory({ applyed: true, - operation: "REMOVE_ROWS", + operation: "DELETE_ROWS", reflection, y, numRows, @@ -1301,7 +1301,7 @@ export class Table implements UserTable { }); return this.shallowCopy({ copyCache: false }); } - public removeCols({ + public deleteCols({ x, numCols, operator = "SYSTEM", @@ -1336,7 +1336,7 @@ export class Table implements UserTable { this.pushHistory({ applyed: true, - operation: "REMOVE_COLS", + operation: "DELETE_COLS", reflection, x, numCols, @@ -1462,13 +1462,13 @@ export class Table implements UserTable { this.area.right -= width; break; } - case "REMOVE_ROWS": { + case "DELETE_ROWS": { const { height } = matrixShape({ matrix: history.idMatrix }); this.idMatrix.splice(history.y, 0, ...history.idMatrix); this.area.bottom += height; break; } - case "REMOVE_COLS": { + case "DELETE_COLS": { const { width } = matrixShape({ matrix: history.idMatrix }); this.idMatrix.forEach((row, i) => { row.splice(history.x, 0, ...history.idMatrix[i]); @@ -1538,13 +1538,13 @@ export class Table implements UserTable { this.area.right += width; break; } - case "REMOVE_ROWS": { + case "DELETE_ROWS": { const { height } = matrixShape({ matrix: history.idMatrix }); this.idMatrix.splice(history.y, height); this.area.bottom -= height; break; } - case "REMOVE_COLS": { + case "DELETE_COLS": { const { width } = matrixShape({ matrix: history.idMatrix }); this.idMatrix.forEach((row) => { row.splice(history.x, width); diff --git a/src/store/helpers.ts b/src/store/helpers.ts index 30498a80..499f0852 100644 --- a/src/store/helpers.ts +++ b/src/store/helpers.ts @@ -51,9 +51,9 @@ export const shouldTracking = (operation: string) => { return true; case "ADD_COLS": return true; - case "REMOVE_ROWS": + case "DELETE_ROWS": return true; - case "REMOVE_COLS": + case "DELETE_COLS": return true; case "MOVE": return true; diff --git a/src/types.ts b/src/types.ts index 6078edc1..75b04021 100644 --- a/src/types.ts +++ b/src/types.ts @@ -186,8 +186,8 @@ export type HistoryAddRowsType = { partial?: true; }; -export type HistoryRemoveRowsType = { - operation: "REMOVE_ROWS"; +export type HistoryDeleteRowsType = { + operation: "DELETE_ROWS"; applyed: boolean; reflection?: StoreReflectionType; y: number; @@ -207,8 +207,8 @@ export type HistoryAddColsType = { partial?: true; }; -export type HistoryRemoveColsType = { - operation: "REMOVE_COLS"; +export type HistoryDeleteColsType = { + operation: "DELETE_COLS"; applyed: boolean; reflection?: StoreReflectionType; x: number; @@ -220,9 +220,9 @@ export type HistoryType = | HistoryUpdateType | HistoryMoveType | HistoryAddRowsType - | HistoryRemoveRowsType + | HistoryDeleteRowsType | HistoryAddColsType - | HistoryRemoveColsType; + | HistoryDeleteColsType; export type Virtualization = { xs: number[]; From 46c669d1c783ddcf75df5f9ee56b1d168cce7b6d Mon Sep 17 00:00:00 2001 From: righ Date: Mon, 29 Jan 2024 00:04:01 +0900 Subject: [PATCH 6/8] fix delete --- .../examples/basic/protection.stories.tsx | 2 +- src/components/ContextMenu.tsx | 2 + src/lib/clipboard.ts | 2 +- src/lib/converters.ts | 2 +- src/lib/structs.ts | 2 +- src/lib/table.ts | 112 ++++++++++-------- src/lib/virtualization.ts | 2 +- src/types.ts | 21 ++-- 8 files changed, 78 insertions(+), 67 deletions(-) diff --git a/.storybook/examples/basic/protection.stories.tsx b/.storybook/examples/basic/protection.stories.tsx index 46933e80..7f55f41b 100644 --- a/.storybook/examples/basic/protection.stories.tsx +++ b/.storybook/examples/basic/protection.stories.tsx @@ -58,4 +58,4 @@ const Sheet = ({ numRows, numCols, defaultWidth }: Props) => { const Template: ComponentStory = (args) => ; export const Protection = Template.bind({}); -Protection.args = { numRows: 1000, numCols: 100, defaultWidth: 50 }; +Protection.args = { numRows: 50, numCols: 20, defaultWidth: 50 }; diff --git a/src/components/ContextMenu.tsx b/src/components/ContextMenu.tsx index 01306ba2..6d32123e 100644 --- a/src/components/ContextMenu.tsx +++ b/src/components/ContextMenu.tsx @@ -248,6 +248,7 @@ export const ContextMenu: React.FC = () => { const newTable = table.deleteRows({ y: selectingTop, numRows: height, + operator: "USER", reflection: { selectingZone, choosing, @@ -274,6 +275,7 @@ export const ContextMenu: React.FC = () => { const newTable = table.deleteCols({ x: selectingLeft, numCols: width, + operator: "USER", reflection: { selectingZone, choosing, diff --git a/src/lib/clipboard.ts b/src/lib/clipboard.ts index 627c33b3..f19e6f0c 100644 --- a/src/lib/clipboard.ts +++ b/src/lib/clipboard.ts @@ -1,4 +1,4 @@ -import { StoreType, AreaType, PointType } from "../types"; +import type { StoreType, AreaType, PointType } from "../types"; import { zoneToArea } from "./structs"; import { solveTable } from "../formula/solver"; diff --git a/src/lib/converters.ts b/src/lib/converters.ts index 5b4078fe..9e4c16ec 100644 --- a/src/lib/converters.ts +++ b/src/lib/converters.ts @@ -1,4 +1,4 @@ -import { Address, PointType } from "../types"; +import type { Address, PointType } from "../types"; import { DEFAULT_ALPHABET_CACHE_SIZE } from "../constants"; const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; diff --git a/src/lib/structs.ts b/src/lib/structs.ts index d4e6b440..3db7a719 100644 --- a/src/lib/structs.ts +++ b/src/lib/structs.ts @@ -1,4 +1,4 @@ -import { +import type { MatrixType, AreaType, ZoneType, diff --git a/src/lib/table.ts b/src/lib/table.ts index b1a89f86..fd209461 100644 --- a/src/lib/table.ts +++ b/src/lib/table.ts @@ -20,9 +20,6 @@ import { StoreReflectionType, ShapeType, OperatorType, - NullableIdMatrix, - NullableIds, - NullableId, } from "../types"; import {areaShape, createMatrix, expandRange, matrixShape, putMatrix} from "./structs"; import { a2p, x2c, p2a, y2r, grantAddressAbsolute } from "./converters"; @@ -31,7 +28,7 @@ import { functions as functionsDefault } from "../formula/mapping"; import { convertFormulaAbsolute, Lexer } from "../formula/evaluator"; import { solveFormula } from "../formula/solver"; -import {DEFAULT_HEIGHT, DEFAULT_WIDTH, HISTORY_LIMIT, OVERSCAN_X, OVERSCAN_Y} from "../constants"; +import {DEFAULT_HEIGHT, DEFAULT_WIDTH, HISTORY_LIMIT} from "../constants"; import { shouldTracking } from "../store/helpers"; import * as protection from "./protection"; @@ -444,10 +441,7 @@ export class Table implements UserTable { return value; } - public getById(id: NullableId) { - if (id == null) { - return undefined; - } + public getById(id: Id) { return this.data[id]; } @@ -717,7 +711,7 @@ export class Table implements UserTable { history.operation === "DELETE_ROWS" || history.operation === "DELETE_COLS" ) { - history.idMatrix.forEach((ids) => { + history.deleted.forEach((ids) => { ids.forEach((id) => { delete this.data[id]; }); @@ -1196,13 +1190,6 @@ export class Table implements UserTable { operator?: OperatorType; reflection?: StoreReflectionType; }) { - for (let i = y; i < y + numRows; i++) { - const cell = this.getByPoint({ y: i, x: 0 }); - if (operator === "USER" && protection.isProtected(cell?.protection, protection.DeleteRow)) { - console.warn(`Cannot delete row ${i}.`); - return this; - } - } if ( this.minNumRows !== -1 && this.getNumRows() - numRows < this.minNumRows @@ -1211,15 +1198,28 @@ export class Table implements UserTable { return this; } - const rows = this.idMatrix.splice(y, numRows); - this.area.bottom -= numRows; + const ys: number[] = []; + for (let i = y; i < y + numRows; i++) { + const cell = this.getByPoint({ y: i, x: 0 }); + if (operator === "USER" && protection.isProtected(cell?.protection, protection.DeleteRow)) { + console.warn(`Cannot delete row ${i}.`); + return this; + } + ys.unshift(i); + } + + const deleted: MatrixType = []; + ys.forEach((y) => { + const row = this.idMatrix.splice(y, 1); + deleted.unshift(row[0]); + }); + this.area.bottom -= ys.length; this.pushHistory({ applyed: true, operation: "DELETE_ROWS", reflection, - y, - numRows, - idMatrix: rows, + ys: ys.reverse(), + deleted, }); return this.shallowCopy({ copyCache: false }); } @@ -1312,14 +1312,6 @@ export class Table implements UserTable { operator?: OperatorType; reflection?: StoreReflectionType; }) { - for (let i = x; i < x + numCols; i++) { - const cell = this.getByPoint({ y: 0, x: i }); - if (operator === "USER" && protection.isProtected(cell?.protection, protection.DeleteCol)) { - console.warn(`Cannot delete col ${i}.`); - return this; - } - } - if ( this.minNumCols !== -1 && this.getNumCols() - numCols < this.minNumCols @@ -1327,20 +1319,34 @@ export class Table implements UserTable { console.error(`At least ${this.minNumCols} column(s) are required.`); return this; } - const rows: IdMatrix = []; + + const xs: number[] = []; + for (let i = x; i < x + numCols; i++) { + const cell = this.getByPoint({ y: 0, x: i }); + if (operator === "USER" && protection.isProtected(cell?.protection, protection.DeleteCol)) { + console.warn(`Cannot delete col ${i}.`); + continue; + } + xs.unshift(i); + } + + const deleted: MatrixType = []; this.idMatrix.forEach((row) => { - const deleted = row.splice(x, numCols); - rows.push(deleted); + const deleting: Ids = []; + deleted.push(deleting); + // reverse and delete + xs.forEach((x) => { + deleting.unshift(...row.splice(x, 1)); + }); }); - this.area.right -= numCols; + this.area.right -= xs.length; this.pushHistory({ applyed: true, operation: "DELETE_COLS", reflection, - x, - numCols, - idMatrix: rows, + xs: xs.reverse(), + deleted, }); return this.shallowCopy({ copyCache: false }); } @@ -1463,17 +1469,21 @@ export class Table implements UserTable { break; } case "DELETE_ROWS": { - const { height } = matrixShape({ matrix: history.idMatrix }); - this.idMatrix.splice(history.y, 0, ...history.idMatrix); - this.area.bottom += height; + const { ys, deleted } = history; + ys.forEach((y, i) => { + this.idMatrix.splice(y, 0, deleted[i]); + }); + this.area.bottom += ys.length; break; } case "DELETE_COLS": { - const { width } = matrixShape({ matrix: history.idMatrix }); + const { xs, deleted } = history; this.idMatrix.forEach((row, i) => { - row.splice(history.x, 0, ...history.idMatrix[i]); + for (let j = 0; j < xs.length; j++) { + row.splice(xs[j], 0, deleted[i][j]); + } }); - this.area.right += width; + this.area.right += xs.length; break; } case "MOVE": { @@ -1539,17 +1549,21 @@ export class Table implements UserTable { break; } case "DELETE_ROWS": { - const { height } = matrixShape({ matrix: history.idMatrix }); - this.idMatrix.splice(history.y, height); - this.area.bottom -= height; + const { ys } = history; + [...ys].reverse().forEach((y) => { + this.idMatrix.splice(y, 1); + }); + this.area.bottom -= ys.length; break; } case "DELETE_COLS": { - const { width } = matrixShape({ matrix: history.idMatrix }); - this.idMatrix.forEach((row) => { - row.splice(history.x, width); + const { xs } = history; + [...xs].reverse().forEach((x) => { + this.idMatrix.forEach((row) => { + row.splice(x, 1); + }) }); - this.area.right -= width; + this.area.right -= xs.length; break; } case "MOVE": { diff --git a/src/lib/virtualization.ts b/src/lib/virtualization.ts index 0539ded1..1f6312ea 100644 --- a/src/lib/virtualization.ts +++ b/src/lib/virtualization.ts @@ -1,7 +1,7 @@ import {DEFAULT_HEIGHT, DEFAULT_WIDTH, OVERSCAN_X, OVERSCAN_Y} from "../constants"; import {range} from "./structs"; import {Table} from "./table"; -import {AreaType, PointType, Virtualization} from "../types"; +import type {PointType, Virtualization} from "../types"; export const getCellRectPositions = ( table: Table, diff --git a/src/types.ts b/src/types.ts index 75b04021..49591c79 100644 --- a/src/types.ts +++ b/src/types.ts @@ -137,11 +137,8 @@ export type Props = { }; export type Id = string; -export type NullableId = Id | undefined; export type Ids = Id[]; -export type NullableIds = NullableId[]; export type IdMatrix = Ids[]; -export type NullableIdMatrix = NullableIds[]; export type Address = string; export type MatricesByAddress = { [origin: Address]: MatrixType }; @@ -168,10 +165,10 @@ export type HistoryMoveType = { reflection?: StoreReflectionType; src: AreaType; dst: AreaType; - matrixFrom: NullableIdMatrix; - matrixTo: NullableIdMatrix; - matrixNew: NullableIdMatrix; - lostRows: MatricesByAddress; + matrixFrom:IdMatrix; + matrixTo: IdMatrix; + matrixNew: IdMatrix; + lostRows: MatricesByAddress; }; export type HistoryAddRowsType = { @@ -190,9 +187,8 @@ export type HistoryDeleteRowsType = { operation: "DELETE_ROWS"; applyed: boolean; reflection?: StoreReflectionType; - y: number; - numRows: number; - idMatrix: IdMatrix; + ys: number[]; + deleted: IdMatrix; }; export type HistoryAddColsType = { @@ -211,9 +207,8 @@ export type HistoryDeleteColsType = { operation: "DELETE_COLS"; applyed: boolean; reflection?: StoreReflectionType; - x: number; - numCols: number; - idMatrix: IdMatrix; + xs: number[]; + deleted: IdMatrix; }; export type HistoryType = From 7f59c6fbe82e3dde56058672ae102f50d838ae70 Mon Sep 17 00:00:00 2001 From: righ Date: Mon, 29 Jan 2024 01:32:23 +0900 Subject: [PATCH 7/8] rename --- .../examples/basic/protection.stories.tsx | 16 +++++----- src/components/ContextMenu.tsx | 14 ++++---- src/components/Editor.tsx | 6 ++-- src/components/HorizontalHeaderCell.tsx | 4 +-- src/components/VerticalHeaderCell.tsx | 4 +-- src/lib/{protection.ts => prevention.ts} | 9 +++--- src/lib/table.ts | 32 +++++++++---------- src/store/actions.ts | 4 +-- src/types.ts | 3 +- 9 files changed, 46 insertions(+), 46 deletions(-) rename src/lib/{protection.ts => prevention.ts} (91%) diff --git a/.storybook/examples/basic/protection.stories.tsx b/.storybook/examples/basic/protection.stories.tsx index 7f55f41b..77f25a51 100644 --- a/.storybook/examples/basic/protection.stories.tsx +++ b/.storybook/examples/basic/protection.stories.tsx @@ -1,7 +1,7 @@ import React from "react"; import { ComponentStory } from "@storybook/react"; import { generateInitial, GridSheet } from "../../../src"; -import * as protection from "../../../src/lib/protection"; +import * as prevention from "../../../src/lib/prevention"; export default { title: "Basic", @@ -25,18 +25,18 @@ const Sheet = ({ numRows, numCols, defaultWidth }: Props) => { cells: { default: { width: defaultWidth }, 4: { - protection: protection.DeleteRow, + prevention: prevention.DeleteRow, }, 1: { - protection: protection.Resize, + prevention: prevention.Resize, style: { backgroundColor: "#eeeeee" }, }, "A:B": { - protection: protection.AddCol | protection.DeleteCol, + prevention: prevention.AddCol | prevention.DeleteCol, style: { backgroundColor: "#dddddd" }, }, A: { - protection: protection.Resize, + prevention: prevention.Resize, style: { backgroundColor: "#eeeeee" }, }, C: { @@ -44,7 +44,7 @@ const Sheet = ({ numRows, numCols, defaultWidth }: Props) => { }, B2: { value: "READONLY", - protection: protection.ReadOnly, + prevention: prevention.ReadOnly, style: { backgroundColor: "#aaaaaa" }, } }, @@ -57,5 +57,5 @@ const Sheet = ({ numRows, numCols, defaultWidth }: Props) => { const Template: ComponentStory = (args) => ; -export const Protection = Template.bind({}); -Protection.args = { numRows: 50, numCols: 20, defaultWidth: 50 }; +export const Prevention = Template.bind({}); +Prevention.args = { numRows: 50, numCols: 20, defaultWidth: 50 }; diff --git a/src/components/ContextMenu.tsx b/src/components/ContextMenu.tsx index 6d32123e..3ae0af63 100644 --- a/src/components/ContextMenu.tsx +++ b/src/components/ContextMenu.tsx @@ -13,7 +13,7 @@ import { import { areaToZone, zoneShape, zoneToArea } from "../lib/structs"; import { Context } from "../store"; -import * as protection from "../lib/protection"; +import * as prevention from "../lib/prevention"; export const ContextMenu: React.FC = () => { const { store, dispatch } = React.useContext(Context); @@ -116,7 +116,7 @@ export const ContextMenu: React.FC = () => {
  • table.maxNumRows) || - protection.isProtected(selectingTopCell?.protection, protection.AddRowAbove) + prevention.isPrevented(selectingTopCell?.prevention, prevention.AddRowAbove) ? "gs-disabled" : "gs-enabled" } @@ -142,7 +142,7 @@ export const ContextMenu: React.FC = () => {
  • table.maxNumRows) || - protection.isProtected(selectingBottomCell?.protection, protection.AddRowBelow) + prevention.isPrevented(selectingBottomCell?.prevention, prevention.AddRowBelow) ? "gs-disabled" : "gs-enabled" } @@ -175,7 +175,7 @@ export const ContextMenu: React.FC = () => {
  • table.maxNumCols) || - protection.isProtected(selectingLeftCell?.protection, protection.AddColLeft) + prevention.isPrevented(selectingLeftCell?.prevention, prevention.AddColLeft) ? "gs-disabled" : "gs-enabled" } @@ -204,7 +204,7 @@ export const ContextMenu: React.FC = () => {
  • table.maxNumCols) || - protection.isProtected(selectingRightCell?.protection, protection.AddColRight) + prevention.isPrevented(selectingRightCell?.prevention, prevention.AddColRight) ? "gs-disabled" : "gs-enabled" } @@ -237,7 +237,7 @@ export const ContextMenu: React.FC = () => {
  • {
  • { @@ -311,7 +311,7 @@ export const Editor: React.FC = () => { if (e.ctrlKey || e.metaKey) { return false; } - if (protection.isProtected(cell?.protection, protection.Write)) { + if (prevention.isPrevented(cell?.prevention, prevention.Write)) { console.warn("This cell is protected from writing."); return false; } @@ -339,7 +339,7 @@ export const Editor: React.FC = () => { e.currentTarget.value = ""; }} onDoubleClick={(e) => { - if (protection.isProtected(cell?.protection, protection.Write)) { + if (prevention.isPrevented(cell?.prevention, prevention.Write)) { console.warn("This cell is protected from writing."); return; } diff --git a/src/components/HorizontalHeaderCell.tsx b/src/components/HorizontalHeaderCell.tsx index 687d5c4b..76b3121d 100644 --- a/src/components/HorizontalHeaderCell.tsx +++ b/src/components/HorizontalHeaderCell.tsx @@ -10,7 +10,7 @@ import { setResizingPositionX, } from "../store/actions"; import { DUMMY_IMG, DEFAULT_WIDTH } from "../constants"; -import * as protection from "../lib/protection"; +import * as prevention from "../lib/prevention"; type Props = { x: number; @@ -106,7 +106,7 @@ export const HorizontalHeaderCell: React.FC = React.memo( > {col?.labeler ? table.getLabel(col.labeler, x) : colId}
    { dispatch(setResizingPositionX([x, e.clientX, e.clientX])); diff --git a/src/components/VerticalHeaderCell.tsx b/src/components/VerticalHeaderCell.tsx index 23d7465e..6309a364 100644 --- a/src/components/VerticalHeaderCell.tsx +++ b/src/components/VerticalHeaderCell.tsx @@ -10,7 +10,7 @@ import { setResizingPositionY, } from "../store/actions"; import { DUMMY_IMG, DEFAULT_HEIGHT } from "../constants"; -import * as protection from "../lib/protection"; +import * as prevention from "../lib/prevention"; type Props = { y: number; @@ -106,7 +106,7 @@ export const VerticalHeaderCell: React.FC = React.memo( > {row?.labeler ? table.getLabel(row.labeler, y) : rowId}
    { dispatch(setResizingPositionY([y, e.clientY, e.clientY])); diff --git a/src/lib/protection.ts b/src/lib/prevention.ts similarity index 91% rename from src/lib/protection.ts rename to src/lib/prevention.ts index 0b42243d..24dd071f 100644 --- a/src/lib/protection.ts +++ b/src/lib/prevention.ts @@ -1,5 +1,4 @@ - -export type Prevention = number; +import { Prevention } from "../types"; export const DeleteRow: Prevention = 0b00000000000000000000000000000000000000000000000000001, // 1 @@ -52,9 +51,9 @@ export const ReadOnly: Prevention = // Move ; -export const isProtected = (protection: Prevention | undefined, flag: Prevention) => { - if (protection === undefined) { +export const isPrevented = (prevention: Prevention | undefined, flag: Prevention) => { + if (prevention === undefined) { return false; } - return (protection & flag) === flag; + return (prevention & flag) === flag; }; diff --git a/src/lib/table.ts b/src/lib/table.ts index fd209461..91e2f85b 100644 --- a/src/lib/table.ts +++ b/src/lib/table.ts @@ -30,7 +30,7 @@ import { solveFormula } from "../formula/solver"; import {DEFAULT_HEIGHT, DEFAULT_WIDTH, HISTORY_LIMIT} from "../constants"; import { shouldTracking } from "../store/helpers"; -import * as protection from "./protection"; +import * as prevention from "./prevention"; type Props = { numRows?: number; @@ -272,7 +272,7 @@ export class Table implements UserTable { ...origin?.style, ...data?.style, }, - protection: (origin?.protection || 0) | (data?.protection || 0), + prevention: (origin?.prevention || 0) | (data?.prevention || 0), }; }); }); @@ -297,7 +297,7 @@ export class Table implements UserTable { ...colDefault?.style, ...cell?.style, }, - protection: (common?.protection || 0) | (rowDefault?.protection || 0) | (colDefault?.protection || 0) | (cell?.protection || 0), + prevention: (common?.prevention || 0) | (rowDefault?.prevention || 0) | (colDefault?.prevention || 0) | (cell?.prevention || 0), } as CellType; stacked.value = convertFormulaAbsolute({ value: stacked?.value, @@ -827,7 +827,7 @@ export class Table implements UserTable { src, (_, id) => { const cell = this.data[id]; - if (operator === 'USER' && protection.isProtected(cell?.protection, protection.MoveFrom)) { + if (operator === 'USER' && prevention.isPrevented(cell?.prevention, prevention.MoveFrom)) { return false; } return true; @@ -841,8 +841,8 @@ export class Table implements UserTable { const srcCell = this.data[srcId]; const dstCell = this.data[dstId]; if (operator === 'USER' && ( - protection.isProtected(srcCell?.protection, protection.MoveFrom) || - protection.isProtected(dstCell?.protection, protection.MoveTo) + prevention.isPrevented(srcCell?.prevention, prevention.MoveFrom) || + prevention.isPrevented(dstCell?.prevention, prevention.MoveTo) )) { return false; } @@ -902,7 +902,7 @@ export class Table implements UserTable { y: topFrom + (i % maxHeight), x: leftFrom + (j % maxWidth), }), - protection: 0, // Is this okay? + prevention: 0, // Is this okay? }; const value = convertFormulaAbsolute({ value: cell?.value, @@ -930,7 +930,7 @@ export class Table implements UserTable { diff, partial = true, updateChangedAt = true, - ignoreFields = ['labeler', 'protection'], + ignoreFields = ['labeler', 'prevention'], operator = 'SYSTEM', }: { diff: CellsByAddressType; @@ -945,7 +945,7 @@ export class Table implements UserTable { Object.keys(diff).forEach((address) => { const cell = { ...diff[address] }; - if (operator === 'USER' && protection.isProtected(cell?.protection, protection.Update)) { + if (operator === 'USER' && prevention.isPrevented(cell?.prevention, prevention.Update)) { return; } @@ -959,22 +959,22 @@ export class Table implements UserTable { ignoreFields.forEach((key) => { cell[key] = current?.[key]; }); - if (operator === 'USER' && protection.isProtected(current?.protection, protection.Write)) { + if (operator === 'USER' && prevention.isPrevented(current?.prevention, prevention.Write)) { cell.value = current?.value; } - if (operator === 'USER' && protection.isProtected(current?.protection, protection.Style)) { + if (operator === 'USER' && prevention.isPrevented(current?.prevention, prevention.Style)) { cell.style = current?.style; cell.justifyContent = current?.justifyContent; cell.alignItems = current?.alignItems; } - if (operator === 'USER' && protection.isProtected(current?.protection, protection.Resize)) { + if (operator === 'USER' && prevention.isPrevented(current?.prevention, prevention.Resize)) { cell.width = current?.width; cell.height = current?.height; } - if (operator === 'USER' && protection.isProtected(current?.protection, protection.SetRenderer)) { + if (operator === 'USER' && prevention.isPrevented(current?.prevention, prevention.SetRenderer)) { cell.renderer = current?.renderer; } - if (operator === 'USER' && protection.isProtected(current?.protection, protection.SetParser)) { + if (operator === 'USER' && prevention.isPrevented(current?.prevention, prevention.SetParser)) { cell.parser = current?.parser; } if (updateChangedAt) { @@ -1201,7 +1201,7 @@ export class Table implements UserTable { const ys: number[] = []; for (let i = y; i < y + numRows; i++) { const cell = this.getByPoint({ y: i, x: 0 }); - if (operator === "USER" && protection.isProtected(cell?.protection, protection.DeleteRow)) { + if (operator === "USER" && prevention.isPrevented(cell?.prevention, prevention.DeleteRow)) { console.warn(`Cannot delete row ${i}.`); return this; } @@ -1323,7 +1323,7 @@ export class Table implements UserTable { const xs: number[] = []; for (let i = x; i < x + numCols; i++) { const cell = this.getByPoint({ y: 0, x: i }); - if (operator === "USER" && protection.isProtected(cell?.protection, protection.DeleteCol)) { + if (operator === "USER" && prevention.isPrevented(cell?.prevention, prevention.DeleteCol)) { console.warn(`Cannot delete col ${i}.`); continue; } diff --git a/src/store/actions.ts b/src/store/actions.ts index 0520cbb8..966782bd 100644 --- a/src/store/actions.ts +++ b/src/store/actions.ts @@ -22,7 +22,7 @@ import { tsv2matrix, p2a } from "../lib/converters"; import { DEFAULT_HEIGHT, DEFAULT_WIDTH } from "../constants"; import { initSearchStatement, restrictPoints } from "./helpers"; import { smartScroll } from "../lib/virtualization"; -import * as protection from "../lib/protection"; +import * as prevention from "../lib/prevention"; const actions: { [s: string]: CoreAction } = {}; @@ -526,7 +526,7 @@ class ClearAction extends CoreAction { for (let x = left; x <= right; x++) { const cell = table.getByPoint({ y, x }); const address = p2a({ y, x }); - if (protection.isProtected(cell?.protection, protection.Write)) { + if (prevention.isPrevented(cell?.prevention, prevention.Write)) { continue; } if (cell?.value != null) { diff --git a/src/types.ts b/src/types.ts index 49591c79..86a1eee3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -50,7 +50,7 @@ export type CellType = { renderer?: string; parser?: string; custom?: Custom; - protection?: number; + prevention?: Prevention; changedAt?: Date; }; @@ -226,3 +226,4 @@ export type Virtualization = { }; export type OperatorType = 'USER' | 'SYSTEM'; +export type Prevention = number; \ No newline at end of file From 0b83d3316b08353ec9b09b25c64c24ba330cc193 Mon Sep 17 00:00:00 2001 From: righ Date: Mon, 29 Jan 2024 01:39:14 +0900 Subject: [PATCH 8/8] update readme --- README.md | 4 ++++ src/lib/prevention.ts | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/README.md b/README.md index 333974f5..834a2042 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ - Context menu - External data manipulation - Autofill +- Protection ## Installation @@ -82,5 +83,8 @@ $ npm install @gridsheet/react-core --save - 0.12.x - Renamed from https://www.npmjs.com/package/react-gridsheet +- 0.13.x + - Support Protection. + ## License [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fwalkframe%2Freact-gridsheet.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fwalkframe%2Freact-gridsheet?ref=badge_large) diff --git a/src/lib/prevention.ts b/src/lib/prevention.ts index 24dd071f..0116237d 100644 --- a/src/lib/prevention.ts +++ b/src/lib/prevention.ts @@ -57,3 +57,48 @@ export const isPrevented = (prevention: Prevention | undefined, flag: Prevention } return (prevention & flag) === flag; }; + +// Don't use this function in production +export const debugOperations = (prevention: Prevention | undefined) => { + const preventions: string[] = []; + if (isPrevented(prevention, DeleteRow)) { + preventions.push("DeleteRow"); + } + if (isPrevented(prevention, DeleteCol)) { + preventions.push("DeleteCol"); + } + if (isPrevented(prevention, AddRowAbove)) { + preventions.push("AddRowAbove"); + } + if (isPrevented(prevention, AddRowBelow)) { + preventions.push("AddRowBelow"); + } + if (isPrevented(prevention, AddColLeft)) { + preventions.push("AddColLeft"); + } + if (isPrevented(prevention, AddColRight)) { + preventions.push("AddColRight"); + } + if (isPrevented(prevention, MoveFrom)) { + preventions.push("MoveFrom"); + } + if (isPrevented(prevention, MoveTo)) { + preventions.push("MoveTo"); + } + if (isPrevented(prevention, Write)) { + preventions.push("Write"); + } + if (isPrevented(prevention, Style)) { + preventions.push("Style"); + } + if (isPrevented(prevention, Resize)) { + preventions.push("Resize"); + } + if (isPrevented(prevention, SetRenderer)) { + preventions.push("SetRenderer"); + } + if (isPrevented(prevention, SetParser)) { + preventions.push("SetParser"); + } + return preventions; +} \ No newline at end of file