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

@tumblerjs/svelte

v0.1.0-alpha.24

Published

Replaceable Svelte components for Tumbler document models.

Readme

@tumblerjs/svelte

Replaceable Svelte 5 UI heads for Tumbler document models. Applications retain complete ownership of their surrounding interface and styling.

Extremely early alpha. Components and props can change without notice, and Office-format coverage remains incomplete.

bun add @tumblerjs/svelte @tumblerjs/sheets @tumblerjs/core
<script lang="ts">
  import { createGridSelection } from "@tumblerjs/core";
  import { FormattingToolbar, SpreadsheetFormulaBar, SpreadsheetGrid } from "@tumblerjs/svelte";

  let selection = $state(createGridSelection({ row: 1, column: 1 }));
</script>

<SpreadsheetFormulaBar worksheet={artifact.worksheet} reference="A1" />
<FormattingToolbar
  state={artifact.formattingState(selection.range)}
  capabilities={artifact.formattingCapabilities(selection.range)}
  onformat={(patch) => artifact = artifact.applyFormatting(selection.range, patch)}
/>
<SpreadsheetGrid
  worksheet={artifact.worksheet}
  calculation={artifact.calculation}
  {selection}
  onselectionchange={(next) => selection = next}
/>

FormattingToolbar is format-neutral. Word, Sheets, and Slides supply the same state and capability contract without replacing application UI. Its font-family field writes arbitrary Office font names rather than limiting files to a browser-dependent preset list.

The grid automatically projects supported conditional font, fill, and border rules from the worksheet. Its source rules and package bytes remain unchanged.

Inline grid edits are always literals. The explicit formula bar treats input beginning with = as a formula and emits a typed formula edit; applications own applying the edit and replacing the artifact.

Unwrapped left-aligned text paints across consecutive empty cells, matching the worksheet convention without widening those cells' interactive hit areas.

The Word head exposes controlled selection and editing without making the DOM canonical state:

<WordDocumentView
  wordDocument={session.artifact.document}
  editable
  {selection}
  onselectionchange={(next) => selection = next}
  ondrawingchange={(change) => session.updateDrawing(change)}
  onedit={(edit) => {
    session.replaceText(edit.selection, edit.value);
    selection = { anchor: edit.caret, focus: edit.caret };
  }}
/>

In edit mode, ondrawingchange enables dragging, eight resize handles, and inline, in-front-of-text, or behind-text placement. Corners preserve proportions; edges resize one dimension. Dragging an inline drawing moves it within the text flow without changing its layout. Arrow keys nudge a focused floating drawing, Shift increases the step, and Escape cancels a drag. Changing the document zoom also cancels an active drawing drag or resize. session.updateDrawing(change) records the position and dimensions as one undoable revision and saves them in the DOCX. Square and tight wrapping are not exposed. Hosts needing only the bottom-right resize handle can still use ondrawingresize with session.resizeDrawing(size).

Word and Sheets support Ctrl+wheel, two-finger touch, and Safari trackpad pinch zoom inside the document viewport without magnifying the surrounding application.

Drawing previews and handles remain inside the rendered page. Clipping does not change document geometry: floating drawings can have negative page offsets or extend beyond the page, and resizing does not impose page or column size limits. The headless engine validates serialized dimensions and signed OOXML position offsets.

Custom document renderers can import WordDrawingView from @tumblerjs/svelte to reuse the same image/chart rendering, selection, dragging, resize handles, and keyboard controls. Pass the layout fragment's drawing, width, height, pageX, and pageY in points, plus position as CSS positioning within your page. The host applies CSS zoom or a transform to the page and passes that factor as scale for gesture coordinates and handle sizing. The host supplies editable, selected, imageurl, inlinePosition for text hit-testing, onselect, and onchange or onresize for committing edits. The component renders in place; it never attaches controls to document.body. Put it inside a positioned, clipped page container, such as position: relative; overflow: hidden, to keep previews and handles out of surrounding UI. WordDocumentView already provides that container.

Applications own history and persistence, or can use WordEditingSession from @tumblerjs/word. Internal bookmark links scroll inside the owned page surface; external targets are passed to the host for its security policy.

PowerPoint

Use the dedicated Slides entry point:

import {
  PresentationSlideView,
  PresentationSlideRail,
  PresentationFormattingToolbar,
} from "@tumblerjs/svelte/slides";

Pass a presentation document and its active slide to PresentationSlideView. Bind PresentationSlideRail to the active slide index for thumbnail navigation. In edit mode, connect object, text, formatting, and shape callbacks to a PresentationEditingSession, then pass the updated document back to the view.

The PowerPoint guide provides complete examples, including undo, redo, and downloading edits. The same guide describes text editing, table-cell navigation, resize handles, and rotation controls.

Tumbler is developed at Kryptonote-Labs/Tumbler.

MIT licensed. See LICENSE.