feat(snippet-shortcuts): Snippet-Expander: ';daily' → 'Daily standup', ';mtg' → 'Meet [tsc:fail]
This commit is contained in:
parent
fb67391eb8
commit
2d04a9ae8c
@ -1,5 +1,8 @@
|
||||
{
|
||||
"completed_features": [],
|
||||
"current_feature": "keyboard-undo-stack",
|
||||
"started_at": "2026-05-23T08:09:40.135892"
|
||||
"current_feature": "snippet-shortcuts",
|
||||
"started_at": "2026-05-23T08:09:40.135892",
|
||||
"attempted_features": [
|
||||
"keyboard-undo-stack"
|
||||
]
|
||||
}
|
||||
@ -2499,3 +2499,20 @@ src/index.ts(27,25): error TS2769: No overload matches this call.
|
||||
Overload 2 of 3, '(plugin: FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
|
||||
Argument of type 'Promise<FastifyMultipartPlugin>' is not assignable to parameter of type 'FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
|
||||
Type 'Promise<FastifyMultipartPlugin>' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTy
|
||||
- `08:10:01` **INFO** Committed feature keyboard-undo-stack
|
||||
- `08:10:01` **INFO** Pushed: rc=0
|
||||
|
||||
## Phase-3 Feature: snippet-shortcuts (2026-05-23 08:10:01)
|
||||
|
||||
- `08:10:01` **INFO** Description: Snippet-Expander: ';daily' → 'Daily standup', ';mtg' → 'Meeting'
|
||||
- `08:10:01` **INFO** Generating apps/web/src/components/SnippetInput.tsx (Drop-in-Input mit snippet-expansion. Snippets-map inline: {';daily':'D…)
|
||||
- `08:10:13` **INFO** wrote 1376 chars in 11.6s (attempt 1)
|
||||
- `08:10:13` **INFO** Running tsc --noEmit on api…
|
||||
- `08:10:14` **WARN** tsc errors:
|
||||
src/index.ts(27,25): error TS2769: No overload matches this call.
|
||||
Overload 1 of 3, '(plugin: FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
|
||||
Argument of type 'Promise<FastifyMultipartPlugin>' is not assignable to parameter of type 'FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
|
||||
Type 'Promise<FastifyMultipartPlugin>' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProvider>, opts: { ...; }, done: (err?: Error | undefined) => void): void'.
|
||||
Overload 2 of 3, '(plugin: FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error.
|
||||
Argument of type 'Promise<FastifyMultipartPlugin>' is not assignable to parameter of type 'FastifyPluginAsync<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
|
||||
Type 'Promise<FastifyMultipartPlugin>' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTy
|
||||
|
||||
46
apps/web/src/components/SnippetInput.tsx
Normal file
46
apps/web/src/components/SnippetInput.tsx
Normal file
@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
|
||||
interface SnippetInputProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
}
|
||||
|
||||
const SNIPPETS: Record<string, string> = {
|
||||
';daily': 'Daily standup',
|
||||
';mtg': 'Meeting',
|
||||
';review': 'Code review',
|
||||
';bug': 'Bugfix ',
|
||||
};
|
||||
|
||||
export const SnippetInput: React.FC<SnippetInputProps> = ({ value, onChange, ...rest }) => {
|
||||
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
const newValue = e.target.value;
|
||||
|
||||
// Find the last occurrence of a semicolon to check for a snippet
|
||||
const lastSemicolonIndex = newValue.lastIndexOf(';');
|
||||
|
||||
if (lastSemicolonIndex !== -1) {
|
||||
const trailingText = newValue.slice(lastSemicolonIndex);
|
||||
|
||||
// Check if the trailing text matches any of our snippet keys
|
||||
const snippetKey = Object.keys(SNIPPETS).find(key => trailingText === key);
|
||||
|
||||
if (snippetKey) {
|
||||
const expandedValue = newValue.slice(0, lastSemicolonIndex) + SNIPPETS[snippetKey];
|
||||
onChange(expandedValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
onChange(newValue);
|
||||
};
|
||||
|
||||
return (
|
||||
<textarea
|
||||
{...rest}
|
||||
value={value}
|
||||
onChange={handleChange}
|
||||
className={`w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500 outline-none transition-all ${rest.className || ''}`}
|
||||
/>
|
||||
);
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user