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(defaultTools) andemoji: 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. Itswidthisnarrow(the default) orsplit, for a tool laid out in two columns on wide screens.private: truekeeps a tool out of Recently used, the Share button (its route is markedprivate) 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: trueadds the tool to the manifest'sshortcuts(the home-screen icon's long-press menu).storageKey: where pins and recents are saved (defaultapp:tools:shortcuts). Set it to keep a key your app already uses, e.g.app:home:shortcutsfor 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.pathstring- The tool's page, an app path such as
/utils/coffee-timer. items.namestringitems.emojistringitems.blurbstring- 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) orsplit, 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.indexstring- The index page's path.
app.tools.list() => readonly Tool[]- Every tool, in order.
app.tools.get(path: string) => Tool | undefinedapp.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.