@xcwds/plugin-tools

A list of small tools for an @xcwds app: an index page, each tool's own page in the route registry, the tools you pin and the ones you used last on Home, and manifest shortcuts. Generalises xcwds.github.io's /utils.

// xcwds.config.ts
import shell from '@xcwds/plugin-shell';
import tools from '@xcwds/plugin-tools';

export default defineConfig({
	brand,
	plugins: [
		shell({
			sections: [
				{ path: '/', label: 'Home', emoji: '๐Ÿ ' },
				{ path: '/utils', label: 'Utils', emoji: '๐Ÿงฐ' }
			]
		}),
		tools({
			path: '/utils',
			title: 'Utils',
			emoji: '๐Ÿงฐ',
			items: [
				{
					path: '/utils/coffee-timer',
					emoji: 'โ˜•',
					name: 'Coffee Timer',
					blurb: '90-second countdown.',
					shortcut: true
				},
				{ path: '/utils/cycle', emoji: '๐ŸŒ™', name: 'Cycle', blurb: 'Private notes.', private: true }
			]
		})
	]
});
/* src/app.css, after Tailwind and the shell's styles */
@import '@xcwds/plugin-tools/styles.css';

The index page and each tool are thin route files in your app (RFC 0001, decision 2):

<!-- src/routes/utils/+page.svelte -->
<script>
	import ToolList from '@xcwds/plugin-tools/ToolList.svelte';
</script>

<main class="page-wide"><ToolList /></main>

Options

  • path (default /tools), title (default Tools) and emoji: the index page.
  • items: the tools, each { path, name, emoji, blurb, private?, shortcut?, width? }. A tool's route gets its name as the title and the index page as its back target. Its width is narrow (the default) or split, for a tool laid out in two columns on wide screens.
  • private: true keeps a tool out of Recently used, the Share button (its route is marked private) and the manifest. Use it for personal tools, and keep their names and emoji discreet: the index page and pinned tools still show them, and the app may be open on a shared screen.
  • shortcut: true adds the tool to the manifest's shortcuts (the home-screen icon's long-press menu).
  • storageKey: where pins and recents are saved (default app:tools:shortcuts). Set it to keep a key your app already uses, e.g. app:home:shortcuts for an app moving from xcwds.github.io's own code, so users keep their pins.

Home and the page entry

With @xcwds/plugin-shell, Home shows Pinned (in your order, with Edit to move or unpin) and Recently used (the last three tools opened, newest first, leaving out pinned and private ones). Opening a tool records it (afterNavigate), quietly: if storage is blocked, nothing is reported, while a pin that can't be saved shows the shell's "Couldn't save" toast. Both are saved as app:tools:shortcuts (see storageKey); tools that no longer exist are dropped when it's read.

app.tools in the page has list(), get(path), index and shortcuts (state, subscribe, togglePin, movePin, visit, reload); HomeShortcuts.svelte is the Home block, should you lay out Home yourself.

Tools from other plugins

A plugin adds its own tool with app.tools?.add(tool) while plugins register, from both its build entry (which adds the tool's page to the route registry, so the plugin doesn't call app.route() for it) and its page entry. Register it after tools() in the config. A tool with no route (added from the page entry only) logs a warning when the app starts.

API

From the package's types and doc comments.

Options (ToolsOptions)

path? string
The index page listing every tool. Defaults to /tools.
title? string
The index page's title. Defaults to Tools.
emoji? string
The index page's emoji.
items? Tool[]
items.path string
The tool's page, an app path such as /utils/coffee-timer.
items.name string
items.emoji string
items.blurb string
One line under the name on the index page.
items.private? boolean
A personal tool (e.g. cycle tracking): never listed under Recently used, never shared from the Share button and never a manifest shortcut. Keep its name and emoji discreet too, since the index page and Home show them.
items.shortcut? boolean
Adds the tool to the manifest's shortcuts (the home-screen icon's long-press menu).
items.width? 'narrow' | 'split'
The page's container: narrow (the default) or split, for a tool that uses two columns when there's room (`<main class="page-split
storageKey? string
Where pins and recents are saved, as a full key starting with the storage prefix. Defaults to app:tools:shortcuts; set it to keep the key an app already uses (xcwds.github.io: app:home:shortcuts).

Decorators

app.tools? AppTools
From @xcwds/plugin-tools.
app.tools.index string
The index page's path.
app.tools.list () => readonly Tool[]
Every tool, in order.
app.tools.get (path: string) => Tool | undefined
app.tools.add (tool: Tool) => void
Adds a tool. Call it while plugins register, from both your build entry (which adds its page to the route registry, so don't also app.route() it) and your page entry.
app.tools.shortcuts? ToolShortcuts
Only in the page.

Edit this page on GitHub