@lapis-notes/lapis-plugin-docs 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +188 -2
- package/dist/docs/DocsBlockMarkdownEditor.svelte +37 -0
- package/dist/docs/DocsBlockMarkdownEditor.svelte.d.ts +13 -0
- package/dist/docs/DocsBlockRefPicker.svelte +75 -0
- package/dist/docs/DocsBlockRefPicker.svelte.d.ts +11 -0
- package/dist/docs/DocsBookEditor.svelte +141 -0
- package/dist/docs/DocsBookEditor.svelte.d.ts +10 -0
- package/dist/docs/DocsBookNavigation.svelte +838 -0
- package/dist/docs/DocsBookNavigation.svelte.d.ts +11 -0
- package/dist/docs/DocsBooksColumn.svelte +82 -0
- package/dist/docs/DocsBooksColumn.svelte.d.ts +10 -0
- package/dist/docs/DocsCardBackMatter.svelte +32 -0
- package/dist/docs/DocsCardBackMatter.svelte.d.ts +10 -0
- package/dist/docs/DocsCardBlockExtra.svelte +43 -0
- package/dist/docs/DocsCardBlockExtra.svelte.d.ts +9 -0
- package/dist/docs/DocsCardPreviewFlip.svelte +143 -0
- package/dist/docs/DocsCardPreviewFlip.svelte.d.ts +17 -0
- package/dist/docs/DocsCardPreviewStack.svelte +135 -0
- package/dist/docs/DocsCardPreviewStack.svelte.d.ts +13 -0
- package/dist/docs/DocsCardPrompt.svelte +33 -0
- package/dist/docs/DocsCardPrompt.svelte.d.ts +8 -0
- package/dist/docs/DocsCardReviewAnswer.svelte +45 -0
- package/dist/docs/DocsCardReviewAnswer.svelte.d.ts +8 -0
- package/dist/docs/DocsCardTagChips.svelte +19 -0
- package/dist/docs/DocsCardTagChips.svelte.d.ts +7 -0
- package/dist/docs/DocsCardsPanel.svelte +232 -0
- package/dist/docs/DocsCardsPanel.svelte.d.ts +17 -0
- package/dist/docs/DocsCardsReview.css +1050 -0
- package/dist/docs/DocsChapterFooter.svelte +248 -0
- package/dist/docs/DocsChapterFooter.svelte.d.ts +11 -0
- package/dist/docs/DocsChapterScrollRing.svelte +101 -0
- package/dist/docs/DocsChapterScrollRing.svelte.d.ts +6 -0
- package/dist/docs/DocsDisplayPanel.css +627 -0
- package/dist/docs/DocsDisplayPanel.svelte +78 -0
- package/dist/docs/DocsDisplayPanel.svelte.d.ts +16 -0
- package/dist/docs/DocsEditorPanel.css +325 -0
- package/dist/docs/DocsEditorPanel.svelte +570 -0
- package/dist/docs/DocsEditorPanel.svelte.d.ts +22 -0
- package/dist/docs/DocsFlipCard.svelte +68 -0
- package/dist/docs/DocsFlipCard.svelte.d.ts +8 -0
- package/dist/docs/DocsFolderDirectoryList.svelte +206 -0
- package/dist/docs/DocsFolderDirectoryList.svelte.d.ts +14 -0
- package/dist/docs/DocsFolderPanel.css +357 -0
- package/dist/docs/DocsFolderPanel.svelte +102 -0
- package/dist/docs/DocsFolderPanel.svelte.d.ts +17 -0
- package/dist/docs/DocsLinksPanel.css +61 -0
- package/dist/docs/DocsLinksPanel.svelte +55 -0
- package/dist/docs/DocsLinksPanel.svelte.d.ts +11 -0
- package/dist/docs/DocsMarkdownField.svelte +93 -0
- package/dist/docs/DocsMarkdownField.svelte.d.ts +11 -0
- package/dist/docs/DocsMarkdownPreview.svelte +278 -0
- package/dist/docs/DocsMarkdownPreview.svelte.d.ts +17 -0
- package/dist/docs/DocsReviewPanel.svelte +63 -0
- package/dist/docs/DocsReviewPanel.svelte.d.ts +11 -0
- package/dist/docs/DocsRichBlock.svelte +291 -0
- package/dist/docs/DocsRichBlock.svelte.d.ts +13 -0
- package/dist/docs/DocsRichDisplay.svelte +316 -0
- package/dist/docs/DocsRichDisplay.svelte.d.ts +14 -0
- package/dist/docs/DocsSlidesPreview.css +243 -0
- package/dist/docs/DocsSlidesPreview.svelte +206 -0
- package/dist/docs/DocsSlidesPreview.svelte.d.ts +10 -0
- package/dist/docs/DocsWorkspace.css +570 -0
- package/dist/docs/DocsWorkspace.svelte +831 -0
- package/dist/docs/DocsWorkspace.svelte.d.ts +48 -0
- package/dist/docs/DocsWorkspaceToolbar.svelte +211 -0
- package/dist/docs/DocsWorkspaceToolbar.svelte.d.ts +27 -0
- package/dist/docs/candidates/ChoiceMenu.svelte +114 -0
- package/dist/docs/candidates/ChoiceMenu.svelte.d.ts +10 -0
- package/dist/docs/candidates/FlipCardDeck.svelte +800 -0
- package/dist/docs/candidates/FlipCardDeck.svelte.d.ts +36 -0
- package/dist/docs/candidates/MarkdownFloatingToc.svelte +313 -0
- package/dist/docs/candidates/MarkdownFloatingToc.svelte.d.ts +14 -0
- package/dist/docs/candidates/SearchableChoicePicker.css +161 -0
- package/dist/docs/candidates/SearchableChoicePicker.svelte +208 -0
- package/dist/docs/candidates/SearchableChoicePicker.svelte.d.ts +19 -0
- package/dist/docs/candidates/StructuredTable.svelte +98 -0
- package/dist/docs/candidates/StructuredTable.svelte.d.ts +8 -0
- package/dist/docs/candidates/StructuredTableEditor.svelte +374 -0
- package/dist/docs/candidates/StructuredTableEditor.svelte.d.ts +12 -0
- package/dist/docs/candidates/TagEditor.svelte +31 -0
- package/dist/docs/candidates/TagEditor.svelte.d.ts +14 -0
- package/dist/docs/candidates/WorkspaceHistoryControls.svelte +112 -0
- package/dist/docs/candidates/WorkspaceHistoryControls.svelte.d.ts +8 -0
- package/dist/docs/candidates/markdown-floating-toc.css +151 -0
- package/dist/docs/candidates/markdown-floating-toc.d.ts +1 -0
- package/dist/docs/candidates/markdown-floating-toc.js +1 -0
- package/dist/docs/docs-anki-import.d.ts +34 -0
- package/dist/docs/docs-anki-import.js +516 -0
- package/dist/docs/docs-book-view-model.d.ts +9 -0
- package/dist/docs/docs-book-view-model.js +71 -0
- package/dist/docs/docs-card-answer-markdown.d.ts +1 -0
- package/dist/docs/docs-card-answer-markdown.js +63 -0
- package/dist/docs/docs-card-display.d.ts +10 -0
- package/dist/docs/docs-card-display.js +18 -0
- package/dist/docs/docs-display-focus.d.ts +7 -0
- package/dist/docs/docs-display-focus.js +42 -0
- package/dist/docs/docs-document-surface.d.ts +7 -0
- package/dist/docs/docs-document-surface.js +25 -0
- package/dist/docs/docs-folder-directory.d.ts +21 -0
- package/dist/docs/docs-folder-directory.js +56 -0
- package/dist/docs/docs-link-mode.d.ts +16 -0
- package/dist/docs/docs-link-mode.js +94 -0
- package/dist/docs/docs-workspace-helpers.d.ts +25 -0
- package/dist/docs/docs-workspace-helpers.js +195 -0
- package/dist/docs/docs.tokens.css +13 -0
- package/dist/docs/import-anki-package.d.ts +10 -0
- package/dist/docs/import-anki-package.js +30 -0
- package/dist/docs/lapis-markdown-extensions.d.ts +9 -0
- package/dist/docs/lapis-markdown-extensions.js +128 -0
- package/dist/docs/pin-reading-chrome.d.ts +4 -0
- package/dist/docs/pin-reading-chrome.js +32 -0
- package/dist/docs/sidebar/DocsFoldersSidebar.svelte +134 -0
- package/dist/docs/sidebar/DocsFoldersSidebar.svelte.d.ts +15 -0
- package/dist/docs/sidebar/DocsLinksSidebar.svelte +105 -0
- package/dist/docs/sidebar/DocsLinksSidebar.svelte.d.ts +11 -0
- package/dist/docs/sidebar/DocsSidebar.css +346 -0
- package/dist/docs/sidebar/DocsSidebar.svelte +430 -0
- package/dist/docs/sidebar/DocsSidebar.svelte.d.ts +18 -0
- package/dist/docs/sidebar/DocsSidebarHost.svelte +139 -0
- package/dist/docs/sidebar/DocsSidebarHost.svelte.d.ts +12 -0
- package/dist/docs/sidebar/DocsTagsSidebar.svelte +176 -0
- package/dist/docs/sidebar/DocsTagsSidebar.svelte.d.ts +12 -0
- package/dist/docs/sidebar/docs-book-note-tree.d.ts +23 -0
- package/dist/docs/sidebar/docs-book-note-tree.js +88 -0
- package/dist/docs/sidebar/docs-note-sort.d.ts +26 -0
- package/dist/docs/sidebar/docs-note-sort.js +54 -0
- package/dist/docs/sidebar/docs-sidebar-filters.d.ts +17 -0
- package/dist/docs/sidebar/docs-sidebar-filters.js +74 -0
- package/dist/docs/sidebar/docs-sidebar-ui-storage.d.ts +24 -0
- package/dist/docs/sidebar/docs-sidebar-ui-storage.js +87 -0
- package/dist/docs/sidebar/docs-source-folder-tree.d.ts +16 -0
- package/dist/docs/sidebar/docs-source-folder-tree.js +143 -0
- package/dist/docs/sidebar/docs-tag-tree.d.ts +17 -0
- package/dist/docs/sidebar/docs-tag-tree.js +84 -0
- package/dist/docs-cards-view.d.ts +18 -0
- package/dist/docs-cards-view.js +52 -0
- package/dist/docs-document-view.d.ts +24 -0
- package/dist/docs-document-view.js +127 -0
- package/dist/docs-document-workspace.svelte +215 -0
- package/dist/docs-document-workspace.svelte.d.ts +16 -0
- package/dist/docs-index.d.ts +5 -0
- package/dist/docs-index.js +49 -0
- package/dist/docs-path.d.ts +6 -0
- package/dist/docs-path.js +10 -0
- package/dist/docs-plugin.d.ts +21 -0
- package/dist/docs-plugin.js +140 -0
- package/dist/docs-repository.d.ts +15 -0
- package/dist/docs-repository.js +75 -0
- package/dist/docs-review-view.d.ts +18 -0
- package/dist/docs-review-view.js +52 -0
- package/dist/docs-settings-tab.d.ts +8 -0
- package/dist/docs-settings-tab.js +25 -0
- package/dist/docs-settings.d.ts +17 -0
- package/dist/docs-settings.js +38 -0
- package/dist/docs-view.d.ts +22 -0
- package/dist/docs-view.js +51 -0
- package/dist/docs-workspace.svelte +394 -0
- package/dist/docs-workspace.svelte.d.ts +15 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +12 -0
- package/dist/model/book.d.ts +6 -0
- package/dist/model/book.js +101 -0
- package/dist/model/coding-runtime.d.ts +4 -0
- package/dist/model/coding-runtime.js +9 -0
- package/dist/model/docs-card-context.d.ts +32 -0
- package/dist/model/docs-card-context.js +89 -0
- package/dist/model/docs-card-preview-stack-motion.d.ts +51 -0
- package/dist/model/docs-card-preview-stack-motion.js +94 -0
- package/dist/model/docs-media-context.d.ts +9 -0
- package/dist/model/docs-media-context.js +18 -0
- package/dist/model/docs-note-list.d.ts +8 -0
- package/dist/model/docs-note-list.js +25 -0
- package/dist/model/docs-relative-media.d.ts +30 -0
- package/dist/model/docs-relative-media.js +116 -0
- package/dist/model/docs-review-constants.d.ts +4 -0
- package/dist/model/docs-review-constants.js +13 -0
- package/dist/model/fsrs.d.ts +14 -0
- package/dist/model/fsrs.js +153 -0
- package/dist/model/graph.d.ts +12 -0
- package/dist/model/graph.js +169 -0
- package/dist/model/index.d.ts +14 -0
- package/dist/model/index.js +14 -0
- package/dist/model/markdown-normalize.d.ts +11 -0
- package/dist/model/markdown-normalize.js +755 -0
- package/dist/model/markdown.d.ts +167 -0
- package/dist/model/markdown.js +365 -0
- package/dist/model/sample.d.ts +7 -0
- package/dist/model/sample.js +524 -0
- package/dist/model/types.d.ts +328 -0
- package/dist/model/types.js +1 -0
- package/dist/model/workspace.d.ts +6 -0
- package/dist/model/workspace.js +81 -0
- package/dist/storybook.css +52 -0
- package/dist/styles.css +1 -0
- package/manifest.json +11 -0
- package/package.json +147 -4
package/README.md
CHANGED
|
@@ -1,3 +1,189 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@lapis-notes/lapis-plugin-docs`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/lapismd/lapis-plugin-docs/actions/workflows/ci.yml)
|
|
4
|
+
[](https://github.com/lapismd/lapis-plugin-docs/actions/workflows/publish-storybook-pages.yml)
|
|
5
|
+
[](https://lapismd.github.io/lapis-plugin-docs/)
|
|
6
|
+
|
|
7
|
+
First-party external Docs plugin for Lapis. It provides vault-native
|
|
8
|
+
`*.doc.md` notes, ordered books, linked knowledge, cards, and FSRS review
|
|
9
|
+
through public Lapis and Design Core surfaces inside the host workspace.
|
|
10
|
+
|
|
11
|
+
The plugin owns the Docs domain model, document view, sidebar, cards, review,
|
|
12
|
+
settings, and native `--ui-docs-*` styling. Hosts own plugin loading, vault
|
|
13
|
+
state, persistence, and application policy.
|
|
14
|
+
|
|
15
|
+
[](registry-assets/banner.full.png)
|
|
16
|
+
|
|
17
|
+
<details>
|
|
18
|
+
<summary>Plugin screenshots</summary>
|
|
19
|
+
|
|
20
|
+
[](registry-assets/gallery/reading.full.png)
|
|
21
|
+
|
|
22
|
+
[](registry-assets/gallery/cards.full.png)
|
|
23
|
+
|
|
24
|
+
</details>
|
|
25
|
+
|
|
26
|
+
## Current package status
|
|
27
|
+
|
|
28
|
+
- Package version: `@lapis-notes/lapis-plugin-docs@0.1.0`.
|
|
29
|
+
- Runtime plugin id: `docs`.
|
|
30
|
+
- Runtime peers: `@lapis-notes/api@^0.2.6`,
|
|
31
|
+
`@lapismd/design-core@^0.12.1`, `@lapismd/mira@~0.1.4`,
|
|
32
|
+
`@lapismd/mira-editor@~0.0.3`, and `svelte@5.56.10`.
|
|
33
|
+
- Canonical repository: `lapismd/lapis-plugin-docs`.
|
|
34
|
+
- Live catalog: <https://lapismd.github.io/lapis-plugin-docs/>.
|
|
35
|
+
- Canonical requirements live in `spec/src/plugins/docs/`; verification
|
|
36
|
+
status is tracked in `spec/src/verification.md`.
|
|
37
|
+
|
|
38
|
+
## Install
|
|
39
|
+
|
|
40
|
+
Hosts load the plugin class through the Lapis plugin lifecycle. `onload`
|
|
41
|
+
registers the Docs projection, document and sidebar views, commands, ribbon,
|
|
42
|
+
and settings.
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
pnpm add @lapis-notes/lapis-plugin-docs
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Import the plugin stylesheet once at the application boundary:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import "@lapis-notes/lapis-plugin-docs/styles.css";
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Runtime surfaces
|
|
55
|
+
|
|
56
|
+
| Surface | Entry | Use for |
|
|
57
|
+
| --- | --- | --- |
|
|
58
|
+
| Docs document | `*.doc.md` exclusive editor-view contribution | Structured editing, reading, slides, cards, and note-scoped review |
|
|
59
|
+
| Docs sidebar | Movable `docs` workspace view | Browse notes, folders, links, tags, due cards, and review queues |
|
|
60
|
+
| Projection | `docs/note` | Index Docs metadata and content from the configured vault root |
|
|
61
|
+
| Cards | Basic and cloze card panels | Create cards, inspect references, and manage scheduling metadata |
|
|
62
|
+
| Review | FSRS-backed note and workspace queues | Study due cards and persist review outcomes to the source note |
|
|
63
|
+
| Import | Lazy Anki package reader | Import supported `.apkg` collections and media into the vault |
|
|
64
|
+
| Settings | Versioned plugin data | Configure the Docs root, which defaults to `docs` |
|
|
65
|
+
|
|
66
|
+
## Document and review coverage
|
|
67
|
+
|
|
68
|
+
Docs files are ordinary Markdown with YAML front matter. The filesystem is
|
|
69
|
+
authoritative: books order their chapters, wiki links and tags form a graph,
|
|
70
|
+
and review state travels with each card in its source document. Structured
|
|
71
|
+
reading uses the host `MarkdownRenderer` when available and public Mira
|
|
72
|
+
preview as the fallback.
|
|
73
|
+
|
|
74
|
+
The bundled sample book exercises structured blocks, Mermaid diagrams,
|
|
75
|
+
slides, links, tags, basic and cloze cards, due queues, and FSRS history. The
|
|
76
|
+
same deterministic fixtures power the package Storybook and the committed
|
|
77
|
+
README screenshots.
|
|
78
|
+
|
|
79
|
+
## Styling contract
|
|
80
|
+
|
|
81
|
+
The plugin uses native CSS, Design Core semantic tokens, and Docs-owned
|
|
82
|
+
`docs-` classes with `--ui-docs-*` custom properties. Production sources stay
|
|
83
|
+
free of Tailwind utility strings (`pnpm check:no-tailwind`).
|
|
84
|
+
|
|
85
|
+
1. Import `@lapis-notes/lapis-plugin-docs/styles.css` once.
|
|
86
|
+
2. Theme through Design Core tokens and Docs custom properties.
|
|
87
|
+
3. Keep package-owned surfaces independent of host-private selectors.
|
|
88
|
+
|
|
89
|
+
## Layout conventions
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
src/
|
|
93
|
+
lib/ plugin class, views, repository, domain model, native CSS
|
|
94
|
+
stories/ App-backed shell, placement, and registry capture stories
|
|
95
|
+
fixtures/
|
|
96
|
+
sample-docs/ deterministic *.doc.md Storybook corpus
|
|
97
|
+
spec/
|
|
98
|
+
src/ canonical specification and verification evidence
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Usage example
|
|
102
|
+
|
|
103
|
+
A Docs document is Markdown with structured front matter:
|
|
104
|
+
|
|
105
|
+
```markdown
|
|
106
|
+
---
|
|
107
|
+
id: spaced-repetition
|
|
108
|
+
title: Spaced repetition
|
|
109
|
+
docType: revision
|
|
110
|
+
tags:
|
|
111
|
+
- learning/memory
|
|
112
|
+
cards:
|
|
113
|
+
- id: retrieval-practice
|
|
114
|
+
type: basic
|
|
115
|
+
status: active
|
|
116
|
+
prompt: Why use retrieval practice?
|
|
117
|
+
answer: Recalling an idea strengthens access to it.
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
# Spaced repetition
|
|
121
|
+
|
|
122
|
+
Review material shortly before it would otherwise be forgotten.
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Storybook and local documentation
|
|
126
|
+
|
|
127
|
+
Run the local catalog (defaults to port 7040):
|
|
128
|
+
|
|
129
|
+
```sh
|
|
130
|
+
pnpm storybook
|
|
131
|
+
pnpm storybook:stop
|
|
132
|
+
pnpm storybook:restart
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Build the static catalog:
|
|
136
|
+
|
|
137
|
+
```sh
|
|
138
|
+
pnpm build-storybook
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`Plugins/Docs/Registry Screenshots` contains the deterministic workspace,
|
|
142
|
+
reading, and cards states used to refresh the committed README media. These
|
|
143
|
+
capture stories are intentionally separate from visual-regression baselines.
|
|
144
|
+
|
|
145
|
+
The canonical specification lives in `spec/src`. Validate it after protected
|
|
146
|
+
source, story, or presentation changes:
|
|
147
|
+
|
|
148
|
+
```sh
|
|
149
|
+
pnpm exec spec-validator search "Storybook"
|
|
150
|
+
pnpm spec:check
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### CI and local parity
|
|
154
|
+
|
|
155
|
+
CI runs specification, quality, unit, package, static Storybook, and sharded
|
|
156
|
+
Storybook interaction lanes on every pull request and push to `main`. The
|
|
157
|
+
static catalog is published to GitHub Pages from `main`.
|
|
158
|
+
|
|
159
|
+
`pnpm test:storybook` runs the Storybook Vitest project with Playwright.
|
|
160
|
+
Interaction and accessibility behaviour stays executable in the capture
|
|
161
|
+
stories; screenshot files are generated from their completed states.
|
|
162
|
+
|
|
163
|
+
## Release and validation
|
|
164
|
+
|
|
165
|
+
Common validation commands:
|
|
166
|
+
|
|
167
|
+
```sh
|
|
168
|
+
pnpm spec:first
|
|
169
|
+
pnpm spec:check
|
|
170
|
+
pnpm check
|
|
171
|
+
pnpm test
|
|
172
|
+
pnpm build
|
|
173
|
+
pnpm publint
|
|
174
|
+
pnpm test:storybook
|
|
175
|
+
pnpm build-storybook
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Further reading
|
|
179
|
+
|
|
180
|
+
| Resource | Use |
|
|
181
|
+
| --- | --- |
|
|
182
|
+
| [`spec/src/plugins/docs/index.md`](./spec/src/plugins/docs/index.md) | Canonical plugin ownership and package requirements |
|
|
183
|
+
| [`spec/src/plugins/docs/runtime.md`](./spec/src/plugins/docs/runtime.md) | Runtime, sidebar, Storybook, and import behaviour |
|
|
184
|
+
| [`spec/src/plugins/docs/notes.md`](./spec/src/plugins/docs/notes.md) | Document model and reading behaviour |
|
|
185
|
+
| [`spec/src/plugins/docs/cards.md`](./spec/src/plugins/docs/cards.md) | Cards and review behaviour |
|
|
186
|
+
| [`spec/src/spec-governance.md`](./spec/src/spec-governance.md) | Governance, validation, and discovery rules |
|
|
187
|
+
| [`spec/src/verification.md`](./spec/src/verification.md) | Requirement verification evidence |
|
|
188
|
+
| [`AGENTS.md`](./AGENTS.md) | Contributor and agent workflow |
|
|
189
|
+
| [`PROVENANCE.md`](./PROVENANCE.md) | Component provenance and exclusions |
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Block Markdown field. Document-mode MarkdownComposer replaces the
|
|
4
|
+
* CodeMirror markdown editor for prose and section bodies.
|
|
5
|
+
*/
|
|
6
|
+
import DocsMarkdownField from "./DocsMarkdownField.svelte";
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
value = $bindable(""),
|
|
10
|
+
placeholder = "Write with Markdown...",
|
|
11
|
+
ariaLabel = "Markdown block",
|
|
12
|
+
minRows: _minRows = 8,
|
|
13
|
+
compact: _compact = true,
|
|
14
|
+
floatingToc: _floatingToc = "off" as const,
|
|
15
|
+
sourcePath: _sourcePath = "",
|
|
16
|
+
attachmentUpload: _attachmentUpload,
|
|
17
|
+
}: {
|
|
18
|
+
value?: string;
|
|
19
|
+
placeholder?: string;
|
|
20
|
+
ariaLabel?: string;
|
|
21
|
+
minRows?: number;
|
|
22
|
+
compact?: boolean;
|
|
23
|
+
floatingToc?: "auto" | "off" | "always";
|
|
24
|
+
sourcePath?: string;
|
|
25
|
+
attachmentUpload?: unknown;
|
|
26
|
+
} = $props();
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<DocsMarkdownField
|
|
30
|
+
{value}
|
|
31
|
+
label={ariaLabel}
|
|
32
|
+
showLabel={false}
|
|
33
|
+
{placeholder}
|
|
34
|
+
onChange={(next) => {
|
|
35
|
+
value = next;
|
|
36
|
+
}}
|
|
37
|
+
/>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
value?: string;
|
|
3
|
+
placeholder?: string;
|
|
4
|
+
ariaLabel?: string;
|
|
5
|
+
minRows?: number;
|
|
6
|
+
compact?: boolean;
|
|
7
|
+
floatingToc?: "auto" | "off" | "always";
|
|
8
|
+
sourcePath?: string;
|
|
9
|
+
attachmentUpload?: unknown;
|
|
10
|
+
};
|
|
11
|
+
declare const DocsBlockMarkdownEditor: import("svelte").Component<$$ComponentProps, {}, "value">;
|
|
12
|
+
type DocsBlockMarkdownEditor = ReturnType<typeof DocsBlockMarkdownEditor>;
|
|
13
|
+
export default DocsBlockMarkdownEditor;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { ReferencePicker } from "@lapismd/design-core/forms";
|
|
3
|
+
import {
|
|
4
|
+
docsBlockIdFromRef,
|
|
5
|
+
docsBlockReferenceIndex,
|
|
6
|
+
docsBlockRefMarker,
|
|
7
|
+
} from "../model/docs-card-context";
|
|
8
|
+
import type { DocsRevisionBlock } from "../model";
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
blocks,
|
|
12
|
+
refs,
|
|
13
|
+
addOpen = $bindable(false),
|
|
14
|
+
onAddOpenChange = () => {},
|
|
15
|
+
onChange,
|
|
16
|
+
}: {
|
|
17
|
+
blocks: DocsRevisionBlock[];
|
|
18
|
+
refs: string[];
|
|
19
|
+
addOpen?: boolean;
|
|
20
|
+
onAddOpenChange?: (open: boolean) => void;
|
|
21
|
+
onChange: (refs: string[]) => void;
|
|
22
|
+
} = $props();
|
|
23
|
+
|
|
24
|
+
const referenceIndex = $derived(docsBlockReferenceIndex(blocks));
|
|
25
|
+
const pickerRefs = $derived(refs.map((id) => docsBlockRefMarker(id)));
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<ReferencePicker
|
|
29
|
+
refs={pickerRefs}
|
|
30
|
+
{referenceIndex}
|
|
31
|
+
{addOpen}
|
|
32
|
+
addLabel="Add block"
|
|
33
|
+
addHeading="Block"
|
|
34
|
+
searchPlaceholder="Search note blocks..."
|
|
35
|
+
emptyLabel="No matching blocks."
|
|
36
|
+
unresolvedLabel="Missing block"
|
|
37
|
+
unresolvedDescription="This block is no longer on the note."
|
|
38
|
+
{onAddOpenChange}
|
|
39
|
+
onChange={(next) => onChange(next.map((ref) => docsBlockIdFromRef(ref)))}
|
|
40
|
+
>
|
|
41
|
+
{#snippet searchOption(reference)}
|
|
42
|
+
<span class="docs-block-ref-option">
|
|
43
|
+
<span class="docs-block-ref-option__title">{reference.label}</span>
|
|
44
|
+
{#if reference.excerpt}
|
|
45
|
+
<span class="docs-block-ref-option__snippet">{reference.excerpt}</span>
|
|
46
|
+
{/if}
|
|
47
|
+
</span>
|
|
48
|
+
{/snippet}
|
|
49
|
+
</ReferencePicker>
|
|
50
|
+
|
|
51
|
+
<style>
|
|
52
|
+
.docs-block-ref-option {
|
|
53
|
+
display: grid;
|
|
54
|
+
min-width: 0;
|
|
55
|
+
gap: 0.1rem;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.docs-block-ref-option__title {
|
|
59
|
+
overflow: hidden;
|
|
60
|
+
color: var(--foreground);
|
|
61
|
+
font-size: 0.75rem;
|
|
62
|
+
font-weight: 650;
|
|
63
|
+
text-overflow: ellipsis;
|
|
64
|
+
white-space: nowrap;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.docs-block-ref-option__snippet {
|
|
68
|
+
overflow: hidden;
|
|
69
|
+
color: var(--muted-foreground);
|
|
70
|
+
font-size: 0.72rem;
|
|
71
|
+
line-height: 1.35;
|
|
72
|
+
text-overflow: ellipsis;
|
|
73
|
+
white-space: nowrap;
|
|
74
|
+
}
|
|
75
|
+
</style>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DocsRevisionBlock } from "../model";
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
blocks: DocsRevisionBlock[];
|
|
4
|
+
refs: string[];
|
|
5
|
+
addOpen?: boolean;
|
|
6
|
+
onAddOpenChange?: (open: boolean) => void;
|
|
7
|
+
onChange: (refs: string[]) => void;
|
|
8
|
+
};
|
|
9
|
+
declare const DocsBlockRefPicker: import("svelte").Component<$$ComponentProps, {}, "addOpen">;
|
|
10
|
+
type DocsBlockRefPicker = ReturnType<typeof DocsBlockRefPicker>;
|
|
11
|
+
export default DocsBlockRefPicker;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import PlusIcon from '@lucide/svelte/icons/plus';
|
|
3
|
+
import { EntryActions, type SearchableChoiceOption } from '@lapismd/design-core/forms';
|
|
4
|
+
import SearchableChoicePicker from './candidates/SearchableChoicePicker.svelte';
|
|
5
|
+
import { slugifyDocsId } from '../model/markdown';
|
|
6
|
+
import type { DocsBookMetadata } from '../model';
|
|
7
|
+
|
|
8
|
+
let {
|
|
9
|
+
book,
|
|
10
|
+
noteOptions = [],
|
|
11
|
+
onChange = () => {}
|
|
12
|
+
}: {
|
|
13
|
+
book: DocsBookMetadata;
|
|
14
|
+
noteOptions?: SearchableChoiceOption[];
|
|
15
|
+
onChange?: (book: DocsBookMetadata) => void;
|
|
16
|
+
} = $props();
|
|
17
|
+
|
|
18
|
+
function normalizeChapterId(value: string) {
|
|
19
|
+
const trimmed = value.trim();
|
|
20
|
+
if (!trimmed) return '';
|
|
21
|
+
return slugifyDocsId(trimmed, trimmed);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function setChapters(chapters: DocsBookMetadata['chapters']) {
|
|
25
|
+
onChange({ chapters });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function patchChapter(chapterIndex: number, noteId: string) {
|
|
29
|
+
setChapters(
|
|
30
|
+
book.chapters.map((chapter, index) =>
|
|
31
|
+
index === chapterIndex ? { noteId } : chapter
|
|
32
|
+
)
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function addChapter() {
|
|
37
|
+
setChapters([...book.chapters, { noteId: '' }]);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function removeChapter(chapterIndex: number) {
|
|
41
|
+
setChapters(book.chapters.filter((_, index) => index !== chapterIndex));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function moveChapter(chapterIndex: number, direction: -1 | 1) {
|
|
45
|
+
const targetIndex = chapterIndex + direction;
|
|
46
|
+
if (targetIndex < 0 || targetIndex >= book.chapters.length) return;
|
|
47
|
+
const nextChapters = [...book.chapters];
|
|
48
|
+
const [chapter] = nextChapters.splice(chapterIndex, 1);
|
|
49
|
+
nextChapters.splice(targetIndex, 0, chapter);
|
|
50
|
+
setChapters(nextChapters);
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<div class="docs-book-editor">
|
|
55
|
+
{#each book.chapters as chapter, chapterIndex (chapterIndex)}
|
|
56
|
+
<EntryActions
|
|
57
|
+
index={chapterIndex}
|
|
58
|
+
total={book.chapters.length}
|
|
59
|
+
removeLabel={`Remove chapter ${chapter.noteId || chapterIndex + 1}`}
|
|
60
|
+
onMove={(direction) => moveChapter(chapterIndex, direction)}
|
|
61
|
+
onRemove={() => removeChapter(chapterIndex)}
|
|
62
|
+
>
|
|
63
|
+
<div class="docs-book-editor__row">
|
|
64
|
+
<span>{chapterIndex + 1}</span>
|
|
65
|
+
<SearchableChoicePicker
|
|
66
|
+
value={chapter.noteId}
|
|
67
|
+
options={noteOptions}
|
|
68
|
+
placeholder="Select note"
|
|
69
|
+
searchPlaceholder="Search notes..."
|
|
70
|
+
emptyLabel="No notes found."
|
|
71
|
+
ariaLabel={`Book chapter ${chapterIndex + 1}`}
|
|
72
|
+
normalize={normalizeChapterId}
|
|
73
|
+
onChange={(noteId) => patchChapter(chapterIndex, noteId)}
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
</EntryActions>
|
|
77
|
+
{/each}
|
|
78
|
+
<button type="button" class="docs-book-editor__add" onclick={addChapter}>
|
|
79
|
+
<PlusIcon aria-hidden="true" />
|
|
80
|
+
<span>Add chapter</span>
|
|
81
|
+
</button>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<style>
|
|
85
|
+
.docs-book-editor {
|
|
86
|
+
display: grid;
|
|
87
|
+
gap: 0.4rem;
|
|
88
|
+
width: 100%;
|
|
89
|
+
min-width: 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.docs-book-editor__row {
|
|
93
|
+
display: grid;
|
|
94
|
+
grid-template-columns: 1.6rem minmax(0, 1fr);
|
|
95
|
+
align-items: center;
|
|
96
|
+
gap: 0.55rem;
|
|
97
|
+
min-width: 0;
|
|
98
|
+
padding-block: 0.2rem;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.docs-book-editor__row > span {
|
|
102
|
+
display: grid;
|
|
103
|
+
width: 1.35rem;
|
|
104
|
+
height: 1.35rem;
|
|
105
|
+
place-items: center;
|
|
106
|
+
border-radius: 999px;
|
|
107
|
+
background: color-mix(in srgb, currentColor 8%, transparent);
|
|
108
|
+
color: var(--muted-foreground);
|
|
109
|
+
font-size: 0.72rem;
|
|
110
|
+
font-weight: 650;
|
|
111
|
+
line-height: 1;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.docs-book-editor__add {
|
|
115
|
+
display: inline-flex;
|
|
116
|
+
align-items: center;
|
|
117
|
+
justify-content: center;
|
|
118
|
+
gap: 0.35rem;
|
|
119
|
+
width: 100%;
|
|
120
|
+
min-height: 2.1rem;
|
|
121
|
+
border: 1px dashed var(--border);
|
|
122
|
+
border-radius: 0.4rem;
|
|
123
|
+
background: transparent;
|
|
124
|
+
color: var(--muted-foreground);
|
|
125
|
+
font-size: 0.82rem;
|
|
126
|
+
font-weight: 650;
|
|
127
|
+
cursor: pointer;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.docs-book-editor__add:hover,
|
|
131
|
+
.docs-book-editor__add:focus-visible {
|
|
132
|
+
border-color: var(--ring);
|
|
133
|
+
color: var(--foreground);
|
|
134
|
+
outline: 0;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.docs-book-editor__add :global(svg) {
|
|
138
|
+
width: 0.95rem;
|
|
139
|
+
height: 0.95rem;
|
|
140
|
+
}
|
|
141
|
+
</style>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type SearchableChoiceOption } from '@lapismd/design-core/forms';
|
|
2
|
+
import type { DocsBookMetadata } from '../model';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
book: DocsBookMetadata;
|
|
5
|
+
noteOptions?: SearchableChoiceOption[];
|
|
6
|
+
onChange?: (book: DocsBookMetadata) => void;
|
|
7
|
+
};
|
|
8
|
+
declare const DocsBookEditor: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
9
|
+
type DocsBookEditor = ReturnType<typeof DocsBookEditor>;
|
|
10
|
+
export default DocsBookEditor;
|