@dxos/plugin-sheet 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"components.mjs","names":[],"sources":["../../src/components/ComputeGraph/ComputeGraphContext.ts","../../src/components/ComputeGraph/ComputeGraphContextProvider.tsx","../../src/components/SheetRoot/SheetContext.ts","../../src/model/sheet-model.ts","../../src/model/useSheetModel.ts","../../src/components/SheetRoot/SheetRoot.tsx","../../src/extensions/editor/sheet-extension.ts","../../src/components/SheetContent/util.ts","../../src/components/SheetContent/SheetContent.tsx","../../src/components/SheetStatusbar/SheetStatusbar.tsx","../../src/components/SheetToolbar/align.ts","../../src/components/SheetToolbar/style.ts","../../src/components/SheetToolbar/useToolbarState.ts","../../src/components/SheetToolbar/SheetToolbar.tsx","../../src/components/Sheet/Sheet.tsx"],"sourcesContent":["//\n// Copyright 2024 DXOS.org\n//\n\nimport { createContext, useContext } from 'react';\n\nimport { type ComputeGraph, type ComputeGraphRegistry } from '@dxos/compute-hyperformula';\nimport { raise } from '@dxos/debug';\nimport { type Space } from '@dxos/react-client/echo';\nimport { useAsyncState } from '@dxos/react-hooks';\n\n// Kept out of `ComputeGraphContextProvider.tsx`: react-refresh only fast-refreshes a module whose exports are all\n// components, so a context and its hook exported beside them force a full page reload on every edit.\n\nexport type ComputeGraphContextType = {\n registry: ComputeGraphRegistry;\n};\n\n/**\n * The compute graph context manages a ComputeGraph for each space.\n */\nexport const ComputeGraphContext = createContext<ComputeGraphContextType | undefined>(undefined);\n\nexport const useComputeGraph = (space?: Space): ComputeGraph | undefined => {\n const { registry } = useContext(ComputeGraphContext) ?? raise(new Error('Missing ComputeGraphContext'));\n const [graph] = useAsyncState(async () => {\n if (space) {\n const graph = registry.getOrCreateGraph(space);\n await graph.open();\n return graph;\n }\n }, [space, registry]);\n\n return graph;\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { type PropsWithChildren } from 'react';\n\nimport { ComputeGraphContext, type ComputeGraphContextType } from './ComputeGraphContext.ts';\n\nexport const ComputeGraphContextProvider = ({ registry, children }: PropsWithChildren<ComputeGraphContextType>) => {\n return <ComputeGraphContext.Provider value={{ registry }}>{children}</ComputeGraphContext.Provider>;\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { createContext, useContext } from 'react';\n\nimport { raise } from '@dxos/debug';\n\nimport { type SheetContextValue } from './SheetRoot.tsx';\n\n// Kept out of `SheetRoot.tsx`: react-refresh only fast-refreshes a module whose exports are all\n// components, so a context and its hook exported beside them force a full page reload on every edit.\n\n// TODO(burdon): Use radix context.\nexport const SheetContext = createContext<SheetContextValue | undefined>(undefined);\n\nexport const useSheetContext = (): SheetContextValue => {\n return useContext(SheetContext) ?? raise(new Error('Missing SheetContext'));\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport {\n type CellAddress,\n type CellRange,\n type CellScalarValue,\n type ComputeGraph,\n type ComputeNode,\n type ComputeNodeEvent,\n DetailedCellError,\n ExportedCellChange,\n type SimpleCellAddress,\n type SimpleCellRange,\n type SimpleDate,\n type SimpleDateTime,\n addressFromA1Notation,\n addressToA1Notation,\n createSheetName,\n isFormula,\n} from '@dxos/compute-hyperformula';\nimport { Resource } from '@dxos/context';\nimport { Obj } from '@dxos/echo';\nimport { Format, TypeEnum } from '@dxos/echo/Format';\nimport { assertArgument, invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { Sheet, SheetCapabilities, SheetUtil } from '#types';\n\n// TODO(burdon): Move to compute.\n// Map sheet types to system types.\n// https://hyperformula.handsontable.com/guide/types-of-values.html\n// - https://github.com/handsontable/hyperformula/blob/master/src/Cell.ts (CellValueType)\n// - https://github.com/handsontable/hyperformula/blob/master/src/interpreter/InterpreterValue.ts (NumberType)\nconst typeMap: Record<string, { type: TypeEnum; format?: Format.TypeFormat }> = {\n BOOLEAN: { type: TypeEnum.Boolean },\n NUMBER_RAW: { type: TypeEnum.Number },\n NUMBER_PERCENT: { type: TypeEnum.Number, format: Format.TypeFormat.Percent },\n NUMBER_CURRENCY: { type: TypeEnum.Number, format: Format.TypeFormat.Currency },\n NUMBER_DATETIME: { type: TypeEnum.String, format: Format.TypeFormat.DateTime },\n NUMBER_DATE: { type: TypeEnum.String, format: Format.TypeFormat.Date },\n NUMBER_TIME: { type: TypeEnum.String, format: Format.TypeFormat.Time },\n};\n\nconst getTopLeft = (range: CellRange): CellAddress => {\n const to = range.to ?? range.from;\n return { row: Math.min(range.from.row, to.row), col: Math.min(range.from.col, to.col) };\n};\n\nconst toSimpleCellAddress = (sheet: number, cell: CellAddress): SimpleCellAddress => ({\n sheet,\n row: cell.row,\n col: cell.col,\n});\n\nconst toModelRange = (sheet: number, range: CellRange): SimpleCellRange => ({\n start: toSimpleCellAddress(sheet, range.from),\n end: toSimpleCellAddress(sheet, range.to ?? range.from),\n});\n\nexport type SheetModelOptions = {\n readonly?: boolean;\n};\n\n/**\n * Spreadsheet data model.\n *\n * [ComputeGraphContext] > [SheetContext]:[SheetModel] > [Sheet.Root]\n */\n// TODO(burdon): Factor out commonality with ComputeNode. Factor out HF.\nexport class SheetModel extends Resource {\n public readonly id = `model-${PublicKey.random().truncate()}`;\n\n // Wraps compute node.\n public readonly update = new Event<ComputeNodeEvent>();\n\n private _node?: ComputeNode;\n\n constructor(\n private readonly _graph: ComputeGraph,\n private readonly _sheet: Sheet.Sheet,\n private readonly _options: SheetModelOptions = {},\n ) {\n super();\n }\n\n get graph() {\n return this._graph;\n }\n\n get sheet() {\n return this._sheet;\n }\n\n get readonly() {\n return this._options.readonly;\n }\n\n get bounds() {\n return {\n rows: this._sheet.rows.length,\n columns: this._sheet.columns.length,\n };\n }\n\n /**\n * Initialize sheet and engine.\n */\n protected override async _open(): Promise<void> {\n log('SheetUtil.initialize', { id: this.id });\n Obj.update(this._sheet, (obj) => {\n SheetUtil.initialize(obj);\n });\n\n this._graph.update.on((event) => {\n if (event.type === 'functionsUpdated') {\n this.reset();\n }\n });\n\n // TODO(burdon): SheetModel should extend ComputeNode and be constructed via the graph.\n this._node = this._graph.getOrCreateNode(\n createSheetName({ type: Obj.getTypename(this._sheet)!, id: this._sheet.id }),\n );\n await this._node.open();\n\n // Listen for model updates (e.g., async calculations).\n const unsubscribe = this._node.update.on((event) => this.update.emit(event));\n this._ctx.onDispose(unsubscribe);\n\n this.reset();\n }\n\n /**\n * Update engine.\n * NOTE: This resets the undo history.\n * @deprecated\n */\n reset(): void {\n invariant(this._node);\n this._node.graph.hf.clearSheet(this._node.sheetId);\n Object.entries(this._sheet.cells).forEach(([key, { value }]) => {\n invariant(this._node);\n const { col, row } = SheetUtil.addressFromIndex(this._sheet, key);\n if (isFormula(value)) {\n const binding = this._graph.mapFunctionBindingFromId(SheetUtil.mapFormulaIndicesToRefs(this._sheet, value));\n if (binding) {\n value = this._graph.mapFormulaToNative(binding);\n } else {\n // If binding is not found, render the cell as empty.\n // This prevents the cell from momentarily rendering an error while the binding is being loaded.\n value = '';\n }\n }\n\n this._node.graph.hf.setCellContents({ sheet: this._node.sheetId, row, col }, value);\n });\n }\n\n /**\n * Recalculate formulas.\n * NOTE: This resets the undo history.\n * https://hyperformula.handsontable.com/guide/volatile-functions.html#volatile-actions\n * @deprecated\n */\n // TODO(burdon): Remove.\n recalculate(): void {\n this._node?.graph.hf.rebuildAndRecalculate();\n }\n\n insertRows(i: number, n = 1): string[] {\n let idx: string[] = [];\n Obj.update(this._sheet, (obj) => {\n idx = SheetUtil.insertIndices(obj.rows, i, n, SheetUtil.MAX_ROWS);\n });\n this.reset();\n return idx;\n }\n\n insertColumns(i: number, n = 1): string[] {\n let idx: string[] = [];\n Obj.update(this._sheet, (obj) => {\n idx = SheetUtil.insertIndices(obj.columns, i, n, SheetUtil.MAX_COLS);\n });\n this.reset();\n return idx;\n }\n\n dropRow(rowIndex: string): SheetCapabilities.SheetAction.RestoreAxis {\n const range = {\n from: SheetUtil.addressFromIndex(this._sheet, `${this._sheet.columns[0]}@${rowIndex}`),\n to: SheetUtil.addressFromIndex(this._sheet, `${this._sheet.columns[this._sheet.columns.length - 1]}@${rowIndex}`),\n };\n const values = this.getCellValues(range).flat();\n const index = this._sheet.rows.indexOf(rowIndex);\n this.clear(range);\n Obj.update(this._sheet, (obj) => {\n obj.rows.splice(index, 1);\n delete obj.rowMeta[rowIndex];\n });\n this.reset();\n return { axis: 'row', index, axisIndex: rowIndex, axisMeta: this._sheet.rowMeta[rowIndex], values };\n }\n\n dropColumn(colIndex: string): SheetCapabilities.SheetAction.RestoreAxis {\n const range = {\n from: SheetUtil.addressFromIndex(this._sheet, `${colIndex}@${this._sheet.rows[0]}`),\n to: SheetUtil.addressFromIndex(this._sheet, `${colIndex}@${this._sheet.rows[this._sheet.rows.length - 1]}`),\n };\n const values = this.getCellValues(range).flat();\n const index = this._sheet.columns.indexOf(colIndex);\n this.clear(range);\n Obj.update(this._sheet, (obj) => {\n obj.columns.splice(index, 1);\n delete obj.columnMeta[colIndex];\n });\n this.reset();\n return { axis: 'col', index, axisIndex: colIndex, axisMeta: this._sheet.rowMeta[colIndex], values };\n }\n\n restoreRow({ index, axisIndex, axisMeta, values }: SheetCapabilities.SheetAction.RestoreAxis): void {\n Obj.update(this._sheet, (obj) => {\n obj.rows.splice(index, 0, axisIndex);\n values.forEach((value, col) => {\n if (value) {\n obj.cells[`${obj.columns[col]}@${axisIndex}`] = { value };\n }\n });\n\n if (axisMeta) {\n obj.rowMeta[axisIndex] = axisMeta;\n }\n });\n this.reset();\n }\n\n restoreColumn({ index, axisIndex, axisMeta, values }: SheetCapabilities.SheetAction.RestoreAxis): void {\n Obj.update(this._sheet, (obj) => {\n obj.columns.splice(index, 0, axisIndex);\n values.forEach((value, row) => {\n if (value) {\n obj.cells[`${axisIndex}@${obj.rows[row]}`] = { value };\n }\n });\n\n if (axisMeta) {\n obj.columnMeta[axisIndex] = axisMeta;\n }\n });\n this.reset();\n }\n\n //\n // Undoable actions.\n // TODO(burdon): Group undoable methods; consistently update hf/sheet.\n //\n\n /**\n * Clear range of values.\n */\n clear(range: CellRange): void {\n invariant(this._node);\n const topLeft = getTopLeft(range);\n const values = this._iterRange(range, () => null);\n this._node.graph.hf.setCellContents(toSimpleCellAddress(this._node.sheetId, topLeft), values);\n Obj.update(this._sheet, (obj) => {\n this._iterRange(range, (cell) => {\n const idx = SheetUtil.addressToIndex(this._sheet, cell);\n delete obj.cells[idx];\n });\n });\n }\n\n cut(range: CellRange): void {\n invariant(this._node);\n this._node.graph.hf.cut(toModelRange(this._node.sheetId, range));\n Obj.update(this._sheet, (obj) => {\n this._iterRange(range, (cell) => {\n const idx = SheetUtil.addressToIndex(this._sheet, cell);\n delete obj.cells[idx];\n });\n });\n }\n\n copy(range: CellRange): void {\n invariant(this._node);\n this._node.graph.hf.copy(toModelRange(this._node.sheetId, range));\n }\n\n paste(cell: CellAddress): void {\n invariant(this._node);\n if (!this._node.graph.hf.isClipboardEmpty()) {\n const changes = this._node.graph.hf.paste(toSimpleCellAddress(this._node.sheetId, cell));\n Obj.update(this._sheet, (obj) => {\n for (const change of changes) {\n if (change instanceof ExportedCellChange) {\n const { address, newValue } = change;\n const idx = SheetUtil.addressToIndex(this._sheet, { row: address.row, col: address.col });\n obj.cells[idx] = { value: newValue };\n }\n }\n });\n }\n }\n\n // TODO(burdon): Display undo/redo state.\n undo(): void {\n invariant(this._node);\n if (this._node.graph.hf.isThereSomethingToUndo()) {\n this._node.graph.hf.undo();\n // this.update.emit();\n }\n }\n\n redo(): void {\n invariant(this._node);\n if (this._node.graph.hf.isThereSomethingToRedo()) {\n this._node.graph.hf.redo();\n // this.update.emit();\n }\n }\n\n /**\n * Get value from sheet.\n */\n getCellValue(cell: CellAddress): CellScalarValue {\n const idx = SheetUtil.addressToIndex(this._sheet, cell);\n return this._sheet.cells[idx]?.value ?? null;\n }\n\n /**\n * Get value as a string for editing.\n */\n getCellText(cell: CellAddress): string | undefined {\n const value = this.getCellValue(cell);\n if (value == null) {\n return undefined;\n }\n\n if (isFormula(value)) {\n return this._graph.mapFunctionBindingFromId(SheetUtil.mapFormulaIndicesToRefs(this._sheet, value));\n } else {\n return String(value);\n }\n }\n\n /**\n * Get array of raw values from sheet.\n */\n getCellValues(range: CellRange): CellScalarValue[][] {\n return this._iterRange(range, (cell) => this.getCellValue(cell));\n }\n\n /**\n * Gets the regular or computed value from the engine.\n */\n getValue(cell: CellAddress): CellScalarValue {\n // Applies rounding and post-processing.\n invariant(this._node);\n const address = toSimpleCellAddress(this._node.sheetId, cell);\n const value = this._node.graph.hf.getCellValue(address);\n if (value instanceof DetailedCellError) {\n // TODO(wittjosiah): Error details should be shown in cell `title`.\n log.warn('cell error', { cell, error: value });\n return value.toString();\n }\n\n return value;\n }\n\n /**\n * Get value type.\n */\n getValueDescription(cell: CellAddress): { type: TypeEnum; format?: Format.TypeFormat } | undefined {\n invariant(this._node);\n const addr = toSimpleCellAddress(this._node.sheetId, cell);\n const type = this._node.graph.hf.getCellValueDetailedType(addr);\n return typeMap[type];\n }\n\n /**\n * Sets the value, updating the sheet and engine.\n */\n setValue(cell: CellAddress, value: CellScalarValue): void {\n invariant(this._node);\n if (this._options.readonly) {\n throw new SheetUtil.ReadonlyException();\n }\n\n // Reallocate if > current bounds.\n let refresh = false;\n if (cell.row >= this._sheet.rows.length) {\n Obj.update(this._sheet, (obj) => {\n SheetUtil.insertIndices(obj.rows, cell.row, 1, SheetUtil.MAX_ROWS);\n });\n refresh = true;\n }\n if (cell.col >= this._sheet.columns.length) {\n Obj.update(this._sheet, (obj) => {\n SheetUtil.insertIndices(obj.columns, cell.col, 1, SheetUtil.MAX_COLS);\n });\n refresh = true;\n }\n\n if (refresh) {\n // TODO(burdon): Remove.\n this.reset();\n }\n\n // Insert into engine.\n this._node.graph.hf.setCellContents({ sheet: this._node.sheetId, row: cell.row, col: cell.col }, [\n [isFormula(value) ? this._graph.mapFormulaToNative(value) : value],\n ]);\n\n // Insert into sheet.\n const idx = SheetUtil.addressToIndex(this._sheet, cell);\n if (value === undefined || value === null) {\n Obj.update(this._sheet, (obj) => {\n delete obj.cells[idx];\n });\n } else {\n if (isFormula(value)) {\n value = this._graph.mapFunctionBindingToId(SheetUtil.mapFormulaRefsToIndices(this._sheet, value));\n }\n\n Obj.update(this._sheet, (obj) => {\n obj.cells[idx] = { value };\n });\n }\n }\n\n /**\n * Sets values from a simple map.\n */\n setValues(values: Record<string, Sheet.CellValue>): void {\n Object.entries(values).forEach(([key, { value }]) => {\n this.setValue(addressFromA1Notation(key), value);\n });\n }\n\n /**\n * Iterate range.\n */\n private _iterRange(range: CellRange, cb: (cell: CellAddress) => CellScalarValue | void): CellScalarValue[][] {\n const to = range.to ?? range.from;\n const rowRange = [Math.min(range.from.row, to.row), Math.max(range.from.row, to.row)];\n const columnRange = [Math.min(range.from.col, to.col), Math.max(range.from.col, to.col)];\n const rows: CellScalarValue[][] = [];\n for (let row = rowRange[0]; row <= rowRange[1]; row++) {\n const rowCells: CellScalarValue[] = [];\n for (let column = columnRange[0]; column <= columnRange[1]; column++) {\n const value = cb({ row, col: column });\n if (value !== undefined) {\n rowCells.push(value);\n }\n }\n\n rows.push(rowCells);\n }\n\n return rows;\n }\n\n // TODO(burdon): Delete index.\n private _deleteIndices(indices: string[], i: number, n: number): void {\n throw new Error('Not implemented');\n }\n\n // TODO(burdon): Move. Cannot use fractional without changing. Switch back to using unique IDs?\n private _moveIndices(indices: string[], i: number, j: number, n: number): void {\n throw new Error('Not implemented');\n }\n\n /**\n * Map from indices to A1 notation.\n */\n mapFormulaIndicesToRefs(formula: string): string {\n assertArgument(isFormula(formula), 'formula');\n return formula.replace(/([a-zA-Z0-9]+)@([a-zA-Z0-9]+)/g, (idx) => {\n return addressToA1Notation(SheetUtil.addressFromIndex(this._sheet, idx));\n });\n }\n\n //\n // Values\n //\n\n /**\n * https://hyperformula.handsontable.com/guide/date-and-time-handling.html#example\n * https://hyperformula.handsontable.com/api/interfaces/configparams.html#nulldate\n * NOTE: TODAY() is number of FULL days since nullDate. It will typically be -1 days from NOW().\n */\n toLocalDate(num: number): Date {\n const { year, month, day, hours, minutes, seconds } = this.toDateTime(num);\n return new Date(year, month - 1, day, hours, minutes, seconds);\n }\n\n toDateTime(num: number): SimpleDateTime {\n invariant(this._node);\n return this._node.graph.hf.numberToDateTime(num) as SimpleDateTime;\n }\n\n toDate(num: number): SimpleDate {\n invariant(this._node);\n return this._node.graph.hf.numberToDate(num) as SimpleDate;\n }\n\n toTime(num: number): SimpleDate {\n invariant(this._node);\n return this._node.graph.hf.numberToTime(num) as SimpleDate;\n }\n}\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nimport { type ComputeGraph } from '@dxos/compute-hyperformula';\n\nimport { Sheet } from '#types';\n\nimport { SheetModel } from '../model/index.ts';\n\nexport type UseSheetModelOptions = {\n readonly?: boolean;\n};\n\nexport const useSheetModel = (\n graph?: ComputeGraph,\n sheet?: Sheet.Sheet,\n { readonly }: UseSheetModelOptions = {},\n): SheetModel | undefined => {\n const [model, setModel] = useState<SheetModel>();\n useEffect(() => {\n if (!graph || !sheet) {\n return;\n }\n\n let model: SheetModel | undefined;\n const t = setTimeout(async () => {\n model = new SheetModel(graph, sheet, { readonly });\n await model.open();\n setModel(model);\n });\n\n return () => {\n clearTimeout(t);\n void model?.close();\n };\n }, [graph, sheet, readonly]);\n\n return model;\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { type PropsWithChildren, useCallback, useState } from 'react';\n\nimport {\n type CellAddress,\n type CellRange,\n type CompleteCellRange,\n type ComputeGraph,\n} from '@dxos/compute-hyperformula';\nimport { Grid, type GridContentProps, type GridEditing, useGridContext } from '@dxos/react-ui-grid';\n\nimport { Sheet } from '#types';\n\nimport { type SheetModel, useSheetModel } from '../../model/index.ts';\nimport { SheetContext } from './SheetContext.ts';\n\nexport type SheetContextValue = {\n id: string;\n attendableId: string;\n model: SheetModel;\n\n // Cursor state.\n // TODO(burdon): Cursor and range should use indices.\n cursor?: CellAddress;\n setCursor: (cell: CellAddress | undefined) => void;\n range?: CellRange;\n setRange: (range: CellRange | undefined) => void;\n cursorFallbackRange?: CompleteCellRange;\n\n // Editing state (undefined if not editing).\n editing: GridEditing;\n setEditing: (editing: GridEditing) => void;\n\n // Active refs\n activeRefs: GridContentProps['activeRefs'];\n setActiveRefs: (activeRefs: GridContentProps['activeRefs']) => void;\n\n // Flags\n ignoreAttention?: boolean;\n\n // Events.\n // TODO(burdon): Generalize.\n onInfo?: () => void;\n};\n\nexport type SheetRootProps = {\n graph: ComputeGraph;\n sheet: Sheet.Sheet;\n attendableId: string;\n readonly?: boolean;\n ignoreAttention?: boolean;\n} & Pick<SheetContextValue, 'onInfo'>;\n\nexport const SheetRoot = ({\n children,\n graph,\n sheet,\n attendableId,\n readonly,\n ignoreAttention,\n onInfo,\n}: PropsWithChildren<SheetRootProps>) => {\n const model = useSheetModel(graph, sheet, { readonly });\n if (!model) {\n return null;\n }\n\n return (\n <Grid.Root id={attendableId}>\n <SheetProviderImpl model={model} attendableId={attendableId} onInfo={onInfo} ignoreAttention={ignoreAttention}>\n {children}\n </SheetProviderImpl>\n </Grid.Root>\n );\n};\n\nconst SheetProviderImpl = ({\n children,\n attendableId,\n ignoreAttention,\n model,\n onInfo,\n}: PropsWithChildren<Pick<SheetContextValue, 'attendableId' | 'ignoreAttention' | 'model' | 'onInfo'>>) => {\n const { id, editing, setEditing } = useGridContext('SheetProvider');\n\n const [cursor, setCursorInternal] = useState<CellAddress>();\n const [range, setRangeInternal] = useState<CellRange>();\n const [cursorFallbackRange, setCursorFallbackRange] = useState<CompleteCellRange>();\n const [activeRefs, setActiveRefs] = useState<GridContentProps['activeRefs']>('');\n\n const setCursor = useCallback(\n (nextCursor?: CellAddress) => {\n setCursorInternal(nextCursor);\n setCursorFallbackRange(\n range?.to ? (range as CompleteCellRange) : nextCursor ? { from: nextCursor!, to: nextCursor! } : undefined,\n );\n },\n [range],\n );\n const setRange = useCallback(\n (nextRange?: CellRange) => {\n setRangeInternal(nextRange);\n setCursorFallbackRange(\n nextRange?.to ? (nextRange as CompleteCellRange) : cursor ? { from: cursor!, to: cursor! } : undefined,\n );\n },\n [cursor],\n );\n\n return (\n <SheetContext.Provider\n value={{\n id,\n attendableId,\n model,\n editing,\n setEditing,\n cursor,\n setCursor,\n range,\n setRange,\n cursorFallbackRange,\n activeRefs,\n setActiveRefs,\n ignoreAttention,\n // TODO(burdon): Change to event.\n onInfo,\n }}\n >\n {children}\n </SheetContext.Provider>\n );\n};\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport {\n type Completion,\n type CompletionContext,\n type CompletionResult,\n acceptCompletion,\n autocompletion,\n completionStatus,\n startCompletion,\n} from '@codemirror/autocomplete';\nimport { HighlightStyle, type Language, syntaxHighlighting } from '@codemirror/language';\nimport { type Extension } from '@codemirror/state';\nimport { type EditorView, ViewPlugin, type ViewUpdate, keymap } from '@codemirror/view';\nimport { type SyntaxNode } from '@lezer/common';\nimport { tags } from '@lezer/highlight';\nimport { spreadsheet } from 'codemirror-lang-spreadsheet';\n\nimport { type FunctionDefinition } from '@dxos/compute-hyperformula';\nimport { RANGE_NOTATION } from '@dxos/compute-hyperformula';\nimport { singleValueFacet } from '@dxos/ui-editor';\nimport { mx } from '@dxos/ui-theme';\n\n/**\n * https://codemirror.net/examples/styling\n * https://lezer.codemirror.net/docs/ref/#highlight\n * https://github.com/luizzappa/codemirror-lang-spreadsheet/blob/main/src/index.ts#L28 (mapping)\n */\n// TODO(burdon): Define light/dark.\nconst highlightStyles = HighlightStyle.define([\n // Function.\n {\n tag: tags.name,\n class: 'text-accent-text',\n },\n // Range.\n {\n tag: tags.tagName,\n class: 'text-pink-text',\n },\n // Values.\n {\n tag: tags.number,\n class: 'text-teal-text',\n },\n {\n tag: tags.bool,\n class: 'text-teal-text',\n },\n {\n tag: tags.string,\n class: 'text-teal-text',\n },\n // Error.\n {\n tag: tags.invalid,\n class: 'text-un-accent',\n },\n]);\n\nconst languageFacet = singleValueFacet<Language>();\n\nexport type SheetExtensionOptions = {\n debug?: boolean;\n functions?: FunctionDefinition[];\n};\n\n/**\n * Spreadsheet formula extension and parser.\n * https://github.com/luizzappa/codemirror-lang-spreadsheet\n * https://github.com/luizzappa/codemirror-app-spreadsheet/blob/master/src/editor.ts\n * https://github.com/codemirror/lang-example\n * https://hyperformula.handsontable.com/guide/key-concepts.html#grammar\n */\nexport const sheetExtension = ({ debug, functions = [] }: SheetExtensionOptions): Extension => {\n const { extension, language } = spreadsheet({\n idiom: 'en-US',\n decimalSeparator: '.',\n });\n\n const createCompletion = (name: string) => {\n const { section = 'Custom', description, syntax } = functions.find((value) => value.name === name) ?? {};\n\n return {\n section,\n label: name,\n info: () => {\n if (!description && !syntax) {\n return null;\n }\n\n // TODO(burdon): Standardize color styles.\n const root = document.createElement('div');\n root.className = 'flex flex-col gap-2 text-sm';\n\n const title = document.createElement('h2');\n title.innerText = name;\n title.className = 'text-lg font-mono text-accent-text';\n root.appendChild(title);\n\n if (description) {\n const info = document.createElement('p');\n info.innerText = description;\n info.className = 'text-fg-subtle';\n root.appendChild(info);\n }\n\n if (syntax) {\n const detail = document.createElement('pre');\n detail.innerText = syntax;\n detail.className = 'whitespace-pre-wrap text-green-text';\n root.appendChild(detail);\n }\n\n return root;\n },\n apply: (view, completion, from, to) => {\n const insertParens = to === view.state.doc.toString().length;\n view.dispatch(\n view.state.update({\n changes: {\n from,\n to,\n insert: completion.label + (insertParens ? '()' : ''),\n },\n selection: {\n anchor: from + completion.label.length + 1,\n },\n }),\n );\n },\n } satisfies Completion;\n };\n\n return [\n extension,\n languageFacet.of(language),\n language.data.of({\n autocomplete: (context: CompletionContext): CompletionResult | null => {\n if (context.state.doc.toString()[0] !== '=') {\n return null;\n }\n const match = context.matchBefore(/\\w*/);\n if (!match || match.from === match.to) {\n return null;\n }\n\n const text = match.text.toUpperCase();\n if (!context.explicit && match.text.length < 2) {\n return null;\n }\n\n return {\n from: match.from,\n options:\n functions?.filter(({ name }) => name.startsWith(text)).map(({ name }) => createCompletion(name)) ?? [],\n };\n },\n }),\n\n syntaxHighlighting(highlightStyles),\n anchorCompletionTooltip,\n autocompletion({\n aboveCursor: false,\n defaultKeymap: true,\n activateOnTyping: true,\n closeOnBlur: !debug,\n icons: false,\n // Cosmetics only. The tooltip is `position: fixed` and CodeMirror computes its coordinates from\n // the cursor, so overriding `left`/`top` here measures them against the viewport instead of the\n // cell — which pinned the completion list to the top-left corner of the window.\n tooltipClass: () =>\n mx(\n '-m-0! border border-h-0! [&>ul]:min-w-[198px]!',\n '[&>ul>li[aria-selected]]:bg-accent-bg!',\n 'border-separator',\n ),\n }),\n keymap.of([\n {\n key: 'Tab',\n run: (view) => {\n return completionStatus(view.state) === 'active' ? acceptCompletion(view) : startCompletion(view);\n },\n },\n ]),\n\n // Parsing.\n // StateField.define({\n // create: (state) => {},\n // update: (value, tr) => {\n // log.info('update');\n // syntaxTree(tr.state).iterate({\n // enter: ({ type, from, to }) => {\n // log.info('node', { type: type.name, from, to });\n // },\n // });\n // },\n // }),\n ];\n};\n\nexport type SelectionRange = { from: number; to: number };\n\nexport interface RangeController {\n setRange(range: string): void;\n}\n\nexport type RangeExtensionOptions = {\n /**\n * Provides controller callback when extension is initialized.\n */\n onInit?: (controller: RangeController) => void;\n /**\n * Called when the active range changes.\n * @param state The current state.\n * @param state.activeRange undefined if no range is active, otherwise a possibly partially defined range.\n */\n onStateChange?: (state: { activeRange: string | undefined }) => void;\n};\n\n/**\n * Tracks the currently active cell within a formula and provides a callback to modify it.\n */\nexport const rangeExtension = ({ onInit, onStateChange }: RangeExtensionOptions): Extension => {\n let view: EditorView;\n let activeRange: SelectionRange | undefined;\n\n // Called externally to provide current range.\n const notifier: RangeController = {\n setRange: (range: string) => {\n if (activeRange) {\n view.dispatch(\n view.state.update({\n changes: { ...activeRange, insert: range.toString() },\n selection: { anchor: activeRange.from + range.length },\n }),\n );\n }\n\n view.focus();\n },\n };\n\n return ViewPlugin.fromClass(\n class {\n constructor(_view: EditorView) {\n view = _view;\n onInit?.(notifier);\n }\n\n update(view: ViewUpdate) {\n const { anchor } = view.state.selection.ranges[0];\n\n // Find first Range or cell at cursor.\n activeRange = undefined;\n const language = view.state.facet(languageFacet);\n const { topNode } = language.parser.parse(view.state.doc.toString());\n visitTree(topNode, ({ type, from, to }) => {\n if (from <= anchor && to >= anchor) {\n switch (type.name) {\n case 'Function':\n // Mark but keep looking.\n activeRange = { from: to, to };\n break;\n\n case 'CloseParen':\n // Mark but keep looking.\n activeRange = { from, to: from };\n break;\n\n case 'RangeToken':\n case 'CellToken':\n activeRange = { from, to };\n return true;\n }\n }\n\n return false;\n });\n\n // Allow start of formula.\n if (!activeRange && view.state.doc.toString()[0] === '=') {\n const str = view.state.doc.sliceString(1);\n if (RANGE_NOTATION.test(str)) {\n activeRange = { from: 1, to: str.length + 1 };\n } else {\n activeRange = { from: str.length + 1, to: str.length + 1 };\n }\n }\n\n onStateChange?.({\n activeRange: activeRange ? view.state.doc.sliceString(activeRange.from, activeRange.to) : undefined,\n });\n }\n },\n );\n};\n\n/**\n * Lezer parse result visitor.\n */\nconst visitTree = (node: SyntaxNode, callback: (node: SyntaxNode) => boolean): boolean => {\n if (callback(node)) {\n return true;\n }\n\n for (let child = node.firstChild; child !== null; child = child.nextSibling) {\n if (visitTree(child, callback)) {\n return true;\n }\n }\n\n return false;\n};\n\n/**\n * Pins the completion tooltip to the editing cell rather than to the cursor.\n *\n * CodeMirror anchors it at the completion's start offset — a few pixels in from the cell's edge, and\n * further in the longer the expression before the function name — overlapping the cell's lower\n * border. In a grid the cell is the meaningful anchor.\n *\n * Driven by a DOM observer rather than the plugin's `update`: CodeMirror creates and positions the\n * tooltip in its measure phase, which runs *after* the update, so an update-time correction either\n * finds no tooltip or is immediately overwritten. Which side it opens on is still CodeMirror's call,\n * so a tooltip near the bottom of the window still flips above the cell.\n */\nconst anchorCompletionTooltip = ViewPlugin.fromClass(\n class {\n private readonly _observer = new MutationObserver(() => this._pin());\n\n constructor(private readonly _view: EditorView) {\n this._observer.observe(_view.dom, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['style', 'class'],\n });\n }\n\n destroy(): void {\n this._observer.disconnect();\n }\n\n /** Idempotent: writing values it already holds would retrigger the observer. */\n private _pin(): void {\n const tooltip = this._view.dom.querySelector<HTMLElement>('.cm-tooltip-autocomplete');\n if (!tooltip) {\n return;\n }\n\n // The cell editor's own box, not `view.dom` — the editor sits inset within it.\n const cell = (this._view.dom.closest('.dx-grid__cell-editor') ?? this._view.dom).getBoundingClientRect();\n const left = cell.left;\n const top = tooltip.classList.contains('cm-tooltip-below')\n ? cell.bottom\n : cell.top - tooltip.getBoundingClientRect().height;\n if (\n Math.abs(Number.parseFloat(tooltip.style.left || '0') - left) < 0.5 &&\n Math.abs(Number.parseFloat(tooltip.style.top || '0') - top) < 0.5\n ) {\n return;\n }\n\n tooltip.style.left = `${left}px`;\n tooltip.style.top = `${top}px`;\n }\n },\n);\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nimport { inRange } from '@dxos/compute-hyperformula';\nimport { Doc } from '@dxos/echo-doc';\nimport { cellClassesForFieldType, parseValue } from '@dxos/react-ui-form';\nimport {\n type DxGridAxisMeta,\n type DxGridCellValue,\n type DxGridElement,\n type DxGridPlane,\n type DxGridPlaneCells,\n type DxGridPlaneRange,\n type GridContentProps,\n colToA1Notation,\n commentedClassName,\n rowToA1Notation,\n} from '@dxos/react-ui-grid';\nimport { mx } from '@dxos/ui-theme';\n\nimport { SheetRange, SheetUtil } from '#types';\n\nimport { type SheetModel } from '../../model/index.ts';\n\nconst createDxGridColumns = (model: SheetModel): DxGridAxisMeta => {\n return model.sheet.columns.reduce(\n (acc: DxGridAxisMeta, columnId, numericIndex) => {\n if (model.sheet.columnMeta[columnId] && model.sheet.columnMeta[columnId].size) {\n acc.grid[numericIndex] = {\n size: model.sheet.columnMeta[columnId].size,\n resizeable: true,\n };\n }\n return acc;\n },\n { grid: {} },\n );\n};\n\nconst createDxGridRows = (model: SheetModel): DxGridAxisMeta => {\n return model.sheet.rows.reduce(\n (acc: DxGridAxisMeta, rowId, numericIndex) => {\n if (model.sheet.rowMeta[rowId] && model.sheet.rowMeta[rowId].size) {\n acc.grid[numericIndex] = {\n size: model.sheet.rowMeta[rowId].size,\n resizeable: true,\n };\n }\n return acc;\n },\n { grid: {} },\n );\n};\n\nconst projectCellProps = (model: SheetModel, col: number, row: number): DxGridCellValue => {\n const address = { col, row };\n const rawValue = model.getValue(address);\n const ranges = model.sheet.ranges?.filter(({ range }) =>\n inRange(SheetUtil.rangeFromIndex(model.sheet, range), address),\n );\n const threadRefs = undefined;\n // TODO(wittjosiah): Update this to get threads via relations.\n // model.sheet.threads\n // ?.filter((thread) => {\n // const range = thread.target?.anchor && parseThreadAnchorAsCellRange(thread.target!.anchor);\n // return thread && range ? inRange(range, address) : false;\n // })\n // .map((thread) => Obj.getURI(thread!))\n // .join(' ');\n\n const description = model.getValueDescription(address);\n const type = description?.type;\n const format = description?.format;\n const classNames = ranges?.map(SheetRange.cellClassNameForRange).reverse();\n\n return {\n value: parseValue({ type, format, value: rawValue }),\n className: mx(cellClassesForFieldType({ type, format }), threadRefs && commentedClassName, classNames),\n dataRefs: threadRefs,\n };\n};\nconst gridCellGetter = (model: SheetModel) => {\n // TODO(thure): Actually use the cache.\n const cachedGridCells: DxGridPlaneCells = {};\n return (nextBounds: DxGridPlaneRange): DxGridPlaneCells => {\n [...Array(nextBounds.end.col - nextBounds.start.col)].forEach((_, c0) => {\n return [...Array(nextBounds.end.row - nextBounds.start.row)].forEach((_, r0) => {\n const col = nextBounds.start.col + c0;\n const row = nextBounds.start.row + r0;\n cachedGridCells[`${col},${row}`] = projectCellProps(model, col, row);\n });\n });\n return cachedGridCells;\n };\n};\n\nexport const rowLabelCell = (row: number) => ({\n value: rowToA1Notation(row),\n className: 'bg-axis-surface! text-axis-text text-end pe-1',\n resizeHandle: 'row',\n});\n\nexport const colLabelCell = (col: number) => ({\n value: colToA1Notation(col),\n className: 'bg-axis-surface! text-axis-text',\n resizeHandle: 'col',\n});\n\nconst cellGetter = (model: SheetModel) => {\n const getGridCells = gridCellGetter(model);\n return (nextBounds: DxGridPlaneRange, plane: DxGridPlane): DxGridPlaneCells => {\n switch (plane) {\n case 'grid':\n return getGridCells(nextBounds);\n case 'fixedStartStart': {\n return {\n '0,0': { className: 'bg-axis-surface!' },\n };\n }\n case 'frozenColsStart':\n return [...Array(nextBounds.end.row - nextBounds.start.row)].reduce((acc, _, r0) => {\n const r = nextBounds.start.row + r0;\n acc[`0,${r}`] = rowLabelCell(r);\n return acc;\n }, {});\n case 'frozenRowsStart':\n return [...Array(nextBounds.end.col - nextBounds.start.col)].reduce((acc, _, c0) => {\n const c = nextBounds.start.col + c0;\n acc[`${c},0`] = colLabelCell(c);\n return acc;\n }, {});\n default:\n return {};\n }\n };\n};\n\nexport const useSheetModelDxGridProps = (\n dxGrid: DxGridElement | null,\n model: SheetModel,\n): Pick<GridContentProps, 'columns' | 'rows'> => {\n const [columns, setColumns] = useState<DxGridAxisMeta>(createDxGridColumns(model));\n const [rows, setRows] = useState<DxGridAxisMeta>(createDxGridRows(model));\n\n useEffect(() => {\n const cellsAccessor = Doc.createAccessor(model.sheet, ['cells']);\n if (dxGrid) {\n dxGrid.getCells = cellGetter(model);\n }\n const handleCellsUpdate = () => {\n dxGrid?.requestUpdate('initialCells');\n };\n cellsAccessor.handle.addListener('change', handleCellsUpdate);\n const unsubscribe = model.graph.update.on(handleCellsUpdate);\n return () => {\n cellsAccessor.handle.removeListener('change', handleCellsUpdate);\n unsubscribe();\n };\n }, [model, dxGrid]);\n\n useEffect(() => {\n const columnMetaAccessor = Doc.createAccessor(model.sheet, ['columnMeta']);\n const rowMetaAccessor = Doc.createAccessor(model.sheet, ['rowMeta']);\n const handleColumnMetaUpdate = () => {\n setColumns(createDxGridColumns(model));\n };\n const handleRowMetaUpdate = () => {\n setRows(createDxGridRows(model));\n };\n columnMetaAccessor.handle.addListener('change', handleColumnMetaUpdate);\n rowMetaAccessor.handle.addListener('change', handleRowMetaUpdate);\n return () => {\n columnMetaAccessor.handle.removeListener('change', handleColumnMetaUpdate);\n rowMetaAccessor.handle.removeListener('change', handleRowMetaUpdate);\n };\n }, [model, dxGrid]);\n\n return { columns, rows };\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport React, {\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n type WheelEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport { type CellRange, rangeToA1Notation } from '@dxos/compute-hyperformula';\nimport { Obj } from '@dxos/echo';\nimport { defaultColSize, defaultRowSize } from '@dxos/lit-grid';\nimport { useAttention } from '@dxos/react-ui-attention';\nimport {\n type DxGridCellIndex,\n type DxGridElement,\n type DxGridPosition,\n type EditorBlurHandler,\n type EditorKeyHandler,\n Grid,\n GridCellEditor,\n type GridContentProps,\n closestCell,\n editorKeys,\n parseCellIndex,\n} from '@dxos/react-ui-grid';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\nimport * as Menu from '@dxos/react-ui/Menu';\nimport * as Util from '@dxos/react-ui/Util';\nimport * as VirtualAnchor from '@dxos/react-ui/VirtualAnchor';\n\nimport { meta } from '#meta';\nimport { SheetCapabilities, SheetOperation, SheetUtil } from '#types';\n\nimport { type RangeController, rangeExtension, sheetExtension } from '../../extensions/index.ts';\nimport { useSelectThreadOnCellFocus } from '../../integrations/index.ts';\nimport { useSheetContext } from '../SheetRoot/index.ts';\nimport { colLabelCell, rowLabelCell, useSheetModelDxGridProps } from './util.ts';\n\nconst inertPosition: DxGridPosition = { plane: 'grid', col: 0, row: 0 };\n\nconst initialCells = {\n grid: {},\n frozenColsStart: [...Array(64)].reduce((acc, _, i) => {\n acc[`0,${i}`] = rowLabelCell(i);\n return acc;\n }, {}),\n frozenRowsStart: [...Array(12)].reduce((acc, _, i) => {\n acc[`${i},0`] = colLabelCell(i);\n return acc;\n }, {}),\n};\n\nconst frozen = {\n frozenColsStart: 1,\n frozenRowsStart: 1,\n};\n\nconst sheetColDefault = {\n frozenColsStart: { size: 48, readonly: true, focusUnfurl: false },\n grid: { size: defaultColSize, resizeable: true },\n};\nconst sheetRowDefault = {\n frozenRowsStart: { size: defaultRowSize, readonly: true, focusUnfurl: false },\n grid: { size: defaultRowSize, resizeable: true },\n};\n\nexport type SheetContentProps = {};\n\nexport const SheetContent = Util.composable<HTMLDivElement, SheetContentProps>((props, forwardedRef) => {\n const { t } = UiHooks.useTranslation(meta.profile.key);\n const {\n id,\n attendableId,\n model,\n editing,\n setCursor,\n setRange,\n cursor,\n cursorFallbackRange,\n activeRefs,\n setActiveRefs,\n ignoreAttention,\n } = useSheetContext();\n\n // NOTE(thure): using `useState` instead of `useRef` works with refs provided by `@lit/react` and gives us\n // a reliable dependency for `useEffect` whereas `useLayoutEffect` does not guarantee the element will be defined.\n const [dxGrid, setDxGrid] = useState<DxGridElement | null>(null);\n const [extraplanarFocus, setExtraplanarFocus] = useState<DxGridPosition | null>(null);\n const { invokePromise } = Hooks.useOperationInvoker();\n const rangeController = useRef<RangeController>(null);\n const { hasAttention } = useAttention(id);\n\n const handleFocus = useCallback(\n (event: FocusEvent) => {\n if (!editing) {\n const cell = closestCell(event.target);\n if (cell) {\n if (cell.plane === 'grid') {\n setCursor({ col: cell.col, row: cell.row });\n setExtraplanarFocus(null);\n } else {\n setExtraplanarFocus(cell);\n }\n } else {\n setExtraplanarFocus(null);\n }\n }\n },\n [editing],\n );\n\n // TODO(burdon): Validate formula before closing: hf.validateFormula();\n const handleClose = useCallback<EditorKeyHandler>(\n (_value, event) => {\n if (event) {\n const { key, shift } = event;\n const axis = ['Enter', 'ArrowUp', 'ArrowDown'].includes(key)\n ? 'row'\n : ['Tab', 'ArrowLeft', 'ArrowRight'].includes(key)\n ? 'col'\n : undefined;\n const delta = key.startsWith('Arrow') ? (['ArrowUp', 'ArrowLeft'].includes(key) ? -1 : 1) : shift ? -1 : 1;\n dxGrid?.refocus(axis, delta);\n }\n },\n [model, editing, dxGrid],\n );\n\n const handleBlur = useCallback<EditorBlurHandler>(\n (value) => {\n if (value !== undefined) {\n model.setValue(parseCellIndex(editing!.index), value);\n }\n },\n [model, editing],\n );\n\n const handleAxisResize = useCallback<NonNullable<GridContentProps['onAxisResize']>>(\n ({ axis, size, index: numericIndex }) => {\n Obj.update(model.sheet, (sheet) => {\n if (axis === 'row') {\n const rowId = sheet.rows[parseInt(numericIndex)];\n sheet.rowMeta[rowId] ??= {};\n sheet.rowMeta[rowId].size = size;\n } else {\n const columnId = sheet.columns[parseInt(numericIndex)];\n sheet.columnMeta[columnId] ??= {};\n sheet.columnMeta[columnId].size = size;\n }\n });\n },\n [model],\n );\n\n const handleSelect = useCallback<NonNullable<GridContentProps['onSelect']>>(\n ({ minCol, maxCol, minRow, maxRow }) => {\n const range: CellRange = { from: { col: minCol, row: minRow } };\n if (minCol !== maxCol || minRow !== maxRow) {\n range.to = { col: maxCol, row: maxRow };\n }\n if (editing) {\n // Update range selection in formula.\n rangeController.current?.setRange(rangeToA1Notation(range));\n } else {\n // Setting range while editing causes focus to move to null, avoid doing so.\n setRange(range.to ? range : undefined);\n }\n },\n [editing],\n );\n\n const handleWheel = useCallback(\n (event: WheelEvent) => {\n if (!ignoreAttention && !hasAttention) {\n event.stopPropagation();\n }\n },\n [hasAttention, ignoreAttention],\n );\n\n const selectEntireAxis = useCallback(\n (pos: DxGridPosition) => {\n switch (pos.plane) {\n case 'frozenRowsStart':\n return dxGrid?.setSelection({\n start: { col: pos.col, row: 0, plane: 'grid' },\n end: {\n col: pos.col,\n row: model.sheet.rows.length - 1,\n plane: 'grid',\n },\n });\n case 'frozenColsStart':\n return dxGrid?.setSelection({\n start: { row: pos.row, col: 0, plane: 'grid' },\n end: {\n row: pos.row,\n col: model.sheet.columns.length - 1,\n plane: 'grid',\n },\n });\n }\n },\n [dxGrid, model.sheet],\n );\n\n const handleClick = useCallback(\n (event: MouseEvent) => {\n const cell = closestCell(event.target);\n if (cell) {\n selectEntireAxis(cell);\n }\n },\n [selectEntireAxis],\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n switch (event.key) {\n case 'Backspace':\n case 'Delete':\n event.preventDefault();\n return cursorFallbackRange && model.clear(cursorFallbackRange);\n case 'Enter':\n case 'Space':\n if (dxGrid && extraplanarFocus) {\n switch (extraplanarFocus.plane) {\n case 'frozenRowsStart':\n case 'frozenColsStart':\n event.preventDefault();\n return selectEntireAxis(extraplanarFocus);\n }\n }\n }\n if (event.metaKey || event.ctrlKey) {\n switch (event.key) {\n case 'x':\n case 'X':\n event.preventDefault();\n return cursorFallbackRange && model.cut(cursorFallbackRange);\n case 'c':\n case 'C':\n event.preventDefault();\n return cursorFallbackRange && model.copy(cursorFallbackRange);\n case 'v':\n case 'V':\n event.preventDefault();\n return cursor && model.paste(cursor);\n case 'z':\n event.preventDefault();\n return event.shiftKey ? model.redo() : model.undo();\n case 'Z':\n case 'y':\n event.preventDefault();\n return model.redo();\n }\n }\n },\n [cursorFallbackRange, model, cursor, extraplanarFocus, selectEntireAxis],\n );\n\n const contextMenuAnchorRef = useRef<HTMLButtonElement | null>(null);\n const [contextMenuOpen, setContextMenuOpen] = useState<DxGridPosition | null>(null);\n const contextMenuAxis = contextMenuOpen?.plane.startsWith('frozenRows') ? 'col' : 'row';\n\n const handleContextMenu = useCallback((event: MouseEvent) => {\n const cell = closestCell(event.target);\n if (cell && cell.plane.startsWith('frozen')) {\n event.preventDefault();\n contextMenuAnchorRef.current = event.target as HTMLButtonElement;\n setContextMenuOpen(cell);\n }\n }, []);\n\n const handleAxisMenuAction = useCallback(\n (operation: 'insert-before' | 'insert-after' | 'drop') => {\n switch (operation) {\n case 'insert-before':\n case 'insert-after':\n return invokePromise(SheetOperation.InsertAxis, {\n model,\n axis: contextMenuAxis,\n index: contextMenuOpen![contextMenuAxis] + (operation === 'insert-before' ? 0 : 1),\n });\n case 'drop':\n return invokePromise(SheetOperation.DropAxis, {\n model,\n axis: contextMenuAxis,\n axisIndex: model.sheet[contextMenuAxis === 'row' ? 'rows' : 'columns'][contextMenuOpen![contextMenuAxis]],\n });\n }\n },\n [contextMenuAxis, contextMenuOpen, model, invokePromise],\n );\n\n const { columns, rows } = useSheetModelDxGridProps(dxGrid, model);\n\n const extensions = useMemo(\n () => [\n editorKeys({\n onClose: handleClose,\n ...(editing?.initialContent && { onNav: handleClose }),\n }),\n sheetExtension({ functions: model.graph.getFunctions() }),\n rangeExtension({\n onInit: (fn) => (rangeController.current = fn),\n onStateChange: (state) => {\n if (dxGrid) {\n // This can’t dispatch a setState in this component, otherwise the cell editor remounts and loses focus.\n dxGrid.mode = typeof state.activeRange === 'undefined' ? 'edit' : 'edit-select';\n }\n },\n }),\n ],\n [model, handleClose, editing],\n );\n\n const getCellContent = useCallback(\n (index: DxGridCellIndex) => {\n return model.getCellText(parseCellIndex(index));\n },\n [model],\n );\n\n const [gridInstances] = Hooks.useCapabilities(SheetCapabilities.GridInstances);\n useEffect(() => {\n if (dxGrid && gridInstances) {\n gridInstances.register(attendableId, dxGrid, setActiveRefs);\n return () => gridInstances.unregister(attendableId);\n }\n }, [dxGrid, gridInstances, attendableId, setActiveRefs]);\n\n useSelectThreadOnCellFocus();\n\n return (\n <div ref={forwardedRef} {...Util.composableProps(props, { classNames: 'relative min-h-0' })}>\n <GridCellEditor getCellContent={getCellContent} extensions={extensions} onBlur={handleBlur} />\n <Grid.Content\n className='[--dx-grid-base:var(--base-surface)] [&_.dx-grid]:absolute [&_.dx-grid]:inset-0'\n initialCells={initialCells}\n limitColumns={SheetUtil.DEFAULT_COLS}\n limitRows={SheetUtil.DEFAULT_ROWS}\n columns={columns}\n rows={rows}\n columnDefault={sheetColDefault}\n rowDefault={sheetRowDefault}\n activeRefs={activeRefs}\n frozen={frozen}\n overscroll='trap'\n onAxisResize={handleAxisResize}\n onSelect={handleSelect}\n onFocus={handleFocus}\n onWheelCapture={handleWheel}\n onKeyDown={handleKeyDown}\n onContextMenu={handleContextMenu}\n onClick={handleClick}\n ref={setDxGrid}\n />\n <Menu.Root\n open={!!contextMenuOpen}\n onOpenChange={({ open: nextOpen }) => setContextMenuOpen(nextOpen ? inertPosition : null)}\n positioning={{\n ...VirtualAnchor.virtualAnchor(contextMenuAnchorRef),\n placement: contextMenuAxis === 'col' ? 'bottom' : 'right',\n gutter: 4,\n overflowPadding: 8,\n }}\n >\n <Menu.Content>\n <Menu.Item\n item={{\n value: 'insert-before',\n label: t(`add-${contextMenuAxis}-before.label`),\n icon: contextMenuAxis === 'col' ? 'ph--columns-plus-left--regular' : 'ph--rows-plus-top--regular',\n }}\n onClick={() => handleAxisMenuAction('insert-before')}\n data-testid={`grid.${contextMenuAxis}.insert-before`}\n />\n <Menu.Item\n item={{\n value: 'insert-after',\n label: t(`add-${contextMenuAxis}-after.label`),\n icon: contextMenuAxis === 'col' ? 'ph--columns-plus-right--regular' : 'ph--rows-plus-bottom--regular',\n }}\n onClick={() => handleAxisMenuAction('insert-after')}\n data-testid={`grid.${contextMenuAxis}.insert-after`}\n />\n <Menu.Item\n item={{ value: 'drop', label: t(`delete-${contextMenuAxis}.label`), icon: 'ph--backspace--regular' }}\n onClick={() => handleAxisMenuAction('drop')}\n data-testid={`grid.${contextMenuAxis}.drop`}\n />\n </Menu.Content>\n </Menu.Root>\n </div>\n );\n});\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport React from 'react';\n\nimport { addressToA1Notation, isFormula, rangeToA1Notation } from '@dxos/compute-hyperformula';\nimport * as Icon from '@dxos/react-ui/Icon';\nimport * as Util from '@dxos/react-ui/Util';\nimport { mx } from '@dxos/ui-theme';\n\nimport { SheetUtil } from '#types';\n\nimport { useSheetContext } from '../SheetRoot/index.ts';\n\nexport type SheetStatusbarProps = {};\n\nexport const SheetStatusbar = Util.composable<HTMLDivElement, SheetStatusbarProps>((props, forwardedRef) => {\n const { className, ...rest } = Util.composableProps(props);\n const { model, cursor, range } = useSheetContext();\n\n let value;\n let formula = false;\n if (cursor) {\n value = model.getCellValue(cursor);\n if (isFormula(value)) {\n value = model.graph.mapFunctionBindingFromId(SheetUtil.mapFormulaIndicesToRefs(model.sheet, value));\n formula = true;\n } else if (value != null) {\n value = String(value);\n }\n }\n\n return (\n <div\n ref={forwardedRef}\n {...rest}\n className={mx(\n 'flex shrink-0 justify-between items-center px-4 py-1 text-sm dx-toolbar-surface border-y !border-separator-subtle',\n className,\n )}\n >\n <div className='flex gap-4 items-center'>\n <div className='flex w-16 items-center font-mono'>\n {(range && rangeToA1Notation(range)) || (cursor && addressToA1Notation(cursor))}\n </div>\n <div className='flex gap-2 items-center'>\n <Icon.Icon icon='ph--function--regular' classNames={['text-green-text', formula ? 'visible' : 'invisible']} />\n <span className='font-mono'>{value}</span>\n </div>\n </div>\n </div>\n );\n});\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { RegistryContext } from '@effect/atom-react/RegistryContext';\nimport type * as Registry from 'effect/reactivity/AtomRegistry';\nimport { useContext, useEffect } from 'react';\n\nimport { type CompleteCellRange, inRange } from '@dxos/compute-hyperformula';\nimport { Obj } from '@dxos/echo';\nimport {\n type ActionGraphProps,\n type ToolbarMenuActionGroupProperties,\n createMenuAction,\n createMenuItemGroup,\n} from '@dxos/react-ui-menu';\n\nimport { meta } from '#meta';\nimport { SheetRange, SheetUtil } from '#types';\n\nimport { type SheetModel } from '../../model/index.ts';\nimport { useSheetContext } from '../SheetRoot/index.ts';\nimport { type ToolbarState, type ToolbarStateAtom } from './useToolbarState.ts';\n\nexport type AlignAction = { key: SheetRange.AlignKey; value: SheetRange.AlignValue };\n\nexport type AlignState = { [SheetRange.alignKey]: SheetRange.AlignValue | undefined };\n\nconst aligns: Record<SheetRange.AlignValue, string> = {\n start: 'ph--text-align-left--regular',\n center: 'ph--text-align-center--regular',\n end: 'ph--text-align-right--regular',\n};\n\nexport const useAlignState = (stateAtom: ToolbarStateAtom) => {\n const registry = useContext(RegistryContext);\n const { cursor, model } = useSheetContext();\n useEffect(() => {\n // TODO(thure): Can this O(n) call be memoized?\n const alignValue = (\n cursor\n ? model.sheet.ranges?.findLast(\n ({ range, key }) =>\n key === SheetRange.alignKey && inRange(SheetUtil.rangeFromIndex(model.sheet, range), cursor),\n )?.value\n : undefined\n ) as SheetRange.AlignValue | undefined;\n const prev = registry.get(stateAtom);\n registry.set(stateAtom, { ...prev, [SheetRange.alignKey]: alignValue });\n }, [cursor, model.sheet, registry, stateAtom]);\n};\n\nconst createAlignGroupAction = (value?: SheetRange.AlignValue) =>\n createMenuItemGroup('align', {\n label: ['align.label', { ns: meta.profile.key }],\n variant: 'toggleGroup',\n selectCardinality: 'single',\n value: `${SheetRange.alignKey}--${value}`,\n } as ToolbarMenuActionGroupProperties);\n\ntype AlignActionsContext = {\n model: SheetModel;\n state: ToolbarState;\n stateAtom: ToolbarStateAtom;\n registry: Registry.AtomRegistry;\n cursorFallbackRange?: CompleteCellRange;\n};\n\nconst createAlignActions = ({ model, state, stateAtom, registry, cursorFallbackRange }: AlignActionsContext) =>\n Object.entries(aligns).map(([alignValue, icon]) => {\n return createMenuAction<AlignAction>(\n `${SheetRange.alignKey}--${alignValue}`,\n () => {\n if (!cursorFallbackRange) {\n return;\n }\n const index =\n model.sheet.ranges?.findIndex(\n (range) =>\n range.key === SheetRange.alignKey &&\n inRange(SheetUtil.rangeFromIndex(model.sheet, range.range), cursorFallbackRange.from),\n ) ?? -1;\n const nextRangeEntity = {\n range: SheetUtil.rangeToIndex(model.sheet, cursorFallbackRange),\n key: SheetRange.alignKey,\n value: alignValue as SheetRange.AlignValue,\n };\n const currentState = registry.get(stateAtom);\n if (index < 0) {\n Obj.update(model.sheet, (obj) => {\n obj.ranges?.push(nextRangeEntity);\n });\n registry.set(stateAtom, { ...currentState, [SheetRange.alignKey]: nextRangeEntity.value });\n } else if (model.sheet.ranges![index].value === nextRangeEntity.value) {\n Obj.update(model.sheet, (obj) => {\n obj.ranges?.splice(index, 1);\n });\n registry.set(stateAtom, { ...currentState, [SheetRange.alignKey]: undefined });\n } else {\n Obj.update(model.sheet, (obj) => {\n obj.ranges?.splice(index, 1, nextRangeEntity);\n });\n registry.set(stateAtom, { ...currentState, [SheetRange.alignKey]: nextRangeEntity.value });\n }\n },\n {\n key: SheetRange.alignKey,\n value: alignValue as SheetRange.AlignValue,\n checked: state[SheetRange.alignKey] === alignValue,\n label: [`range-value.${alignValue}.label`, { ns: meta.profile.key }],\n icon,\n testId: `grid.toolbar.${SheetRange.alignKey}.${alignValue}`,\n },\n );\n });\n\nexport const createAlign = (context: AlignActionsContext): ActionGraphProps => {\n const alignGroup = createAlignGroupAction(context.state[SheetRange.alignKey]);\n const alignActions = createAlignActions(context);\n return {\n nodes: [alignGroup, ...alignActions],\n edges: [\n { source: 'root', target: 'align', relation: 'child' },\n ...alignActions.map(({ id }) => ({ source: alignGroup.id, target: id, relation: 'child' })),\n ],\n };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { RegistryContext } from '@effect/atom-react/RegistryContext';\nimport type * as Registry from 'effect/reactivity/AtomRegistry';\nimport { useContext, useEffect } from 'react';\n\nimport { type CompleteCellRange, inRange } from '@dxos/compute-hyperformula';\nimport { Obj } from '@dxos/echo';\nimport {\n type ActionGraphProps,\n type ToolbarMenuActionGroupProperties,\n createMenuAction,\n createMenuItemGroup,\n} from '@dxos/react-ui-menu';\n\nimport { meta } from '#meta';\nimport { SheetRange, SheetUtil } from '#types';\n\nimport { type SheetModel } from '../../model/index.ts';\nimport { useSheetContext } from '../SheetRoot/index.ts';\nimport { type ToolbarState, type ToolbarStateAtom } from './useToolbarState.ts';\n\nexport type StyleState = Partial<Record<SheetRange.StyleValue, boolean>>;\n\nexport type StyleAction = { key: SheetRange.StyleKey; value: SheetRange.StyleValue };\n\nconst styles: Record<SheetRange.StyleValue, string> = {\n highlight: 'ph--highlighter--regular',\n softwrap: 'ph--paragraph--regular',\n};\n\nexport const useStyleState = (stateAtom: ToolbarStateAtom) => {\n const registry = useContext(RegistryContext);\n const { cursorFallbackRange, model } = useSheetContext();\n\n useEffect(() => {\n let highlight = false;\n let softwrap = false;\n if (cursorFallbackRange && model.sheet.ranges) {\n model.sheet.ranges\n .filter(\n ({ range, key }) =>\n key === 'style' && inRange(SheetUtil.rangeFromIndex(model.sheet, range), cursorFallbackRange.from),\n )\n .forEach(({ value }) => {\n if (value === 'highlight') {\n highlight = true;\n }\n if (value === 'softwrap') {\n softwrap = true;\n }\n });\n }\n const prev = registry.get(stateAtom);\n registry.set(stateAtom, { ...prev, highlight, softwrap });\n }, [cursorFallbackRange, model.sheet, registry, stateAtom]);\n};\n\nconst createStyleGroup = (state: StyleState) => {\n return createMenuItemGroup('style', {\n variant: 'toggleGroup',\n selectCardinality: 'multiple',\n value: Object.keys(styles)\n .filter((key) => !!state[key as SheetRange.StyleValue])\n .map((styleValue) => `style--${styleValue}`),\n } as ToolbarMenuActionGroupProperties);\n};\n\ntype StyleActionsContext = {\n model: SheetModel;\n state: ToolbarState;\n stateAtom: ToolbarStateAtom;\n registry: Registry.AtomRegistry;\n cursorFallbackRange?: CompleteCellRange;\n};\n\nconst createStyleActions = ({ model, state, stateAtom, registry, cursorFallbackRange }: StyleActionsContext) =>\n Object.entries(styles).map(([styleValue, icon]) => {\n return createMenuAction<StyleAction>(\n `style--${styleValue}`,\n () => {\n if (!cursorFallbackRange) {\n return;\n }\n const index =\n model.sheet.ranges?.findIndex(\n (range) =>\n range.key === 'style' &&\n inRange(SheetUtil.rangeFromIndex(model.sheet, range.range), cursorFallbackRange.from),\n ) ?? -1;\n const nextRangeEntity = {\n range: SheetUtil.rangeToIndex(model.sheet, cursorFallbackRange),\n key: 'style',\n value: styleValue as SheetRange.StyleValue,\n };\n const currentState = registry.get(stateAtom);\n if (\n model.sheet.ranges\n .filter(\n ({ range, key: rangeKey }) =>\n rangeKey === 'style' && inRange(SheetUtil.rangeFromIndex(model.sheet, range), cursorFallbackRange.from),\n )\n .some(({ value: rangeValue }) => rangeValue === styleValue)\n ) {\n // this value should be unset\n if (index >= 0) {\n Obj.update(model.sheet, (obj) => {\n obj.ranges?.splice(index, 1);\n });\n }\n registry.set(stateAtom, { ...currentState, [nextRangeEntity.value]: false });\n } else {\n Obj.update(model.sheet, (obj) => {\n obj.ranges?.push(nextRangeEntity);\n });\n registry.set(stateAtom, { ...currentState, [nextRangeEntity.value]: true });\n }\n },\n {\n key: 'style',\n value: styleValue as SheetRange.StyleValue,\n icon,\n label: [`range-value.${styleValue}.label`, { ns: meta.profile.key }],\n checked: !!state[styleValue as SheetRange.StyleValue],\n },\n );\n });\n\nexport const createStyle = (context: StyleActionsContext): ActionGraphProps => {\n const styleGroupAction = createStyleGroup(context.state);\n const styleActions = createStyleActions(context);\n return {\n nodes: [styleGroupAction, ...styleActions],\n edges: [\n { source: 'root', target: 'style', relation: 'child' },\n ...styleActions.map(({ id }) => ({ source: styleGroupAction.id, target: id, relation: 'child' })),\n ],\n };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Atom from 'effect/reactivity/Atom';\nimport { useMemo } from 'react';\n\nimport { type AlignState } from './align.ts';\nimport { type StyleState } from './style.ts';\n\nexport type ToolbarState = Partial<StyleState & AlignState>;\nexport type ToolbarStateAtom = Atom.Writable<ToolbarState>;\n\n/**\n * Creates a reactive toolbar state Atom.\n */\nexport const useToolbarState = (initialState: ToolbarState = {}): ToolbarStateAtom => {\n return useMemo(() => Atom.make<ToolbarState>(initialState).pipe(Atom.keepAlive), []);\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { RegistryContext } from '@effect/atom-react/RegistryContext';\nimport * as Atom from 'effect/reactivity/Atom';\nimport type * as Registry from 'effect/reactivity/AtomRegistry';\nimport React, { useContext, useMemo } from 'react';\n\nimport * as Hooks from '@dxos/app-toolkit/Hooks';\nimport { type CompleteCellRange } from '@dxos/compute-hyperformula';\nimport {\n type ActionGraphProps,\n ActionToolbar,\n createGapSeparator,\n graphActions,\n isToolbarAction,\n useMenuActions,\n} from '@dxos/react-ui-menu';\nimport * as Util from '@dxos/react-ui/Util';\n\nimport { type SheetModel } from '../../model/index.ts';\nimport { useSheetContext } from '../SheetRoot/index.ts';\nimport { createAlign, useAlignState } from './align.ts';\nimport { createStyle, useStyleState } from './style.ts';\nimport { type ToolbarStateAtom, useToolbarState } from './useToolbarState.ts';\n\ntype ToolbarActionsContext = {\n model: SheetModel;\n stateAtom: ToolbarStateAtom;\n registry: Registry.AtomRegistry;\n cursorFallbackRange?: CompleteCellRange;\n customActions?: Atom.Atom<ActionGraphProps>;\n};\n\nconst createToolbarActions = ({\n model,\n stateAtom,\n registry,\n cursorFallbackRange,\n customActions,\n}: ToolbarActionsContext): Atom.Atom<ActionGraphProps> => {\n return Atom.make((get) => {\n const state = get(stateAtom);\n const context = { model, state, stateAtom, registry, cursorFallbackRange };\n const align = createAlign(context);\n const style = createStyle(context);\n const gap = createGapSeparator();\n\n const graph: ActionGraphProps = {\n nodes: [...align.nodes, ...style.nodes, ...gap.nodes],\n edges: [...align.edges, ...style.edges, ...gap.edges],\n };\n\n if (customActions) {\n const custom = get(customActions);\n graph.nodes.push(...custom.nodes);\n graph.edges.push(...custom.edges);\n }\n\n return graph;\n });\n};\n\nexport type SheetToolbarProps = {};\n\nexport const SheetToolbar = Util.composable<HTMLDivElement, SheetToolbarProps>((props, forwardedRef) => {\n const { attendableId, model, cursorFallbackRange } = useSheetContext();\n const stateAtom = useToolbarState({});\n const registry = useContext(RegistryContext);\n useAlignState(stateAtom);\n useStyleState(stateAtom);\n\n const { graph } = Hooks.useAppGraph();\n const customActions = useMemo(() => {\n return Atom.make((get) => graphActions(graph, get, attendableId, { filter: isToolbarAction }));\n }, [graph, attendableId]);\n\n const actionsCreator = useMemo(\n () => createToolbarActions({ model, stateAtom, registry, cursorFallbackRange, customActions }),\n [model, stateAtom, registry, cursorFallbackRange, customActions],\n );\n const menuActions = useMenuActions(actionsCreator);\n\n return (\n <ActionToolbar {...menuActions} attendableId={attendableId} {...Util.composableProps(props)} ref={forwardedRef} />\n );\n});\n\nSheetToolbar.displayName = 'SheetToolbar';\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { SheetContent } from '../SheetContent/index.ts';\nimport { SheetRoot } from '../SheetRoot/index.ts';\nimport { SheetStatusbar } from '../SheetStatusbar/index.ts';\nimport { SheetToolbar } from '../SheetToolbar/index.ts';\n\nexport { type SheetContextValue, type SheetRootProps } from '../SheetRoot/index.ts';\nexport { type SheetContentProps } from '../SheetContent/index.ts';\nexport { type SheetToolbarProps } from '../SheetToolbar/index.ts';\nexport { type SheetStatusbarProps } from '../SheetStatusbar/index.ts';\n\nexport const Sheet = {\n Root: SheetRoot,\n Toolbar: SheetToolbar,\n Content: SheetContent,\n Statusbar: SheetStatusbar,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"components.mjs","names":[],"sources":["../../src/components/ComputeGraph/ComputeGraphContext.ts","../../src/components/ComputeGraph/ComputeGraphContextProvider.tsx","../../src/components/SheetRoot/SheetContext.ts","../../src/model/sheet-model.ts","../../src/model/useSheetModel.ts","../../src/components/SheetRoot/SheetRoot.tsx","../../src/extensions/editor/sheet-extension.ts","../../src/components/SheetContent/util.ts","../../src/components/SheetContent/SheetContent.tsx","../../src/components/SheetStatusbar/SheetStatusbar.tsx","../../src/components/SheetToolbar/align.ts","../../src/components/SheetToolbar/style.ts","../../src/components/SheetToolbar/useToolbarState.ts","../../src/components/SheetToolbar/SheetToolbar.tsx","../../src/components/Sheet/Sheet.tsx"],"sourcesContent":["//\n// Copyright 2024 DXOS.org\n//\n\nimport { createContext, useContext } from 'react';\n\nimport { type ComputeGraph, type ComputeGraphRegistry } from '@dxos/compute-hyperformula';\nimport { raise } from '@dxos/debug';\nimport { type Space } from '@dxos/react-client/echo';\nimport { useAsyncState } from '@dxos/react-hooks';\n\n// Kept out of `ComputeGraphContextProvider.tsx`: react-refresh only fast-refreshes a module whose exports are all\n// components, so a context and its hook exported beside them force a full page reload on every edit.\n\nexport type ComputeGraphContextType = {\n registry: ComputeGraphRegistry;\n};\n\n/**\n * The compute graph context manages a ComputeGraph for each space.\n */\nexport const ComputeGraphContext = createContext<ComputeGraphContextType | undefined>(undefined);\n\nexport const useComputeGraph = (space?: Space): ComputeGraph | undefined => {\n const { registry } = useContext(ComputeGraphContext) ?? raise(new Error('Missing ComputeGraphContext'));\n const [graph] = useAsyncState(async () => {\n if (space) {\n const graph = registry.getOrCreateGraph(space);\n await graph.open();\n return graph;\n }\n }, [space, registry]);\n\n return graph;\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { type PropsWithChildren } from 'react';\n\nimport { ComputeGraphContext, type ComputeGraphContextType } from './ComputeGraphContext.ts';\n\nexport const ComputeGraphContextProvider = ({ registry, children }: PropsWithChildren<ComputeGraphContextType>) => {\n return <ComputeGraphContext.Provider value={{ registry }}>{children}</ComputeGraphContext.Provider>;\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { createContext, useContext } from 'react';\n\nimport { raise } from '@dxos/debug';\n\nimport { type SheetContextValue } from './SheetRoot.tsx';\n\n// Kept out of `SheetRoot.tsx`: react-refresh only fast-refreshes a module whose exports are all\n// components, so a context and its hook exported beside them force a full page reload on every edit.\n\n// TODO(burdon): Use radix context.\nexport const SheetContext = createContext<SheetContextValue | undefined>(undefined);\n\nexport const useSheetContext = (): SheetContextValue => {\n return useContext(SheetContext) ?? raise(new Error('Missing SheetContext'));\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { Event } from '@dxos/async';\nimport {\n type CellAddress,\n type CellRange,\n type CellScalarValue,\n type ComputeGraph,\n type ComputeNode,\n type ComputeNodeEvent,\n DetailedCellError,\n ExportedCellChange,\n type SimpleCellAddress,\n type SimpleCellRange,\n type SimpleDate,\n type SimpleDateTime,\n addressFromA1Notation,\n addressToA1Notation,\n createSheetName,\n isFormula,\n} from '@dxos/compute-hyperformula';\nimport { Resource } from '@dxos/context';\nimport { Obj } from '@dxos/echo';\nimport { Format, TypeEnum } from '@dxos/echo/Format';\nimport { assertArgument, invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { Sheet, SheetCapabilities, SheetUtil } from '#types';\n\n// TODO(burdon): Move to compute.\n// Map sheet types to system types.\n// https://hyperformula.handsontable.com/guide/types-of-values.html\n// - https://github.com/handsontable/hyperformula/blob/master/src/Cell.ts (CellValueType)\n// - https://github.com/handsontable/hyperformula/blob/master/src/interpreter/InterpreterValue.ts (NumberType)\nconst typeMap: Record<string, { type: TypeEnum; format?: Format.TypeFormat }> = {\n BOOLEAN: { type: TypeEnum.Boolean },\n NUMBER_RAW: { type: TypeEnum.Number },\n NUMBER_PERCENT: { type: TypeEnum.Number, format: Format.TypeFormat.Percent },\n NUMBER_CURRENCY: { type: TypeEnum.Number, format: Format.TypeFormat.Currency },\n NUMBER_DATETIME: { type: TypeEnum.String, format: Format.TypeFormat.DateTime },\n NUMBER_DATE: { type: TypeEnum.String, format: Format.TypeFormat.Date },\n NUMBER_TIME: { type: TypeEnum.String, format: Format.TypeFormat.Time },\n};\n\nconst getTopLeft = (range: CellRange): CellAddress => {\n const to = range.to ?? range.from;\n return { row: Math.min(range.from.row, to.row), col: Math.min(range.from.col, to.col) };\n};\n\nconst toSimpleCellAddress = (sheet: number, cell: CellAddress): SimpleCellAddress => ({\n sheet,\n row: cell.row,\n col: cell.col,\n});\n\nconst toModelRange = (sheet: number, range: CellRange): SimpleCellRange => ({\n start: toSimpleCellAddress(sheet, range.from),\n end: toSimpleCellAddress(sheet, range.to ?? range.from),\n});\n\nexport type SheetModelOptions = {\n readonly?: boolean;\n};\n\n/**\n * Spreadsheet data model.\n *\n * [ComputeGraphContext] > [SheetContext]:[SheetModel] > [Sheet.Root]\n */\n// TODO(burdon): Factor out commonality with ComputeNode. Factor out HF.\nexport class SheetModel extends Resource {\n public readonly id = `model-${PublicKey.random().truncate()}`;\n\n // Wraps compute node.\n public readonly update = new Event<ComputeNodeEvent>();\n\n private _node?: ComputeNode;\n\n constructor(\n private readonly _graph: ComputeGraph,\n private readonly _sheet: Sheet.Sheet,\n private readonly _options: SheetModelOptions = {},\n ) {\n super();\n }\n\n get graph() {\n return this._graph;\n }\n\n get sheet() {\n return this._sheet;\n }\n\n get readonly() {\n return this._options.readonly;\n }\n\n get bounds() {\n return {\n rows: this._sheet.rows.length,\n columns: this._sheet.columns.length,\n };\n }\n\n /**\n * Initialize sheet and engine.\n */\n protected override async _open(): Promise<void> {\n log('SheetUtil.initialize', { id: this.id });\n Obj.update(this._sheet, (obj) => {\n SheetUtil.initialize(obj);\n });\n\n this._graph.update.on((event) => {\n if (event.type === 'functionsUpdated') {\n this.reset();\n }\n });\n\n // TODO(burdon): SheetModel should extend ComputeNode and be constructed via the graph.\n this._node = this._graph.getOrCreateNode(\n createSheetName({ type: Obj.getTypename(this._sheet)!, id: this._sheet.id }),\n );\n await this._node.open();\n\n // Listen for model updates (e.g., async calculations).\n const unsubscribe = this._node.update.on((event) => this.update.emit(event));\n this._ctx.onDispose(unsubscribe);\n\n this.reset();\n }\n\n /**\n * Update engine.\n * NOTE: This resets the undo history.\n * @deprecated\n */\n reset(): void {\n invariant(this._node);\n this._node.graph.hf.clearSheet(this._node.sheetId);\n Object.entries(this._sheet.cells).forEach(([key, { value }]) => {\n invariant(this._node);\n const { col, row } = SheetUtil.addressFromIndex(this._sheet, key);\n if (isFormula(value)) {\n const binding = this._graph.mapFunctionBindingFromId(SheetUtil.mapFormulaIndicesToRefs(this._sheet, value));\n if (binding) {\n value = this._graph.mapFormulaToNative(binding);\n } else {\n // If binding is not found, render the cell as empty.\n // This prevents the cell from momentarily rendering an error while the binding is being loaded.\n value = '';\n }\n }\n\n this._node.graph.hf.setCellContents({ sheet: this._node.sheetId, row, col }, value);\n });\n }\n\n /**\n * Recalculate formulas.\n * NOTE: This resets the undo history.\n * https://hyperformula.handsontable.com/guide/volatile-functions.html#volatile-actions\n * @deprecated\n */\n // TODO(burdon): Remove.\n recalculate(): void {\n this._node?.graph.hf.rebuildAndRecalculate();\n }\n\n insertRows(i: number, n = 1): string[] {\n let idx: string[] = [];\n Obj.update(this._sheet, (obj) => {\n idx = SheetUtil.insertIndices(obj.rows, i, n, SheetUtil.MAX_ROWS);\n });\n this.reset();\n return idx;\n }\n\n insertColumns(i: number, n = 1): string[] {\n let idx: string[] = [];\n Obj.update(this._sheet, (obj) => {\n idx = SheetUtil.insertIndices(obj.columns, i, n, SheetUtil.MAX_COLS);\n });\n this.reset();\n return idx;\n }\n\n dropRow(rowIndex: string): SheetCapabilities.SheetAction.RestoreAxis {\n const range = {\n from: SheetUtil.addressFromIndex(this._sheet, `${this._sheet.columns[0]}@${rowIndex}`),\n to: SheetUtil.addressFromIndex(this._sheet, `${this._sheet.columns[this._sheet.columns.length - 1]}@${rowIndex}`),\n };\n const values = this.getCellValues(range).flat();\n const index = this._sheet.rows.indexOf(rowIndex);\n this.clear(range);\n Obj.update(this._sheet, (obj) => {\n obj.rows.splice(index, 1);\n delete obj.rowMeta[rowIndex];\n });\n this.reset();\n return { axis: 'row', index, axisIndex: rowIndex, axisMeta: this._sheet.rowMeta[rowIndex], values };\n }\n\n dropColumn(colIndex: string): SheetCapabilities.SheetAction.RestoreAxis {\n const range = {\n from: SheetUtil.addressFromIndex(this._sheet, `${colIndex}@${this._sheet.rows[0]}`),\n to: SheetUtil.addressFromIndex(this._sheet, `${colIndex}@${this._sheet.rows[this._sheet.rows.length - 1]}`),\n };\n const values = this.getCellValues(range).flat();\n const index = this._sheet.columns.indexOf(colIndex);\n this.clear(range);\n Obj.update(this._sheet, (obj) => {\n obj.columns.splice(index, 1);\n delete obj.columnMeta[colIndex];\n });\n this.reset();\n return { axis: 'col', index, axisIndex: colIndex, axisMeta: this._sheet.rowMeta[colIndex], values };\n }\n\n restoreRow({ index, axisIndex, axisMeta, values }: SheetCapabilities.SheetAction.RestoreAxis): void {\n Obj.update(this._sheet, (obj) => {\n obj.rows.splice(index, 0, axisIndex);\n values.forEach((value, col) => {\n if (value) {\n obj.cells[`${obj.columns[col]}@${axisIndex}`] = { value };\n }\n });\n\n if (axisMeta) {\n obj.rowMeta[axisIndex] = axisMeta;\n }\n });\n this.reset();\n }\n\n restoreColumn({ index, axisIndex, axisMeta, values }: SheetCapabilities.SheetAction.RestoreAxis): void {\n Obj.update(this._sheet, (obj) => {\n obj.columns.splice(index, 0, axisIndex);\n values.forEach((value, row) => {\n if (value) {\n obj.cells[`${axisIndex}@${obj.rows[row]}`] = { value };\n }\n });\n\n if (axisMeta) {\n obj.columnMeta[axisIndex] = axisMeta;\n }\n });\n this.reset();\n }\n\n //\n // Undoable actions.\n // TODO(burdon): Group undoable methods; consistently update hf/sheet.\n //\n\n /**\n * Clear range of values.\n */\n clear(range: CellRange): void {\n invariant(this._node);\n const topLeft = getTopLeft(range);\n const values = this._iterRange(range, () => null);\n this._node.graph.hf.setCellContents(toSimpleCellAddress(this._node.sheetId, topLeft), values);\n Obj.update(this._sheet, (obj) => {\n this._iterRange(range, (cell) => {\n const idx = SheetUtil.addressToIndex(this._sheet, cell);\n delete obj.cells[idx];\n });\n });\n }\n\n cut(range: CellRange): void {\n invariant(this._node);\n this._node.graph.hf.cut(toModelRange(this._node.sheetId, range));\n Obj.update(this._sheet, (obj) => {\n this._iterRange(range, (cell) => {\n const idx = SheetUtil.addressToIndex(this._sheet, cell);\n delete obj.cells[idx];\n });\n });\n }\n\n copy(range: CellRange): void {\n invariant(this._node);\n this._node.graph.hf.copy(toModelRange(this._node.sheetId, range));\n }\n\n paste(cell: CellAddress): void {\n invariant(this._node);\n if (!this._node.graph.hf.isClipboardEmpty()) {\n const changes = this._node.graph.hf.paste(toSimpleCellAddress(this._node.sheetId, cell));\n Obj.update(this._sheet, (obj) => {\n for (const change of changes) {\n if (change instanceof ExportedCellChange) {\n const { address, newValue } = change;\n const idx = SheetUtil.addressToIndex(this._sheet, { row: address.row, col: address.col });\n obj.cells[idx] = { value: newValue };\n }\n }\n });\n }\n }\n\n // TODO(burdon): Display undo/redo state.\n undo(): void {\n invariant(this._node);\n if (this._node.graph.hf.isThereSomethingToUndo()) {\n this._node.graph.hf.undo();\n // this.update.emit();\n }\n }\n\n redo(): void {\n invariant(this._node);\n if (this._node.graph.hf.isThereSomethingToRedo()) {\n this._node.graph.hf.redo();\n // this.update.emit();\n }\n }\n\n /**\n * Get value from sheet.\n */\n getCellValue(cell: CellAddress): CellScalarValue {\n const idx = SheetUtil.addressToIndex(this._sheet, cell);\n return this._sheet.cells[idx]?.value ?? null;\n }\n\n /**\n * Get value as a string for editing.\n */\n getCellText(cell: CellAddress): string | undefined {\n const value = this.getCellValue(cell);\n if (value == null) {\n return undefined;\n }\n\n if (isFormula(value)) {\n return this._graph.mapFunctionBindingFromId(SheetUtil.mapFormulaIndicesToRefs(this._sheet, value));\n } else {\n return String(value);\n }\n }\n\n /**\n * Get array of raw values from sheet.\n */\n getCellValues(range: CellRange): CellScalarValue[][] {\n return this._iterRange(range, (cell) => this.getCellValue(cell));\n }\n\n /**\n * Gets the regular or computed value from the engine.\n */\n getValue(cell: CellAddress): CellScalarValue {\n // Applies rounding and post-processing.\n invariant(this._node);\n const address = toSimpleCellAddress(this._node.sheetId, cell);\n const value = this._node.graph.hf.getCellValue(address);\n if (value instanceof DetailedCellError) {\n // TODO(wittjosiah): Error details should be shown in cell `title`.\n log.warn('cell error', { cell, error: value });\n return value.toString();\n }\n\n return value;\n }\n\n /**\n * Get value type.\n */\n getValueDescription(cell: CellAddress): { type: TypeEnum; format?: Format.TypeFormat } | undefined {\n invariant(this._node);\n const addr = toSimpleCellAddress(this._node.sheetId, cell);\n const type = this._node.graph.hf.getCellValueDetailedType(addr);\n return typeMap[type];\n }\n\n /**\n * Sets the value, updating the sheet and engine.\n */\n setValue(cell: CellAddress, value: CellScalarValue): void {\n invariant(this._node);\n if (this._options.readonly) {\n throw new SheetUtil.ReadonlyException();\n }\n\n // Reallocate if > current bounds.\n let refresh = false;\n if (cell.row >= this._sheet.rows.length) {\n Obj.update(this._sheet, (obj) => {\n SheetUtil.insertIndices(obj.rows, cell.row, 1, SheetUtil.MAX_ROWS);\n });\n refresh = true;\n }\n if (cell.col >= this._sheet.columns.length) {\n Obj.update(this._sheet, (obj) => {\n SheetUtil.insertIndices(obj.columns, cell.col, 1, SheetUtil.MAX_COLS);\n });\n refresh = true;\n }\n\n if (refresh) {\n // TODO(burdon): Remove.\n this.reset();\n }\n\n // Insert into engine.\n this._node.graph.hf.setCellContents({ sheet: this._node.sheetId, row: cell.row, col: cell.col }, [\n [isFormula(value) ? this._graph.mapFormulaToNative(value) : value],\n ]);\n\n // Insert into sheet.\n const idx = SheetUtil.addressToIndex(this._sheet, cell);\n if (value === undefined || value === null) {\n Obj.update(this._sheet, (obj) => {\n delete obj.cells[idx];\n });\n } else {\n if (isFormula(value)) {\n value = this._graph.mapFunctionBindingToId(SheetUtil.mapFormulaRefsToIndices(this._sheet, value));\n }\n\n Obj.update(this._sheet, (obj) => {\n obj.cells[idx] = { value };\n });\n }\n }\n\n /**\n * Sets values from a simple map.\n */\n setValues(values: Record<string, Sheet.CellValue>): void {\n Object.entries(values).forEach(([key, { value }]) => {\n this.setValue(addressFromA1Notation(key), value);\n });\n }\n\n /**\n * Iterate range.\n */\n private _iterRange(range: CellRange, cb: (cell: CellAddress) => CellScalarValue | void): CellScalarValue[][] {\n const to = range.to ?? range.from;\n const rowRange = [Math.min(range.from.row, to.row), Math.max(range.from.row, to.row)];\n const columnRange = [Math.min(range.from.col, to.col), Math.max(range.from.col, to.col)];\n const rows: CellScalarValue[][] = [];\n for (let row = rowRange[0]; row <= rowRange[1]; row++) {\n const rowCells: CellScalarValue[] = [];\n for (let column = columnRange[0]; column <= columnRange[1]; column++) {\n const value = cb({ row, col: column });\n if (value !== undefined) {\n rowCells.push(value);\n }\n }\n\n rows.push(rowCells);\n }\n\n return rows;\n }\n\n // TODO(burdon): Delete index.\n private _deleteIndices(indices: string[], i: number, n: number): void {\n throw new Error('Not implemented');\n }\n\n // TODO(burdon): Move. Cannot use fractional without changing. Switch back to using unique IDs?\n private _moveIndices(indices: string[], i: number, j: number, n: number): void {\n throw new Error('Not implemented');\n }\n\n /**\n * Map from indices to A1 notation.\n */\n mapFormulaIndicesToRefs(formula: string): string {\n assertArgument(isFormula(formula), 'formula');\n return formula.replace(/([a-zA-Z0-9]+)@([a-zA-Z0-9]+)/g, (idx) => {\n return addressToA1Notation(SheetUtil.addressFromIndex(this._sheet, idx));\n });\n }\n\n //\n // Values\n //\n\n /**\n * https://hyperformula.handsontable.com/guide/date-and-time-handling.html#example\n * https://hyperformula.handsontable.com/api/interfaces/configparams.html#nulldate\n * NOTE: TODAY() is number of FULL days since nullDate. It will typically be -1 days from NOW().\n */\n toLocalDate(num: number): Date {\n const { year, month, day, hours, minutes, seconds } = this.toDateTime(num);\n return new Date(year, month - 1, day, hours, minutes, seconds);\n }\n\n toDateTime(num: number): SimpleDateTime {\n invariant(this._node);\n return this._node.graph.hf.numberToDateTime(num) as SimpleDateTime;\n }\n\n toDate(num: number): SimpleDate {\n invariant(this._node);\n return this._node.graph.hf.numberToDate(num) as SimpleDate;\n }\n\n toTime(num: number): SimpleDate {\n invariant(this._node);\n return this._node.graph.hf.numberToTime(num) as SimpleDate;\n }\n}\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nimport { type ComputeGraph } from '@dxos/compute-hyperformula';\n\nimport { Sheet } from '#types';\n\nimport { SheetModel } from '../model/index.ts';\n\nexport type UseSheetModelOptions = {\n readonly?: boolean;\n};\n\nexport const useSheetModel = (\n graph?: ComputeGraph,\n sheet?: Sheet.Sheet,\n { readonly }: UseSheetModelOptions = {},\n): SheetModel | undefined => {\n const [model, setModel] = useState<SheetModel>();\n useEffect(() => {\n if (!graph || !sheet) {\n return;\n }\n\n let model: SheetModel | undefined;\n const t = setTimeout(async () => {\n model = new SheetModel(graph, sheet, { readonly });\n await model.open();\n setModel(model);\n });\n\n return () => {\n clearTimeout(t);\n void model?.close();\n };\n }, [graph, sheet, readonly]);\n\n return model;\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { type PropsWithChildren, useCallback, useState } from 'react';\n\nimport {\n type CellAddress,\n type CellRange,\n type CompleteCellRange,\n type ComputeGraph,\n} from '@dxos/compute-hyperformula';\nimport { Grid, type GridContentProps, type GridEditing, useGridContext } from '@dxos/react-ui-grid';\n\nimport { Sheet } from '#types';\n\nimport { type SheetModel, useSheetModel } from '../../model/index.ts';\nimport { SheetContext } from './SheetContext.ts';\n\nexport type SheetContextValue = {\n id: string;\n attendableId: string;\n model: SheetModel;\n\n // Cursor state.\n // TODO(burdon): Cursor and range should use indices.\n cursor?: CellAddress;\n setCursor: (cell: CellAddress | undefined) => void;\n range?: CellRange;\n setRange: (range: CellRange | undefined) => void;\n cursorFallbackRange?: CompleteCellRange;\n\n // Editing state (undefined if not editing).\n editing: GridEditing;\n setEditing: (editing: GridEditing) => void;\n\n // Active refs\n activeRefs: GridContentProps['activeRefs'];\n setActiveRefs: (activeRefs: GridContentProps['activeRefs']) => void;\n\n // Flags\n ignoreAttention?: boolean;\n\n // Events.\n // TODO(burdon): Generalize.\n onInfo?: () => void;\n};\n\nexport type SheetRootProps = {\n graph: ComputeGraph;\n sheet: Sheet.Sheet;\n attendableId: string;\n readonly?: boolean;\n ignoreAttention?: boolean;\n} & Pick<SheetContextValue, 'onInfo'>;\n\nexport const SheetRoot = ({\n children,\n graph,\n sheet,\n attendableId,\n readonly,\n ignoreAttention,\n onInfo,\n}: PropsWithChildren<SheetRootProps>) => {\n const model = useSheetModel(graph, sheet, { readonly });\n if (!model) {\n return null;\n }\n\n return (\n <Grid.Root id={attendableId}>\n <SheetProviderImpl model={model} attendableId={attendableId} onInfo={onInfo} ignoreAttention={ignoreAttention}>\n {children}\n </SheetProviderImpl>\n </Grid.Root>\n );\n};\n\nconst SheetProviderImpl = ({\n children,\n attendableId,\n ignoreAttention,\n model,\n onInfo,\n}: PropsWithChildren<Pick<SheetContextValue, 'attendableId' | 'ignoreAttention' | 'model' | 'onInfo'>>) => {\n const { id, editing, setEditing } = useGridContext('SheetProvider');\n\n const [cursor, setCursorInternal] = useState<CellAddress>();\n const [range, setRangeInternal] = useState<CellRange>();\n const [cursorFallbackRange, setCursorFallbackRange] = useState<CompleteCellRange>();\n const [activeRefs, setActiveRefs] = useState<GridContentProps['activeRefs']>('');\n\n const setCursor = useCallback(\n (nextCursor?: CellAddress) => {\n setCursorInternal(nextCursor);\n setCursorFallbackRange(\n range?.to ? (range as CompleteCellRange) : nextCursor ? { from: nextCursor!, to: nextCursor! } : undefined,\n );\n },\n [range],\n );\n const setRange = useCallback(\n (nextRange?: CellRange) => {\n setRangeInternal(nextRange);\n setCursorFallbackRange(\n nextRange?.to ? (nextRange as CompleteCellRange) : cursor ? { from: cursor!, to: cursor! } : undefined,\n );\n },\n [cursor],\n );\n\n return (\n <SheetContext.Provider\n value={{\n id,\n attendableId,\n model,\n editing,\n setEditing,\n cursor,\n setCursor,\n range,\n setRange,\n cursorFallbackRange,\n activeRefs,\n setActiveRefs,\n ignoreAttention,\n // TODO(burdon): Change to event.\n onInfo,\n }}\n >\n {children}\n </SheetContext.Provider>\n );\n};\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport {\n type Completion,\n type CompletionContext,\n type CompletionResult,\n acceptCompletion,\n autocompletion,\n completionStatus,\n startCompletion,\n} from '@codemirror/autocomplete';\nimport { HighlightStyle, type Language, syntaxHighlighting } from '@codemirror/language';\nimport { type Extension } from '@codemirror/state';\nimport { type EditorView, ViewPlugin, type ViewUpdate, keymap } from '@codemirror/view';\nimport { type SyntaxNode } from '@lezer/common';\nimport { tags } from '@lezer/highlight';\nimport { spreadsheet } from 'codemirror-lang-spreadsheet';\n\nimport { type FunctionDefinition } from '@dxos/compute-hyperformula';\nimport { RANGE_NOTATION } from '@dxos/compute-hyperformula';\nimport { singleValueFacet } from '@dxos/ui-editor';\nimport { mx } from '@dxos/ui-theme';\n\n/**\n * https://codemirror.net/examples/styling\n * https://lezer.codemirror.net/docs/ref/#highlight\n * https://github.com/luizzappa/codemirror-lang-spreadsheet/blob/main/src/index.ts#L28 (mapping)\n */\n// TODO(burdon): Define light/dark.\nconst highlightStyles = HighlightStyle.define([\n // Function.\n {\n tag: tags.name,\n class: 'text-accent-text',\n },\n // Range.\n {\n tag: tags.tagName,\n class: 'text-pink-text',\n },\n // Values.\n {\n tag: tags.number,\n class: 'text-teal-text',\n },\n {\n tag: tags.bool,\n class: 'text-teal-text',\n },\n {\n tag: tags.string,\n class: 'text-teal-text',\n },\n // Error.\n {\n tag: tags.invalid,\n class: 'text-un-accent',\n },\n]);\n\nconst languageFacet = singleValueFacet<Language>();\n\nexport type SheetExtensionOptions = {\n debug?: boolean;\n functions?: FunctionDefinition[];\n};\n\n/**\n * Spreadsheet formula extension and parser.\n * https://github.com/luizzappa/codemirror-lang-spreadsheet\n * https://github.com/luizzappa/codemirror-app-spreadsheet/blob/master/src/editor.ts\n * https://github.com/codemirror/lang-example\n * https://hyperformula.handsontable.com/guide/key-concepts.html#grammar\n */\nexport const sheetExtension = ({ debug, functions = [] }: SheetExtensionOptions): Extension => {\n const { extension, language } = spreadsheet({\n idiom: 'en-US',\n decimalSeparator: '.',\n });\n\n const createCompletion = (name: string) => {\n const { section = 'Custom', description, syntax } = functions.find((value) => value.name === name) ?? {};\n\n return {\n section,\n label: name,\n info: () => {\n if (!description && !syntax) {\n return null;\n }\n\n // TODO(burdon): Standardize color styles.\n const root = document.createElement('div');\n root.className = 'flex flex-col gap-2 text-sm';\n\n const title = document.createElement('h2');\n title.innerText = name;\n title.className = 'text-lg font-mono text-accent-text';\n root.appendChild(title);\n\n if (description) {\n const info = document.createElement('p');\n info.innerText = description;\n info.className = 'text-fg-subtle';\n root.appendChild(info);\n }\n\n if (syntax) {\n const detail = document.createElement('pre');\n detail.innerText = syntax;\n detail.className = 'whitespace-pre-wrap text-green-text';\n root.appendChild(detail);\n }\n\n return root;\n },\n apply: (view, completion, from, to) => {\n const insertParens = to === view.state.doc.toString().length;\n view.dispatch(\n view.state.update({\n changes: {\n from,\n to,\n insert: completion.label + (insertParens ? '()' : ''),\n },\n selection: {\n anchor: from + completion.label.length + 1,\n },\n }),\n );\n },\n } satisfies Completion;\n };\n\n return [\n extension,\n languageFacet.of(language),\n language.data.of({\n autocomplete: (context: CompletionContext): CompletionResult | null => {\n if (context.state.doc.toString()[0] !== '=') {\n return null;\n }\n const match = context.matchBefore(/\\w*/);\n if (!match || match.from === match.to) {\n return null;\n }\n\n const text = match.text.toUpperCase();\n if (!context.explicit && match.text.length < 2) {\n return null;\n }\n\n return {\n from: match.from,\n options:\n functions?.filter(({ name }) => name.startsWith(text)).map(({ name }) => createCompletion(name)) ?? [],\n };\n },\n }),\n\n syntaxHighlighting(highlightStyles),\n anchorCompletionTooltip,\n autocompletion({\n aboveCursor: false,\n defaultKeymap: true,\n activateOnTyping: true,\n closeOnBlur: !debug,\n icons: false,\n // Cosmetics only. The tooltip is `position: fixed` and CodeMirror computes its coordinates from\n // the cursor, so overriding `left`/`top` here measures them against the viewport instead of the\n // cell — which pinned the completion list to the top-left corner of the window.\n tooltipClass: () =>\n mx(\n '-m-0! border border-h-0! [&>ul]:min-w-[198px]!',\n '[&>ul>li[aria-selected]]:bg-accent-bg!',\n 'border-separator',\n ),\n }),\n keymap.of([\n {\n key: 'Tab',\n run: (view) => {\n return completionStatus(view.state) === 'active' ? acceptCompletion(view) : startCompletion(view);\n },\n },\n ]),\n\n // Parsing.\n // StateField.define({\n // create: (state) => {},\n // update: (value, tr) => {\n // log.info('update');\n // syntaxTree(tr.state).iterate({\n // enter: ({ type, from, to }) => {\n // log.info('node', { type: type.name, from, to });\n // },\n // });\n // },\n // }),\n ];\n};\n\nexport type SelectionRange = { from: number; to: number };\n\nexport interface RangeController {\n setRange(range: string): void;\n}\n\nexport type RangeExtensionOptions = {\n /**\n * Provides controller callback when extension is initialized.\n */\n onInit?: (controller: RangeController) => void;\n /**\n * Called when the active range changes.\n * @param state The current state.\n * @param state.activeRange undefined if no range is active, otherwise a possibly partially defined range.\n */\n onStateChange?: (state: { activeRange: string | undefined }) => void;\n};\n\n/**\n * Tracks the currently active cell within a formula and provides a callback to modify it.\n */\nexport const rangeExtension = ({ onInit, onStateChange }: RangeExtensionOptions): Extension => {\n let view: EditorView;\n let activeRange: SelectionRange | undefined;\n\n // Called externally to provide current range.\n const notifier: RangeController = {\n setRange: (range: string) => {\n if (activeRange) {\n view.dispatch(\n view.state.update({\n changes: { ...activeRange, insert: range.toString() },\n selection: { anchor: activeRange.from + range.length },\n }),\n );\n }\n\n view.focus();\n },\n };\n\n return ViewPlugin.fromClass(\n class {\n constructor(_view: EditorView) {\n view = _view;\n onInit?.(notifier);\n }\n\n update(view: ViewUpdate) {\n const { anchor } = view.state.selection.ranges[0];\n\n // Find first Range or cell at cursor.\n activeRange = undefined;\n const language = view.state.facet(languageFacet);\n const { topNode } = language.parser.parse(view.state.doc.toString());\n visitTree(topNode, ({ type, from, to }) => {\n if (from <= anchor && to >= anchor) {\n switch (type.name) {\n case 'Function':\n // Mark but keep looking.\n activeRange = { from: to, to };\n break;\n\n case 'CloseParen':\n // Mark but keep looking.\n activeRange = { from, to: from };\n break;\n\n case 'RangeToken':\n case 'CellToken':\n activeRange = { from, to };\n return true;\n }\n }\n\n return false;\n });\n\n // Allow start of formula.\n if (!activeRange && view.state.doc.toString()[0] === '=') {\n const str = view.state.doc.sliceString(1);\n if (RANGE_NOTATION.test(str)) {\n activeRange = { from: 1, to: str.length + 1 };\n } else {\n activeRange = { from: str.length + 1, to: str.length + 1 };\n }\n }\n\n onStateChange?.({\n activeRange: activeRange ? view.state.doc.sliceString(activeRange.from, activeRange.to) : undefined,\n });\n }\n },\n );\n};\n\n/**\n * Lezer parse result visitor.\n */\nconst visitTree = (node: SyntaxNode, callback: (node: SyntaxNode) => boolean): boolean => {\n if (callback(node)) {\n return true;\n }\n\n for (let child = node.firstChild; child !== null; child = child.nextSibling) {\n if (visitTree(child, callback)) {\n return true;\n }\n }\n\n return false;\n};\n\n/**\n * Pins the completion tooltip to the editing cell rather than to the cursor.\n *\n * CodeMirror anchors it at the completion's start offset — a few pixels in from the cell's edge, and\n * further in the longer the expression before the function name — overlapping the cell's lower\n * border. In a grid the cell is the meaningful anchor.\n *\n * Driven by a DOM observer rather than the plugin's `update`: CodeMirror creates and positions the\n * tooltip in its measure phase, which runs *after* the update, so an update-time correction either\n * finds no tooltip or is immediately overwritten. Which side it opens on is still CodeMirror's call,\n * so a tooltip near the bottom of the window still flips above the cell.\n */\nconst anchorCompletionTooltip = ViewPlugin.fromClass(\n class {\n private readonly _observer = new MutationObserver(() => this._pin());\n\n constructor(private readonly _view: EditorView) {\n this._observer.observe(_view.dom, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['style', 'class'],\n });\n }\n\n destroy(): void {\n this._observer.disconnect();\n }\n\n /** Idempotent: writing values it already holds would retrigger the observer. */\n private _pin(): void {\n const tooltip = this._view.dom.querySelector<HTMLElement>('.cm-tooltip-autocomplete');\n if (!tooltip) {\n return;\n }\n\n // The cell editor's own box, not `view.dom` — the editor sits inset within it.\n const cell = (this._view.dom.closest('.dx-grid__cell-editor') ?? this._view.dom).getBoundingClientRect();\n const left = cell.left;\n const top = tooltip.classList.contains('cm-tooltip-below')\n ? cell.bottom\n : cell.top - tooltip.getBoundingClientRect().height;\n if (\n Math.abs(Number.parseFloat(tooltip.style.left || '0') - left) < 0.5 &&\n Math.abs(Number.parseFloat(tooltip.style.top || '0') - top) < 0.5\n ) {\n return;\n }\n\n tooltip.style.left = `${left}px`;\n tooltip.style.top = `${top}px`;\n }\n },\n);\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { useEffect, useState } from 'react';\n\nimport { inRange } from '@dxos/compute-hyperformula';\nimport { Doc } from '@dxos/echo-doc';\nimport { cellClassesForFieldType, parseValue } from '@dxos/react-ui-form';\nimport {\n type DxGridAxisMeta,\n type DxGridCellValue,\n type DxGridElement,\n type DxGridPlane,\n type DxGridPlaneCells,\n type DxGridPlaneRange,\n type GridContentProps,\n colToA1Notation,\n commentedClassName,\n rowToA1Notation,\n} from '@dxos/react-ui-grid';\nimport { mx } from '@dxos/ui-theme';\n\nimport { SheetRange, SheetUtil } from '#types';\n\nimport { type SheetModel } from '../../model/index.ts';\n\nconst createDxGridColumns = (model: SheetModel): DxGridAxisMeta => {\n return model.sheet.columns.reduce(\n (acc: DxGridAxisMeta, columnId, numericIndex) => {\n if (model.sheet.columnMeta[columnId] && model.sheet.columnMeta[columnId].size) {\n acc.grid[numericIndex] = {\n size: model.sheet.columnMeta[columnId].size,\n resizeable: true,\n };\n }\n return acc;\n },\n { grid: {} },\n );\n};\n\nconst createDxGridRows = (model: SheetModel): DxGridAxisMeta => {\n return model.sheet.rows.reduce(\n (acc: DxGridAxisMeta, rowId, numericIndex) => {\n if (model.sheet.rowMeta[rowId] && model.sheet.rowMeta[rowId].size) {\n acc.grid[numericIndex] = {\n size: model.sheet.rowMeta[rowId].size,\n resizeable: true,\n };\n }\n return acc;\n },\n { grid: {} },\n );\n};\n\nconst projectCellProps = (model: SheetModel, col: number, row: number): DxGridCellValue => {\n const address = { col, row };\n const rawValue = model.getValue(address);\n const ranges = model.sheet.ranges?.filter(({ range }) =>\n inRange(SheetUtil.rangeFromIndex(model.sheet, range), address),\n );\n const threadRefs = undefined;\n // TODO(wittjosiah): Update this to get threads via relations.\n // model.sheet.threads\n // ?.filter((thread) => {\n // const range = thread.target?.anchor && parseThreadAnchorAsCellRange(thread.target!.anchor);\n // return thread && range ? inRange(range, address) : false;\n // })\n // .map((thread) => Obj.getURI(thread!))\n // .join(' ');\n\n const description = model.getValueDescription(address);\n const type = description?.type;\n const format = description?.format;\n const classNames = ranges?.map(SheetRange.cellClassNameForRange).reverse();\n\n return {\n value: parseValue({ type, format, value: rawValue }),\n className: mx(cellClassesForFieldType({ type, format }), threadRefs && commentedClassName, classNames),\n dataRefs: threadRefs,\n };\n};\nconst gridCellGetter = (model: SheetModel) => {\n // TODO(thure): Actually use the cache.\n const cachedGridCells: DxGridPlaneCells = {};\n return (nextBounds: DxGridPlaneRange): DxGridPlaneCells => {\n [...Array(nextBounds.end.col - nextBounds.start.col)].forEach((_, c0) => {\n return [...Array(nextBounds.end.row - nextBounds.start.row)].forEach((_, r0) => {\n const col = nextBounds.start.col + c0;\n const row = nextBounds.start.row + r0;\n cachedGridCells[`${col},${row}`] = projectCellProps(model, col, row);\n });\n });\n return cachedGridCells;\n };\n};\n\nexport const rowLabelCell = (row: number) => ({\n value: rowToA1Notation(row),\n className: 'bg-axis-surface! text-axis-text text-end pe-1',\n resizeHandle: 'row',\n});\n\nexport const colLabelCell = (col: number) => ({\n value: colToA1Notation(col),\n className: 'bg-axis-surface! text-axis-text',\n resizeHandle: 'col',\n});\n\nconst cellGetter = (model: SheetModel) => {\n const getGridCells = gridCellGetter(model);\n return (nextBounds: DxGridPlaneRange, plane: DxGridPlane): DxGridPlaneCells => {\n switch (plane) {\n case 'grid':\n return getGridCells(nextBounds);\n case 'fixedStartStart': {\n return {\n '0,0': { className: 'bg-axis-surface!' },\n };\n }\n case 'frozenColsStart':\n return [...Array(nextBounds.end.row - nextBounds.start.row)].reduce((acc, _, r0) => {\n const r = nextBounds.start.row + r0;\n acc[`0,${r}`] = rowLabelCell(r);\n return acc;\n }, {});\n case 'frozenRowsStart':\n return [...Array(nextBounds.end.col - nextBounds.start.col)].reduce((acc, _, c0) => {\n const c = nextBounds.start.col + c0;\n acc[`${c},0`] = colLabelCell(c);\n return acc;\n }, {});\n default:\n return {};\n }\n };\n};\n\nexport const useSheetModelDxGridProps = (\n dxGrid: DxGridElement | null,\n model: SheetModel,\n): Pick<GridContentProps, 'columns' | 'rows'> => {\n const [columns, setColumns] = useState<DxGridAxisMeta>(createDxGridColumns(model));\n const [rows, setRows] = useState<DxGridAxisMeta>(createDxGridRows(model));\n\n useEffect(() => {\n const cellsAccessor = Doc.createAccessor(model.sheet, ['cells']);\n if (dxGrid) {\n dxGrid.getCells = cellGetter(model);\n }\n const handleCellsUpdate = () => {\n dxGrid?.requestUpdate('initialCells');\n };\n cellsAccessor.handle.addListener('change', handleCellsUpdate);\n const unsubscribe = model.graph.update.on(handleCellsUpdate);\n return () => {\n cellsAccessor.handle.removeListener('change', handleCellsUpdate);\n unsubscribe();\n };\n }, [model, dxGrid]);\n\n useEffect(() => {\n const columnMetaAccessor = Doc.createAccessor(model.sheet, ['columnMeta']);\n const rowMetaAccessor = Doc.createAccessor(model.sheet, ['rowMeta']);\n const handleColumnMetaUpdate = () => {\n setColumns(createDxGridColumns(model));\n };\n const handleRowMetaUpdate = () => {\n setRows(createDxGridRows(model));\n };\n columnMetaAccessor.handle.addListener('change', handleColumnMetaUpdate);\n rowMetaAccessor.handle.addListener('change', handleRowMetaUpdate);\n return () => {\n columnMetaAccessor.handle.removeListener('change', handleColumnMetaUpdate);\n rowMetaAccessor.handle.removeListener('change', handleRowMetaUpdate);\n };\n }, [model, dxGrid]);\n\n return { columns, rows };\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport React, {\n type FocusEvent,\n type KeyboardEvent,\n type MouseEvent,\n type WheelEvent,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport { type CellRange, rangeToA1Notation } from '@dxos/compute-hyperformula';\nimport { Obj } from '@dxos/echo';\nimport { defaultColSize, defaultRowSize } from '@dxos/lit-grid';\nimport { useAttention } from '@dxos/react-ui-attention';\nimport {\n type DxGridCellIndex,\n type DxGridElement,\n type DxGridPosition,\n type EditorBlurHandler,\n type EditorKeyHandler,\n Grid,\n GridCellEditor,\n type GridContentProps,\n closestCell,\n editorKeys,\n parseCellIndex,\n} from '@dxos/react-ui-grid';\nimport * as UiHooks from '@dxos/react-ui/Hooks';\nimport * as Menu from '@dxos/react-ui/Menu';\nimport * as Util from '@dxos/react-ui/Util';\nimport * as VirtualAnchor from '@dxos/react-ui/VirtualAnchor';\n\nimport { meta } from '#meta';\nimport { SheetCapabilities, SheetOperation, SheetUtil } from '#types';\n\nimport { type RangeController, rangeExtension, sheetExtension } from '../../extensions/index.ts';\nimport { useSelectThreadOnCellFocus } from '../../integrations/index.ts';\nimport { useSheetContext } from '../SheetRoot/index.ts';\nimport { colLabelCell, rowLabelCell, useSheetModelDxGridProps } from './util.ts';\n\nconst inertPosition: DxGridPosition = { plane: 'grid', col: 0, row: 0 };\n\nconst initialCells = {\n grid: {},\n frozenColsStart: [...Array(64)].reduce((acc, _, i) => {\n acc[`0,${i}`] = rowLabelCell(i);\n return acc;\n }, {}),\n frozenRowsStart: [...Array(12)].reduce((acc, _, i) => {\n acc[`${i},0`] = colLabelCell(i);\n return acc;\n }, {}),\n};\n\nconst frozen = {\n frozenColsStart: 1,\n frozenRowsStart: 1,\n};\n\nconst sheetColDefault = {\n frozenColsStart: { size: 48, readonly: true, focusUnfurl: false },\n grid: { size: defaultColSize, resizeable: true },\n};\nconst sheetRowDefault = {\n frozenRowsStart: { size: defaultRowSize, readonly: true, focusUnfurl: false },\n grid: { size: defaultRowSize, resizeable: true },\n};\n\nexport type SheetContentProps = {};\n\nexport const SheetContent = Util.composable<HTMLDivElement, SheetContentProps>((props, forwardedRef) => {\n const { t } = UiHooks.useTranslation(meta.profile.key);\n const {\n id,\n attendableId,\n model,\n editing,\n setCursor,\n setRange,\n cursor,\n cursorFallbackRange,\n activeRefs,\n setActiveRefs,\n ignoreAttention,\n } = useSheetContext();\n\n // NOTE(thure): using `useState` instead of `useRef` works with refs provided by `@lit/react` and gives us\n // a reliable dependency for `useEffect` whereas `useLayoutEffect` does not guarantee the element will be defined.\n const [dxGrid, setDxGrid] = useState<DxGridElement | null>(null);\n const [extraplanarFocus, setExtraplanarFocus] = useState<DxGridPosition | null>(null);\n const { invokePromise } = Hooks.useOperationInvoker();\n const rangeController = useRef<RangeController>(null);\n const { hasAttention } = useAttention(id);\n\n const handleFocus = useCallback(\n (event: FocusEvent) => {\n if (!editing) {\n const cell = closestCell(event.target);\n if (cell) {\n if (cell.plane === 'grid') {\n setCursor({ col: cell.col, row: cell.row });\n setExtraplanarFocus(null);\n } else {\n setExtraplanarFocus(cell);\n }\n } else {\n setExtraplanarFocus(null);\n }\n }\n },\n [editing],\n );\n\n // TODO(burdon): Validate formula before closing: hf.validateFormula();\n const handleClose = useCallback<EditorKeyHandler>(\n (_value, event) => {\n if (event) {\n const { key, shift } = event;\n const axis = ['Enter', 'ArrowUp', 'ArrowDown'].includes(key)\n ? 'row'\n : ['Tab', 'ArrowLeft', 'ArrowRight'].includes(key)\n ? 'col'\n : undefined;\n const delta = key.startsWith('Arrow') ? (['ArrowUp', 'ArrowLeft'].includes(key) ? -1 : 1) : shift ? -1 : 1;\n dxGrid?.refocus(axis, delta);\n }\n },\n [model, editing, dxGrid],\n );\n\n const handleBlur = useCallback<EditorBlurHandler>(\n (value) => {\n if (value !== undefined) {\n model.setValue(parseCellIndex(editing!.index), value);\n }\n },\n [model, editing],\n );\n\n const handleAxisResize = useCallback<NonNullable<GridContentProps['onAxisResize']>>(\n ({ axis, size, index: numericIndex }) => {\n Obj.update(model.sheet, (sheet) => {\n if (axis === 'row') {\n const rowId = sheet.rows[parseInt(numericIndex)];\n sheet.rowMeta[rowId] ??= {};\n sheet.rowMeta[rowId].size = size;\n } else {\n const columnId = sheet.columns[parseInt(numericIndex)];\n sheet.columnMeta[columnId] ??= {};\n sheet.columnMeta[columnId].size = size;\n }\n });\n },\n [model],\n );\n\n const handleSelect = useCallback<NonNullable<GridContentProps['onSelect']>>(\n ({ minCol, maxCol, minRow, maxRow }) => {\n const range: CellRange = { from: { col: minCol, row: minRow } };\n if (minCol !== maxCol || minRow !== maxRow) {\n range.to = { col: maxCol, row: maxRow };\n }\n if (editing) {\n // Update range selection in formula.\n rangeController.current?.setRange(rangeToA1Notation(range));\n } else {\n // Setting range while editing causes focus to move to null, avoid doing so.\n setRange(range.to ? range : undefined);\n }\n },\n [editing],\n );\n\n const handleWheel = useCallback(\n (event: WheelEvent) => {\n if (!ignoreAttention && !hasAttention) {\n event.stopPropagation();\n }\n },\n [hasAttention, ignoreAttention],\n );\n\n const selectEntireAxis = useCallback(\n (pos: DxGridPosition) => {\n switch (pos.plane) {\n case 'frozenRowsStart':\n return dxGrid?.setSelection({\n start: { col: pos.col, row: 0, plane: 'grid' },\n end: {\n col: pos.col,\n row: model.sheet.rows.length - 1,\n plane: 'grid',\n },\n });\n case 'frozenColsStart':\n return dxGrid?.setSelection({\n start: { row: pos.row, col: 0, plane: 'grid' },\n end: {\n row: pos.row,\n col: model.sheet.columns.length - 1,\n plane: 'grid',\n },\n });\n }\n },\n [dxGrid, model.sheet],\n );\n\n const handleClick = useCallback(\n (event: MouseEvent) => {\n const cell = closestCell(event.target);\n if (cell) {\n selectEntireAxis(cell);\n }\n },\n [selectEntireAxis],\n );\n\n const handleKeyDown = useCallback(\n (event: KeyboardEvent) => {\n switch (event.key) {\n case 'Backspace':\n case 'Delete':\n event.preventDefault();\n return cursorFallbackRange && model.clear(cursorFallbackRange);\n case 'Enter':\n case 'Space':\n if (dxGrid && extraplanarFocus) {\n switch (extraplanarFocus.plane) {\n case 'frozenRowsStart':\n case 'frozenColsStart':\n event.preventDefault();\n return selectEntireAxis(extraplanarFocus);\n }\n }\n }\n if (event.metaKey || event.ctrlKey) {\n switch (event.key) {\n case 'x':\n case 'X':\n event.preventDefault();\n return cursorFallbackRange && model.cut(cursorFallbackRange);\n case 'c':\n case 'C':\n event.preventDefault();\n return cursorFallbackRange && model.copy(cursorFallbackRange);\n case 'v':\n case 'V':\n event.preventDefault();\n return cursor && model.paste(cursor);\n case 'z':\n event.preventDefault();\n return event.shiftKey ? model.redo() : model.undo();\n case 'Z':\n case 'y':\n event.preventDefault();\n return model.redo();\n }\n }\n },\n [cursorFallbackRange, model, cursor, extraplanarFocus, selectEntireAxis],\n );\n\n const contextMenuAnchorRef = useRef<HTMLButtonElement | null>(null);\n const [contextMenuOpen, setContextMenuOpen] = useState<DxGridPosition | null>(null);\n const contextMenuAxis = contextMenuOpen?.plane.startsWith('frozenRows') ? 'col' : 'row';\n\n const handleContextMenu = useCallback((event: MouseEvent) => {\n const cell = closestCell(event.target);\n if (cell && cell.plane.startsWith('frozen')) {\n event.preventDefault();\n contextMenuAnchorRef.current = event.target as HTMLButtonElement;\n setContextMenuOpen(cell);\n }\n }, []);\n\n const handleAxisMenuAction = useCallback(\n (operation: 'insert-before' | 'insert-after' | 'drop') => {\n switch (operation) {\n case 'insert-before':\n case 'insert-after':\n return invokePromise(SheetOperation.InsertAxis, {\n model,\n axis: contextMenuAxis,\n index: contextMenuOpen![contextMenuAxis] + (operation === 'insert-before' ? 0 : 1),\n });\n case 'drop':\n return invokePromise(SheetOperation.DropAxis, {\n model,\n axis: contextMenuAxis,\n axisIndex: model.sheet[contextMenuAxis === 'row' ? 'rows' : 'columns'][contextMenuOpen![contextMenuAxis]],\n });\n }\n },\n [contextMenuAxis, contextMenuOpen, model, invokePromise],\n );\n\n const { columns, rows } = useSheetModelDxGridProps(dxGrid, model);\n\n const extensions = useMemo(\n () => [\n editorKeys({\n onClose: handleClose,\n ...(editing?.initialContent && { onNav: handleClose }),\n }),\n sheetExtension({ functions: model.graph.getFunctions() }),\n rangeExtension({\n onInit: (fn) => (rangeController.current = fn),\n onStateChange: (state) => {\n if (dxGrid) {\n // This can’t dispatch a setState in this component, otherwise the cell editor remounts and loses focus.\n dxGrid.mode = typeof state.activeRange === 'undefined' ? 'edit' : 'edit-select';\n }\n },\n }),\n ],\n [model, handleClose, editing],\n );\n\n const getCellContent = useCallback(\n (index: DxGridCellIndex) => {\n return model.getCellText(parseCellIndex(index));\n },\n [model],\n );\n\n const [gridInstances] = Hooks.useCapabilities(SheetCapabilities.GridInstances);\n useEffect(() => {\n if (dxGrid && gridInstances) {\n gridInstances.register(attendableId, dxGrid, setActiveRefs);\n return () => gridInstances.unregister(attendableId);\n }\n }, [dxGrid, gridInstances, attendableId, setActiveRefs]);\n\n useSelectThreadOnCellFocus();\n\n return (\n <div ref={forwardedRef} {...Util.composableProps(props, { classNames: 'relative min-h-0' })}>\n <GridCellEditor getCellContent={getCellContent} extensions={extensions} onBlur={handleBlur} />\n <Grid.Content\n className='[--dx-grid-base:var(--base-surface)] [&_.dx-grid]:absolute [&_.dx-grid]:inset-0'\n initialCells={initialCells}\n limitColumns={SheetUtil.DEFAULT_COLS}\n limitRows={SheetUtil.DEFAULT_ROWS}\n columns={columns}\n rows={rows}\n columnDefault={sheetColDefault}\n rowDefault={sheetRowDefault}\n activeRefs={activeRefs}\n frozen={frozen}\n overscroll='trap'\n onAxisResize={handleAxisResize}\n onSelect={handleSelect}\n onFocus={handleFocus}\n onWheelCapture={handleWheel}\n onKeyDown={handleKeyDown}\n onContextMenu={handleContextMenu}\n onClick={handleClick}\n ref={setDxGrid}\n />\n <Menu.Root\n open={!!contextMenuOpen}\n onOpenChange={({ open: nextOpen }) => setContextMenuOpen(nextOpen ? inertPosition : null)}\n positioning={{\n ...VirtualAnchor.virtualAnchor(contextMenuAnchorRef),\n placement: contextMenuAxis === 'col' ? 'bottom' : 'right',\n gutter: 4,\n overflowPadding: 8,\n }}\n >\n <Menu.Content>\n <Menu.Item\n item={{\n value: 'insert-before',\n label: t(`add-${contextMenuAxis}-before.label`),\n icon: contextMenuAxis === 'col' ? 'ph--columns-plus-left--regular' : 'ph--rows-plus-top--regular',\n }}\n onClick={() => handleAxisMenuAction('insert-before')}\n data-testid={`grid.${contextMenuAxis}.insert-before`}\n />\n <Menu.Item\n item={{\n value: 'insert-after',\n label: t(`add-${contextMenuAxis}-after.label`),\n icon: contextMenuAxis === 'col' ? 'ph--columns-plus-right--regular' : 'ph--rows-plus-bottom--regular',\n }}\n onClick={() => handleAxisMenuAction('insert-after')}\n data-testid={`grid.${contextMenuAxis}.insert-after`}\n />\n <Menu.Item\n item={{ value: 'drop', label: t(`delete-${contextMenuAxis}.label`), icon: 'ph--backspace--regular' }}\n onClick={() => handleAxisMenuAction('drop')}\n data-testid={`grid.${contextMenuAxis}.drop`}\n />\n </Menu.Content>\n </Menu.Root>\n </div>\n );\n});\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport React from 'react';\n\nimport { addressToA1Notation, isFormula, rangeToA1Notation } from '@dxos/compute-hyperformula';\nimport * as Icon from '@dxos/react-ui/Icon';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Util from '@dxos/react-ui/Util';\n\nimport { SheetUtil } from '#types';\n\nimport { useSheetContext } from '../SheetRoot/index.ts';\n\nexport type SheetStatusbarProps = {};\n\nexport const SheetStatusbar = Util.composable<HTMLDivElement, SheetStatusbarProps>((props, forwardedRef) => {\n const { model, cursor, range } = useSheetContext();\n\n let value;\n let formula = false;\n if (cursor) {\n value = model.getCellValue(cursor);\n if (isFormula(value)) {\n value = model.graph.mapFunctionBindingFromId(SheetUtil.mapFormulaIndicesToRefs(model.sheet, value));\n formula = true;\n } else if (value != null) {\n value = String(value);\n }\n }\n\n return (\n <Layout.Flex\n justify='between'\n align='center'\n {...Util.composableProps(props, {\n classNames: 'shrink-0 px-4 py-1 text-sm dx-toolbar-surface border-y !border-separator-subtle',\n })}\n ref={forwardedRef}\n >\n <Layout.Flex gap='lg' align='center'>\n <Layout.Flex align='center' classNames='w-16 font-mono'>\n {(range && rangeToA1Notation(range)) || (cursor && addressToA1Notation(cursor))}\n </Layout.Flex>\n <Layout.Flex gap='sm' align='center'>\n <Icon.Icon icon='ph--function--regular' classNames={['text-green-text', formula ? 'visible' : 'invisible']} />\n <span className='font-mono'>{value}</span>\n </Layout.Flex>\n </Layout.Flex>\n </Layout.Flex>\n );\n});\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { RegistryContext } from '@effect/atom-react/RegistryContext';\nimport type * as Registry from 'effect/reactivity/AtomRegistry';\nimport { useContext, useEffect } from 'react';\n\nimport { type CompleteCellRange, inRange } from '@dxos/compute-hyperformula';\nimport { Obj } from '@dxos/echo';\nimport {\n type ActionGraphProps,\n type ToolbarMenuActionGroupProperties,\n createMenuAction,\n createMenuItemGroup,\n} from '@dxos/react-ui-menu';\n\nimport { meta } from '#meta';\nimport { SheetRange, SheetUtil } from '#types';\n\nimport { type SheetModel } from '../../model/index.ts';\nimport { useSheetContext } from '../SheetRoot/index.ts';\nimport { type ToolbarState, type ToolbarStateAtom } from './useToolbarState.ts';\n\nexport type AlignAction = { key: SheetRange.AlignKey; value: SheetRange.AlignValue };\n\nexport type AlignState = { [SheetRange.alignKey]: SheetRange.AlignValue | undefined };\n\nconst aligns: Record<SheetRange.AlignValue, string> = {\n start: 'ph--text-align-left--regular',\n center: 'ph--text-align-center--regular',\n end: 'ph--text-align-right--regular',\n};\n\nexport const useAlignState = (stateAtom: ToolbarStateAtom) => {\n const registry = useContext(RegistryContext);\n const { cursor, model } = useSheetContext();\n useEffect(() => {\n // TODO(thure): Can this O(n) call be memoized?\n const alignValue = (\n cursor\n ? model.sheet.ranges?.findLast(\n ({ range, key }) =>\n key === SheetRange.alignKey && inRange(SheetUtil.rangeFromIndex(model.sheet, range), cursor),\n )?.value\n : undefined\n ) as SheetRange.AlignValue | undefined;\n const prev = registry.get(stateAtom);\n registry.set(stateAtom, { ...prev, [SheetRange.alignKey]: alignValue });\n }, [cursor, model.sheet, registry, stateAtom]);\n};\n\nconst createAlignGroupAction = (value?: SheetRange.AlignValue) =>\n createMenuItemGroup('align', {\n label: ['align.label', { ns: meta.profile.key }],\n variant: 'toggleGroup',\n selectCardinality: 'single',\n value: `${SheetRange.alignKey}--${value}`,\n } as ToolbarMenuActionGroupProperties);\n\ntype AlignActionsContext = {\n model: SheetModel;\n state: ToolbarState;\n stateAtom: ToolbarStateAtom;\n registry: Registry.AtomRegistry;\n cursorFallbackRange?: CompleteCellRange;\n};\n\nconst createAlignActions = ({ model, state, stateAtom, registry, cursorFallbackRange }: AlignActionsContext) =>\n Object.entries(aligns).map(([alignValue, icon]) => {\n return createMenuAction<AlignAction>(\n `${SheetRange.alignKey}--${alignValue}`,\n () => {\n if (!cursorFallbackRange) {\n return;\n }\n const index =\n model.sheet.ranges?.findIndex(\n (range) =>\n range.key === SheetRange.alignKey &&\n inRange(SheetUtil.rangeFromIndex(model.sheet, range.range), cursorFallbackRange.from),\n ) ?? -1;\n const nextRangeEntity = {\n range: SheetUtil.rangeToIndex(model.sheet, cursorFallbackRange),\n key: SheetRange.alignKey,\n value: alignValue as SheetRange.AlignValue,\n };\n const currentState = registry.get(stateAtom);\n if (index < 0) {\n Obj.update(model.sheet, (obj) => {\n obj.ranges?.push(nextRangeEntity);\n });\n registry.set(stateAtom, { ...currentState, [SheetRange.alignKey]: nextRangeEntity.value });\n } else if (model.sheet.ranges![index].value === nextRangeEntity.value) {\n Obj.update(model.sheet, (obj) => {\n obj.ranges?.splice(index, 1);\n });\n registry.set(stateAtom, { ...currentState, [SheetRange.alignKey]: undefined });\n } else {\n Obj.update(model.sheet, (obj) => {\n obj.ranges?.splice(index, 1, nextRangeEntity);\n });\n registry.set(stateAtom, { ...currentState, [SheetRange.alignKey]: nextRangeEntity.value });\n }\n },\n {\n key: SheetRange.alignKey,\n value: alignValue as SheetRange.AlignValue,\n checked: state[SheetRange.alignKey] === alignValue,\n label: [`range-value.${alignValue}.label`, { ns: meta.profile.key }],\n icon,\n testId: `grid.toolbar.${SheetRange.alignKey}.${alignValue}`,\n },\n );\n });\n\nexport const createAlign = (context: AlignActionsContext): ActionGraphProps => {\n const alignGroup = createAlignGroupAction(context.state[SheetRange.alignKey]);\n const alignActions = createAlignActions(context);\n return {\n nodes: [alignGroup, ...alignActions],\n edges: [\n { source: 'root', target: 'align', relation: 'child' },\n ...alignActions.map(({ id }) => ({ source: alignGroup.id, target: id, relation: 'child' })),\n ],\n };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { RegistryContext } from '@effect/atom-react/RegistryContext';\nimport type * as Registry from 'effect/reactivity/AtomRegistry';\nimport { useContext, useEffect } from 'react';\n\nimport { type CompleteCellRange, inRange } from '@dxos/compute-hyperformula';\nimport { Obj } from '@dxos/echo';\nimport {\n type ActionGraphProps,\n type ToolbarMenuActionGroupProperties,\n createMenuAction,\n createMenuItemGroup,\n} from '@dxos/react-ui-menu';\n\nimport { meta } from '#meta';\nimport { SheetRange, SheetUtil } from '#types';\n\nimport { type SheetModel } from '../../model/index.ts';\nimport { useSheetContext } from '../SheetRoot/index.ts';\nimport { type ToolbarState, type ToolbarStateAtom } from './useToolbarState.ts';\n\nexport type StyleState = Partial<Record<SheetRange.StyleValue, boolean>>;\n\nexport type StyleAction = { key: SheetRange.StyleKey; value: SheetRange.StyleValue };\n\nconst styles: Record<SheetRange.StyleValue, string> = {\n highlight: 'ph--highlighter--regular',\n softwrap: 'ph--paragraph--regular',\n};\n\nexport const useStyleState = (stateAtom: ToolbarStateAtom) => {\n const registry = useContext(RegistryContext);\n const { cursorFallbackRange, model } = useSheetContext();\n\n useEffect(() => {\n let highlight = false;\n let softwrap = false;\n if (cursorFallbackRange && model.sheet.ranges) {\n model.sheet.ranges\n .filter(\n ({ range, key }) =>\n key === 'style' && inRange(SheetUtil.rangeFromIndex(model.sheet, range), cursorFallbackRange.from),\n )\n .forEach(({ value }) => {\n if (value === 'highlight') {\n highlight = true;\n }\n if (value === 'softwrap') {\n softwrap = true;\n }\n });\n }\n const prev = registry.get(stateAtom);\n registry.set(stateAtom, { ...prev, highlight, softwrap });\n }, [cursorFallbackRange, model.sheet, registry, stateAtom]);\n};\n\nconst createStyleGroup = (state: StyleState) => {\n return createMenuItemGroup('style', {\n variant: 'toggleGroup',\n selectCardinality: 'multiple',\n value: Object.keys(styles)\n .filter((key) => !!state[key as SheetRange.StyleValue])\n .map((styleValue) => `style--${styleValue}`),\n } as ToolbarMenuActionGroupProperties);\n};\n\ntype StyleActionsContext = {\n model: SheetModel;\n state: ToolbarState;\n stateAtom: ToolbarStateAtom;\n registry: Registry.AtomRegistry;\n cursorFallbackRange?: CompleteCellRange;\n};\n\nconst createStyleActions = ({ model, state, stateAtom, registry, cursorFallbackRange }: StyleActionsContext) =>\n Object.entries(styles).map(([styleValue, icon]) => {\n return createMenuAction<StyleAction>(\n `style--${styleValue}`,\n () => {\n if (!cursorFallbackRange) {\n return;\n }\n const index =\n model.sheet.ranges?.findIndex(\n (range) =>\n range.key === 'style' &&\n inRange(SheetUtil.rangeFromIndex(model.sheet, range.range), cursorFallbackRange.from),\n ) ?? -1;\n const nextRangeEntity = {\n range: SheetUtil.rangeToIndex(model.sheet, cursorFallbackRange),\n key: 'style',\n value: styleValue as SheetRange.StyleValue,\n };\n const currentState = registry.get(stateAtom);\n if (\n model.sheet.ranges\n .filter(\n ({ range, key: rangeKey }) =>\n rangeKey === 'style' && inRange(SheetUtil.rangeFromIndex(model.sheet, range), cursorFallbackRange.from),\n )\n .some(({ value: rangeValue }) => rangeValue === styleValue)\n ) {\n // this value should be unset\n if (index >= 0) {\n Obj.update(model.sheet, (obj) => {\n obj.ranges?.splice(index, 1);\n });\n }\n registry.set(stateAtom, { ...currentState, [nextRangeEntity.value]: false });\n } else {\n Obj.update(model.sheet, (obj) => {\n obj.ranges?.push(nextRangeEntity);\n });\n registry.set(stateAtom, { ...currentState, [nextRangeEntity.value]: true });\n }\n },\n {\n key: 'style',\n value: styleValue as SheetRange.StyleValue,\n icon,\n label: [`range-value.${styleValue}.label`, { ns: meta.profile.key }],\n checked: !!state[styleValue as SheetRange.StyleValue],\n },\n );\n });\n\nexport const createStyle = (context: StyleActionsContext): ActionGraphProps => {\n const styleGroupAction = createStyleGroup(context.state);\n const styleActions = createStyleActions(context);\n return {\n nodes: [styleGroupAction, ...styleActions],\n edges: [\n { source: 'root', target: 'style', relation: 'child' },\n ...styleActions.map(({ id }) => ({ source: styleGroupAction.id, target: id, relation: 'child' })),\n ],\n };\n};\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Atom from 'effect/reactivity/Atom';\nimport { useMemo } from 'react';\n\nimport { type AlignState } from './align.ts';\nimport { type StyleState } from './style.ts';\n\nexport type ToolbarState = Partial<StyleState & AlignState>;\nexport type ToolbarStateAtom = Atom.Writable<ToolbarState>;\n\n/**\n * Creates a reactive toolbar state Atom.\n */\nexport const useToolbarState = (initialState: ToolbarState = {}): ToolbarStateAtom => {\n return useMemo(() => Atom.make<ToolbarState>(initialState).pipe(Atom.keepAlive), []);\n};\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport { RegistryContext } from '@effect/atom-react/RegistryContext';\nimport * as Atom from 'effect/reactivity/Atom';\nimport type * as Registry from 'effect/reactivity/AtomRegistry';\nimport React, { useContext, useMemo } from 'react';\n\nimport * as Hooks from '@dxos/app-toolkit/Hooks';\nimport { type CompleteCellRange } from '@dxos/compute-hyperformula';\nimport {\n type ActionGraphProps,\n ActionToolbar,\n createGapSeparator,\n graphActions,\n isToolbarAction,\n useMenuActions,\n} from '@dxos/react-ui-menu';\nimport * as Util from '@dxos/react-ui/Util';\n\nimport { type SheetModel } from '../../model/index.ts';\nimport { useSheetContext } from '../SheetRoot/index.ts';\nimport { createAlign, useAlignState } from './align.ts';\nimport { createStyle, useStyleState } from './style.ts';\nimport { type ToolbarStateAtom, useToolbarState } from './useToolbarState.ts';\n\ntype ToolbarActionsContext = {\n model: SheetModel;\n stateAtom: ToolbarStateAtom;\n registry: Registry.AtomRegistry;\n cursorFallbackRange?: CompleteCellRange;\n customActions?: Atom.Atom<ActionGraphProps>;\n};\n\nconst createToolbarActions = ({\n model,\n stateAtom,\n registry,\n cursorFallbackRange,\n customActions,\n}: ToolbarActionsContext): Atom.Atom<ActionGraphProps> => {\n return Atom.make((get) => {\n const state = get(stateAtom);\n const context = { model, state, stateAtom, registry, cursorFallbackRange };\n const align = createAlign(context);\n const style = createStyle(context);\n const gap = createGapSeparator();\n\n const graph: ActionGraphProps = {\n nodes: [...align.nodes, ...style.nodes, ...gap.nodes],\n edges: [...align.edges, ...style.edges, ...gap.edges],\n };\n\n if (customActions) {\n const custom = get(customActions);\n graph.nodes.push(...custom.nodes);\n graph.edges.push(...custom.edges);\n }\n\n return graph;\n });\n};\n\nexport type SheetToolbarProps = {};\n\nexport const SheetToolbar = Util.composable<HTMLDivElement, SheetToolbarProps>((props, forwardedRef) => {\n const { attendableId, model, cursorFallbackRange } = useSheetContext();\n const stateAtom = useToolbarState({});\n const registry = useContext(RegistryContext);\n useAlignState(stateAtom);\n useStyleState(stateAtom);\n\n const { graph } = Hooks.useAppGraph();\n const customActions = useMemo(() => {\n return Atom.make((get) => graphActions(graph, get, attendableId, { filter: isToolbarAction }));\n }, [graph, attendableId]);\n\n const actionsCreator = useMemo(\n () => createToolbarActions({ model, stateAtom, registry, cursorFallbackRange, customActions }),\n [model, stateAtom, registry, cursorFallbackRange, customActions],\n );\n const menuActions = useMenuActions(actionsCreator);\n\n return (\n <ActionToolbar {...menuActions} attendableId={attendableId} {...Util.composableProps(props)} ref={forwardedRef} />\n );\n});\n\nSheetToolbar.displayName = 'SheetToolbar';\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { SheetContent } from '../SheetContent/index.ts';\nimport { SheetRoot } from '../SheetRoot/index.ts';\nimport { SheetStatusbar } from '../SheetStatusbar/index.ts';\nimport { SheetToolbar } from '../SheetToolbar/index.ts';\n\nexport { type SheetContextValue, type SheetRootProps } from '../SheetRoot/index.ts';\nexport { type SheetContentProps } from '../SheetContent/index.ts';\nexport { type SheetToolbarProps } from '../SheetToolbar/index.ts';\nexport { type SheetStatusbarProps } from '../SheetStatusbar/index.ts';\n\nexport const Sheet = {\n Root: SheetRoot,\n Toolbar: SheetToolbar,\n Content: SheetContent,\n Statusbar: SheetStatusbar,\n};\n"],"mappings":"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"}
package/dist/lib/meta.mjs CHANGED
@@ -25,7 +25,11 @@ var dx_config_default = Config2.make({ plugin: {
25
25
  },
26
26
  source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-sheet",
27
27
  spec: "PLUGIN.mdl",
28
- screenshots: [{ dark: "https://media.dxos.network/plugin-details-sheet-dark.png" }, { dark: "https://pub-39066a86073446d7b77b1c157b660bb5.r2.dev/demos/2026-08-27-qa-flows/plugin-sheet-QA-1.webm" }],
28
+ screenshots: [
29
+ { dark: "https://media.dxos.network/plugin-details-sheet-dark.png" },
30
+ { dark: "https://pub-39066a86073446d7b77b1c157b660bb5.r2.dev/demos/2026-08-27-qa-flows/plugin-sheet-QA-1.webm" },
31
+ { dark: "https://assets.composer.space/demos/2026-10-09-plugin-sheet.mp4?v=f7e67bab" }
32
+ ],
29
33
  tags: ["alpha"]
30
34
  } });
