@lapis-notes/bookmarks 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/CHANGELOG.md +6 -0
- package/LICENSE.md +8 -0
- package/README.md +20 -0
- package/dist/activate-bookmark.d.ts +11 -0
- package/dist/activate-bookmark.js +113 -0
- package/dist/add-bookmark-dialog.svelte +83 -0
- package/dist/add-bookmark-dialog.svelte.d.ts +15 -0
- package/dist/bookmarks-filter.d.ts +2 -0
- package/dist/bookmarks-filter.js +19 -0
- package/dist/bookmarks-panel.svelte +654 -0
- package/dist/bookmarks-panel.svelte.d.ts +13 -0
- package/dist/bookmarks-plugin.d.ts +15 -0
- package/dist/bookmarks-plugin.js +170 -0
- package/dist/bookmarks-schema.d.ts +75 -0
- package/dist/bookmarks-schema.js +258 -0
- package/dist/bookmarks-store.d.ts +44 -0
- package/dist/bookmarks-store.js +143 -0
- package/dist/bookmarks-view-type.d.ts +2 -0
- package/dist/bookmarks-view-type.js +2 -0
- package/dist/bookmarks-view.d.ts +21 -0
- package/dist/bookmarks-view.js +43 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +9 -0
- package/dist/mount-dialog.d.ts +8 -0
- package/dist/mount-dialog.js +16 -0
- package/dist/pick-bookmark-group.svelte +76 -0
- package/dist/pick-bookmark-group.svelte.d.ts +16 -0
- package/dist/public-components.d.ts +1 -0
- package/dist/public-components.js +1 -0
- package/dist/styles.css +1 -0
- package/manifest.json +26 -0
- package/package.json +72 -0
- package/styles.css +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { View, type WorkspaceLeaf } from "@lapis-notes/api";
|
|
2
|
+
import type { BookmarksStore } from "./bookmarks-store";
|
|
3
|
+
export interface BookmarksViewHost {
|
|
4
|
+
store: BookmarksStore;
|
|
5
|
+
promptAddBookmark(): Promise<void>;
|
|
6
|
+
createGroup(parentCtime: number | null): Promise<{
|
|
7
|
+
ctime: number;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
export declare class BookmarksView extends View {
|
|
11
|
+
#private;
|
|
12
|
+
private readonly host;
|
|
13
|
+
constructor(leaf: WorkspaceLeaf, host: BookmarksViewHost);
|
|
14
|
+
getViewType(): string;
|
|
15
|
+
getDisplayText(): string;
|
|
16
|
+
getIcon(): string;
|
|
17
|
+
protected onOpen(): Promise<void>;
|
|
18
|
+
protected onClose(): Promise<void>;
|
|
19
|
+
onload(): void;
|
|
20
|
+
onunload(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { View } from "@lapis-notes/api";
|
|
2
|
+
import { mount, unmount } from "svelte";
|
|
3
|
+
import BookmarksPanel from "./bookmarks-panel.svelte";
|
|
4
|
+
import { BookmarksViewType } from "./bookmarks-view-type";
|
|
5
|
+
export class BookmarksView extends View {
|
|
6
|
+
host;
|
|
7
|
+
#component = null;
|
|
8
|
+
constructor(leaf, host) {
|
|
9
|
+
super(leaf);
|
|
10
|
+
this.host = host;
|
|
11
|
+
}
|
|
12
|
+
getViewType() {
|
|
13
|
+
return BookmarksViewType;
|
|
14
|
+
}
|
|
15
|
+
getDisplayText() {
|
|
16
|
+
return "Bookmarks";
|
|
17
|
+
}
|
|
18
|
+
getIcon() {
|
|
19
|
+
return "bookmark";
|
|
20
|
+
}
|
|
21
|
+
onOpen() {
|
|
22
|
+
return Promise.resolve();
|
|
23
|
+
}
|
|
24
|
+
onClose() {
|
|
25
|
+
return Promise.resolve();
|
|
26
|
+
}
|
|
27
|
+
onload() {
|
|
28
|
+
this.#component = mount(BookmarksPanel, {
|
|
29
|
+
target: this.containerEl,
|
|
30
|
+
props: {
|
|
31
|
+
app: this.app,
|
|
32
|
+
store: this.host.store,
|
|
33
|
+
onBookmarkActive: () => void this.host.promptAddBookmark(),
|
|
34
|
+
onNewGroup: (parentCtime) => this.host.createGroup(parentCtime),
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
onunload() {
|
|
39
|
+
if (this.#component)
|
|
40
|
+
void unmount(this.#component);
|
|
41
|
+
this.#component = null;
|
|
42
|
+
}
|
|
43
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import "./styles.css";
|
|
2
|
+
export { default as manifest } from "../../manifest.json";
|
|
3
|
+
export { activateBookmark, bookmarkableTarget } from "./activate-bookmark";
|
|
4
|
+
export { BookmarksPanel } from "./public-components";
|
|
5
|
+
export { BookmarksPlugin } from "./bookmarks-plugin";
|
|
6
|
+
export { BOOKMARKS_PLUGIN_ID, BookmarksViewType, } from "./bookmarks-view-type";
|
|
7
|
+
export { BookmarksStore } from "./bookmarks-store";
|
|
8
|
+
export { BookmarksView } from "./bookmarks-view";
|
|
9
|
+
export { bookmarkIcon, bookmarkLabel, cloneBookmarkItems, isFileBookmark, isFolderBookmark, isGraphBookmark, isGroupBookmark, isSearchBookmark, isUrlBookmark, parseBookmarksDocument, } from "./bookmarks-schema";
|
|
10
|
+
export type { BookmarkItem, BookmarksDocument } from "./bookmarks-schema";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import "./styles.css";
|
|
2
|
+
export { default as manifest } from "../../manifest.json";
|
|
3
|
+
export { activateBookmark, bookmarkableTarget } from "./activate-bookmark";
|
|
4
|
+
export { BookmarksPanel } from "./public-components";
|
|
5
|
+
export { BookmarksPlugin } from "./bookmarks-plugin";
|
|
6
|
+
export { BOOKMARKS_PLUGIN_ID, BookmarksViewType, } from "./bookmarks-view-type";
|
|
7
|
+
export { BookmarksStore } from "./bookmarks-store";
|
|
8
|
+
export { BookmarksView } from "./bookmarks-view";
|
|
9
|
+
export { bookmarkIcon, bookmarkLabel, cloneBookmarkItems, isFileBookmark, isFolderBookmark, isGraphBookmark, isGroupBookmark, isSearchBookmark, isUrlBookmark, parseBookmarksDocument, } from "./bookmarks-schema";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Component } from "svelte";
|
|
2
|
+
import type { App } from "@lapis-notes/api";
|
|
3
|
+
export declare function dialogPortalPropsForApp(app: App): {
|
|
4
|
+
to: HTMLElement;
|
|
5
|
+
};
|
|
6
|
+
export declare function mountDialog<Props extends Record<string, unknown>>(app: App, component: Component<Props>, props: Props): {
|
|
7
|
+
close: () => void;
|
|
8
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { mount, unmount } from "svelte";
|
|
2
|
+
export function dialogPortalPropsForApp(app) {
|
|
3
|
+
return { to: app.workspace.getCommandHostDocument().body };
|
|
4
|
+
}
|
|
5
|
+
export function mountDialog(app, component, props) {
|
|
6
|
+
const target = app.workspace.getCommandHostDocument().body;
|
|
7
|
+
const instance = mount(component, {
|
|
8
|
+
target,
|
|
9
|
+
props,
|
|
10
|
+
});
|
|
11
|
+
return {
|
|
12
|
+
close: () => {
|
|
13
|
+
void unmount(instance);
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import * as CommandView from "@lapismd/design-core/shadcn/command-view";
|
|
3
|
+
import * as Dialog from "@lapismd/design-core/shadcn/dialog";
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
open = true,
|
|
7
|
+
groups,
|
|
8
|
+
portalProps,
|
|
9
|
+
onCancel,
|
|
10
|
+
onSelect,
|
|
11
|
+
}: {
|
|
12
|
+
open?: boolean;
|
|
13
|
+
groups: Array<{ ctime: number | null; label: string; description?: string }>;
|
|
14
|
+
portalProps: { to: HTMLElement };
|
|
15
|
+
onCancel: () => void;
|
|
16
|
+
onSelect: (ctime: number | null, createTitle?: string) => void;
|
|
17
|
+
} = $props();
|
|
18
|
+
|
|
19
|
+
let query = $state("");
|
|
20
|
+
|
|
21
|
+
const trimmed = $derived(query.trim());
|
|
22
|
+
const filtered = $derived.by(() => {
|
|
23
|
+
if (!trimmed) return groups;
|
|
24
|
+
const needle = trimmed.toLocaleLowerCase();
|
|
25
|
+
return groups.filter((group) =>
|
|
26
|
+
`${group.label} ${group.description ?? ""}`
|
|
27
|
+
.toLocaleLowerCase()
|
|
28
|
+
.includes(needle),
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
const createCandidate = $derived.by(() => {
|
|
32
|
+
if (!trimmed) return null;
|
|
33
|
+
const exists = groups.some(
|
|
34
|
+
(group) => group.label.toLocaleLowerCase() === trimmed.toLocaleLowerCase(),
|
|
35
|
+
);
|
|
36
|
+
return exists ? null : trimmed;
|
|
37
|
+
});
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<Dialog.Root
|
|
41
|
+
{open}
|
|
42
|
+
onOpenChange={(next) => {
|
|
43
|
+
if (!next) onCancel();
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
<Dialog.Content {portalProps} class="bookmarks-group-picker" showCloseButton={false}>
|
|
47
|
+
<Dialog.Header class="sr-only">
|
|
48
|
+
<Dialog.Title>Bookmark group</Dialog.Title>
|
|
49
|
+
<Dialog.Description>Choose an existing group or create one</Dialog.Description>
|
|
50
|
+
</Dialog.Header>
|
|
51
|
+
<CommandView.Root shouldFilter={false}>
|
|
52
|
+
<CommandView.Input
|
|
53
|
+
bind:value={query}
|
|
54
|
+
placeholder="Search bookmark groups…"
|
|
55
|
+
/>
|
|
56
|
+
<CommandView.List aria-label="Bookmark groups">
|
|
57
|
+
{#if createCandidate}
|
|
58
|
+
<CommandView.Item
|
|
59
|
+
onSelect={() => onSelect(null, createCandidate)}
|
|
60
|
+
>
|
|
61
|
+
<CommandView.ItemLabel>Create “{createCandidate}”</CommandView.ItemLabel>
|
|
62
|
+
</CommandView.Item>
|
|
63
|
+
{/if}
|
|
64
|
+
{#each filtered as group (String(group.ctime) + group.label)}
|
|
65
|
+
<CommandView.Item onSelect={() => onSelect(group.ctime)}>
|
|
66
|
+
<CommandView.ItemLabel>{group.label}</CommandView.ItemLabel>
|
|
67
|
+
{#if group.description}
|
|
68
|
+
<CommandView.ItemDescription>{group.description}</CommandView.ItemDescription>
|
|
69
|
+
{/if}
|
|
70
|
+
</CommandView.Item>
|
|
71
|
+
{/each}
|
|
72
|
+
<CommandView.Empty>No bookmark groups</CommandView.Empty>
|
|
73
|
+
</CommandView.List>
|
|
74
|
+
</CommandView.Root>
|
|
75
|
+
</Dialog.Content>
|
|
76
|
+
</Dialog.Root>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
open?: boolean;
|
|
3
|
+
groups: Array<{
|
|
4
|
+
ctime: number | null;
|
|
5
|
+
label: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
}>;
|
|
8
|
+
portalProps: {
|
|
9
|
+
to: HTMLElement;
|
|
10
|
+
};
|
|
11
|
+
onCancel: () => void;
|
|
12
|
+
onSelect: (ctime: number | null, createTitle?: string) => void;
|
|
13
|
+
};
|
|
14
|
+
declare const PickBookmarkGroup: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
15
|
+
type PickBookmarkGroup = ReturnType<typeof PickBookmarkGroup>;
|
|
16
|
+
export default PickBookmarkGroup;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as BookmarksPanel } from "./bookmarks-panel.svelte";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as BookmarksPanel } from "./bookmarks-panel.svelte";
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/* Bookmarks currently uses host and component-scoped styles only. */
|
package/manifest.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "bookmarks",
|
|
3
|
+
"name": "Bookmarks",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"minAppVersion": "0.1.0",
|
|
6
|
+
"description": "Bookmark files, folders, searches, and groups",
|
|
7
|
+
"author": "Lapis Notes",
|
|
8
|
+
"lapis": {
|
|
9
|
+
"manifestVersion": 1,
|
|
10
|
+
"source": "official",
|
|
11
|
+
"locked": false,
|
|
12
|
+
"enabledByDefault": true,
|
|
13
|
+
"runtime": {
|
|
14
|
+
"entries": {
|
|
15
|
+
"workspace": {
|
|
16
|
+
"path": "main.mjs",
|
|
17
|
+
"format": "esm",
|
|
18
|
+
"sharedDependencies": [
|
|
19
|
+
"@lapis-notes/api"
|
|
20
|
+
],
|
|
21
|
+
"requiresReloadOnUpdate": false
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lapis-notes/bookmarks",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Lapis Notes bookmarks plugin",
|
|
5
|
+
"license": "AGPL-3.0-or-later",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"manifest.json",
|
|
10
|
+
"styles.css",
|
|
11
|
+
"README.md",
|
|
12
|
+
"CHANGELOG.md",
|
|
13
|
+
"LICENSE.md",
|
|
14
|
+
"!dist/**/*.test.*",
|
|
15
|
+
"!dist/**/*.spec.*"
|
|
16
|
+
],
|
|
17
|
+
"sideEffects": [
|
|
18
|
+
"**/*.css"
|
|
19
|
+
],
|
|
20
|
+
"svelte": "./dist/index.js",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"svelte": "./dist/index.js",
|
|
26
|
+
"import": "./dist/index.js",
|
|
27
|
+
"default": "./dist/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./manifest.json": "./manifest.json",
|
|
30
|
+
"./styles.css": "./styles.css"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@lapis-notes/api": "^0.1.0",
|
|
34
|
+
"@lapismd/design-core": "^0.1.0",
|
|
35
|
+
"@lucide/svelte": "^0.523.0"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"svelte": "^5.0.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@sveltejs/package": "^2.5.0",
|
|
42
|
+
"@sveltejs/vite-plugin-svelte": "^5.1.1",
|
|
43
|
+
"@tsconfig/svelte": "^5.0.5",
|
|
44
|
+
"publint": "^0.3.12",
|
|
45
|
+
"svelte": "^5.38.2",
|
|
46
|
+
"svelte-check": "^4.3.1",
|
|
47
|
+
"typescript": "~5.8.3",
|
|
48
|
+
"vite": "^6.4.2",
|
|
49
|
+
"vitest": "^4.1.8"
|
|
50
|
+
},
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "git+https://github.com/lapismd/lapis-plugins.git",
|
|
54
|
+
"directory": "packages/bookmarks"
|
|
55
|
+
},
|
|
56
|
+
"homepage": "https://github.com/lapismd/lapis-plugins/tree/main/packages/bookmarks#readme",
|
|
57
|
+
"bugs": {
|
|
58
|
+
"url": "https://github.com/lapismd/lapis-plugins/issues"
|
|
59
|
+
},
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"build": "pnpm run prepack",
|
|
65
|
+
"check": "pnpm check:svelte && pnpm check:types",
|
|
66
|
+
"check:svelte": "svelte-check --tsconfig ./tsconfig.app.json --fail-on-warnings --output human",
|
|
67
|
+
"check:types": "tsc -p tsconfig.node.json --noEmit",
|
|
68
|
+
"test": "vitest run --passWithNoTests",
|
|
69
|
+
"publint": "publint",
|
|
70
|
+
"pack": "pnpm pack --pack-destination ../../.release/npm"
|
|
71
|
+
}
|
|
72
|
+
}
|
package/styles.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import "./dist/styles.css";
|