Page parts
The cover, the icon and the title of a starter page, where they are stored, their keys, and how to replace or remove each one.
Above the blocks, a starter page has a cover, an icon and a title, and under the title its properties. Each is stored in the document’s data (edytor.data), so it is saved with value, syncs in a room and undoes like a block edit: each change is one undo step.
| Part | Stored as | A user |
|---|---|---|
| Cover | data.cover: { url, position }, position from 0 (top) to 100 (bottom) |
adds one (Add cover), changes it by a link or an upload, repositions it, removes it |
| Icon | data.icon: { emoji } or { url } |
picks an emoji, links or uploads an image, removes it |
| Title | data.title: a string |
types it; Enter moves into the first block |
import type { JSONDoc } from 'edytor';
import type { StarterPageData } from '$lib/components/edytor/starter/index.js';
const data: StarterPageData = {
title: 'Launch plan',
icon: { emoji: '🚀' },
cover: { url: 'https://images.example.com/sky.jpg', position: 40 }
};
export const value: JSONDoc = { data, children: [] };
Add icon and Add cover show when the page header is hovered or holds the focus (always on a touch screen), only where there is no icon or cover yet. A readonly view shows the parts and none of their controls.
Keys
| Where | Key | Does |
|---|---|---|
| Title | Enter, or ↓ at its end | puts the caret at the start of the first block |
| Title | Mod+Z, Mod+Shift+Z | the view’s undo and redo (the title’s edits are history steps) |
| Icon picker | arrow keys, Enter | move through the emoji, pick one |
| Any popover | Esc, a press outside | closes it, the focus back on its button |
| Reposition | ↑/↓ (Shift: by 10), Enter, Esc | moves the image, saves, cancels |
The popovers are shadcn Popovers: dialogs named by their purpose (Icon options, Cover options), the focus inside while open. The reposition control is a slider with its value, and the title is a textbox named Page title.
Replace a part
cover, icon and title take false to leave a part out, or a snippet to draw it yourself. The snippet gets the part’s value, a set that writes it (one undo step), readonly and, for the cover and the icon, upload:
<script lang="ts">
import {
StarterEditor,
type StarterTitlePayload
} from '$lib/components/edytor/starter/index.js';
</script>
{#snippet title({ title, set, enter, readonly }: StarterTitlePayload)}
<input
class="my-title"
value={title}
disabled={readonly}
aria-label="Title"
oninput={(event) => set(event.currentTarget.value)}
onkeydown={(event) => event.key === 'Enter' && enter()}
/>
{/snippet}
<StarterEditor {title} cover={false} icon={false} />
A cover or icon snippet renders even when there is none yet (cover is undefined): draw your own add button there. Add cover and Add icon are the default parts’ own.
Edge cases
- Add cover adds a soft gradient at once; Change cover then takes a link or an upload. A link must be
https:,http:or adata:image/URL. - A failed upload logs its error and leaves the part as it was.
- Two people repositioning the same cover: the last Save wins, as for any one property.