@autumnsgrove/groveengine 0.6.1 → 0.6.3
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/dist/auth/jwt.d.ts +10 -4
- package/dist/auth/jwt.js +18 -4
- package/dist/auth/session.d.ts +22 -15
- package/dist/auth/session.js +35 -16
- package/dist/components/admin/GutterManager.svelte +81 -139
- package/dist/components/admin/GutterManager.svelte.d.ts +6 -6
- package/dist/components/admin/MarkdownEditor.svelte +80 -23
- package/dist/components/admin/MarkdownEditor.svelte.d.ts +14 -8
- package/dist/components/admin/composables/useAmbientSounds.svelte.d.ts +52 -2
- package/dist/components/admin/composables/useAmbientSounds.svelte.js +38 -4
- package/dist/components/admin/composables/useCommandPalette.svelte.d.ts +80 -10
- package/dist/components/admin/composables/useCommandPalette.svelte.js +45 -5
- package/dist/components/admin/composables/useDraftManager.svelte.d.ts +76 -14
- package/dist/components/admin/composables/useDraftManager.svelte.js +44 -10
- package/dist/components/admin/composables/useEditorTheme.svelte.d.ts +168 -2
- package/dist/components/admin/composables/useEditorTheme.svelte.js +40 -7
- package/dist/components/admin/composables/useSlashCommands.svelte.d.ts +94 -22
- package/dist/components/admin/composables/useSlashCommands.svelte.js +58 -9
- package/dist/components/admin/composables/useSnippets.svelte.d.ts +51 -2
- package/dist/components/admin/composables/useSnippets.svelte.js +35 -3
- package/dist/components/admin/composables/useWritingSession.svelte.d.ts +64 -6
- package/dist/components/admin/composables/useWritingSession.svelte.js +42 -5
- package/dist/components/custom/ContentWithGutter.svelte +53 -23
- package/dist/components/custom/ContentWithGutter.svelte.d.ts +6 -14
- package/dist/components/custom/GutterItem.svelte +1 -1
- package/dist/components/custom/LeftGutter.svelte +43 -13
- package/dist/components/custom/LeftGutter.svelte.d.ts +6 -6
- package/dist/config/ai-models.js +1 -1
- package/dist/groveauth/client.js +11 -11
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -2
- package/dist/server/logger.d.ts +74 -26
- package/dist/server/logger.js +133 -184
- package/dist/server/services/cache.js +1 -10
- package/dist/ui/components/charts/ActivityOverview.svelte +14 -3
- package/dist/ui/components/charts/ActivityOverview.svelte.d.ts +10 -7
- package/dist/ui/components/charts/RepoBreakdown.svelte +9 -3
- package/dist/ui/components/charts/RepoBreakdown.svelte.d.ts +12 -11
- package/dist/ui/components/charts/Sparkline.svelte +18 -7
- package/dist/ui/components/charts/Sparkline.svelte.d.ts +21 -2
- package/dist/ui/components/gallery/ImageGallery.svelte +12 -8
- package/dist/ui/components/gallery/ImageGallery.svelte.d.ts +2 -2
- package/dist/ui/components/gallery/Lightbox.svelte +5 -2
- package/dist/ui/components/gallery/ZoomableImage.svelte +8 -5
- package/dist/ui/components/primitives/accordion/index.d.ts +1 -1
- package/dist/ui/components/primitives/input/input.svelte.d.ts +1 -1
- package/dist/ui/components/primitives/tabs/index.d.ts +1 -1
- package/dist/ui/components/primitives/textarea/textarea.svelte.d.ts +1 -1
- package/dist/ui/components/ui/Button.svelte +5 -0
- package/dist/ui/components/ui/Button.svelte.d.ts +4 -1
- package/dist/ui/components/ui/Input.svelte +4 -0
- package/dist/ui/components/ui/Input.svelte.d.ts +3 -1
- package/dist/ui/components/ui/Logo.svelte +86 -0
- package/dist/ui/components/ui/Logo.svelte.d.ts +25 -0
- package/dist/ui/components/ui/LogoLoader.svelte +71 -0
- package/dist/ui/components/ui/LogoLoader.svelte.d.ts +9 -0
- package/dist/ui/components/ui/index.d.ts +2 -0
- package/dist/ui/components/ui/index.js +2 -0
- package/dist/ui/tailwind.preset.js +8 -8
- package/dist/utils/api.js +2 -1
- package/dist/utils/debounce.d.ts +4 -3
- package/dist/utils/debounce.js +10 -6
- package/dist/utils/gallery.d.ts +58 -32
- package/dist/utils/gallery.js +111 -129
- package/dist/utils/gutter.d.ts +47 -26
- package/dist/utils/gutter.js +116 -124
- package/dist/utils/imageProcessor.d.ts +66 -19
- package/dist/utils/imageProcessor.js +31 -10
- package/dist/utils/index.d.ts +11 -11
- package/dist/utils/index.js +4 -3
- package/dist/utils/json.js +1 -1
- package/dist/utils/markdown.d.ts +183 -103
- package/dist/utils/markdown.js +517 -678
- package/dist/utils/sanitize.d.ts +22 -12
- package/dist/utils/sanitize.js +268 -282
- package/dist/utils/validation.js +4 -3
- package/package.json +4 -3
|
@@ -3,13 +3,50 @@
|
|
|
3
3
|
* Manages the command palette (Cmd+K) functionality
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {Object} PaletteAction
|
|
8
|
+
* @property {string} id
|
|
9
|
+
* @property {string} label
|
|
10
|
+
* @property {string} shortcut
|
|
11
|
+
* @property {() => void} action
|
|
12
|
+
* @property {string} [themeKey]
|
|
13
|
+
* @property {boolean} [isTheme]
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {Object} CommandPaletteState
|
|
18
|
+
* @property {boolean} open
|
|
19
|
+
* @property {string} query
|
|
20
|
+
* @property {number} selectedIndex
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {Object} CommandPaletteOptions
|
|
25
|
+
* @property {() => PaletteAction[]} [getActions] - Function to get available actions
|
|
26
|
+
* @property {() => Record<string, any>} [getThemes] - Function to get available themes
|
|
27
|
+
* @property {() => string} [getCurrentTheme] - Function to get current theme
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @typedef {Object} CommandPaletteManager
|
|
32
|
+
* @property {CommandPaletteState} state
|
|
33
|
+
* @property {boolean} isOpen
|
|
34
|
+
* @property {string} query
|
|
35
|
+
* @property {number} selectedIndex
|
|
36
|
+
* @property {() => PaletteAction[]} getAllCommands
|
|
37
|
+
* @property {() => PaletteAction[]} getFilteredCommands
|
|
38
|
+
* @property {() => void} open
|
|
39
|
+
* @property {() => void} close
|
|
40
|
+
* @property {() => void} toggle
|
|
41
|
+
* @property {(direction: 'up' | 'down') => void} navigate
|
|
42
|
+
* @property {(index: number) => PaletteAction | undefined} execute
|
|
43
|
+
* @property {(query: string) => void} setQuery
|
|
44
|
+
*/
|
|
45
|
+
|
|
6
46
|
/**
|
|
7
47
|
* Creates a command palette manager with Svelte 5 runes
|
|
8
|
-
* @param {
|
|
9
|
-
* @
|
|
10
|
-
* @param {Function} options.getThemes - Function to get available themes
|
|
11
|
-
* @param {Function} options.getCurrentTheme - Function to get current theme
|
|
12
|
-
* @returns {object} Command palette state and controls
|
|
48
|
+
* @param {CommandPaletteOptions} options - Configuration options
|
|
49
|
+
* @returns {CommandPaletteManager} Command palette state and controls
|
|
13
50
|
*/
|
|
14
51
|
export function useCommandPalette(options = {}) {
|
|
15
52
|
const { getActions, getThemes, getCurrentTheme } = options;
|
|
@@ -66,6 +103,7 @@ export function useCommandPalette(options = {}) {
|
|
|
66
103
|
}
|
|
67
104
|
}
|
|
68
105
|
|
|
106
|
+
/** @param {'up' | 'down'} direction */
|
|
69
107
|
function navigate(direction) {
|
|
70
108
|
const filtered = getFilteredCommands();
|
|
71
109
|
const count = filtered.length;
|
|
@@ -78,6 +116,7 @@ export function useCommandPalette(options = {}) {
|
|
|
78
116
|
}
|
|
79
117
|
}
|
|
80
118
|
|
|
119
|
+
/** @param {number} index */
|
|
81
120
|
function execute(index) {
|
|
82
121
|
const filtered = getFilteredCommands();
|
|
83
122
|
const cmd = filtered[index];
|
|
@@ -88,6 +127,7 @@ export function useCommandPalette(options = {}) {
|
|
|
88
127
|
return cmd;
|
|
89
128
|
}
|
|
90
129
|
|
|
130
|
+
/** @param {string} query */
|
|
91
131
|
function setQuery(query) {
|
|
92
132
|
state.query = query;
|
|
93
133
|
state.selectedIndex = 0;
|
|
@@ -1,17 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} StoredDraft
|
|
3
|
+
* @property {string} content
|
|
4
|
+
* @property {string} savedAt
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {Object} DraftManagerOptions
|
|
8
|
+
* @property {string|null} [draftKey] - Unique key for localStorage
|
|
9
|
+
* @property {() => string} [getContent] - Function to get current content
|
|
10
|
+
* @property {(content: string) => void} [setContent] - Function to set content
|
|
11
|
+
* @property {(draft: StoredDraft) => void} [onDraftRestored] - Callback when draft is restored
|
|
12
|
+
* @property {boolean} [readonly] - Whether editor is readonly
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {Object} DraftManager
|
|
16
|
+
* @property {boolean} hasDraft
|
|
17
|
+
* @property {boolean} draftRestorePrompt
|
|
18
|
+
* @property {StoredDraft|null} storedDraft
|
|
19
|
+
* @property {string} lastSavedContent
|
|
20
|
+
* @property {(initialContent: string) => void} init
|
|
21
|
+
* @property {(content: string) => void} scheduleSave
|
|
22
|
+
* @property {() => void} saveDraft
|
|
23
|
+
* @property {() => void} clearDraft
|
|
24
|
+
* @property {() => void} restoreDraft
|
|
25
|
+
* @property {() => void} discardDraft
|
|
26
|
+
* @property {() => {hasDraft: boolean, storedDraft: StoredDraft|null}} getStatus
|
|
27
|
+
* @property {(content: string) => boolean} hasUnsavedChanges
|
|
28
|
+
* @property {() => void} cleanup
|
|
29
|
+
*/
|
|
1
30
|
/**
|
|
2
31
|
* Creates a draft manager with Svelte 5 runes
|
|
3
|
-
* @param {
|
|
4
|
-
* @
|
|
5
|
-
* @param {Function} options.getContent - Function to get current content
|
|
6
|
-
* @param {Function} options.setContent - Function to set content
|
|
7
|
-
* @param {Function} options.onDraftRestored - Callback when draft is restored
|
|
8
|
-
* @param {boolean} options.readonly - Whether editor is readonly
|
|
9
|
-
* @returns {object} Draft state and controls
|
|
32
|
+
* @param {DraftManagerOptions} options - Configuration options
|
|
33
|
+
* @returns {DraftManager} Draft state and controls
|
|
10
34
|
*/
|
|
11
|
-
export function useDraftManager(options?:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
35
|
+
export function useDraftManager(options?: DraftManagerOptions): DraftManager;
|
|
36
|
+
export type StoredDraft = {
|
|
37
|
+
content: string;
|
|
38
|
+
savedAt: string;
|
|
39
|
+
};
|
|
40
|
+
export type DraftManagerOptions = {
|
|
41
|
+
/**
|
|
42
|
+
* - Unique key for localStorage
|
|
43
|
+
*/
|
|
44
|
+
draftKey?: string | null | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* - Function to get current content
|
|
47
|
+
*/
|
|
48
|
+
getContent?: (() => string) | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* - Function to set content
|
|
51
|
+
*/
|
|
52
|
+
setContent?: ((content: string) => void) | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* - Callback when draft is restored
|
|
55
|
+
*/
|
|
56
|
+
onDraftRestored?: ((draft: StoredDraft) => void) | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* - Whether editor is readonly
|
|
59
|
+
*/
|
|
60
|
+
readonly?: boolean | undefined;
|
|
61
|
+
};
|
|
62
|
+
export type DraftManager = {
|
|
63
|
+
hasDraft: boolean;
|
|
64
|
+
draftRestorePrompt: boolean;
|
|
65
|
+
storedDraft: StoredDraft | null;
|
|
66
|
+
lastSavedContent: string;
|
|
67
|
+
init: (initialContent: string) => void;
|
|
68
|
+
scheduleSave: (content: string) => void;
|
|
69
|
+
saveDraft: () => void;
|
|
70
|
+
clearDraft: () => void;
|
|
71
|
+
restoreDraft: () => void;
|
|
72
|
+
discardDraft: () => void;
|
|
73
|
+
getStatus: () => {
|
|
74
|
+
hasDraft: boolean;
|
|
75
|
+
storedDraft: StoredDraft | null;
|
|
76
|
+
};
|
|
77
|
+
hasUnsavedChanges: (content: string) => boolean;
|
|
78
|
+
cleanup: () => void;
|
|
79
|
+
};
|
|
@@ -5,27 +5,56 @@
|
|
|
5
5
|
|
|
6
6
|
const AUTO_SAVE_DELAY = 2000; // 2 seconds
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {Object} StoredDraft
|
|
10
|
+
* @property {string} content
|
|
11
|
+
* @property {string} savedAt
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {Object} DraftManagerOptions
|
|
16
|
+
* @property {string|null} [draftKey] - Unique key for localStorage
|
|
17
|
+
* @property {() => string} [getContent] - Function to get current content
|
|
18
|
+
* @property {(content: string) => void} [setContent] - Function to set content
|
|
19
|
+
* @property {(draft: StoredDraft) => void} [onDraftRestored] - Callback when draft is restored
|
|
20
|
+
* @property {boolean} [readonly] - Whether editor is readonly
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {Object} DraftManager
|
|
25
|
+
* @property {boolean} hasDraft
|
|
26
|
+
* @property {boolean} draftRestorePrompt
|
|
27
|
+
* @property {StoredDraft|null} storedDraft
|
|
28
|
+
* @property {string} lastSavedContent
|
|
29
|
+
* @property {(initialContent: string) => void} init
|
|
30
|
+
* @property {(content: string) => void} scheduleSave
|
|
31
|
+
* @property {() => void} saveDraft
|
|
32
|
+
* @property {() => void} clearDraft
|
|
33
|
+
* @property {() => void} restoreDraft
|
|
34
|
+
* @property {() => void} discardDraft
|
|
35
|
+
* @property {() => {hasDraft: boolean, storedDraft: StoredDraft|null}} getStatus
|
|
36
|
+
* @property {(content: string) => boolean} hasUnsavedChanges
|
|
37
|
+
* @property {() => void} cleanup
|
|
38
|
+
*/
|
|
39
|
+
|
|
8
40
|
/**
|
|
9
41
|
* Creates a draft manager with Svelte 5 runes
|
|
10
|
-
* @param {
|
|
11
|
-
* @
|
|
12
|
-
* @param {Function} options.getContent - Function to get current content
|
|
13
|
-
* @param {Function} options.setContent - Function to set content
|
|
14
|
-
* @param {Function} options.onDraftRestored - Callback when draft is restored
|
|
15
|
-
* @param {boolean} options.readonly - Whether editor is readonly
|
|
16
|
-
* @returns {object} Draft state and controls
|
|
42
|
+
* @param {DraftManagerOptions} options - Configuration options
|
|
43
|
+
* @returns {DraftManager} Draft state and controls
|
|
17
44
|
*/
|
|
18
|
-
export function useDraftManager(options = {}) {
|
|
45
|
+
export function useDraftManager(options = /** @type {DraftManagerOptions} */ ({})) {
|
|
19
46
|
const { draftKey, getContent, setContent, onDraftRestored, readonly } = options;
|
|
20
47
|
|
|
21
48
|
let lastSavedContent = $state("");
|
|
49
|
+
/** @type {ReturnType<typeof setTimeout> | null} */
|
|
22
50
|
let draftSaveTimer = $state(null);
|
|
23
51
|
let hasDraft = $state(false);
|
|
24
52
|
let draftRestorePrompt = $state(false);
|
|
53
|
+
/** @type {StoredDraft | null} */
|
|
25
54
|
let storedDraft = $state(null);
|
|
26
55
|
|
|
27
56
|
function saveDraft() {
|
|
28
|
-
if (!draftKey || readonly) return;
|
|
57
|
+
if (!draftKey || readonly || !getContent) return;
|
|
29
58
|
|
|
30
59
|
const content = getContent();
|
|
31
60
|
try {
|
|
@@ -81,9 +110,12 @@ export function useDraftManager(options = {}) {
|
|
|
81
110
|
|
|
82
111
|
function discardDraft() {
|
|
83
112
|
clearDraft();
|
|
84
|
-
|
|
113
|
+
if (getContent) {
|
|
114
|
+
lastSavedContent = getContent();
|
|
115
|
+
}
|
|
85
116
|
}
|
|
86
117
|
|
|
118
|
+
/** @param {string} content */
|
|
87
119
|
function scheduleSave(content) {
|
|
88
120
|
if (!draftKey || readonly) return;
|
|
89
121
|
|
|
@@ -101,6 +133,7 @@ export function useDraftManager(options = {}) {
|
|
|
101
133
|
}, AUTO_SAVE_DELAY);
|
|
102
134
|
}
|
|
103
135
|
|
|
136
|
+
/** @param {string} initialContent */
|
|
104
137
|
function init(initialContent) {
|
|
105
138
|
// Check for existing draft on mount
|
|
106
139
|
if (draftKey) {
|
|
@@ -124,6 +157,7 @@ export function useDraftManager(options = {}) {
|
|
|
124
157
|
return { hasDraft, storedDraft };
|
|
125
158
|
}
|
|
126
159
|
|
|
160
|
+
/** @param {string} content */
|
|
127
161
|
function hasUnsavedChanges(content) {
|
|
128
162
|
return content !== lastSavedContent;
|
|
129
163
|
}
|
|
@@ -1,8 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} Theme
|
|
3
|
+
* @property {string} name
|
|
4
|
+
* @property {string} label
|
|
5
|
+
* @property {string} desc
|
|
6
|
+
* @property {string} accent
|
|
7
|
+
* @property {string} accentDim
|
|
8
|
+
* @property {string} accentBright
|
|
9
|
+
* @property {string} accentGlow
|
|
10
|
+
* @property {string} bg
|
|
11
|
+
* @property {string} bgSecondary
|
|
12
|
+
* @property {string} bgTertiary
|
|
13
|
+
* @property {string} border
|
|
14
|
+
* @property {string} borderAccent
|
|
15
|
+
* @property {string} text
|
|
16
|
+
* @property {string} textDim
|
|
17
|
+
* @property {string} statusBg
|
|
18
|
+
* @property {string} statusBorder
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* @typedef {Object} EditorThemeManager
|
|
22
|
+
* @property {string} currentTheme
|
|
23
|
+
* @property {Record<string, Theme>} themes
|
|
24
|
+
* @property {() => void} loadTheme
|
|
25
|
+
* @property {(themeName: string) => void} setTheme
|
|
26
|
+
*/
|
|
1
27
|
/**
|
|
2
28
|
* Creates an editor theme manager with Svelte 5 runes
|
|
3
|
-
* @returns {
|
|
29
|
+
* @returns {EditorThemeManager} Theme state and controls
|
|
4
30
|
*/
|
|
5
|
-
|
|
31
|
+
/** @typedef {keyof typeof themes} ThemeName */
|
|
32
|
+
export function useEditorTheme(): {
|
|
33
|
+
readonly currentTheme: "grove" | "amber" | "matrix" | "dracula" | "nord" | "rose";
|
|
34
|
+
themes: {
|
|
35
|
+
grove: {
|
|
36
|
+
name: string;
|
|
37
|
+
label: string;
|
|
38
|
+
desc: string;
|
|
39
|
+
accent: string;
|
|
40
|
+
accentDim: string;
|
|
41
|
+
accentBright: string;
|
|
42
|
+
accentGlow: string;
|
|
43
|
+
bg: string;
|
|
44
|
+
bgSecondary: string;
|
|
45
|
+
bgTertiary: string;
|
|
46
|
+
border: string;
|
|
47
|
+
borderAccent: string;
|
|
48
|
+
text: string;
|
|
49
|
+
textDim: string;
|
|
50
|
+
statusBg: string;
|
|
51
|
+
statusBorder: string;
|
|
52
|
+
};
|
|
53
|
+
amber: {
|
|
54
|
+
name: string;
|
|
55
|
+
label: string;
|
|
56
|
+
desc: string;
|
|
57
|
+
accent: string;
|
|
58
|
+
accentDim: string;
|
|
59
|
+
accentBright: string;
|
|
60
|
+
accentGlow: string;
|
|
61
|
+
bg: string;
|
|
62
|
+
bgSecondary: string;
|
|
63
|
+
bgTertiary: string;
|
|
64
|
+
border: string;
|
|
65
|
+
borderAccent: string;
|
|
66
|
+
text: string;
|
|
67
|
+
textDim: string;
|
|
68
|
+
statusBg: string;
|
|
69
|
+
statusBorder: string;
|
|
70
|
+
};
|
|
71
|
+
matrix: {
|
|
72
|
+
name: string;
|
|
73
|
+
label: string;
|
|
74
|
+
desc: string;
|
|
75
|
+
accent: string;
|
|
76
|
+
accentDim: string;
|
|
77
|
+
accentBright: string;
|
|
78
|
+
accentGlow: string;
|
|
79
|
+
bg: string;
|
|
80
|
+
bgSecondary: string;
|
|
81
|
+
bgTertiary: string;
|
|
82
|
+
border: string;
|
|
83
|
+
borderAccent: string;
|
|
84
|
+
text: string;
|
|
85
|
+
textDim: string;
|
|
86
|
+
statusBg: string;
|
|
87
|
+
statusBorder: string;
|
|
88
|
+
};
|
|
89
|
+
dracula: {
|
|
90
|
+
name: string;
|
|
91
|
+
label: string;
|
|
92
|
+
desc: string;
|
|
93
|
+
accent: string;
|
|
94
|
+
accentDim: string;
|
|
95
|
+
accentBright: string;
|
|
96
|
+
accentGlow: string;
|
|
97
|
+
bg: string;
|
|
98
|
+
bgSecondary: string;
|
|
99
|
+
bgTertiary: string;
|
|
100
|
+
border: string;
|
|
101
|
+
borderAccent: string;
|
|
102
|
+
text: string;
|
|
103
|
+
textDim: string;
|
|
104
|
+
statusBg: string;
|
|
105
|
+
statusBorder: string;
|
|
106
|
+
};
|
|
107
|
+
nord: {
|
|
108
|
+
name: string;
|
|
109
|
+
label: string;
|
|
110
|
+
desc: string;
|
|
111
|
+
accent: string;
|
|
112
|
+
accentDim: string;
|
|
113
|
+
accentBright: string;
|
|
114
|
+
accentGlow: string;
|
|
115
|
+
bg: string;
|
|
116
|
+
bgSecondary: string;
|
|
117
|
+
bgTertiary: string;
|
|
118
|
+
border: string;
|
|
119
|
+
borderAccent: string;
|
|
120
|
+
text: string;
|
|
121
|
+
textDim: string;
|
|
122
|
+
statusBg: string;
|
|
123
|
+
statusBorder: string;
|
|
124
|
+
};
|
|
125
|
+
rose: {
|
|
126
|
+
name: string;
|
|
127
|
+
label: string;
|
|
128
|
+
desc: string;
|
|
129
|
+
accent: string;
|
|
130
|
+
accentDim: string;
|
|
131
|
+
accentBright: string;
|
|
132
|
+
accentGlow: string;
|
|
133
|
+
bg: string;
|
|
134
|
+
bgSecondary: string;
|
|
135
|
+
bgTertiary: string;
|
|
136
|
+
border: string;
|
|
137
|
+
borderAccent: string;
|
|
138
|
+
text: string;
|
|
139
|
+
textDim: string;
|
|
140
|
+
statusBg: string;
|
|
141
|
+
statusBorder: string;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
loadTheme: () => void;
|
|
145
|
+
setTheme: (themeName: string) => void;
|
|
146
|
+
};
|
|
6
147
|
export namespace themes {
|
|
7
148
|
namespace grove {
|
|
8
149
|
let name: string;
|
|
@@ -193,3 +334,28 @@ export namespace themes {
|
|
|
193
334
|
export { statusBorder_5 as statusBorder };
|
|
194
335
|
}
|
|
195
336
|
}
|
|
337
|
+
export type Theme = {
|
|
338
|
+
name: string;
|
|
339
|
+
label: string;
|
|
340
|
+
desc: string;
|
|
341
|
+
accent: string;
|
|
342
|
+
accentDim: string;
|
|
343
|
+
accentBright: string;
|
|
344
|
+
accentGlow: string;
|
|
345
|
+
bg: string;
|
|
346
|
+
bgSecondary: string;
|
|
347
|
+
bgTertiary: string;
|
|
348
|
+
border: string;
|
|
349
|
+
borderAccent: string;
|
|
350
|
+
text: string;
|
|
351
|
+
textDim: string;
|
|
352
|
+
statusBg: string;
|
|
353
|
+
statusBorder: string;
|
|
354
|
+
};
|
|
355
|
+
export type EditorThemeManager = {
|
|
356
|
+
currentTheme: string;
|
|
357
|
+
themes: Record<string, Theme>;
|
|
358
|
+
loadTheme: () => void;
|
|
359
|
+
setTheme: (themeName: string) => void;
|
|
360
|
+
};
|
|
361
|
+
export type ThemeName = keyof typeof themes;
|
|
@@ -117,15 +117,46 @@ export const themes = {
|
|
|
117
117
|
},
|
|
118
118
|
};
|
|
119
119
|
|
|
120
|
+
/**
|
|
121
|
+
* @typedef {Object} Theme
|
|
122
|
+
* @property {string} name
|
|
123
|
+
* @property {string} label
|
|
124
|
+
* @property {string} desc
|
|
125
|
+
* @property {string} accent
|
|
126
|
+
* @property {string} accentDim
|
|
127
|
+
* @property {string} accentBright
|
|
128
|
+
* @property {string} accentGlow
|
|
129
|
+
* @property {string} bg
|
|
130
|
+
* @property {string} bgSecondary
|
|
131
|
+
* @property {string} bgTertiary
|
|
132
|
+
* @property {string} border
|
|
133
|
+
* @property {string} borderAccent
|
|
134
|
+
* @property {string} text
|
|
135
|
+
* @property {string} textDim
|
|
136
|
+
* @property {string} statusBg
|
|
137
|
+
* @property {string} statusBorder
|
|
138
|
+
*/
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @typedef {Object} EditorThemeManager
|
|
142
|
+
* @property {string} currentTheme
|
|
143
|
+
* @property {Record<string, Theme>} themes
|
|
144
|
+
* @property {() => void} loadTheme
|
|
145
|
+
* @property {(themeName: string) => void} setTheme
|
|
146
|
+
*/
|
|
147
|
+
|
|
120
148
|
/**
|
|
121
149
|
* Creates an editor theme manager with Svelte 5 runes
|
|
122
|
-
* @returns {
|
|
150
|
+
* @returns {EditorThemeManager} Theme state and controls
|
|
123
151
|
*/
|
|
152
|
+
/** @typedef {keyof typeof themes} ThemeName */
|
|
153
|
+
|
|
124
154
|
export function useEditorTheme() {
|
|
125
|
-
let currentTheme = $state("grove");
|
|
155
|
+
let currentTheme = $state(/** @type {ThemeName} */ ("grove"));
|
|
126
156
|
|
|
157
|
+
/** @param {string} themeName */
|
|
127
158
|
function applyTheme(themeName) {
|
|
128
|
-
const theme = themes[themeName];
|
|
159
|
+
const theme = themes[/** @type {ThemeName} */ (themeName)];
|
|
129
160
|
if (!theme) return;
|
|
130
161
|
|
|
131
162
|
const root = document.documentElement;
|
|
@@ -147,8 +178,8 @@ export function useEditorTheme() {
|
|
|
147
178
|
function loadTheme() {
|
|
148
179
|
try {
|
|
149
180
|
const stored = localStorage.getItem(THEME_STORAGE_KEY);
|
|
150
|
-
if (stored && themes[stored]) {
|
|
151
|
-
currentTheme = stored;
|
|
181
|
+
if (stored && themes[/** @type {ThemeName} */ (stored)]) {
|
|
182
|
+
currentTheme = /** @type {ThemeName} */ (stored);
|
|
152
183
|
applyTheme(stored);
|
|
153
184
|
}
|
|
154
185
|
} catch (e) {
|
|
@@ -156,6 +187,7 @@ export function useEditorTheme() {
|
|
|
156
187
|
}
|
|
157
188
|
}
|
|
158
189
|
|
|
190
|
+
/** @param {string} themeName */
|
|
159
191
|
function saveTheme(themeName) {
|
|
160
192
|
try {
|
|
161
193
|
localStorage.setItem(THEME_STORAGE_KEY, themeName);
|
|
@@ -164,9 +196,10 @@ export function useEditorTheme() {
|
|
|
164
196
|
}
|
|
165
197
|
}
|
|
166
198
|
|
|
199
|
+
/** @param {string} themeName */
|
|
167
200
|
function setTheme(themeName) {
|
|
168
|
-
if (!themes[themeName]) return;
|
|
169
|
-
currentTheme = themeName;
|
|
201
|
+
if (!themes[/** @type {ThemeName} */ (themeName)]) return;
|
|
202
|
+
currentTheme = /** @type {ThemeName} */ (themeName);
|
|
170
203
|
applyTheme(themeName);
|
|
171
204
|
saveTheme(themeName);
|
|
172
205
|
}
|
|
@@ -1,32 +1,104 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Creates a slash commands manager with Svelte 5 runes
|
|
3
|
-
* @param {
|
|
4
|
-
* @
|
|
5
|
-
* @param {Function} options.getContent - Function to get content
|
|
6
|
-
* @param {Function} options.setContent - Function to set content
|
|
7
|
-
* @param {Function} options.getSnippets - Function to get user snippets
|
|
8
|
-
* @param {Function} options.onOpenSnippetsModal - Callback to open snippets modal
|
|
9
|
-
* @returns {object} Slash commands state and controls
|
|
3
|
+
* @param {SlashCommandsOptions} options - Configuration options
|
|
4
|
+
* @returns {SlashCommandsManager} Slash commands state and controls
|
|
10
5
|
*/
|
|
11
|
-
export function useSlashCommands(options?:
|
|
12
|
-
getTextareaRef: Function;
|
|
13
|
-
getContent: Function;
|
|
14
|
-
setContent: Function;
|
|
15
|
-
getSnippets: Function;
|
|
16
|
-
onOpenSnippetsModal: Function;
|
|
17
|
-
}): object;
|
|
6
|
+
export function useSlashCommands(options?: SlashCommandsOptions): SlashCommandsManager;
|
|
18
7
|
/**
|
|
19
8
|
* Slash Commands Composable
|
|
20
9
|
* Manages the slash command menu and execution
|
|
21
10
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {Object} SlashCommand
|
|
13
|
+
* @property {string} id
|
|
14
|
+
* @property {string} label
|
|
15
|
+
* @property {string} insert
|
|
16
|
+
* @property {number} [cursorOffset]
|
|
17
|
+
* @property {boolean} [isSnippet]
|
|
18
|
+
* @property {boolean} [isAction]
|
|
19
|
+
* @property {(() => void)} [action]
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {Object} SlashMenuState
|
|
23
|
+
* @property {boolean} open
|
|
24
|
+
* @property {string} query
|
|
25
|
+
* @property {{x: number, y: number}} position
|
|
26
|
+
* @property {number} selectedIndex
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* @typedef {Object} SlashCommandsOptions
|
|
30
|
+
* @property {() => HTMLTextAreaElement|null} [getTextareaRef] - Function to get textarea reference
|
|
31
|
+
* @property {() => string} [getContent] - Function to get content
|
|
32
|
+
* @property {(content: string) => void} [setContent] - Function to set content
|
|
33
|
+
* @property {() => Array<{id: string, name: string, content: string}>} [getSnippets] - Function to get user snippets
|
|
34
|
+
* @property {() => void} [onOpenSnippetsModal] - Callback to open snippets modal
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* @typedef {Object} SlashCommandsManager
|
|
38
|
+
* @property {SlashMenuState} menu
|
|
39
|
+
* @property {boolean} isOpen
|
|
40
|
+
* @property {() => SlashCommand[]} getAllCommands
|
|
41
|
+
* @property {() => SlashCommand[]} getFilteredCommands
|
|
42
|
+
* @property {() => void} open
|
|
43
|
+
* @property {() => void} close
|
|
44
|
+
* @property {(direction: 'up' | 'down') => void} navigate
|
|
45
|
+
* @property {(index: number) => void} execute
|
|
46
|
+
* @property {(key: string, cursorPos: number, content: string) => boolean} shouldTrigger
|
|
47
|
+
*/
|
|
48
|
+
/** @type {SlashCommand[]} */
|
|
49
|
+
export const baseSlashCommands: SlashCommand[];
|
|
50
|
+
export type SlashCommand = {
|
|
28
51
|
id: string;
|
|
29
52
|
label: string;
|
|
30
53
|
insert: string;
|
|
31
|
-
cursorOffset
|
|
32
|
-
|
|
54
|
+
cursorOffset?: number | undefined;
|
|
55
|
+
isSnippet?: boolean | undefined;
|
|
56
|
+
isAction?: boolean | undefined;
|
|
57
|
+
action?: (() => void) | undefined;
|
|
58
|
+
};
|
|
59
|
+
export type SlashMenuState = {
|
|
60
|
+
open: boolean;
|
|
61
|
+
query: string;
|
|
62
|
+
position: {
|
|
63
|
+
x: number;
|
|
64
|
+
y: number;
|
|
65
|
+
};
|
|
66
|
+
selectedIndex: number;
|
|
67
|
+
};
|
|
68
|
+
export type SlashCommandsOptions = {
|
|
69
|
+
/**
|
|
70
|
+
* - Function to get textarea reference
|
|
71
|
+
*/
|
|
72
|
+
getTextareaRef?: (() => HTMLTextAreaElement | null) | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* - Function to get content
|
|
75
|
+
*/
|
|
76
|
+
getContent?: (() => string) | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* - Function to set content
|
|
79
|
+
*/
|
|
80
|
+
setContent?: ((content: string) => void) | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* - Function to get user snippets
|
|
83
|
+
*/
|
|
84
|
+
getSnippets?: (() => Array<{
|
|
85
|
+
id: string;
|
|
86
|
+
name: string;
|
|
87
|
+
content: string;
|
|
88
|
+
}>) | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* - Callback to open snippets modal
|
|
91
|
+
*/
|
|
92
|
+
onOpenSnippetsModal?: (() => void) | undefined;
|
|
93
|
+
};
|
|
94
|
+
export type SlashCommandsManager = {
|
|
95
|
+
menu: SlashMenuState;
|
|
96
|
+
isOpen: boolean;
|
|
97
|
+
getAllCommands: () => SlashCommand[];
|
|
98
|
+
getFilteredCommands: () => SlashCommand[];
|
|
99
|
+
open: () => void;
|
|
100
|
+
close: () => void;
|
|
101
|
+
navigate: (direction: "up" | "down") => void;
|
|
102
|
+
execute: (index: number) => void;
|
|
103
|
+
shouldTrigger: (key: string, cursorPos: number, content: string) => boolean;
|
|
104
|
+
};
|