Development Guide
This guide covers the development workflow, tools, and best practices for contributing to GridSheet.
Development Setup
Prerequisites
- Node.js: Version 24.1.0
- pnpm: For package management
- Git: For version control
Installation
# Clone the repository
git clone https://github.com/your-org/gridsheet.git
cd gridsheet
# Install dependencies
pnpm install
Development Scripts
# Start Storybook development server
pnpm dev
# Start documentation development server
pnpm doc
# Run unit tests
pnpm test
# Run e2e tests (uses server)
pnpm e2e
# Run linting and apply prettier
pnpm lint:fix
Testing Strategy
Testing Policy
GridSheet follows a specific testing strategy:
- Formula Functions: When adding new formula functions, unit tests are required
- Other Features: All other features are covered by e2e tests
- Component Behavior: Use e2e tests to verify component interactions and user workflows
- Integration: E2e tests ensure proper integration between components
E2E Test Example
import { test, expect } from '@playwright/test';
import { ctrl, drag, paste } from './utils';
test('time + delta, time + number(days)', async ({ page }) => {
await page.goto('http://localhost:5233/iframe.html?id=basic-simple--sheet&viewMode=story');
const a4 = page.locator("[data-address='A4']");
const b4 = page.locator("[data-address='B4']");
const c4 = page.locator("[data-address='C4']");
const a5 = page.locator("[data-address='A5']");
expect(await a4.locator('.gs-cell-rendered').textContent()).toBe('2022-03-05 12:34:56');
expect(await b4.locator('.gs-cell-rendered').textContent()).toBe('11:11:11');
expect(await c4.locator('.gs-cell-rendered').textContent()).toBe('2022-03-05 23:46:07');
expect(await a5.locator('.gs-cell-rendered').textContent()).toBe('2022-03-04 23:34:56');
});
Available Utilities:
The E2E test suite provides utility functions for common operations:
ctrl
: Helper for Ctrl key combinationsdrag
: Helper for drag and drop operationspaste
: Helper for paste operations
These utilities are available in e2e/utils.ts
and can be imported to simplify test writing.
Formula Functions
Creating Custom Formula Functions
When adding new formula functions to GridSheet, follow these guidelines:
Google Spreadsheet Compatibility
When adding new functions, prioritize those that are also supported by Google Spreadsheet:
- Target Functions: Focus on functions that exist in Google Sheets
- Specification Matching: Follow Google Sheets' function specifications and behavior
- Parameter Compatibility: Match argument types, order, and validation rules
- Return Value Consistency: Ensure return values match Google Sheets' behavior
- Error Handling: Implement the same error conditions and messages
BaseFunction Inheritance
All custom formula functions must extend the BaseFunction
class:
import { BaseFunction, ensureString } from '@gridsheet/react-core';
class CustomFunction extends BaseFunction {
// Required properties for documentation
example = 'CUSTOM_FUNCTION("value", 123)';
helpText = ['Performs a custom operation on the input values'];
helpArgs = [
{ name: 'value', description: 'The input value to process' },
{ name: 'number', description: 'A numeric parameter' }
];
// Required validation method
protected validate() {
if (this.bareArgs.length !== 2) {
throw new Error('CUSTOM_FUNCTION requires exactly 2 arguments');
}
// Ensure proper types
this.bareArgs[0] = ensureString(this.bareArgs[0]);
this.bareArgs[1] = Number(this.bareArgs[1]);
}
// Required main implementation
protected main(value: string, number: number) {
// Your custom logic here
return `Processed: ${value} with ${number}`;
}
}
Documentation Properties
Every formula function must include these properties for future help system integration:
example
: Shows how to use the function in a formulahelpText
: Array of description strings explaining what the function doeshelpArgs
: Array of argument descriptions with name and description
Function Registration
Functions must be registered in formula/mapping.ts
:
// formula/mapping.ts
import { CustomFunction } from './functions/CustomFunction';
export const functions = {
// ... existing functions
CUSTOM_FUNCTION: CustomFunction,
};
Documentation
API Documentation
# Start documentation development server
pnpm doc
# Build documentation
pnpm build:docs
Storybook
# Start Storybook development server
pnpm dev
# Build Storybook
pnpm build:storybook
Contributing
Pull Request Process
- Create Feature Branch:
git checkout -b feature/new-feature
- Make Changes: Implement your feature
- Run Tests: Ensure all tests pass (
pnpm test
) - Update Documentation: Update relevant docs
- Submit PR: Create pull request with description
Code Review Checklist
- Code follows style guidelines
- Tests are included and passing
- Documentation is updated
- No breaking changes (or documented)
- Performance impact considered
Release Process
- Version Bump: Update version in package.json
- Build: Run full build and test suite
- Publish: Publish to npm