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

gosling-designer-vec

v0.0.66

Published

[![npm version](https://img.shields.io/npm/v/gosling-designer-vec.svg)](https://www.npmjs.com/package/gosling-designer-vec)

Readme

Gosling Designer VEC

npm version

Gosling is equipped with visualization authoring interfaces, such as graphical template-base, shelf configuration, and natural language interfaces.

VEC (Visualization Editor Component) supports creating and customizing interactive genomics data visualization.

The repo is based on gosling-lang/blace.

Peer Dependencies

gosling-designer-vec externalizes @dnd-kit/core, react, and react-dom so that your application and VEC share the same module instances. Install them alongside VEC:

pnpm add gosling-designer-vec @dnd-kit/core react react-dom

If you don't use @dnd-kit/core yourself, you still need it installed — VEC uses it internally for its drag-and-drop UI. No extra setup is required; VEC wraps itself in its own DndContext by default.

If you do use @dnd-kit/core and need VEC's droppables to participate in your DndContext, see External DnD Context below.

How to Use

Basic Usage

<GoslingDesignerVEC
  visualization={Examples.visualizations[exIndex]} // `GDVis` or `undefined`
  data={Examples.data} // `GDData[]` or `undefined`
  isPublished={false} // Is this visualization published by a user?
  isChatMode={true} // This will hide several panels on the right and show the chatbot interface
  userMode="guest" // 'viewer' | 'editor' | 'admin' | 'guest'
  onPublish={published => {
    console.warn(`The current visualization has been ${published ? 'published' : 'unpublished'}`);
  }}
  onChange={vis => console.warn('The visualization spec has been changed', vis)}
  hideDataPanel={false} // Should the VEC's data panel be hidden?
>
  <div> ... </div> // a child element that will be shown right above the VEC's data panel
</GoslingDesignerVEC>

External DnD Context

If you need to wrap GoslingDesignerVEC alongside your own draggable content in a shared DndContext (from @dnd-kit/core), use the externalDndContext prop together with the exported useGoslingDndHandlers hook and AppStateProvider.

When externalDndContext is set, VEC skips rendering its own DndContext and AppStateProvider, so you must provide both externally.

import {
  GoslingDesignerVEC,
  AppStateProvider,
  useGoslingDndHandlers,
} from 'gosling-designer-vec';
import { DndContext } from '@dnd-kit/core';

function MyDndWrapper({ children, ...vecProps }) {
  const { collisionDetection, onDragStart, onDragEnd, dragOverlay } =
    useGoslingDndHandlers();

  // Optionally customize the drop animation:
  //   useGoslingDndHandlers({ dropAnimation: null })          — disable animation
  //   useGoslingDndHandlers({ dropAnimation: { duration: 200, easing: 'ease' } }) — custom

  return (
    <DndContext
      collisionDetection={collisionDetection}
      onDragStart={onDragStart}
      onDragEnd={onDragEnd}
    >
      <GoslingDesignerVEC {...vecProps} externalDndContext />
      {children}
      {dragOverlay}
    </DndContext>
  );
}

// Wrap everything in AppStateProvider so VEC and your components share state
function App() {
  return (
    <AppStateProvider data={data} visualization={visualization} {...otherProps}>
      <MyDndWrapper visualization={visualization} data={data}>
        {/* your own draggable content */}
      </MyDndWrapper>
    </AppStateProvider>
  );
}

Custom Mode Widget

The bottom-center mode widget (undo/redo, export, publish, etc.) can be replaced or hidden via the ModeWidget prop. Pass a component to fully replace it, null to hide it entirely, or leave it undefined for the default.

A custom widget receives ModeWidgetProps (onJsonImport, onJsonExport, onPngExport, PublishMenu, className) and can read/write the same state as the default via the exported hooks:

import {
  GoslingDesignerVEC,
  ModeWidgetProps,
  useVisualizationValue,
  useUndo,
  useRedo,
  useCanUndo,
  useCanRedo,
  useModeStatus,
  useToggleSetting,
} from 'gosling-designer-vec';

function MyModeWidget({ onJsonExport, onPngExport }: ModeWidgetProps) {
  const vis = useVisualizationValue();
  const undo = useUndo();
  const redo = useRedo();
  const canUndo = useCanUndo();
  const canRedo = useCanRedo();
  const isPresentMode = useModeStatus('isPresentMode');
  const toggle = useToggleSetting();

  return (
    <div className="absolute bottom-4 right-4 flex gap-2 rounded-xl bg-white p-3 shadow-lg">
      <button disabled={!canUndo} onClick={undo}>Undo</button>
      <button disabled={!canRedo} onClick={redo}>Redo</button>
      <button onClick={onJsonExport}>Export JSON</button>
      <button onClick={onPngExport}>Export PNG</button>
      <button onClick={() => toggle('isPresentMode')}>
        {isPresentMode ? 'Edit' : 'Present'}
      </button>
    </div>
  );
}

<GoslingDesignerVEC ModeWidget={MyModeWidget} />
// Or hide it entirely and render your own elsewhere:
<GoslingDesignerVEC ModeWidget={null} />

The default ModeWidget is also exported, so you can wrap or extend it instead of rewriting.

Styling & Layout

Every slot in the layout accepts a Tailwind class override via classNames. Conflicting utilities (widths, backgrounds, etc.) cleanly replace the defaults. The root frame also accepts className and style directly; style is merged onto the root and overrides the default height: calc(100vh - 44px).

<GoslingDesignerVEC
  style={{ height: '100%' }}
  classNames={{
    root: 'rounded-xl shadow-xl bg-white',
    leftPanel: 'w-[320px] bg-slate-50',
    rightPanel: 'w-[360px]',
    bottomPanel: 'h-[320px]',
    canvas: 'bg-white',
    modeWidget: 'top-[16px] bottom-auto', // move the ModeWidget to the top
  }}
/>

Slots: root, leftPanel, rightPanel, bottomPanel, canvas, modeWidget. See FrameClassNames.

Exports

| Export | Type | Description | |---|---|---| | GoslingDesignerVEC | Component | Main editor component | | Examples | Object | Example visualizations and data | | ModeWidget | Component | Default mode widget — exported so you can wrap or extend it | | useGoslingDndHandlers | Hook | DnD handlers for external DndContext integration. Accepts an optional { dropAnimation } to customize or disable (null) the drag overlay animation. | | useVisualizationValue | Hook | Read the current visualization (same atom the default ModeWidget uses) | | useUndo / useRedo | Hook | Trigger undo / redo | | useCanUndo / useCanRedo | Hook | Boolean: whether undo / redo is available | | useActiveStatusOfPanelsAndModesValue | Hook | Read the full mode status object | | useModeStatus | Hook | Read a single field from the mode status (e.g. useModeStatus('isPresentMode')) | | useToggleSetting | Hook | Toggle any field on the mode status (e.g. toggle('isPresentMode')) | | useOnPublishValue | Hook | Read the onPublish callback supplied via props | | useOnAddToWorkspaceValue | Hook | Read the onAddToWorkspace callback supplied via props | | AppStateProvider | Component | Jotai/Bunshi state provider (needed with externalDndContext) | | AppStateProviderProps | Type | Props for AppStateProvider | | FrameProps | Type | Props for GoslingDesignerVEC | | FrameClassNames | Type | Per-slot className overrides (root, leftPanel, rightPanel, bottomPanel, canvas, modeWidget) | | ModeWidgetProps | Type | Props passed to a custom ModeWidget | | ModeStatus | Type | Shape returned by useActiveStatusOfPanelsAndModesValue | | GDData | Type | Data schema type | | DataSchema | Namespace | Data schema definitions | | VisSchema | Namespace | Visualization schema definitions |

Development

Prerequisite

Installing pnpm v10.

Run Demo

pnpm install
pnpm start

This will open the demo website (\demo). Any edits to packages will be updated to the demo page in your browser.

For other commands, refer to the scripts defined in package.json.

Initial Dataset

The initial list of data that needs to be loaded on the Goslign Designer interface can be changed below:

https://github.com/gosling-lang/gosling-designer/blob/fca3de067308e3d5dcaec1c679d1c71283bb5c66/src/views-data-explorer/DataExplorer.tsx#L9

Styling

For styling UI components, we use tailwindcss. This way, we do not create separate CSS files but, instead, add styles directly to className. Refer to its documentation.