UNPKG

@sunnysideup/npm-page-favourites-bookmarker

Version:
180 lines (129 loc) 5.12 kB
# @sunnysideup/npm-page-favourites-bookmarker Tiny in-page bookmark manager with a heart button, overlay list, and optional server sync (email/phone verification supported). ## Features - Heart button on every page to toggle bookmark (saves URL + title). - Overlay list of bookmarks (hotkey toggle), with remove and drag-to-sort. - Uses `localStorage` or `sessionStorage`. - Optional server sync: - Sends events on add/remove/sort. - If logged in, it can sync with existing lists - Zero dependencies, plain ESM. ## Install ```bash npm i @sunnysideup/npm-page-favourites-bookmarker ``` ## Usage ### with a bundler (Vite/Webpack/Rollup) ```js import { PageFaves } from '@sunnysideup/npm-page-favourites-bookmarker'; ``` ```scss @import "@sunnysideup/npm-page-favourites-bookmarker/styles"; ``` ### without a bundler (Vite/Webpack/Rollup) Check where `node_modules` lives ...and then add this (with additional path segments, if needed). ```html <link rel="stylesheet" href="/node_modules/@sunnysideup/npm-page-favourites-bookmarker/src/index.css"> <script type="module"> import { PageFaves } from '/node_modules/@sunnysideup/npm-page-favourites-bookmarker/src/index.js' </script> ``` ### initialising the module (with or without a bundler (Vite/Webpack/Rollup)) #### Initialising the module ```js import { PageFaves } from '@sunnysideup/npm-page-favourites-bookmarker' const pf = new PageFaves({ storage: 'local', // or 'session' baseUrl: 'https://api.example.com/my-controller', // enables server I/O endpoints: { events: '/track', bookmarks: '/user/bookmarks' }, heartPositionLeftRight: 'right', // 'left' | 'right' heartPositionTopBottom: 'bottom', // 'top' | 'bottom' overlayHotkey: 'KeyB', // press CTRL+SHIFT+B syncOnLoad: true }) pf.init() ``` ### Per-page configuration (page wins) Add a small script before you import/initialise: ```html <script> window.npmPageFavouritesBookmarker = { // whether to render on this page (overrides defaults and constructor opts) loadOnThisPage: true, // login awareness for overlay userIsLoggedIn: false, loginUrl: '/account/login', // optional positioning overrides heartPositionLeftRight: 'right', heartPositionTopBottom: 'bottom' } </script> ``` ### Customising templates (optional) You can override any template in templates. Example: ```js import { PageFaves } from '@sunnysideup/npm-page-favourites-bookmarker' import { defaultTemplates } from '@sunnysideup/npm-page-favourites-bookmarker/src/ui/templates.js' import '@sunnysideup/npm-page-favourites-bookmarker/src/index.css' const pf = new PageFaves({ templates: { heart: ({ onClick, onShowOverlay, position, isOn }) => { const wrap = document.createElement('div') wrap.className = `my-heart-wrap my-${position.leftRight} my-${position.topBottom}` const open = document.createElement('button') open.textContent = '≡' open.addEventListener('click', e => { e.preventDefault(); onShowOverlay() }) wrap.append(open) const btn = document.createElement('button') btn.textContent = isOn() ? '★' : '☆' btn.addEventListener('click', e => { e.preventDefault(); onClick() }) wrap.append(btn) return wrap }, overlayBar: (args) => defaultTemplates.overlayBar(args), overlayShell: () => { const wrap = document.createElement('div'); wrap.className = 'my-overlay' const list = document.createElement('div'); list.className = 'my-overlay-list' wrap.append(list); return { wrap, list } }, overlayRow: ({ item }) => { const row = document.createElement('div') row.className = 'my-row' row.textContent = item.title || item.url row.addEventListener('click', () => window.open(item.url, '_blank')) return row } } }) pf.init() ``` ## Hotkeys - **Open overlay:** CTRL + SHIFT + B (uses overlayHotkey: 'KeyB'). - **Close overlay:** ESC. ## Server sync behaviour No network calls are made unless `baseUrl` is provided. On `init()`, if `syncOnLoad` is true and `userIsLoggedIn` is true, the client pulls bookmarks from {bookmarks} and merges with local. This initial pull is throttled to at most once every 10 minutes. Every add/remove/reorder triggers a POST {events}. ## API ### Bookmark methods - `add(url, title)` → add a bookmark - `remove(url)` → remove bookmark - `toggleCurrent()` → toggle current page - `list()` → get all bookmarks - `isBookmarked(url)` → check if URL is saved ### Overlay - `showOverlay()` - `hideOverlay()` ### sync - `syncFromServer()` → pull bookmarks and and merge with local (only if baseUrl set) #### Server Endpoints You can override each endpoint individually in `endpoints`. - `POST {events}` → `{ type, payload, at }` (called on add/remove/reorder) - `GET {bookmarks}` → `[{ url, title, ts }]` ## Back-end Server Integration If you use Silverstripe CMS, check out the integration package: [sunnysideup/silverstripe-page-favourites-bookmarker](https://github.com/sunnysideup/silverstripe-page-favourites-bookmarker)