phormat
v0.0.32
Published
Source-canonical block Markdown editor for Svelte 5
Downloads
1,715
Readme
Phormat
Source-canonical block Markdown editor for Svelte 5. Markdown source is the persisted representation; a typed block tree is the in-memory editing model.
Monorepo note: The npm package is
phormat. This repository folder may still be namedmd-editor.
Install
npm install phormatPeer dependencies (install in your app):
svelte^5.0.0phoundry-ui>=0.0.18@iconify/svelte^4.0.0 || ^5.0.0
In a Phoundry monorepo, use a file: dependency (e.g. "phormat": "file:../md-editor") and run npm run prepack in this repo after editing package source.
Publishing
Maintainers: see docs/publishing.md. Quick path: npm run release after npm login and ensuring phoundry-ui@>=0.0.18 is on npm.
Styles
Import phoundry-ui styles (host-owned) plus Phormat’s editor CSS / Tailwind @source scan:
@import 'phoundry-ui/styles';
@import 'phoundry-ui/themes/default-dark/theme.css';
@import 'phormat/styles';phormat/styles does not re-import phoundry-ui — that keeps the host’s selected UI package authoritative when nested copies exist.
Overlay setup
Phormat uses phoundry-ui mono icons, context menus, and inline formatting popovers. Register the mono collection, call setupOverlays() once in your root layout, and render the overlay hosts:
<script>
import { ContextMenuOverlay, PopoverOverlay, setupOverlays } from 'phoundry-ui';
import { registerPhoundryMono } from 'phoundry-ui/icons';
registerPhoundryMono();
setupOverlays();
</script>
<ContextMenuOverlay />
<PopoverOverlay />Phormat opens the inline formatting toolbar and link-edit chrome via popover.open({ content }) — empty PopoverOverlay is enough. Optional package exports InlineFormattingToolbar / LinkEditPopoverHost remain for hosts that prefer default-child mounting. See the demo layout.
Quick start
<script>
import { PhormatEditor } from 'phormat';
let source = $state('# Hello\n\nEdit me.');
</script>
<PhormatEditor value={source} onchange={(next) => (source = next)} />For file-backed apps, the parent owns load/save and passes value / onchange; call markSaved() on the internal state only if you use MarkdownEditor directly. With PhormatEditor, track persistence against your own on-disk baseline and use bind:embedder to prepare a focused inline draft before writing or closing (see package usage).
Package exports
| Import | Purpose |
|--------|---------|
| phormat | PhormatEditor, InlineFormattingToolbar, LinkEditPopoverHost, MarkdownEditor state class, model types and helpers |
| phormat/styles | Editor CSS + Tailwind @source for packaged Phormat components (host imports phoundry-ui/styles) |
| phormat/demo | Browser-only demo helpers (file load, localStorage drafts, download) — not for production file I/O |
Documentation
- Package usage — embedder API, props, dirty baseline, demo vs production boundaries
- Architecture overview — internal pipeline and extension points (contributors)
- Context glossary — domain terms
Demo app
npm install
npm run devDev server: http://127.0.0.1:5181/ (pinned with strictPort; see vite.config.ts). If you see the Phoundry marketing site instead, a stale phoundry-website dev server is squatting on 5181 — stop it and restart Phormat.
The SvelteKit route at src/routes/+page.svelte is a reference implementation using phormat/demo for browser file upload, draft recovery, and export.
Scripts
| Command | Description |
|---------|-------------|
| npm run dev | Demo dev server |
| npm run check | Typecheck |
| npm run test | Unit tests |
| npm run prepack | Build library (dist/) |
| npm run pack:local | Build + create .tgz for inspection |
| npm run release | Patch version, build, npm publish |
