svelte-incant 0.1.0 → 0.2.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 +80 -18
- package/dist/components/kbds.svelte +18 -7
- package/dist/components/kbds.svelte.d.ts +0 -1
- package/dist/components/ui/input/index.d.ts +2 -2
- package/dist/components/ui/input/index.js +2 -2
- package/dist/components/ui/input/input.svelte +13 -13
- package/dist/components/ui/input/input.svelte.d.ts +5 -5
- package/dist/components/ui/tabs/index.d.ts +5 -5
- package/dist/components/ui/tabs/index.js +5 -5
- package/dist/components/ui/tabs/tabs-content.svelte +3 -3
- package/dist/components/ui/tabs/tabs-content.svelte.d.ts +1 -1
- package/dist/components/ui/tabs/tabs-list.svelte +4 -8
- package/dist/components/ui/tabs/tabs-list.svelte.d.ts +1 -1
- package/dist/components/ui/tabs/tabs-trigger.svelte +3 -3
- package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +1 -1
- package/dist/components/ui/tabs/tabs.svelte +4 -4
- package/dist/components/ui/tabs/tabs.svelte.d.ts +1 -1
- package/package.json +16 -12
package/README.md
CHANGED
|
@@ -4,9 +4,42 @@ A keyboard shortcut management library for Svelte 5.
|
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
### Prerequisites
|
|
8
|
+
|
|
9
|
+
This package requires **Tailwind CSS 4** and **shadcn-svelte** to be installed and configured in your project.
|
|
10
|
+
|
|
11
|
+
### Setup
|
|
12
|
+
|
|
13
|
+
1. **Install and configure Tailwind CSS** (if not already):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bunx sv add tailwind
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
2. **Initialize shadcn-svelte** (if not already):
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bunx shadcn-svelte@latest init
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Follow the official [shadcn-svelte installation guide](https://shadcn-svelte.com/docs/installation) for detailed instructions.
|
|
26
|
+
|
|
27
|
+
3. **Install the package** (peer dependencies are installed automatically):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
bun add svelte-incant
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
4. **Add @source directive** to your CSS file where Tailwind is configured (e.g., `src/app.css` or similar):
|
|
34
|
+
|
|
35
|
+
```css
|
|
36
|
+
@import 'tailwindcss';
|
|
37
|
+
|
|
38
|
+
/* Add this line to include svelte-incant utility classes */
|
|
39
|
+
@source '../../node_modules/svelte-incant/**/*.{svelte,js,ts}';
|
|
40
|
+
|
|
41
|
+
/* rest of your styles here */
|
|
42
|
+
```
|
|
10
43
|
|
|
11
44
|
## Usage
|
|
12
45
|
|
|
@@ -14,7 +47,7 @@ Add `Palette` component to your root layout to enable the shortcut overlay:
|
|
|
14
47
|
|
|
15
48
|
```svelte
|
|
16
49
|
<script>
|
|
17
|
-
|
|
50
|
+
import { Palette } from 'svelte-incant';
|
|
18
51
|
</script>
|
|
19
52
|
|
|
20
53
|
<Palette />
|
|
@@ -26,13 +59,13 @@ Register keyboard shortcuts with the `Shortcut` component:
|
|
|
26
59
|
|
|
27
60
|
```svelte
|
|
28
61
|
<script>
|
|
29
|
-
|
|
62
|
+
import { Shortcut } from 'svelte-incant';
|
|
30
63
|
</script>
|
|
31
64
|
|
|
32
65
|
<Shortcut
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
66
|
+
keys={['control', 's']}
|
|
67
|
+
description="Save document"
|
|
68
|
+
action={() => console.log('Save document')}
|
|
36
69
|
/>
|
|
37
70
|
```
|
|
38
71
|
|
|
@@ -40,11 +73,11 @@ For focusing elements (like inputs), use the `Focus` component:
|
|
|
40
73
|
|
|
41
74
|
```svelte
|
|
42
75
|
<script>
|
|
43
|
-
|
|
76
|
+
import { Focus } from 'svelte-incant';
|
|
44
77
|
</script>
|
|
45
78
|
|
|
46
79
|
<Focus keys={['control', 'e']} description="Focus search input">
|
|
47
|
-
|
|
80
|
+
<input type="text" placeholder="Search..." />
|
|
48
81
|
</Focus>
|
|
49
82
|
```
|
|
50
83
|
|
|
@@ -52,20 +85,20 @@ Or attach shortcuts directly to an element using the `@attach` directive:
|
|
|
52
85
|
|
|
53
86
|
```svelte
|
|
54
87
|
<script>
|
|
55
|
-
|
|
88
|
+
import { shortcut } from 'svelte-incant';
|
|
56
89
|
</script>
|
|
57
90
|
|
|
58
91
|
<input
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
92
|
+
type="text"
|
|
93
|
+
placeholder="Type something..."
|
|
94
|
+
{@attach shortcut({
|
|
95
|
+
keys: ['meta', 'i'],
|
|
96
|
+
description: 'Focus text input'
|
|
97
|
+
})}
|
|
65
98
|
/>
|
|
66
99
|
```
|
|
67
100
|
|
|
68
|
-
The `@attach` directive focuses the element it attaches to directly, as opposed to the `Focus` component, which wraps
|
|
101
|
+
The `@attach` directive focuses the element it attaches to directly, as opposed to the `Focus` component, which wraps children in a `div` and focuses that.
|
|
69
102
|
|
|
70
103
|
## Features
|
|
71
104
|
|
|
@@ -73,3 +106,32 @@ The `@attach` directive focuses the element it attaches to directly, as opposed
|
|
|
73
106
|
- **Route-specific Shortcuts**: Shortcuts only run when their component is mounted, allowing different shortcuts in different routes
|
|
74
107
|
- **Focus Management**: Easily manage focus states with keyboard shortcuts
|
|
75
108
|
- **Component-based**: Use components or directives to register shortcuts
|
|
109
|
+
- **Shadcn-svelte Integration**: Full styling integration with shadcn-svelte components
|
|
110
|
+
|
|
111
|
+
## Troubleshooting
|
|
112
|
+
|
|
113
|
+
### Styles are missing or components look unstyled
|
|
114
|
+
|
|
115
|
+
1. **Check @source directive**: Make sure you added the `@source` directive to your CSS file as shown in the installation steps.
|
|
116
|
+
|
|
117
|
+
2. **Verify Tailwind 4**: Ensure you're using Tailwind CSS v4, as the `@source` directive is a v4 feature:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
bun list tailwindcss
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
3. **Check shadcn-svelte setup**: Make sure shadcn-svelte is properly initialized with all required CSS variables and theme configuration.
|
|
124
|
+
|
|
125
|
+
4. **Build your project**: Sometimes you need to restart your development server or rebuild your project for changes to take effect.
|
|
126
|
+
|
|
127
|
+
### Peer dependency errors
|
|
128
|
+
|
|
129
|
+
If you see errors about missing peer dependencies, ensure you have the required packages installed:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Check if peer dependencies are installed
|
|
133
|
+
bun list | grep -E "(bits-ui|runed|@lucide/svelte)"
|
|
134
|
+
|
|
135
|
+
# If missing, install them manually
|
|
136
|
+
bun add bits-ui runed @lucide/svelte
|
|
137
|
+
```
|
|
@@ -3,11 +3,9 @@
|
|
|
3
3
|
import { keyToSymbol } from '../utils.js';
|
|
4
4
|
|
|
5
5
|
let {
|
|
6
|
-
keys
|
|
7
|
-
separator = 'or'
|
|
6
|
+
keys
|
|
8
7
|
}: {
|
|
9
8
|
keys: string | string[] | string[][];
|
|
10
|
-
separator?: string;
|
|
11
9
|
} = $props();
|
|
12
10
|
|
|
13
11
|
type KeyCombination = string[];
|
|
@@ -19,13 +17,26 @@
|
|
|
19
17
|
? [keys as string[]]
|
|
20
18
|
: (keys as KeyCombination[])
|
|
21
19
|
);
|
|
20
|
+
|
|
21
|
+
const formatter: Intl.ListFormat = $derived(
|
|
22
|
+
new Intl.ListFormat(undefined, {
|
|
23
|
+
style: 'long',
|
|
24
|
+
type: 'disjunction'
|
|
25
|
+
})
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const formattedParts = $derived.by(() => {
|
|
29
|
+
const combos = keyGroups.map((group) => group.map(keyToSymbol).join(' '));
|
|
30
|
+
return formatter.formatToParts(combos);
|
|
31
|
+
});
|
|
22
32
|
</script>
|
|
23
33
|
|
|
24
34
|
<Kbd.Group class="text-xs">
|
|
25
|
-
{#each
|
|
26
|
-
{#if
|
|
27
|
-
<
|
|
35
|
+
{#each formattedParts as part (part)}
|
|
36
|
+
{#if part.type === 'element'}
|
|
37
|
+
<Kbd.Root>{part.value}</Kbd.Root>
|
|
38
|
+
{:else}
|
|
39
|
+
<span class="mx-1 text-muted-foreground">{part.value}</span>
|
|
28
40
|
{/if}
|
|
29
|
-
<Kbd.Root>{group.map(keyToSymbol).join(' ')}</Kbd.Root>
|
|
30
41
|
{/each}
|
|
31
42
|
</Kbd.Group>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import Root from
|
|
2
|
-
export { Root, Root as Input
|
|
1
|
+
import Root from './input.svelte';
|
|
2
|
+
export { Root, Root as Input };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import type { HTMLInputAttributes, HTMLInputTypeAttribute } from
|
|
3
|
-
import { cn, type WithElementRef } from
|
|
2
|
+
import type { HTMLInputAttributes, HTMLInputTypeAttribute } from 'svelte/elements';
|
|
3
|
+
import { cn, type WithElementRef } from '../../../utils.js';
|
|
4
4
|
|
|
5
|
-
type InputType = Exclude<HTMLInputTypeAttribute,
|
|
5
|
+
type InputType = Exclude<HTMLInputTypeAttribute, 'file'>;
|
|
6
6
|
|
|
7
7
|
type Props = WithElementRef<
|
|
8
|
-
Omit<HTMLInputAttributes,
|
|
9
|
-
({ type:
|
|
8
|
+
Omit<HTMLInputAttributes, 'type'> &
|
|
9
|
+
({ type: 'file'; files?: FileList } | { type?: InputType; files?: undefined })
|
|
10
10
|
>;
|
|
11
11
|
|
|
12
12
|
let {
|
|
@@ -15,19 +15,19 @@
|
|
|
15
15
|
type,
|
|
16
16
|
files = $bindable(),
|
|
17
17
|
class: className,
|
|
18
|
-
|
|
18
|
+
'data-slot': dataSlot = 'input',
|
|
19
19
|
...restProps
|
|
20
20
|
}: Props = $props();
|
|
21
21
|
</script>
|
|
22
22
|
|
|
23
|
-
{#if type ===
|
|
23
|
+
{#if type === 'file'}
|
|
24
24
|
<input
|
|
25
25
|
bind:this={ref}
|
|
26
26
|
data-slot={dataSlot}
|
|
27
27
|
class={cn(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
'flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 pt-1.5 text-sm font-medium shadow-xs ring-offset-background transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 dark:bg-input/30',
|
|
29
|
+
'focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50',
|
|
30
|
+
'aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40',
|
|
31
31
|
className
|
|
32
32
|
)}
|
|
33
33
|
type="file"
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
bind:this={ref}
|
|
41
41
|
data-slot={dataSlot}
|
|
42
42
|
class={cn(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
'flex h-9 w-full min-w-0 rounded-md border border-input bg-background px-3 py-1 text-base shadow-xs ring-offset-background transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 md:text-sm dark:bg-input/30',
|
|
44
|
+
'focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50',
|
|
45
|
+
'aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40',
|
|
46
46
|
className
|
|
47
47
|
)}
|
|
48
48
|
{type}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { HTMLInputAttributes, HTMLInputTypeAttribute } from
|
|
2
|
-
import { type WithElementRef } from
|
|
3
|
-
type InputType = Exclude<HTMLInputTypeAttribute,
|
|
4
|
-
type Props = WithElementRef<Omit<HTMLInputAttributes,
|
|
5
|
-
type:
|
|
1
|
+
import type { HTMLInputAttributes, HTMLInputTypeAttribute } from 'svelte/elements';
|
|
2
|
+
import { type WithElementRef } from '../../../utils.js';
|
|
3
|
+
type InputType = Exclude<HTMLInputTypeAttribute, 'file'>;
|
|
4
|
+
type Props = WithElementRef<Omit<HTMLInputAttributes, 'type'> & ({
|
|
5
|
+
type: 'file';
|
|
6
6
|
files?: FileList;
|
|
7
7
|
} | {
|
|
8
8
|
type?: InputType;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import Root from
|
|
2
|
-
import Content from
|
|
3
|
-
import List from
|
|
4
|
-
import Trigger from
|
|
5
|
-
export { Root, Content, List, Trigger, Root as Tabs, Content as TabsContent, List as TabsList, Trigger as TabsTrigger
|
|
1
|
+
import Root from './tabs.svelte';
|
|
2
|
+
import Content from './tabs-content.svelte';
|
|
3
|
+
import List from './tabs-list.svelte';
|
|
4
|
+
import Trigger from './tabs-trigger.svelte';
|
|
5
|
+
export { Root, Content, List, Trigger, Root as Tabs, Content as TabsContent, List as TabsList, Trigger as TabsTrigger };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import Root from
|
|
2
|
-
import Content from
|
|
3
|
-
import List from
|
|
4
|
-
import Trigger from
|
|
1
|
+
import Root from './tabs.svelte';
|
|
2
|
+
import Content from './tabs-content.svelte';
|
|
3
|
+
import List from './tabs-list.svelte';
|
|
4
|
+
import Trigger from './tabs-trigger.svelte';
|
|
5
5
|
export { Root, Content, List, Trigger,
|
|
6
6
|
//
|
|
7
|
-
Root as Tabs, Content as TabsContent, List as TabsList, Trigger as TabsTrigger
|
|
7
|
+
Root as Tabs, Content as TabsContent, List as TabsList, Trigger as TabsTrigger };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { Tabs as TabsPrimitive } from
|
|
3
|
-
import { cn } from
|
|
2
|
+
import { Tabs as TabsPrimitive } from 'bits-ui';
|
|
3
|
+
import { cn } from '../../../utils.js';
|
|
4
4
|
|
|
5
5
|
let {
|
|
6
6
|
ref = $bindable(null),
|
|
@@ -12,6 +12,6 @@
|
|
|
12
12
|
<TabsPrimitive.Content
|
|
13
13
|
bind:ref
|
|
14
14
|
data-slot="tabs-content"
|
|
15
|
-
class={cn(
|
|
15
|
+
class={cn('flex-1 outline-none', className)}
|
|
16
16
|
{...restProps}
|
|
17
17
|
/>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Tabs as TabsPrimitive } from
|
|
1
|
+
import { Tabs as TabsPrimitive } from 'bits-ui';
|
|
2
2
|
declare const TabsContent: import("svelte").Component<TabsPrimitive.ContentProps, {}, "ref">;
|
|
3
3
|
type TabsContent = ReturnType<typeof TabsContent>;
|
|
4
4
|
export default TabsContent;
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { Tabs as TabsPrimitive } from
|
|
3
|
-
import { cn } from
|
|
2
|
+
import { Tabs as TabsPrimitive } from 'bits-ui';
|
|
3
|
+
import { cn } from '../../../utils.js';
|
|
4
4
|
|
|
5
|
-
let {
|
|
6
|
-
ref = $bindable(null),
|
|
7
|
-
class: className,
|
|
8
|
-
...restProps
|
|
9
|
-
}: TabsPrimitive.ListProps = $props();
|
|
5
|
+
let { ref = $bindable(null), class: className, ...restProps }: TabsPrimitive.ListProps = $props();
|
|
10
6
|
</script>
|
|
11
7
|
|
|
12
8
|
<TabsPrimitive.List
|
|
13
9
|
bind:ref
|
|
14
10
|
data-slot="tabs-list"
|
|
15
11
|
class={cn(
|
|
16
|
-
|
|
12
|
+
'inline-flex h-9 w-fit items-center justify-center rounded-lg bg-muted p-[3px] text-muted-foreground',
|
|
17
13
|
className
|
|
18
14
|
)}
|
|
19
15
|
{...restProps}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { Tabs as TabsPrimitive } from
|
|
3
|
-
import { cn } from
|
|
2
|
+
import { Tabs as TabsPrimitive } from 'bits-ui';
|
|
3
|
+
import { cn } from '../../../utils.js';
|
|
4
4
|
|
|
5
5
|
let {
|
|
6
6
|
ref = $bindable(null),
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
bind:ref
|
|
14
14
|
data-slot="tabs-trigger"
|
|
15
15
|
class={cn(
|
|
16
|
-
"
|
|
16
|
+
"inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:shadow-sm dark:text-muted-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 dark:data-[state=active]:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
17
17
|
className
|
|
18
18
|
)}
|
|
19
19
|
{...restProps}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Tabs as TabsPrimitive } from
|
|
1
|
+
import { Tabs as TabsPrimitive } from 'bits-ui';
|
|
2
2
|
declare const TabsTrigger: import("svelte").Component<TabsPrimitive.TriggerProps, {}, "ref">;
|
|
3
3
|
type TabsTrigger = ReturnType<typeof TabsTrigger>;
|
|
4
4
|
export default TabsTrigger;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { Tabs as TabsPrimitive } from
|
|
3
|
-
import { cn } from
|
|
2
|
+
import { Tabs as TabsPrimitive } from 'bits-ui';
|
|
3
|
+
import { cn } from '../../../utils.js';
|
|
4
4
|
|
|
5
5
|
let {
|
|
6
6
|
ref = $bindable(null),
|
|
7
|
-
value = $bindable(
|
|
7
|
+
value = $bindable(''),
|
|
8
8
|
class: className,
|
|
9
9
|
...restProps
|
|
10
10
|
}: TabsPrimitive.RootProps = $props();
|
|
@@ -14,6 +14,6 @@
|
|
|
14
14
|
bind:ref
|
|
15
15
|
bind:value
|
|
16
16
|
data-slot="tabs"
|
|
17
|
-
class={cn(
|
|
17
|
+
class={cn('flex flex-col gap-2', className)}
|
|
18
18
|
{...restProps}
|
|
19
19
|
/>
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-incant",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
|
+
"repository": "https://github.com/mastermakrela/svelte-incant",
|
|
6
|
+
"bugs": "https://github.com/mastermakrela/svelte-incant/issues",
|
|
7
|
+
"homepage": "https://svelte-incant.mastermakrela.com/",
|
|
8
|
+
"author": "mastermakrela <github@mastermakrela.com>",
|
|
5
9
|
"scripts": {
|
|
6
10
|
"dev": "vite dev",
|
|
7
11
|
"build": "vite build && npm run prepack",
|
|
@@ -22,9 +26,7 @@
|
|
|
22
26
|
"!dist/**/*.test.*",
|
|
23
27
|
"!dist/**/*.spec.*"
|
|
24
28
|
],
|
|
25
|
-
"sideEffects":
|
|
26
|
-
"**/*.css"
|
|
27
|
-
],
|
|
29
|
+
"sideEffects": false,
|
|
28
30
|
"svelte": "./dist/index.js",
|
|
29
31
|
"types": "./dist/index.d.ts",
|
|
30
32
|
"type": "module",
|
|
@@ -35,7 +37,8 @@
|
|
|
35
37
|
}
|
|
36
38
|
},
|
|
37
39
|
"peerDependencies": {
|
|
38
|
-
"svelte": "^5.0.0"
|
|
40
|
+
"svelte": "^5.0.0",
|
|
41
|
+
"bits-ui": "^2.0.0"
|
|
39
42
|
},
|
|
40
43
|
"devDependencies": {
|
|
41
44
|
"@eslint/compat": "^1.4.0",
|
|
@@ -69,12 +72,7 @@
|
|
|
69
72
|
"typescript-eslint": "^8.48.1",
|
|
70
73
|
"vite": "^7.2.6",
|
|
71
74
|
"vitest": "^4.0.15",
|
|
72
|
-
"vitest-browser-svelte": "^2.0.1"
|
|
73
|
-
},
|
|
74
|
-
"keywords": [
|
|
75
|
-
"svelte"
|
|
76
|
-
],
|
|
77
|
-
"dependencies": {
|
|
75
|
+
"vitest-browser-svelte": "^2.0.1",
|
|
78
76
|
"@lucide/svelte": "^0.561.0",
|
|
79
77
|
"clsx": "^2.1.1",
|
|
80
78
|
"copy-to-clipboard": "^3.3.3",
|
|
@@ -83,5 +81,11 @@
|
|
|
83
81
|
"tailwind-merge": "^3.4.0",
|
|
84
82
|
"tailwind-variants": "^3.2.2",
|
|
85
83
|
"tw-animate-css": "^1.4.0"
|
|
86
|
-
}
|
|
84
|
+
},
|
|
85
|
+
"keywords": [
|
|
86
|
+
"svelte",
|
|
87
|
+
"keyboard shortcuts",
|
|
88
|
+
"shortcuts"
|
|
89
|
+
],
|
|
90
|
+
"dependencies": {}
|
|
87
91
|
}
|