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 🙏

© 2024 – Pkg Stats / Ryan Hefner

sidenotes

v1.1.1

Published

[![sidenotes on npm](https://img.shields.io/npm/v/sidenotes.svg)](https://www.npmjs.com/package/sidenotes) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/curvenote/sidenotes/main/LICENSE) ![CI](https://github.com/cu

Downloads

15

Readme

sidenotes

sidenotes on npm MIT License CI demo

Position floating sidenotes/comments next to a document with inline references.

Goals

  • Place notes/comments to the side of one or more documents with inline references.
  • When an inline reference is clicked, animate the relevant sidenote to be as close as possible and move non-relevant sidenotes out of the way without overlapping.
  • Do not provide UI or impose any styling, only placement.

Use cases

  • Comment streams next to a document. This is showing Curvenote, which is a scientific writing platform that connects to Jupyter. Comments Using Sidenotes

Choices

  • Use React, Redux & Typescript
  • Used Redux rather than a hook approach (open to discussion if people are passionate!)

Constraints

  • Multiple documents on the page, currently based on the wrapping <article> ID
  • Multiple inline references per sidenote, wrapped in <InlineAnchor>; InlineAnchor is a span
  • Have fallback placements to a <AnchorBase>; AnchorBase is a div
  • Provide actions to attach non-react bases, anchors or reposition sidenotes
  • All positioning is based on the article, and works with relative, fixed or absolute positioning.

Demo

The demo is pretty basic, and not nearly as pretty as the gif above, just blue, green and red divs floating around. See index.tsx for full the code/setup.

yarn install
yarn start

sidenotes

Getting Started:

yarn add sidenotes

React Setup:

<article id="{docId}" onClick="{deselect}">
  <AnchorBase anchor="{baseId}">
    Content with <InlineAnchor sidenote="{sidenoteId}">inline reference</InlineAnchor>
  </AnchorBase>
  <div className="sidenotes">
    <Sidenote sidenote="{sidenoteId}" base="{baseId}"> Your custom UI, e.g. a comment </Sidenote>
  </div>
</article>

The sidenotes class is the only CSS that is recommended. You can import it directly, or look at it and change it (~30 lines of scss). To import from javascript (assuming your bundler works with CSS):

import 'sidenotes/dist/sidenotes.css';

Simple Javascript

You can also use sidenotes from vanilla javascript, this is done by first connecting the ID.

// First dispatch the action to connect to any ID in the dom
store.dispatch(actions.connectAnchor(docId, sidenoteId, anchorId));

// Then setup your handlers to select that anchor on click
<span
  id={anchorId}
  onClickCapture={(event) => {
    event.stopPropagation();
    store.dispatch(actions.selectAnchor(docId, anchorId));
  }}
>
  Select a Sidenote with JavaScript! 🚀
</span>;

// To clean up later, disconnect the anchor
store.dispatch(actions.disconnectAnchor(docId, anchorId));

Redux state

Once you create your own store, add a sidenotes.reducer, it must be called sidenotes. Then pass the store to setup with options of padding between sidenotes.

import { combineReducers, applyMiddleware, createStore } from 'redux';
import thunkMiddleware from 'redux-thunk';
import * as sidenotes from 'sidenotes';

const reducer = combineReducers({
  yourStuff: yourReducers,
  sidenotes: sidenotes.reducer, // Add this to your reducers
});
// Create your store as normal, must have thunkMiddleware
const store = createStore(reducer, applyMiddleware(thunkMiddleware));

// Then ensure that you pass the `store` to setup the sidenotes
sidenotes.setup(store as sidenotes.Store, { padding: 10 })

Redux State

The sidenotes.ui state has the following structure:

sidenotes:
  ui:
    docs:
      [docId]:
        anchors:
          [anchorId]: { id: string, sidenote: string, element: [span] }
        sidenotes:
          [sidenoteId]: { inlineAnchors: string[], top: number, id: string, baseAnchors: string[] }
        id: string
        selectedAnchor: string
        selectedNote: string

Actions

It is common to put a click handler on the body (or similar) to deselect any sidenotes. This can be difficult to stop in some cases, but can be anticipated with a onClickCapture that fires the disableNextDeselectSidenote action. This intercepts the redux action and stops it from happening for one time.

Roadmap

  • Have a better mobile solution that places notes at the bottom.