31
35
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"meta.mjs","names":[],"sources":["../../dx.config.ts","../../src/meta.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Config2 } from '@dxos/app-framework/config';\nimport { trim } from '@dxos/util';\n\nexport default Config2.make({\n plugin: {\n key: 'org.dxos.plugin.sheet',\n name: 'Sheet',\n author: 'DXOS',\n description: trim`\n Full-featured spreadsheet for DXOS Composer backed by ECHO for local-first, real-time collaborative editing.\n Cells, row/column metadata, and range-based formatting are all stored as ECHO objects and replicated to peers instantly.\n\n Formula evaluation is powered by HyperFormula, providing over 400 built-in functions covering arithmetic, statistics,\n text manipulation, date/time, financial, and logical operations. Formulas are stored with internal cell indices and\n translated to A1-notation on display, keeping references stable across row and column insertions.\n\n The plugin integrates with plugin-markdown to expose formula results inside document fenced code blocks, and\n contributes anchor-navigation support so other plugins can scroll and highlight specific cell ranges by DXN reference.\n AI agents can invoke sheet operations — insert/drop axes, scroll to anchor, and read or write cell values — through\n the standard operations framework.\n `,\n icon: { key: 'ph--grid-nine--regular', hue: 'indigo' },\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-sheet',\n spec: 'PLUGIN.mdl',\n screenshots: [\n { dark: 'https://media.dxos.network/plugin-details-sheet-dark.png' },\n { dark: 'https://pub-39066a86073446d7b77b1c157b660bb5.r2.dev/demos/2026-08-27-qa-flows/plugin-sheet-QA-1.webm' },\n ],\n tags: ['alpha'],\n },\n});\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Plugin from '@dxos/app-framework/Plugin';\n\nimport config from '../dx.config.ts';\n\nexport const meta = Plugin.getMetaFromConfig(config);\n"],"mappings":";;;;AAOA,IAAA,oBAAe,QAAQ,KAAK,EAC1B,QAAQ;CACN,KAAK;CACL,MAAM;CACN,QAAQ;CACR,aAAa,IAAI;;;;;;;;;;;;;CAajB,MAAM;EAAE,KAAK;EAA0B,KAAK;CAAS;CACrD,QAAQ;CACR,MAAM;CACN,aAAa,CACX,EAAE,MAAM,2DAA2D,GACnE,EAAE,MAAM,uGAAuG,CACjH;CACA,MAAM,CAAC,OAAO;AAChB,EACF,CAAC;;;AC1BD,IAAa,OAAO,OAAO,kBAAkB,iBAAM"}
1
+ {"version":3,"file":"meta.mjs","names":[],"sources":["../../dx.config.ts","../../src/meta.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Config2 } from '@dxos/app-framework/config';\nimport { trim } from '@dxos/util';\n\nexport default Config2.make({\n plugin: {\n key: 'org.dxos.plugin.sheet',\n name: 'Sheet',\n author: 'DXOS',\n description: trim`\n Full-featured spreadsheet for DXOS Composer backed by ECHO for local-first, real-time collaborative editing.\n Cells, row/column metadata, and range-based formatting are all stored as ECHO objects and replicated to peers instantly.\n\n Formula evaluation is powered by HyperFormula, providing over 400 built-in functions covering arithmetic, statistics,\n text manipulation, date/time, financial, and logical operations. Formulas are stored with internal cell indices and\n translated to A1-notation on display, keeping references stable across row and column insertions.\n\n The plugin integrates with plugin-markdown to expose formula results inside document fenced code blocks, and\n contributes anchor-navigation support so other plugins can scroll and highlight specific cell ranges by DXN reference.\n AI agents can invoke sheet operations — insert/drop axes, scroll to anchor, and read or write cell values — through\n the standard operations framework.\n `,\n icon: { key: 'ph--grid-nine--regular', hue: 'indigo' },\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-sheet',\n spec: 'PLUGIN.mdl',\n screenshots: [\n { dark: 'https://media.dxos.network/plugin-details-sheet-dark.png' },\n { dark: 'https://pub-39066a86073446d7b77b1c157b660bb5.r2.dev/demos/2026-08-27-qa-flows/plugin-sheet-QA-1.webm' },\n { dark: 'https://assets.composer.space/demos/2026-10-09-plugin-sheet.mp4?v=f7e67bab' },\n ],\n tags: ['alpha'],\n },\n});\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Plugin from '@dxos/app-framework/Plugin';\n\nimport config from '../dx.config.ts';\n\nexport const meta = Plugin.getMetaFromConfig(config);\n"],"mappings":";;;;AAOA,IAAA,oBAAe,QAAQ,KAAK,EAC1B,QAAQ;CACN,KAAK;CACL,MAAM;CACN,QAAQ;CACR,aAAa,IAAI;;;;;;;;;;;;;CAajB,MAAM;EAAE,KAAK;EAA0B,KAAK;CAAS;CACrD,QAAQ;CACR,MAAM;CACN,aAAa;EACX,EAAE,MAAM,2DAA2D;EACnE,EAAE,MAAM,uGAAuG;EAC/G,EAAE,MAAM,6EAA6E;CACvF;CACA,MAAM,CAAC,OAAO;AAChB,EACF,CAAC;;;AC3BD,IAAa,OAAO,OAAO,kBAAkB,iBAAM"}
@@ -1 +1 @@
1
- {"version":3,"file":"SheetStatusbar.d.ts","sourceRoot":"","sources":["../../../../../src/components/SheetStatusbar/SheetStatusbar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAW1B,MAAM,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAErC,eAAO,MAAM,cAAc;;6GAoCzB,CAAC"}
1
+ {"version":3,"file":"SheetStatusbar.d.ts","sourceRoot":"","sources":["../../../../../src/components/SheetStatusbar/SheetStatusbar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAW1B,MAAM,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAErC,eAAO,MAAM,cAAc;;6GAmCzB,CAAC"}