@immich/ui 0.51.0 → 0.53.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/dist/components/Badge/Badge.svelte +5 -5
- package/dist/components/CommandPalette/CommandPaletteDefaultProvider.svelte +14 -0
- package/dist/components/CommandPalette/CommandPaletteDefaultProvider.svelte.d.ts +8 -0
- package/dist/components/CommandPalette/CommandPaletteItem.svelte +2 -21
- package/dist/components/CommandPalette/CommandPaletteItem.svelte.d.ts +0 -1
- package/dist/components/CommandPalette/CommandPaletteProvider.svelte +18 -0
- package/dist/components/CommandPalette/CommandPaletteProvider.svelte.d.ts +7 -0
- package/dist/components/Heading/Heading.svelte +6 -13
- package/dist/components/Markdown/Heading.svelte +9 -12
- package/dist/components/Modal/Modal.svelte +1 -4
- package/dist/components/Textarea/Textarea.svelte +8 -2
- package/dist/components/Toast/ToastPanel.svelte +19 -16
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/internal/Button.svelte +10 -1
- package/dist/internal/CommandPaletteModal.svelte +26 -23
- package/dist/internal/CommandPaletteModal.svelte.d.ts +3 -1
- package/dist/services/command-palette-manager.svelte.d.ts +19 -77
- package/dist/services/command-palette-manager.svelte.js +44 -152
- package/dist/site/SiteFooter.svelte +3 -0
- package/dist/site/constants.d.ts +1 -0
- package/dist/site/constants.js +2 -1
- package/dist/types.d.ts +1 -0
- package/dist/utilities/common.d.ts +1 -0
- package/dist/utilities/common.js +7 -0
- package/dist/utilities/internal.d.ts +3 -1
- package/dist/utilities/internal.js +3 -0
- package/package.json +1 -1
- package/dist/components/CommandPalette/CommandPaletteContext.svelte +0 -18
- package/dist/components/CommandPalette/CommandPaletteContext.svelte.d.ts +0 -7
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
},
|
|
38
38
|
textSize: styleVariants.textSize,
|
|
39
39
|
paddingSize: {
|
|
40
|
-
tiny: 'px-
|
|
41
|
-
small: 'px-
|
|
42
|
-
medium: 'px-
|
|
43
|
-
large: 'px-
|
|
44
|
-
giant: 'px-
|
|
40
|
+
tiny: 'px-1.5 py-1',
|
|
41
|
+
small: 'px-1.75 py-0.75',
|
|
42
|
+
medium: 'px-2.5 py-1',
|
|
43
|
+
large: 'px-2.75 py-1',
|
|
44
|
+
giant: 'px-3 py-1.25',
|
|
45
45
|
},
|
|
46
46
|
roundedSize: {
|
|
47
47
|
tiny: 'rounded-lg',
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import CommandPaletteProvider from './CommandPaletteProvider.svelte';
|
|
3
|
+
import { defaultProvider } from '../../services/command-palette-manager.svelte.js';
|
|
4
|
+
import type { ActionItem } from '../../types.js';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
name: string;
|
|
8
|
+
actions?: ActionItem[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const { name, actions = [] }: Props = $props();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<CommandPaletteProvider providers={[defaultProvider({ name, actions })]} />
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ActionItem } from '../../types.js';
|
|
2
|
+
type Props = {
|
|
3
|
+
name: string;
|
|
4
|
+
actions?: ActionItem[];
|
|
5
|
+
};
|
|
6
|
+
declare const CommandPaletteDefaultProvider: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type CommandPaletteDefaultProvider = ReturnType<typeof CommandPaletteDefaultProvider>;
|
|
8
|
+
export default CommandPaletteDefaultProvider;
|
|
@@ -3,26 +3,18 @@
|
|
|
3
3
|
import Badge from '../Badge/Badge.svelte';
|
|
4
4
|
import Button from '../Button/Button.svelte';
|
|
5
5
|
import Icon from '../Icon/Icon.svelte';
|
|
6
|
-
import IconButton from '../IconButton/IconButton.svelte';
|
|
7
6
|
import Kbd from '../Kbd/Kbd.svelte';
|
|
8
7
|
import Text from '../Text/Text.svelte';
|
|
9
8
|
import type { ActionItem } from '../../types.js';
|
|
10
9
|
import { cleanClass } from '../../utilities/internal.js';
|
|
11
|
-
import { mdiClose } from '@mdi/js';
|
|
12
10
|
|
|
13
11
|
type Props = {
|
|
14
12
|
item: ActionItem;
|
|
15
13
|
selected: boolean;
|
|
16
14
|
onSelect: () => void;
|
|
17
|
-
onRemove?: () => void;
|
|
18
15
|
};
|
|
19
16
|
|
|
20
|
-
const { item, selected,
|
|
21
|
-
|
|
22
|
-
const handleRemove = (event: MouseEvent) => {
|
|
23
|
-
event.stopPropagation();
|
|
24
|
-
onRemove?.();
|
|
25
|
-
};
|
|
17
|
+
const { item, selected, onSelect }: Props = $props();
|
|
26
18
|
|
|
27
19
|
const shortcuts =
|
|
28
20
|
item.shortcuts === undefined ? [] : Array.isArray(item.shortcuts) ? item.shortcuts : [item.shortcuts];
|
|
@@ -66,18 +58,7 @@
|
|
|
66
58
|
{/if}
|
|
67
59
|
</div>
|
|
68
60
|
</div>
|
|
69
|
-
{#if
|
|
70
|
-
<IconButton
|
|
71
|
-
size="small"
|
|
72
|
-
onclick={handleRemove}
|
|
73
|
-
class="shrink-0"
|
|
74
|
-
icon={mdiClose}
|
|
75
|
-
shape="round"
|
|
76
|
-
variant="ghost"
|
|
77
|
-
color="secondary"
|
|
78
|
-
aria-label="Remove"
|
|
79
|
-
/>
|
|
80
|
-
{:else if renderedShortcuts.length > 0}
|
|
61
|
+
{#if renderedShortcuts.length > 0}
|
|
81
62
|
<div class="flex shrink-0 flex-col justify-end gap-1">
|
|
82
63
|
{#each renderedShortcuts as shortcut (shortcut.join('-'))}
|
|
83
64
|
<div class="flex justify-end">
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { commandPaletteManager, type ActionProvider } from '../../services/command-palette-manager.svelte.js';
|
|
3
|
+
|
|
4
|
+
type Props = {
|
|
5
|
+
providers: ActionProvider[];
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const { providers }: Props = $props();
|
|
9
|
+
|
|
10
|
+
$effect(() => {
|
|
11
|
+
const callbacks: Array<() => void> = [];
|
|
12
|
+
for (const provider of providers) {
|
|
13
|
+
callbacks.push(commandPaletteManager.addProvider(provider));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return () => callbacks.forEach((callback) => callback());
|
|
17
|
+
});
|
|
18
|
+
</script>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ActionProvider } from '../../services/command-palette-manager.svelte.js';
|
|
2
|
+
type Props = {
|
|
3
|
+
providers: ActionProvider[];
|
|
4
|
+
};
|
|
5
|
+
declare const CommandPaletteProvider: import("svelte").Component<Props, {}, "">;
|
|
6
|
+
type CommandPaletteProvider = ReturnType<typeof CommandPaletteProvider>;
|
|
7
|
+
export default CommandPaletteProvider;
|
|
@@ -20,25 +20,18 @@
|
|
|
20
20
|
children: Snippet;
|
|
21
21
|
} & HTMLAttributes<HTMLElement>;
|
|
22
22
|
|
|
23
|
-
const {
|
|
24
|
-
tag = 'p',
|
|
25
|
-
size = 'medium',
|
|
26
|
-
fontWeight = 'semi-bold',
|
|
27
|
-
class: className,
|
|
28
|
-
children,
|
|
29
|
-
...restProps
|
|
30
|
-
}: Props = $props();
|
|
23
|
+
const { tag = 'p', size = 'medium', fontWeight = 'bold', class: className, children, ...restProps }: Props = $props();
|
|
31
24
|
|
|
32
25
|
const styles = tv({
|
|
33
26
|
base: 'leading-none tracking-tight',
|
|
34
27
|
variants: {
|
|
35
28
|
size: {
|
|
36
|
-
tiny: 'text-
|
|
37
|
-
small: 'text-
|
|
38
|
-
medium: 'text-
|
|
29
|
+
tiny: 'text-base',
|
|
30
|
+
small: 'text-lg',
|
|
31
|
+
medium: 'text-xl',
|
|
39
32
|
large: 'text-3xl',
|
|
40
|
-
giant: 'text-
|
|
41
|
-
title: 'text-
|
|
33
|
+
giant: 'text-5xl',
|
|
34
|
+
title: 'text-7xl',
|
|
42
35
|
},
|
|
43
36
|
},
|
|
44
37
|
});
|
|
@@ -11,33 +11,30 @@
|
|
|
11
11
|
|
|
12
12
|
const { children, id, level }: Props = $props();
|
|
13
13
|
|
|
14
|
-
const getSizeAndTag = (level?: number): { size: Size; tag: HeadingTag } => {
|
|
14
|
+
const getSizeAndTag = (level?: number): { size: Size; tag: HeadingTag; padding: string } => {
|
|
15
15
|
switch (level) {
|
|
16
16
|
case 1: {
|
|
17
|
-
return { size: 'giant', tag: 'h1' };
|
|
17
|
+
return { size: 'giant', tag: 'h1', padding: 'mb-6' };
|
|
18
18
|
}
|
|
19
19
|
case 2: {
|
|
20
|
-
return { size: 'large', tag: 'h2' };
|
|
20
|
+
return { size: 'large', tag: 'h2', padding: 'my-4' };
|
|
21
21
|
}
|
|
22
22
|
case 3: {
|
|
23
|
-
return { size: 'medium', tag: 'h3' };
|
|
23
|
+
return { size: 'medium', tag: 'h3', padding: 'my-3' };
|
|
24
24
|
}
|
|
25
25
|
case 4: {
|
|
26
|
-
return { size: 'small', tag: 'h4' };
|
|
26
|
+
return { size: 'small', tag: 'h4', padding: 'my-1' };
|
|
27
27
|
}
|
|
28
28
|
case 5: {
|
|
29
|
-
return { size: 'tiny', tag: 'h5' };
|
|
30
|
-
}
|
|
31
|
-
case 6: {
|
|
32
|
-
return { size: 'tiny', tag: 'h6' };
|
|
29
|
+
return { size: 'tiny', tag: 'h5', padding: 'my-0.5' };
|
|
33
30
|
}
|
|
34
31
|
default: {
|
|
35
|
-
return { size: 'tiny', tag: 'p' };
|
|
32
|
+
return { size: 'tiny', tag: 'p', padding: '' };
|
|
36
33
|
}
|
|
37
34
|
}
|
|
38
35
|
};
|
|
39
36
|
|
|
40
|
-
let { size, tag } = $derived(getSizeAndTag(level));
|
|
37
|
+
let { size, tag, padding } = $derived(getSizeAndTag(level));
|
|
41
38
|
</script>
|
|
42
39
|
|
|
43
|
-
<Heading {size} {tag} class=
|
|
40
|
+
<Heading {size} {tag} class={padding} {id} {children} />
|
|
@@ -10,11 +10,10 @@
|
|
|
10
10
|
import Logo from '../Logo/Logo.svelte';
|
|
11
11
|
import TooltipProvider from '../Tooltip/TooltipProvider.svelte';
|
|
12
12
|
import { ChildKey, zIndex } from '../../constants.js';
|
|
13
|
-
import { commandPaletteManager } from '../../services/command-palette-manager.svelte.js';
|
|
14
13
|
import type { ModalSize } from '../../types.js';
|
|
15
14
|
import { cleanClass } from '../../utilities/internal.js';
|
|
16
15
|
import { Dialog } from 'bits-ui';
|
|
17
|
-
import {
|
|
16
|
+
import { tick, type Snippet } from 'svelte';
|
|
18
17
|
import { tv } from 'tailwind-variants';
|
|
19
18
|
|
|
20
19
|
type Props = {
|
|
@@ -87,8 +86,6 @@
|
|
|
87
86
|
|
|
88
87
|
const interactOutsideBehavior = $derived(closeOnBackdropClick ? 'close' : 'ignore');
|
|
89
88
|
const escapeKeydownBehavior = $derived(closeOnEsc ? 'close' : 'ignore');
|
|
90
|
-
|
|
91
|
-
onMount(() => commandPaletteManager.pushContextLayer());
|
|
92
89
|
</script>
|
|
93
90
|
|
|
94
91
|
<Dialog.Root open={true} onOpenChange={(isOpen: boolean) => !isOpen && handleClose()}>
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { styleVariants } from '../../styles.js';
|
|
6
6
|
import type { TextareaProps } from '../../types.js';
|
|
7
7
|
import { cleanClass, generateId } from '../../utilities/internal.js';
|
|
8
|
+
import { onMount } from 'svelte';
|
|
8
9
|
import type { FormEventHandler } from 'svelte/elements';
|
|
9
10
|
import { tv } from 'tailwind-variants';
|
|
10
11
|
|
|
@@ -53,15 +54,20 @@
|
|
|
53
54
|
const labelId = `label-${id}`;
|
|
54
55
|
const descriptionId = $derived(description ? `description-${id}` : undefined);
|
|
55
56
|
|
|
56
|
-
const
|
|
57
|
-
const element = event.target as HTMLTextAreaElement;
|
|
57
|
+
const autogrow = (element: HTMLTextAreaElement | null) => {
|
|
58
58
|
if (element && grow) {
|
|
59
|
+
element.style.minHeight = '0';
|
|
59
60
|
element.style.height = 'auto';
|
|
60
61
|
element.style.height = `${element.scrollHeight}px`;
|
|
61
62
|
}
|
|
63
|
+
};
|
|
62
64
|
|
|
65
|
+
const onInput: FormEventHandler<HTMLTextAreaElement> = (event) => {
|
|
66
|
+
autogrow(event.target as HTMLTextAreaElement);
|
|
63
67
|
restProps?.oninput?.(event);
|
|
64
68
|
};
|
|
69
|
+
|
|
70
|
+
onMount(() => autogrow(ref));
|
|
65
71
|
</script>
|
|
66
72
|
|
|
67
73
|
<div class="flex w-full flex-col gap-1" bind:this={containerRef}>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import Toast from './Toast.svelte';
|
|
3
|
+
import TooltipProvider from '../Tooltip/TooltipProvider.svelte';
|
|
3
4
|
import { zIndex } from '../../constants.js';
|
|
4
5
|
import { isCustomToast } from '../../services/toast-manager.svelte.js';
|
|
5
6
|
import type { ToastPanelProps } from '../../types.js';
|
|
@@ -10,19 +11,21 @@
|
|
|
10
11
|
const isEmpty = $derived(items.length === 0);
|
|
11
12
|
</script>
|
|
12
13
|
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
{#
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
14
|
+
<TooltipProvider>
|
|
15
|
+
<div
|
|
16
|
+
class={cleanClass(
|
|
17
|
+
isEmpty ? 'hidden' : 'absolute top-0 right-0 flex flex-col items-end justify-end gap-2 p-4',
|
|
18
|
+
zIndex.ToastPanel,
|
|
19
|
+
className,
|
|
20
|
+
)}
|
|
21
|
+
{...props}
|
|
22
|
+
>
|
|
23
|
+
{#each items as item (item.id)}
|
|
24
|
+
{#if isCustomToast(item)}
|
|
25
|
+
<item.component {...item.props} />
|
|
26
|
+
{:else}
|
|
27
|
+
<Toast {...item} />
|
|
28
|
+
{/if}
|
|
29
|
+
{/each}
|
|
30
|
+
</div>
|
|
31
|
+
</TooltipProvider>
|
package/dist/index.d.ts
CHANGED
|
@@ -29,7 +29,8 @@ export { default as Checkbox } from './components/Checkbox/Checkbox.svelte';
|
|
|
29
29
|
export { default as CloseButton } from './components/CloseButton/CloseButton.svelte';
|
|
30
30
|
export { default as Code } from './components/Code/Code.svelte';
|
|
31
31
|
export { default as CodeBlock } from './components/CodeBlock/CodeBlock.svelte';
|
|
32
|
-
export { default as
|
|
32
|
+
export { default as CommandPaletteDefaultProvider } from './components/CommandPalette/CommandPaletteDefaultProvider.svelte';
|
|
33
|
+
export { default as CommandPaletteProvider } from './components/CommandPalette/CommandPaletteProvider.svelte';
|
|
33
34
|
export { default as ConfirmModal } from './components/ConfirmModal/ConfirmModal.svelte';
|
|
34
35
|
export { default as Container } from './components/Container/Container.svelte';
|
|
35
36
|
export { default as ContextMenuButton } from './components/ContextMenu/ContextMenuButton.svelte';
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,8 @@ export { default as Checkbox } from './components/Checkbox/Checkbox.svelte';
|
|
|
31
31
|
export { default as CloseButton } from './components/CloseButton/CloseButton.svelte';
|
|
32
32
|
export { default as Code } from './components/Code/Code.svelte';
|
|
33
33
|
export { default as CodeBlock } from './components/CodeBlock/CodeBlock.svelte';
|
|
34
|
-
export { default as
|
|
34
|
+
export { default as CommandPaletteDefaultProvider } from './components/CommandPalette/CommandPaletteDefaultProvider.svelte';
|
|
35
|
+
export { default as CommandPaletteProvider } from './components/CommandPalette/CommandPaletteProvider.svelte';
|
|
35
36
|
export { default as ConfirmModal } from './components/ConfirmModal/ConfirmModal.svelte';
|
|
36
37
|
export { default as Container } from './components/Container/Container.svelte';
|
|
37
38
|
export { default as ContextMenuButton } from './components/ContextMenu/ContextMenuButton.svelte';
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
const disabled = $derived((restProps as HTMLButtonAttributes).disabled || loading);
|
|
38
38
|
|
|
39
39
|
const buttonVariants = tv({
|
|
40
|
-
base: '
|
|
40
|
+
base: 'flex items-center justify-center gap-1 rounded-md text-sm font-medium outline-offset-2 transition-colors focus-visible:outline-2',
|
|
41
41
|
variants: {
|
|
42
42
|
disabled: {
|
|
43
43
|
true: 'disabled:pointer-events-none disabled:opacity-50 aria-disabled:opacity-50',
|
|
@@ -69,6 +69,14 @@
|
|
|
69
69
|
large: 'rounded-xl',
|
|
70
70
|
giant: 'rounded-2xl',
|
|
71
71
|
},
|
|
72
|
+
focusOutlineColor: {
|
|
73
|
+
primary: 'outline-primary',
|
|
74
|
+
secondary: 'outline-dark',
|
|
75
|
+
success: 'outline-success',
|
|
76
|
+
danger: 'outline-danger',
|
|
77
|
+
warning: 'outline-warning',
|
|
78
|
+
info: 'outline-info',
|
|
79
|
+
},
|
|
72
80
|
filledColor: styleVariants.filledColor,
|
|
73
81
|
filledColorHover: styleVariants.filledColorHover,
|
|
74
82
|
outlineColor: {
|
|
@@ -112,6 +120,7 @@
|
|
|
112
120
|
filledColorHover: variant === 'filled' ? color : undefined,
|
|
113
121
|
outlineColor: variant === 'outline' ? color : undefined,
|
|
114
122
|
ghostColor: variant === 'ghost' ? color : undefined,
|
|
123
|
+
focusOutlineColor: color,
|
|
115
124
|
}),
|
|
116
125
|
className,
|
|
117
126
|
),
|
|
@@ -15,13 +15,17 @@
|
|
|
15
15
|
type CommandPaletteTranslations,
|
|
16
16
|
} from '../services/command-palette-manager.svelte.js';
|
|
17
17
|
import { t } from '../services/translation.svelte.js';
|
|
18
|
+
import type { ActionItem } from '../types.js';
|
|
18
19
|
import { mdiArrowDown, mdiArrowUp, mdiKeyboardEsc, mdiKeyboardReturn, mdiMagnify } from '@mdi/js';
|
|
19
20
|
|
|
20
21
|
type Props = {
|
|
21
|
-
onClose: () => void;
|
|
22
|
+
onClose: (action?: ActionItem) => void;
|
|
22
23
|
translations?: CommandPaletteTranslations;
|
|
24
|
+
initialQuery?: string;
|
|
23
25
|
};
|
|
24
26
|
|
|
27
|
+
const { onClose, translations, initialQuery = '' }: Props = $props();
|
|
28
|
+
|
|
25
29
|
const handleUp = (event: KeyboardEvent) => handleNavigate(event, 'up');
|
|
26
30
|
const handleDown = (event: KeyboardEvent) => handleNavigate(event, 'down');
|
|
27
31
|
const handleSelect = (event: KeyboardEvent) => handleNavigate(event, 'select');
|
|
@@ -30,23 +34,31 @@
|
|
|
30
34
|
|
|
31
35
|
switch (direction) {
|
|
32
36
|
case 'up': {
|
|
33
|
-
commandPaletteManager.
|
|
37
|
+
selectedIndex = Math.max((selectedIndex === 0 ? commandPaletteManager.items.length : selectedIndex) - 1, 0);
|
|
34
38
|
break;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
case 'down': {
|
|
38
|
-
commandPaletteManager.
|
|
42
|
+
if (!query && commandPaletteManager.items.length === 0) {
|
|
43
|
+
commandPaletteManager.loadAllItems();
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
selectedIndex = (selectedIndex + 1) % commandPaletteManager.items.length || 0;
|
|
39
48
|
break;
|
|
40
49
|
}
|
|
41
50
|
|
|
42
51
|
case 'select': {
|
|
43
|
-
|
|
52
|
+
onClose(commandPaletteManager.items[selectedIndex]);
|
|
44
53
|
break;
|
|
45
54
|
}
|
|
46
55
|
}
|
|
47
56
|
};
|
|
48
57
|
|
|
49
|
-
|
|
58
|
+
let selectedIndex = $state(0);
|
|
59
|
+
let query = $state(initialQuery);
|
|
60
|
+
|
|
61
|
+
$effect(() => commandPaletteManager.queryUpdate(query));
|
|
50
62
|
</script>
|
|
51
63
|
|
|
52
64
|
<svelte:window
|
|
@@ -61,43 +73,34 @@
|
|
|
61
73
|
]}
|
|
62
74
|
/>
|
|
63
75
|
|
|
64
|
-
<Modal size="large" {onClose} closeOnBackdropClick class="max-h-[
|
|
76
|
+
<Modal size="large" {onClose} closeOnBackdropClick class="max-h-[85vh] lg:max-h-[75vh]">
|
|
65
77
|
<ModalHeader>
|
|
66
78
|
<div class="flex place-items-center gap-1">
|
|
67
79
|
<Input
|
|
68
|
-
bind:value={
|
|
80
|
+
bind:value={query}
|
|
69
81
|
placeholder={t('search_placeholder', translations)}
|
|
70
82
|
leadingIcon={mdiMagnify}
|
|
71
83
|
tabindex={1}
|
|
72
84
|
/>
|
|
73
85
|
<div>
|
|
74
|
-
<CloseButton onclick={() =>
|
|
86
|
+
<CloseButton onclick={() => onClose()} class="md:hidden" />
|
|
75
87
|
</div>
|
|
76
88
|
</div>
|
|
77
89
|
</ModalHeader>
|
|
78
90
|
<ModalBody>
|
|
79
91
|
<Stack gap={2}>
|
|
80
|
-
{#if
|
|
81
|
-
{#if commandPaletteManager.
|
|
92
|
+
{#if query}
|
|
93
|
+
{#if commandPaletteManager.items.length === 0}
|
|
82
94
|
<Text>{t('search_no_results', translations)}</Text>
|
|
83
95
|
{/if}
|
|
84
|
-
{:else if commandPaletteManager.recentItems.length > 0}
|
|
85
|
-
<Text>{t('search_recently_used', translations)}</Text>
|
|
86
96
|
{:else}
|
|
87
97
|
<Text>{t('command_palette_prompt_default', translations)}</Text>
|
|
88
98
|
{/if}
|
|
89
99
|
|
|
90
|
-
{#if commandPaletteManager.
|
|
100
|
+
{#if commandPaletteManager.items.length > 0}
|
|
91
101
|
<div class="flex flex-col">
|
|
92
|
-
{#each commandPaletteManager.
|
|
93
|
-
<CommandPaletteItem
|
|
94
|
-
{item}
|
|
95
|
-
selected={commandPaletteManager.selectedIndex === i}
|
|
96
|
-
onRemove={commandPaletteManager.query || commandPaletteManager.isShowAll
|
|
97
|
-
? undefined
|
|
98
|
-
: () => commandPaletteManager.remove(i)}
|
|
99
|
-
onSelect={() => commandPaletteManager.select(i)}
|
|
100
|
-
/>
|
|
102
|
+
{#each commandPaletteManager.items as item, i (item.id)}
|
|
103
|
+
<CommandPaletteItem {item} selected={selectedIndex === i} onSelect={() => onClose(item)} />
|
|
101
104
|
{/each}
|
|
102
105
|
</div>
|
|
103
106
|
{/if}
|
|
@@ -105,7 +108,7 @@
|
|
|
105
108
|
</ModalBody>
|
|
106
109
|
<ModalFooter>
|
|
107
110
|
<div class="flex w-full justify-around">
|
|
108
|
-
{#if commandPaletteManager.
|
|
111
|
+
{#if !query && commandPaletteManager.items.length === 0}
|
|
109
112
|
<div class="flex place-items-center gap-1">
|
|
110
113
|
<span class="flex gap-1 rounded bg-gray-300 p-1 dark:bg-gray-500">
|
|
111
114
|
<Icon icon={mdiArrowDown} size="1rem" />
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type CommandPaletteTranslations } from '../services/command-palette-manager.svelte.js';
|
|
2
|
+
import type { ActionItem } from '../types.js';
|
|
2
3
|
type Props = {
|
|
3
|
-
onClose: () => void;
|
|
4
|
+
onClose: (action?: ActionItem) => void;
|
|
4
5
|
translations?: CommandPaletteTranslations;
|
|
6
|
+
initialQuery?: string;
|
|
5
7
|
};
|
|
6
8
|
declare const CommandPaletteModal: import("svelte").Component<Props, {}, "">;
|
|
7
9
|
type CommandPaletteModal = ReturnType<typeof CommandPaletteModal>;
|
|
@@ -1,64 +1,20 @@
|
|
|
1
|
-
import type { ActionItem,
|
|
1
|
+
import type { ActionItem, MaybePromise, TranslationProps } from '../types.js';
|
|
2
2
|
export type CommandPaletteTranslations = TranslationProps<'search_placeholder' | 'search_no_results' | 'search_recently_used' | 'command_palette_prompt_default' | 'command_palette_to_select' | 'command_palette_to_close' | 'command_palette_to_navigate' | 'command_palette_to_show_all' | 'global'>;
|
|
3
|
-
export
|
|
3
|
+
export type ActionProvider = {
|
|
4
|
+
name: string;
|
|
5
|
+
onSearch: (query?: string) => MaybePromise<ActionItem[]>;
|
|
6
|
+
};
|
|
7
|
+
export declare const defaultProvider: ({ name, actions }: {
|
|
8
|
+
name: string;
|
|
9
|
+
actions: ActionItem[];
|
|
10
|
+
}) => {
|
|
11
|
+
name: string;
|
|
12
|
+
onSearch: (query?: string) => ActionItem[];
|
|
13
|
+
};
|
|
4
14
|
declare class CommandPaletteManager {
|
|
5
15
|
#private;
|
|
6
|
-
|
|
7
|
-
items: ({
|
|
8
|
-
title: string;
|
|
9
|
-
description?: string;
|
|
10
|
-
type?: string;
|
|
11
|
-
searchText?: string;
|
|
12
|
-
icon: import("../types.js").IconLike;
|
|
13
|
-
iconClass?: string;
|
|
14
|
-
color?: import("../types.js").Color;
|
|
15
|
-
onAction: import("../types.js").ActionItemHandler;
|
|
16
|
-
shortcuts?: MaybeArray<import("../actions/shortcut.js").Shortcut>;
|
|
17
|
-
shortcutOptions?: {
|
|
18
|
-
ignoreInputFields?: boolean;
|
|
19
|
-
preventDefault?: boolean;
|
|
20
|
-
};
|
|
21
|
-
isGlobal?: boolean;
|
|
22
|
-
} & import("../types.js").IfLike & {
|
|
23
|
-
id: string;
|
|
24
|
-
})[];
|
|
25
|
-
filteredItems: ({
|
|
26
|
-
title: string;
|
|
27
|
-
description?: string;
|
|
28
|
-
type?: string;
|
|
29
|
-
searchText?: string;
|
|
30
|
-
icon: import("../types.js").IconLike;
|
|
31
|
-
iconClass?: string;
|
|
32
|
-
color?: import("../types.js").Color;
|
|
33
|
-
onAction: import("../types.js").ActionItemHandler;
|
|
34
|
-
shortcuts?: MaybeArray<import("../actions/shortcut.js").Shortcut>;
|
|
35
|
-
shortcutOptions?: {
|
|
36
|
-
ignoreInputFields?: boolean;
|
|
37
|
-
preventDefault?: boolean;
|
|
38
|
-
};
|
|
39
|
-
isGlobal?: boolean;
|
|
40
|
-
} & import("../types.js").IfLike & {
|
|
41
|
-
id: string;
|
|
42
|
-
})[];
|
|
43
|
-
recentItems: ({
|
|
44
|
-
title: string;
|
|
45
|
-
description?: string;
|
|
46
|
-
type?: string;
|
|
47
|
-
searchText?: string;
|
|
48
|
-
icon: import("../types.js").IconLike;
|
|
49
|
-
iconClass?: string;
|
|
50
|
-
color?: import("../types.js").Color;
|
|
51
|
-
onAction: import("../types.js").ActionItemHandler;
|
|
52
|
-
shortcuts?: MaybeArray<import("../actions/shortcut.js").Shortcut>;
|
|
53
|
-
shortcutOptions?: {
|
|
54
|
-
ignoreInputFields?: boolean;
|
|
55
|
-
preventDefault?: boolean;
|
|
56
|
-
};
|
|
57
|
-
isGlobal?: boolean;
|
|
58
|
-
} & import("../types.js").IfLike & {
|
|
59
|
-
id: string;
|
|
60
|
-
})[];
|
|
61
|
-
results: ({
|
|
16
|
+
get isEnabled(): boolean;
|
|
17
|
+
get items(): ({
|
|
62
18
|
title: string;
|
|
63
19
|
description?: string;
|
|
64
20
|
type?: string;
|
|
@@ -67,7 +23,7 @@ declare class CommandPaletteManager {
|
|
|
67
23
|
iconClass?: string;
|
|
68
24
|
color?: import("../types.js").Color;
|
|
69
25
|
onAction: import("../types.js").ActionItemHandler;
|
|
70
|
-
shortcuts?: MaybeArray<import("../actions/shortcut.js").Shortcut>;
|
|
26
|
+
shortcuts?: import("../types.js").MaybeArray<import("../actions/shortcut.js").Shortcut>;
|
|
71
27
|
shortcutOptions?: {
|
|
72
28
|
ignoreInputFields?: boolean;
|
|
73
29
|
preventDefault?: boolean;
|
|
@@ -76,26 +32,12 @@ declare class CommandPaletteManager {
|
|
|
76
32
|
} & import("../types.js").IfLike & {
|
|
77
33
|
id: string;
|
|
78
34
|
})[];
|
|
79
|
-
get isEnabled(): boolean;
|
|
80
35
|
enable(): void;
|
|
81
|
-
get query(): string;
|
|
82
|
-
set query(query: string);
|
|
83
|
-
get isShowAll(): boolean;
|
|
84
|
-
get isEmpty(): boolean;
|
|
85
36
|
setTranslations(translations?: CommandPaletteTranslations): void;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
select(selectedIndex?: number): Promise<void>;
|
|
91
|
-
remove(index: number): void;
|
|
92
|
-
up(): void;
|
|
93
|
-
down(): void;
|
|
94
|
-
reset(): void;
|
|
95
|
-
addCommands(itemOrItems: MaybeArray<ActionItem>): () => void;
|
|
96
|
-
removeCommands(itemOrItems: MaybeArray<{
|
|
97
|
-
id: string;
|
|
98
|
-
}>): void;
|
|
37
|
+
queryUpdate(query: string): void;
|
|
38
|
+
open(initialQuery?: string): void;
|
|
39
|
+
loadAllItems(): void;
|
|
40
|
+
addProvider(provider: ActionProvider): () => void;
|
|
99
41
|
}
|
|
100
42
|
export declare const commandPaletteManager: CommandPaletteManager;
|
|
101
43
|
export {};
|
|
@@ -1,39 +1,23 @@
|
|
|
1
|
-
import { matchesShortcut, shortcuts
|
|
1
|
+
import { matchesShortcut, shortcuts } from '../actions/shortcut.js';
|
|
2
2
|
import CommandPaletteModal from '../internal/CommandPaletteModal.svelte';
|
|
3
|
-
import { generateId, isEnabled } from '../utilities/internal.js';
|
|
4
3
|
import { modalManager } from './modal-manager.svelte.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
.toLowerCase();
|
|
11
|
-
};
|
|
12
|
-
const isMatch = ({ title, description, type, searchText = asText(title, description, type) }, query) => {
|
|
13
|
-
if (!query) {
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
return searchText.includes(query);
|
|
17
|
-
};
|
|
4
|
+
import { asArray, generateId, getSearchString, isEnabled } from '../utilities/internal.js';
|
|
5
|
+
export const defaultProvider = ({ name, actions }) => ({
|
|
6
|
+
name,
|
|
7
|
+
onSearch: (query) => query ? actions.filter((action) => getSearchString(action).includes(query.toLowerCase())) : actions,
|
|
8
|
+
});
|
|
18
9
|
class CommandPaletteManager {
|
|
19
|
-
#query = $state('');
|
|
20
|
-
selectedIndex = $state(0);
|
|
21
|
-
#isEnabled = $state(false);
|
|
22
|
-
#normalizedQuery = $derived(this.#query.toLowerCase());
|
|
23
|
-
#modal;
|
|
24
10
|
#translations = {};
|
|
11
|
+
#providers = [];
|
|
12
|
+
#isEnabled = false;
|
|
25
13
|
#isOpen = false;
|
|
26
|
-
#
|
|
27
|
-
#globalLayer = $state({ items: [], recentItems: [] });
|
|
28
|
-
#layers = $state([{ items: [], recentItems: [] }]);
|
|
29
|
-
items = $derived([...this.#globalLayer.items, ...this.#layers.at(-1).items].filter(isEnabled));
|
|
30
|
-
filteredItems = $derived(this.items.filter((item) => isMatch(item, this.#normalizedQuery)).slice(0, 100));
|
|
31
|
-
recentItems = $derived([...this.#globalLayer.recentItems, ...this.#layers.at(-1).recentItems].filter(isEnabled));
|
|
32
|
-
results = $derived(this.#isShowAll ? this.items : this.#query ? this.filteredItems : this.recentItems);
|
|
33
|
-
#isEmpty = $derived(!this.#isShowAll && !this.#query && this.results.length === 0);
|
|
14
|
+
#items = $state([]);
|
|
34
15
|
get isEnabled() {
|
|
35
16
|
return this.#isEnabled;
|
|
36
17
|
}
|
|
18
|
+
get items() {
|
|
19
|
+
return this.#items;
|
|
20
|
+
}
|
|
37
21
|
enable() {
|
|
38
22
|
if (this.#isEnabled) {
|
|
39
23
|
return;
|
|
@@ -48,146 +32,54 @@ class CommandPaletteManager {
|
|
|
48
32
|
document.body.addEventListener('keydown', (event) => this.#handleKeydown(event));
|
|
49
33
|
}
|
|
50
34
|
}
|
|
51
|
-
get query() {
|
|
52
|
-
return this.#query;
|
|
53
|
-
}
|
|
54
|
-
set query(query) {
|
|
55
|
-
this.#query = query;
|
|
56
|
-
if (this.#isShowAll && query) {
|
|
57
|
-
this.#isShowAll = false;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
get isShowAll() {
|
|
61
|
-
return this.#isShowAll;
|
|
62
|
-
}
|
|
63
|
-
get isEmpty() {
|
|
64
|
-
return this.#isEmpty;
|
|
65
|
-
}
|
|
66
|
-
async #handleKeydown(event) {
|
|
67
|
-
const command = this.items.find(({ shortcuts }) => {
|
|
68
|
-
if (!shortcuts) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
if (shortcuts)
|
|
72
|
-
return Array.isArray(shortcuts)
|
|
73
|
-
? shortcuts.some((shortcut) => matchesShortcut(event, shortcut))
|
|
74
|
-
: matchesShortcut(event, shortcuts);
|
|
75
|
-
});
|
|
76
|
-
if (!command) {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
const { ignoreInputFields = true, preventDefault = true } = command.shortcutOptions ?? {};
|
|
80
|
-
if (ignoreInputFields && shouldIgnoreEvent(event)) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
if (preventDefault) {
|
|
84
|
-
event.preventDefault();
|
|
85
|
-
}
|
|
86
|
-
await command.onAction(command);
|
|
87
|
-
}
|
|
88
35
|
setTranslations(translations = {}) {
|
|
89
36
|
this.#translations = translations;
|
|
90
37
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
// we do not want the command palette to have its own context layer
|
|
96
|
-
if (this.#isOpen) {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
this.#layers.push({ items: [], recentItems: [] });
|
|
100
|
-
return () => this.popContextLayer();
|
|
101
|
-
}
|
|
102
|
-
popContextLayer() {
|
|
103
|
-
if (this.#layers.length > 1) {
|
|
104
|
-
this.#layers = this.#layers.slice(0, -1);
|
|
105
|
-
}
|
|
38
|
+
async #onSearch(query) {
|
|
39
|
+
const newItems = await Promise.all(this.#providers.map((provider) => Promise.resolve(provider.onSearch(query))));
|
|
40
|
+
this.#items = newItems.flat().map((item) => ({ ...item, id: generateId() }));
|
|
106
41
|
}
|
|
107
|
-
|
|
108
|
-
if (
|
|
42
|
+
queryUpdate(query) {
|
|
43
|
+
if (!query) {
|
|
44
|
+
this.#items = [];
|
|
109
45
|
return;
|
|
110
46
|
}
|
|
111
|
-
this
|
|
112
|
-
this.#isOpen = true;
|
|
113
|
-
const { close, onClose } = modalManager.open(CommandPaletteModal, { translations: this.#translations });
|
|
114
|
-
this.#modal = { close };
|
|
115
|
-
void onClose.then(() => this.#onClose());
|
|
47
|
+
void this.#onSearch(query);
|
|
116
48
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
49
|
+
async #handleKeydown(event) {
|
|
50
|
+
const actions = await Promise.all(this.#providers.map((provider) => Promise.resolve(provider.onSearch())));
|
|
51
|
+
for (const action of actions.flat()) {
|
|
52
|
+
const shortcuts = asArray(action.shortcuts);
|
|
53
|
+
if (shortcuts.some((shortcut) => matchesShortcut(event, shortcut)) && isEnabled(action)) {
|
|
54
|
+
action?.onAction(action);
|
|
55
|
+
}
|
|
120
56
|
}
|
|
121
|
-
return this.#modal.close();
|
|
122
57
|
}
|
|
123
|
-
#onClose() {
|
|
124
|
-
|
|
125
|
-
this.#modal = undefined;
|
|
58
|
+
async #onClose(action) {
|
|
59
|
+
await action?.onAction(action);
|
|
126
60
|
this.#isOpen = false;
|
|
127
|
-
this.#
|
|
128
|
-
}
|
|
129
|
-
async select(selectedIndex) {
|
|
130
|
-
const selected = this.results[selectedIndex ?? this.selectedIndex];
|
|
131
|
-
if (!selected) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
if (selected.isGlobal) {
|
|
135
|
-
this.#globalLayer.recentItems = this.#globalLayer.recentItems.filter(({ id }) => id !== selected.id);
|
|
136
|
-
this.#globalLayer.recentItems.unshift(selected);
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
this.#layers.at(-1).recentItems = this.#layers.at(-1).recentItems.filter(({ id }) => id !== selected.id);
|
|
140
|
-
this.#layers.at(-1)?.recentItems.unshift(selected);
|
|
141
|
-
}
|
|
142
|
-
await selected.onAction(selected);
|
|
143
|
-
await this.close();
|
|
144
|
-
}
|
|
145
|
-
remove(index) {
|
|
146
|
-
const item = this.recentItems.at(index);
|
|
147
|
-
if (!item) {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
this.#globalLayer.recentItems = this.#globalLayer.recentItems.filter(({ id }) => id !== item.id);
|
|
151
|
-
this.#layers.at(-1).recentItems = this.#layers.at(-1).recentItems.filter(({ id }) => id !== item.id);
|
|
61
|
+
this.#items = [];
|
|
152
62
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
156
|
-
down() {
|
|
157
|
-
if (this.#isEmpty) {
|
|
158
|
-
this.#isShowAll = true;
|
|
63
|
+
open(initialQuery) {
|
|
64
|
+
if (this.#isOpen) {
|
|
159
65
|
return;
|
|
160
66
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
this.#
|
|
166
|
-
this.#
|
|
67
|
+
const { onClose } = modalManager.open(CommandPaletteModal, {
|
|
68
|
+
translations: this.#translations,
|
|
69
|
+
initialQuery,
|
|
70
|
+
});
|
|
71
|
+
this.#isOpen = true;
|
|
72
|
+
void onClose.then((action) => this.#onClose(action));
|
|
167
73
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const itemsWithId = items.map((item) => ({
|
|
171
|
-
...item,
|
|
172
|
-
id: generateId(),
|
|
173
|
-
}));
|
|
174
|
-
const globalItems = itemsWithId.filter(({ isGlobal }) => isGlobal);
|
|
175
|
-
const localItems = itemsWithId.filter(({ isGlobal }) => !isGlobal);
|
|
176
|
-
this.#globalLayer.items.push(...globalItems);
|
|
177
|
-
this.#layers.at(-1).items.push(...localItems);
|
|
178
|
-
return () => this.removeCommands(itemsWithId);
|
|
74
|
+
loadAllItems() {
|
|
75
|
+
void this.#onSearch();
|
|
179
76
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
recentItems: layer.recentItems.filter(({ id }) => !ids[id]),
|
|
184
|
-
};
|
|
77
|
+
addProvider(provider) {
|
|
78
|
+
this.#providers.push(provider);
|
|
79
|
+
return () => this.#removeProvider(provider);
|
|
185
80
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const ids = items.reduce((acc, { id }) => ({ ...acc, [id]: true }), {});
|
|
189
|
-
this.#layers = this.#layers.map((layer) => this.#removeCommands(layer, ids));
|
|
190
|
-
this.#globalLayer = this.#removeCommands(this.#globalLayer, ids);
|
|
81
|
+
#removeProvider(provider) {
|
|
82
|
+
this.#providers = this.#providers.filter((actionProvider) => actionProvider !== provider);
|
|
191
83
|
}
|
|
192
84
|
}
|
|
193
85
|
export const commandPaletteManager = new CommandPaletteManager();
|
|
@@ -31,6 +31,9 @@
|
|
|
31
31
|
<SiteFooterLink href={Constants.Sites.Docs} text="Documentation" />
|
|
32
32
|
<SiteFooterLink href={Constants.Sites.My} text="My Immich" />
|
|
33
33
|
<SiteFooterLink href={Constants.Sites.Api} text="Immich API" />
|
|
34
|
+
<SiteFooterLink href={Constants.Sites.Data} text="Immich Data" />
|
|
35
|
+
<SiteFooterLink href={Constants.Sites.Datasets} text="Immich Datasets" />
|
|
36
|
+
<SiteFooterLink href={Constants.Sites.Awesome} text="Awesome Immich" />
|
|
34
37
|
</Stack>
|
|
35
38
|
|
|
36
39
|
<Stack>
|
package/dist/site/constants.d.ts
CHANGED
package/dist/site/constants.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { goto } from '$app/navigation';
|
|
2
|
-
import { asText } from '../
|
|
2
|
+
import { asText } from '../utilities/common.js';
|
|
3
3
|
import { mdiOpenInNew } from '@mdi/js';
|
|
4
4
|
export const Constants = {
|
|
5
5
|
Socials: {
|
|
@@ -29,6 +29,7 @@ export const Constants = {
|
|
|
29
29
|
Get: 'https://get.immich.app/',
|
|
30
30
|
My: 'https://my.immich.app/',
|
|
31
31
|
Store: 'https://immich.store/',
|
|
32
|
+
Awesome: 'https://awesome.immich.app/',
|
|
32
33
|
Ui: 'https://ui.immich.app/',
|
|
33
34
|
},
|
|
34
35
|
Pages: {
|
package/dist/types.d.ts
CHANGED
package/dist/utilities/common.js
CHANGED
|
@@ -60,3 +60,10 @@ export const resolveMetadata = (site, page, article) => {
|
|
|
60
60
|
: undefined,
|
|
61
61
|
};
|
|
62
62
|
};
|
|
63
|
+
export const asText = (...items) => {
|
|
64
|
+
return items
|
|
65
|
+
.filter((item) => item !== undefined && item !== null)
|
|
66
|
+
.map((items) => String(items))
|
|
67
|
+
.join('|')
|
|
68
|
+
.toLowerCase();
|
|
69
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Color, IconLike, IfLike, TextColor } from '../types.js';
|
|
1
|
+
import type { ActionItem, Color, IconLike, IfLike, MaybeArray, TextColor } from '../types.js';
|
|
2
2
|
export declare const cleanClass: (...classNames: unknown[]) => string;
|
|
3
3
|
export declare const withPrefix: (key: string) => string;
|
|
4
4
|
export declare const generateId: () => string;
|
|
@@ -10,3 +10,5 @@ export declare const resolveIcon: ({ icons, color, override, fallback, }: {
|
|
|
10
10
|
icons: Partial<Record<Color | TextColor, string>>;
|
|
11
11
|
}) => IconLike | undefined;
|
|
12
12
|
export declare const isEnabled: ({ $if }: IfLike) => boolean;
|
|
13
|
+
export declare const asArray: <T>(items?: MaybeArray<T>) => T[];
|
|
14
|
+
export declare const getSearchString: ({ title, description, type, searchText }: ActionItem) => string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { asText } from './common.js';
|
|
1
2
|
import { twMerge } from 'tailwind-merge';
|
|
2
3
|
export const cleanClass = (...classNames) => {
|
|
3
4
|
return twMerge(classNames
|
|
@@ -25,3 +26,5 @@ export const resolveIcon = ({ icons, color, override, fallback, }) => {
|
|
|
25
26
|
return icons[color] ?? fallback;
|
|
26
27
|
};
|
|
27
28
|
export const isEnabled = ({ $if }) => $if?.() ?? true;
|
|
29
|
+
export const asArray = (items) => (Array.isArray(items) ? items : items ? [items] : []);
|
|
30
|
+
export const getSearchString = ({ title, description, type, searchText }) => searchText ?? asText(title, description, type);
|
package/package.json
CHANGED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { commandPaletteManager } from '../../services/command-palette-manager.svelte';
|
|
3
|
-
import type { ActionItem } from '../../types.js';
|
|
4
|
-
import { untrack } from 'svelte';
|
|
5
|
-
|
|
6
|
-
type Props = {
|
|
7
|
-
commands?: ActionItem[];
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const { commands = [] }: Props = $props();
|
|
11
|
-
|
|
12
|
-
$effect(() => {
|
|
13
|
-
// prevent reactivity loop
|
|
14
|
-
const addCommands = (commands: ActionItem[]) => untrack(() => commandPaletteManager.addCommands(commands));
|
|
15
|
-
|
|
16
|
-
return addCommands(commands);
|
|
17
|
-
});
|
|
18
|
-
</script>
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { ActionItem } from '../../types.js';
|
|
2
|
-
type Props = {
|
|
3
|
-
commands?: ActionItem[];
|
|
4
|
-
};
|
|
5
|
-
declare const CommandPaletteContext: import("svelte").Component<Props, {}, "">;
|
|
6
|
-
type CommandPaletteContext = ReturnType<typeof CommandPaletteContext>;
|
|
7
|
-
export default CommandPaletteContext;
|