npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

luckysheet_lite

v1.0.0

Published

A lightweight spreadsheet library for web applications

Readme

luckysheet_lite

A lightweight yet feature-rich spreadsheet library for web applications.

Installation

npm install luckysheet_lite

Basic Usage

<div id="sheet-container"></div>
import LuckySheetLite from 'luckysheet_lite';

const sheet = new LuckySheetLite({
  container: '#sheet-container',
  columns: [
    { header: 'Name', key: 'name', width: 150 },
    { header: 'Age', key: 'age', width: 80, type: 'number' },
    { header: 'Email', key: 'email', width: 200 }
  ],
  data: [
    { name: 'John', age: 30, email: '[email protected]' },
    { name: 'Jane', age: 25, email: '[email protected]' }
  ]
});

Features

1. Sorting

Click column headers to sort ascending/descending.

// Programmatic sorting
sheet.sort('name');

2. Filtering

Each column has a filter input row.

// Programmatic filtering
sheet.setFilter('name', 'john');
sheet.clearFilters();

3. Cell Merge

// Merge cells: startRow, startCol, rowspan, colspan
sheet.mergeCells(0, 0, 2, 2);

// Unmerge
sheet.unmergeCells(0, 0);

4. Copy/Paste

// Copy selected rows
sheet.copySelectedRows();

// Paste at row index
sheet.pasteRows(5);

// Copy single cell to clipboard
sheet.copyCellToClipboard(0, 'name');

5. Export

sheet.exportToCSV('data.csv');
sheet.exportToJSON('data.json');
sheet.exportToExcel('data.xls');

6. Frozen Rows/Columns

const sheet = new LuckySheetLite({
  container: '#sheet',
  columns: [...],
  frozenColumns: 2,  // Freeze first 2 columns
  frozenRows: 1      // Freeze first row
});

7. Pagination

const sheet = new LuckySheetLite({
  container: '#sheet',
  columns: [...],
  pagination: {
    enabled: true,
    pageSize: 25,
    currentPage: 1
  }
});

// Navigate pages
sheet.goToPage(2);

8. Tree Structure (Hierarchical Data)

const sheet = new LuckySheetLite({
  container: '#sheet',
  columns: [
    { header: 'Department', key: 'name', width: 200 },
    { header: 'Budget', key: 'budget', width: 100 }
  ],
  treeMode: true,
  treeColumn: 'name',
  data: [
    { _id: '1', name: 'Engineering', budget: 100000 },
    { _id: '2', _parentId: '1', name: 'Frontend', budget: 40000 },
    { _id: '3', _parentId: '1', name: 'Backend', budget: 60000 },
    { _id: '4', _parentId: '2', name: 'React Team', budget: 20000 }
  ]
});

// Toggle tree node
sheet.toggleTreeNode(0);

9. Checkbox Selection

const sheet = new LuckySheetLite({
  container: '#sheet',
  columns: [...],
  showCheckbox: true,
  showRowNumber: true,
  onRowSelect: (selectedRows) => {
    console.log('Selected:', selectedRows);
  }
});

// Get selected rows
const selected = sheet.getSelectedRows();

// Select rows programmatically
sheet.selectRows([0, 1, 2]);

10. Context Menu (Right-click)

Right-click on any cell to access:

  • Copy / Copy Row / Paste
  • Insert Row Above / Below
  • Delete Row
  • Export CSV / JSON
const sheet = new LuckySheetLite({
  container: '#sheet',
  columns: [...],
  contextMenu: true  // enabled by default
});

11. Column Resize

Drag column borders to resize. Enabled by default.

columns: [
  { header: 'Name', key: 'name', resizable: true },   // default
  { header: 'ID', key: 'id', resizable: false }       // disable resize
]

12. Keyboard Navigation

  • Arrow keys: Navigate cells
  • Enter: Edit cell
  • Escape: Cancel edit
  • Delete: Clear cell
  • Ctrl+C: Copy cell

Full Options

const sheet = new LuckySheetLite({
  // Required
  container: '#sheet-container',
  columns: ColumnConfig[],

  // Data
  data: Record<string, any>[],

  // Appearance
  rowHeight: 30,
  headerHeight: 35,

  // Features
  editable: true,
  showCheckbox: false,
  showRowNumber: false,
  contextMenu: true,

  // Frozen
  frozenColumns: 0,
  frozenRows: 0,

  // Pagination
  pagination: {
    enabled: false,
    pageSize: 50,
    currentPage: 1
  },

  // Tree Mode
  treeMode: false,
  treeColumn: 'firstColumnKey',

  // Callbacks
  onCellChange: (row, col, value) => {},
  onRowSelect: (rows) => {},
  onSort: (column, direction) => {},
  onFilter: (filters) => {},
  onRowExpand: (row, expanded) => {}
});

Column Configuration

interface ColumnConfig {
  header: string;           // Column header text
  key: string;              // Data key
  width?: number;           // Width in pixels
  type?: 'text' | 'number' | 'checkbox' | 'date';
  sortable?: boolean;       // Enable sorting (default: true)
  filterable?: boolean;     // Enable filtering (default: true)
  resizable?: boolean;      // Enable resize (default: true)
  frozen?: boolean;         // Freeze column
}

API Methods

| Method | Description | |--------|-------------| | getCellValue(row, col) | Get cell value | | setCellValue(row, col, value) | Set cell value | | setCellStyle(row, col, style) | Apply cell style | | addRow(data?) | Add row at end | | insertRow(index, data?) | Insert row at index | | removeRow(index) | Remove row | | getData() | Get all data | | setData(data) | Replace all data | | getRowCount() | Get row count | | getColumnCount() | Get column count | | sort(column) | Sort by column | | setFilter(column, value) | Set column filter | | clearFilters() | Clear all filters | | mergeCells(row, col, rowspan, colspan) | Merge cells | | unmergeCells(row, col) | Unmerge cells | | copySelectedRows() | Copy selected rows | | pasteRows(startRow) | Paste rows | | exportToCSV(filename) | Export to CSV | | exportToJSON(filename) | Export to JSON | | exportToExcel(filename) | Export to Excel | | getSelectedRows() | Get selected row indices | | selectRows(rows) | Select rows | | goToPage(page) | Go to page | | toggleTreeNode(row) | Expand/collapse tree node | | refresh() | Re-render sheet | | destroy() | Clean up |

Cell Styling

sheet.setCellStyle(0, 'name', {
  backgroundColor: '#ffeb3b',
  color: '#333',
  fontWeight: 'bold',
  textAlign: 'center',
  fontSize: '16px',
  border: '2px solid red'
});

License

MIT